mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
refactor: update the variable interfaces. (#8388)
This commit is contained in:
@@ -4,8 +4,7 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import {IVariableModel} from './i_variable_model.js';
|
||||
import {State} from '../serialization/variables.js';
|
||||
import type {IVariableModel, IVariableState} from './i_variable_model.js';
|
||||
|
||||
/**
|
||||
* Variable maps are container objects responsible for storing and managing the
|
||||
@@ -14,7 +13,7 @@ import {State} from '../serialization/variables.js';
|
||||
* Any of these methods may define invariants about which names and types are
|
||||
* legal, and throw if they are not met.
|
||||
*/
|
||||
export interface IVariableMap<T extends IVariableModel, U extends State> {
|
||||
export interface IVariableMap<T extends IVariableModel<IVariableState>> {
|
||||
/* Returns the variable corresponding to the given ID, or null if none. */
|
||||
getVariableById(id: string): T | null;
|
||||
|
||||
@@ -46,6 +45,9 @@ export interface IVariableMap<T extends IVariableModel, U extends State> {
|
||||
*/
|
||||
createVariable(name: string, id?: string, type?: string | null): T;
|
||||
|
||||
/* Adds a variable to this variable map. */
|
||||
addVariable(variable: T): void;
|
||||
|
||||
/**
|
||||
* Changes the name of the given variable to the name provided and returns the
|
||||
* renamed variable.
|
||||
@@ -60,13 +62,4 @@ export interface IVariableMap<T extends IVariableModel, U extends State> {
|
||||
|
||||
/* Removes all variables from this variable map. */
|
||||
clear(): void;
|
||||
|
||||
/* Returns an object representing the serialized state of the variable. */
|
||||
saveVariable(variable: T): U;
|
||||
|
||||
/**
|
||||
* Creates a variable in this variable map corresponding to the given state
|
||||
* (produced by a call to `saveVariable`).
|
||||
*/
|
||||
loadVariable(state: U): T;
|
||||
}
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
import type {Workspace} from '../workspace.js';
|
||||
|
||||
/* Representation of a variable. */
|
||||
export interface IVariableModel {
|
||||
export interface IVariableModel<T extends IVariableState> {
|
||||
/* Returns the unique ID of this variable. */
|
||||
getId(): string;
|
||||
|
||||
@@ -23,4 +25,33 @@ export interface IVariableModel {
|
||||
|
||||
/* Sets the type of this variable. */
|
||||
setType(type: string): this;
|
||||
|
||||
getWorkspace(): Workspace;
|
||||
|
||||
/* Serializes this variable */
|
||||
save(): T;
|
||||
}
|
||||
|
||||
export interface IVariableModelStatic<T extends IVariableState> {
|
||||
new (
|
||||
workspace: Workspace,
|
||||
name: string,
|
||||
type?: string,
|
||||
id?: string,
|
||||
): IVariableModel<T>;
|
||||
|
||||
/**
|
||||
* Creates a new IVariableModel corresponding to the given state on the
|
||||
* specified workspace. This method must be static in your implementation.
|
||||
*/
|
||||
load(state: T, workspace: Workspace): IVariableModel<T>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the state of a given variable.
|
||||
*/
|
||||
export interface IVariableState {
|
||||
name: string;
|
||||
id: string;
|
||||
type?: string;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,12 @@ import type {IPaster} from './interfaces/i_paster.js';
|
||||
import type {ICopyData, ICopyable} from './interfaces/i_copyable.js';
|
||||
import type {IConnectionPreviewer} from './interfaces/i_connection_previewer.js';
|
||||
import type {IDragger} from './interfaces/i_dragger.js';
|
||||
import type {
|
||||
IVariableModel,
|
||||
IVariableModelStatic,
|
||||
IVariableState,
|
||||
} from './interfaces/i_variable_model.js';
|
||||
import type {IVariableMap} from './interfaces/i_variable_map.js';
|
||||
|
||||
/**
|
||||
* A map of maps. With the keys being the type and name of the class we are
|
||||
@@ -109,6 +115,14 @@ export class Type<_T> {
|
||||
|
||||
/** @internal */
|
||||
static PASTER = new Type<IPaster<ICopyData, ICopyable<ICopyData>>>('paster');
|
||||
|
||||
static VARIABLE_MODEL = new Type<IVariableModelStatic<IVariableState>>(
|
||||
'variableModel',
|
||||
);
|
||||
|
||||
static VARIABLE_MAP = new Type<IVariableMap<IVariableModel<IVariableState>>>(
|
||||
'variableMap',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,20 +7,13 @@
|
||||
// Former goog.module ID: Blockly.serialization.variables
|
||||
|
||||
import type {ISerializer} from '../interfaces/i_serializer.js';
|
||||
import type {IVariableState} from '../interfaces/i_variable_model.js';
|
||||
import type {Workspace} from '../workspace.js';
|
||||
|
||||
import * as priorities from './priorities.js';
|
||||
import * as registry from '../registry.js';
|
||||
import * as serializationRegistry from './registry.js';
|
||||
|
||||
/**
|
||||
* Represents the state of a given variable.
|
||||
*/
|
||||
export interface State {
|
||||
name: string;
|
||||
id: string;
|
||||
type: string | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializer for saving and loading variable state.
|
||||
*/
|
||||
@@ -40,23 +33,9 @@ export class VariableSerializer implements ISerializer {
|
||||
* @returns The state of the workspace's variables, or null if there are no
|
||||
* variables.
|
||||
*/
|
||||
save(workspace: Workspace): State[] | null {
|
||||
const variableStates = [];
|
||||
for (const variable of workspace.getAllVariables()) {
|
||||
const state = {
|
||||
'name': variable.name,
|
||||
'id': variable.getId(),
|
||||
};
|
||||
if (variable.type) {
|
||||
(state as AnyDuringMigration)['type'] = variable.type;
|
||||
}
|
||||
variableStates.push(state);
|
||||
}
|
||||
// AnyDuringMigration because: Type '{ name: string; id: string; }[] |
|
||||
// null' is not assignable to type 'State[] | null'.
|
||||
return (
|
||||
variableStates.length ? variableStates : null
|
||||
) as AnyDuringMigration;
|
||||
save(workspace: Workspace): IVariableState[] | null {
|
||||
const variableStates = workspace.getAllVariables().map((v) => v.save());
|
||||
return variableStates.length ? variableStates : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,14 +45,14 @@ export class VariableSerializer implements ISerializer {
|
||||
* @param state The state of the variables to deserialize.
|
||||
* @param workspace The workspace to deserialize into.
|
||||
*/
|
||||
load(state: State[], workspace: Workspace) {
|
||||
for (const varState of state) {
|
||||
workspace.createVariable(
|
||||
varState['name'],
|
||||
varState['type'],
|
||||
varState['id'],
|
||||
);
|
||||
}
|
||||
load(state: IVariableState[], workspace: Workspace) {
|
||||
const VariableModel = registry.getObject(
|
||||
registry.Type.VARIABLE_MODEL,
|
||||
registry.DEFAULT,
|
||||
);
|
||||
state.forEach((s) => {
|
||||
VariableModel?.load(s, workspace);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -15,8 +15,9 @@
|
||||
import './events/events_var_create.js';
|
||||
|
||||
import * as idGenerator from './utils/idgenerator.js';
|
||||
import * as registry from './registry.js';
|
||||
import type {Workspace} from './workspace.js';
|
||||
import {IVariableModel} from './interfaces/i_variable_model.js';
|
||||
import {IVariableModel, IVariableState} from './interfaces/i_variable_model.js';
|
||||
|
||||
/**
|
||||
* Class for a variable model.
|
||||
@@ -24,7 +25,7 @@ import {IVariableModel} from './interfaces/i_variable_model.js';
|
||||
*
|
||||
* @see {Blockly.FieldVariable}
|
||||
*/
|
||||
export class VariableModel implements IVariableModel {
|
||||
export class VariableModel implements IVariableModel<IVariableState> {
|
||||
type: string;
|
||||
private readonly id_: string;
|
||||
|
||||
@@ -95,6 +96,30 @@ export class VariableModel implements IVariableModel {
|
||||
return this;
|
||||
}
|
||||
|
||||
getWorkspace(): Workspace {
|
||||
return this.workspace;
|
||||
}
|
||||
|
||||
save(): IVariableState {
|
||||
const state: IVariableState = {
|
||||
'name': this.getName(),
|
||||
'id': this.getId(),
|
||||
};
|
||||
const type = this.getType();
|
||||
if (type) {
|
||||
state['type'] = type;
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static load(state: IVariableState, workspace: Workspace) {
|
||||
// TODO(adodson): Once VariableMap implements IVariableMap, directly
|
||||
// construct a variable, retrieve the variable map from the workspace,
|
||||
// add the variable to that variable map, and fire a VAR_CREATE event.
|
||||
workspace.createVariable(state['name'], state['type'], state['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom compare function for the VariableModel objects.
|
||||
*
|
||||
@@ -108,3 +133,9 @@ export class VariableModel implements IVariableModel {
|
||||
return var1.name.localeCompare(var2.name, undefined, {sensitivity: 'base'});
|
||||
}
|
||||
}
|
||||
|
||||
registry.register(
|
||||
registry.Type.VARIABLE_MODEL,
|
||||
registry.DEFAULT,
|
||||
VariableModel,
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user