Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add basic observable implementations of procedure interfaces #6489

Merged
Merged
59 changes: 59 additions & 0 deletions core/procedures/observable_parameter_model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import type {IParameterModel} from '../interfaces/i_parameter_model.js';
import {genUid} from '../utils/idgenerator.js';
import type {VariableModel} from '../variable_model.js';
import type {Workspace} from '../workspace.js';


export class ObservableParameterModel implements IParameterModel {
private id: string;
private variable: VariableModel;

constructor(
private readonly workspace: Workspace, name: string, id?: string) {
this.id = id ?? genUid();
this.variable = workspace.createVariable(name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this try .getVariable(name) first, like setName does? And is there a way of doing that by calling setName—i.e., can tsc infer (or be made to infer) that setName does the initialisation on behalf of the constructor?

(Aside: the latter is the sort of thing I bet Ezno can handle no problem, no special annotation required…)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will look into this.

}

/**
* Sets the name of this parameter to the given name.
*/
setName(name: string): this {
if (name == this.variable.name) return this;
this.variable =
this.workspace.getVariable(name) ?? this.workspace.createVariable(name);
return this;
}

/**
* Unimplemented. The built-in ParameterModel does not support typing.
* If you want your procedure blocks to have typed parameters, you need to
* implement your own ParameterModel.
*/
setTypes(_types: string[]): this {
console.warn(
'The built-in ParameterModel does not support typing. You need to ' +
'implement your own custom ParameterModel.');
cpcallen marked this conversation as resolved.
Show resolved Hide resolved
BeksOmega marked this conversation as resolved.
Show resolved Hide resolved
return this;
}

/**
* Returns the unique language-neutral ID for the parameter.
*
* This represents the identify of the variable model which does not change
* over time.
*/
getId(): string {
return this.id;
}

/** Returns the variable model associated with the parameter model. */
getVariableModel(): VariableModel {
return this.variable;
}
}
50 changes: 50 additions & 0 deletions core/procedures/observable_procedure_map.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import type {IProcedureModel} from '../interfaces/i_procedure_model.js';
import type {Workspace} from '../workspace.js';


export class ObservableProcedureMap extends Map<string, IProcedureModel> {
constructor(private readonly workspace: Workspace) {
BeksOmega marked this conversation as resolved.
Show resolved Hide resolved
super();
}

/**
* Adds the given procedure model to the procedure map.
*/
override set(id: string, proc: IProcedureModel): this {
// TODO(#6156): Fire events.
super.set(id, proc);
return this;
}

/**
* Deletes the ProcedureModel with the given ID from the procedure map (if it
* exists).
*/
override delete(id: string): boolean {
// TODO(#6156): Fire events.
return super.delete(id);
}

/**
* Removes all ProcedureModels from the procedure map.
*/
override clear() {
// TODO(#6156): Fire events.
super.clear();
}

/**
* Adds the given ProcedureModel to the map of procedure models, so that
* blocks can find it.
*/
add(proc: IProcedureModel): this {
// TODO(#6156): Fire events.
return this.set(proc.getId(), proc);
}
cpcallen marked this conversation as resolved.
Show resolved Hide resolved
}
101 changes: 101 additions & 0 deletions core/procedures/observable_procedure_model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/

import type {IParameterModel} from '../interfaces/i_parameter_model.js';
import type {IProcedureModel} from '../interfaces/i_procedure_model.js';
import type {Workspace} from '../workspace.js';
import {genUid} from '../utils/idgenerator.js';


export class ObservableProcedureModel implements IProcedureModel {
private id: string;
private name = '';
private parameters: IParameterModel[] = [];
private returnTypes: string[]|null = null;
private enabled = true;

constructor(private readonly workspace: Workspace, id?: string) {
this.id = id ?? genUid();
}

/** Sets the human-readable name of the procedure. */
setName(name: string): this {
this.name = name;
return this;
}

/**
* Inserts a parameter into the list of parameters.
*
* To move a parameter, first delete it, and then re-insert.
*/
insertParameter(parameterModel: IParameterModel, index: number): this {
this.parameters.splice(index, 0, parameterModel);
return this;
}

/** Removes the parameter at the given index from the parameter list. */
deleteParameter(index: number): this {
this.parameters.splice(index, 1);
return this;
}

/**
* Sets the return type(s) of the procedure.
*
* Pass null to represent a procedure that does not return.
*/
setReturnTypes(types: string[]|null): this {
this.returnTypes = types;
return this;
}

/**
* Sets whether this procedure is enabled/disabled. If a procedure is disabled
* all procedure caller blocks should be disabled as well.
*/
setEnabled(enabled: boolean): this {
this.enabled = enabled;
return this;
}

/** Returns the unique language-neutral ID for the procedure. */
getId(): string {
return this.id;
}

/** Returns the human-readable name of the procedure. */
getName(): string {
return this.name;
}

/** Returns the parameter at the given index in the parameter list. */
getParameter(index: number): IParameterModel {
return this.parameters[index];
}

/** Returns an array of all of the parameters in the parameter list. */
getParameters(): IParameterModel[] {
return [...this.parameters];
}

/**
* Returns the return type of the procedure.
*
* Null represents a procedure that does not return a value.
*/
getReturnTypes(): string[]|null {
return this.returnTypes;
}

/**
* Returns whether the procedure is enabled/disabled. If a procedure is
* disabled, all procedure caller blocks should be disabled as well.
*/
getEnabled(): boolean {
return this.enabled;
}
}