Skip to content

Commit

Permalink
feat: 实践命令插件的开发
Browse files Browse the repository at this point in the history
  • Loading branch information
JessYan0913 committed Jul 27, 2023
1 parent 0576e6e commit ede4b10
Show file tree
Hide file tree
Showing 8 changed files with 51 additions and 43 deletions.
1 change: 1 addition & 0 deletions main/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default defineConfig(({ mode }) => {
{ find: '@', replacement: r('./src') },
{ find: /^@pictode\/utils/, replacement: join(__dirname, '../packages/utils/src/index.ts') },
{ find: /^@pictode\/core/, replacement: join(__dirname, '../packages/core/src/index.ts') },
{ find: /^@pictode\/plugin-history/, replacement: join(__dirname, '../packages/plugin-history/src/index.ts') },
{ find: 'vue', replacement: join(__dirname, './node_modules/vue/dist/vue.esm-bundler.js') },
],
},
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from 'fabric';
export * from './app';
export * from './types';
export * from './decorators/expand-app';
Expand Down
1 change: 1 addition & 0 deletions packages/plugin-history/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@pictode/core": "workspace:^0.0.1",
"@pictode/utils": "workspace:^0.0.1",
"dot": "2.0.0-beta.1",
"fabric": "^6.0.0-beta9",
"rimraf": "^3.0.2",
"roughjs": "^4.5.2"
},
Expand Down
25 changes: 25 additions & 0 deletions packages/plugin-history/src/commands/add-object-cmd.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { App } from '@pictode/core';

import { Cmd } from '../types';

import { BaseCmd } from './base';

export class AddObjectCmd extends BaseCmd<Cmd.AddObjectOptions> {
constructor(app: App, options: Cmd.AddObjectOptions) {
super(app, options);
}

public execute(): void {
if (this.options?.object && this.app) {
this.app.canvas.add(this.options.object);
}
}

public undo(): void {
if (this.options?.object && this.app) {
this.app.canvas.remove(this.options.object);
}
}
}

export default AddObjectCmd;
1 change: 1 addition & 0 deletions packages/plugin-history/src/commands/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './add-object-cmd';
57 changes: 14 additions & 43 deletions packages/plugin-history/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { App, Plugin } from '@pictode/core';
import { isSubclass } from '@pictode/utils';

import './methods';

import { BaseCmd } from './commands/base';
import { CmdNotOptionsError, CmdNotRegisterError } from './errors';
import { AddObjectCmd } from './commands';
import { Cmd, Options } from './types';

export type CommandClass<T extends BaseCmd = BaseCmd, O extends Cmd.Options = Cmd.Options> = new (
Expand Down Expand Up @@ -33,53 +32,20 @@ export class History implements Plugin {
this.stackSize = size;
}

public registerCommands<T extends BaseCmd>(commandClasses: CommandClass<T> | Array<CommandClass<T>>): void {
if (!Array.isArray(commandClasses)) {
commandClasses = [commandClasses];
}
commandClasses.forEach((commandClass) => {
if (isSubclass(commandClass, BaseCmd)) {
this.commands[commandClass.name] = commandClass;
}
});
}

public getCommandClass(command: BaseCmd | string): CommandClass {
let result: CommandClass;
if (command instanceof BaseCmd) {
result = this.commands[command.name];
} else {
result = this.commands[command];
}
if (!result) {
throw new CmdNotRegisterError(command);
}
return result;
}

public execute<T extends Cmd.Options>(command: BaseCmd | string, options?: T): void {
let executeCommand: BaseCmd;
const Command = this.getCommandClass(command);
if (command instanceof BaseCmd) {
executeCommand = command;
} else {
if (!options) {
throw new CmdNotOptionsError(command);
}
executeCommand = new Command(this.app, options);
}

public execute(command: BaseCmd, needExecute?: boolean): void {
// 如果命令栈中的命令长度已经超出了最大栈长,则将最早的命令清除
if (this.undoStack.length > this.stackSize) {
this.undoStack.shift();
}

this.undoStack.push(executeCommand);
executeCommand.id = ++this.idCounter;
this.undoStack.push(command);
command.id = ++this.idCounter;

executeCommand.execute();
executeCommand.executed = true;
executeCommand.executeTime = new Date().getTime();
if (needExecute) {
command.execute();
}
command.executed = true;
command.executeTime = new Date().getTime();
this.redoStack = [];
this.app?.emit('stack:changed', {
undoStack: this.undoStack,
Expand Down Expand Up @@ -183,6 +149,11 @@ export class History implements Plugin {

public install(app: App) {
this.app = app;
this.app.canvas.on('object:added', ({ target }) => {
if (this.app) {
this.execute(new AddObjectCmd(this.app, { object: target }));
}
});
}

public dispose(): void {
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-history/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Object as FabricObject } from '@pictode/core';

import { BaseCmd } from './commands/base';
import { CommandClass, History } from './index';

Expand Down Expand Up @@ -32,6 +34,10 @@ export namespace Cmd {
export interface Options {
[key: string]: any;
}

export interface AddObjectOptions {
object: FabricObject;
}
}

export interface Options {
Expand Down
2 changes: 2 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit ede4b10

Please sign in to comment.