diff --git a/core/procedures/observable_parameter_model.ts b/core/procedures/observable_parameter_model.ts new file mode 100644 index 00000000000..4c74a05056a --- /dev/null +++ b/core/procedures/observable_parameter_model.ts @@ -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); + } + + /** + * 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.'); + 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; + } +} diff --git a/core/procedures/observable_procedure_map.ts b/core/procedures/observable_procedure_map.ts new file mode 100644 index 00000000000..db5edfe68d9 --- /dev/null +++ b/core/procedures/observable_procedure_map.ts @@ -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 { + constructor(private readonly workspace: Workspace) { + 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); + } +} diff --git a/core/procedures/observable_procedure_model.ts b/core/procedures/observable_procedure_model.ts new file mode 100644 index 00000000000..335667ab9d2 --- /dev/null +++ b/core/procedures/observable_procedure_model.ts @@ -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; + } +}