图形模板对象调整(添加数据模板和状态模板)

This commit is contained in:
walker 2023-06-20 11:03:15 +08:00
parent 6d905a2fbe
commit 33ac26a825
14 changed files with 365 additions and 46 deletions

View File

@ -0,0 +1,14 @@
syntax = "proto3";
package graphicStates;
//
message CommonState {
string code = 1;
string graphicType = 2;
}
message IscsFan {
CommonState common = 1;
int32 state = 2;
}

View File

@ -2,12 +2,14 @@ import * as pb_1 from 'google-protobuf';
import { import {
ChildTransform, ChildTransform,
GraphicData, GraphicData,
GraphicState,
GraphicTransform, GraphicTransform,
IChildTransform, IChildTransform,
IGraphicTransform, IGraphicTransform,
} from 'src/jlgraphic'; } from 'src/jlgraphic';
import { toStorageTransform } from '..'; import { toStorageTransform } from '..';
import { graphicData } from '../protos/draw_data_storage'; import { graphicData } from '../protos/draw_data_storage';
import { graphicStates } from '../protos/graphic_states';
export interface ICommonInfo { export interface ICommonInfo {
id: string; id: string;
@ -99,3 +101,41 @@ export abstract class GraphicDataBase implements GraphicData {
return pb_1.Message.equals(this._data, other._data); return pb_1.Message.equals(this._data, other._data);
} }
} }
export interface IProtoGraphicState extends pb_1.Message {
common: graphicStates.CommonState;
}
export abstract class GraphicStateBase implements GraphicState {
_state: IProtoGraphicState;
constructor(state: IProtoGraphicState) {
this._state = state;
}
static defaultCommonState(graphicType: string): graphicStates.CommonState {
return new graphicStates.CommonState({
code: '',
graphicType: graphicType,
});
}
getState<S extends IProtoGraphicState>(): S {
return this._state as S;
}
get code(): string {
return this._state.common.code;
}
get graphicType(): string {
return this._state.common.graphicType;
}
clone(): GraphicState {
throw new Error('Method not implemented.');
}
copyFrom(data: GraphicStateBase): void {
pb_1.Message.copyInto(data._state, this._state);
}
eq(data: GraphicStateBase): boolean {
return pb_1.Message.equals(this._state, data._state);
}
}

View File

@ -1,7 +1,12 @@
import * as pb_1 from 'google-protobuf'; import * as pb_1 from 'google-protobuf';
import { IIscsFanData } from 'src/graphics/iscs-fan/IscsFan'; import {
IIscsFanData,
IIscsFanState,
IscsFan,
} from 'src/graphics/iscs-fan/IscsFan';
import { graphicData } from '../protos/draw_data_storage'; import { graphicData } from '../protos/draw_data_storage';
import { GraphicDataBase } from './GraphicDataBase'; import { graphicStates } from '../protos/graphic_states';
import { GraphicDataBase, GraphicStateBase } from './GraphicDataBase';
export class IscsFanData extends GraphicDataBase implements IIscsFanData { export class IscsFanData extends GraphicDataBase implements IIscsFanData {
constructor(data?: graphicData.IscsFan) { constructor(data?: graphicData.IscsFan) {
@ -10,7 +15,7 @@ export class IscsFanData extends GraphicDataBase implements IIscsFanData {
fan = data; fan = data;
} else { } else {
fan = new graphicData.IscsFan({ fan = new graphicData.IscsFan({
common: GraphicDataBase.defaultCommonInfo(), common: GraphicDataBase.defaultCommonInfo(IscsFan.Type),
}); });
} }
super(fan); super(fan);
@ -36,3 +41,31 @@ export class IscsFanData extends GraphicDataBase implements IIscsFanData {
return pb_1.Message.equals(this.data, other.data); return pb_1.Message.equals(this.data, other.data);
} }
} }
export class IscsFanState extends GraphicStateBase implements IIscsFanState {
constructor(proto?: graphicStates.IscsFan) {
let states;
if (proto) {
states = proto;
} else {
states = new graphicStates.IscsFan({
common: GraphicStateBase.defaultCommonState(IscsFan.Type),
});
}
super(states);
}
get states(): graphicStates.IscsFan {
return this.getState<graphicStates.IscsFan>();
}
get state(): number {
return this.states.state;
}
set state(v: number) {
this.states.state = v;
}
clone(): IscsFanState {
return new IscsFanState(this.states.cloneMessage());
}
}

View File

@ -1,8 +1,8 @@
import { fromUint8Array, toUint8Array } from 'js-base64'; import { fromUint8Array, toUint8Array } from 'js-base64';
import { IPointData, Point } from 'pixi.js'; import { IPointData, Point } from 'pixi.js';
import { IscsFan } from 'src/graphics/iscs-fan/IscsFan'; import { IscsFan, IscsFanTemplate } from 'src/graphics/iscs-fan/IscsFan';
import { IscsFanDraw } from 'src/graphics/iscs-fan/IscsFanDrawAssistant'; import { IscsFanDraw } from 'src/graphics/iscs-fan/IscsFanDrawAssistant';
import { Link } from 'src/graphics/link/Link'; import { Link, LinkTemplate } from 'src/graphics/link/Link';
import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant'; import { LinkDraw } from 'src/graphics/link/LinkDrawAssistant';
import { Rect } from 'src/graphics/rect/Rect'; import { Rect } from 'src/graphics/rect/Rect';
import { RectDraw } from 'src/graphics/rect/RectDrawAssistant'; import { RectDraw } from 'src/graphics/rect/RectDrawAssistant';
@ -11,7 +11,7 @@ import { PlatformDraw } from 'src/graphics/platform/PlatformDrawAssistant';
import { Station } from 'src/graphics/station/Station'; import { Station } from 'src/graphics/station/Station';
import { Train } from 'src/graphics/train/Train'; import { Train } from 'src/graphics/train/Train';
import { StationDraw } from 'src/graphics/station/StationDrawAssistant'; import { StationDraw } from 'src/graphics/station/StationDrawAssistant';
import { Signal } from 'src/graphics/signal/Signal'; import { Signal, SignalTemplate } from 'src/graphics/signal/Signal';
import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant'; import { SignalDraw } from 'src/graphics/signal/SignalDrawAssistant';
import { TrainDraw } from 'src/graphics/train/TrainDrawAssistant'; import { TrainDraw } from 'src/graphics/train/TrainDrawAssistant';
import { import {
@ -24,7 +24,7 @@ import {
} from 'src/jlgraphic'; } from 'src/jlgraphic';
import { ContextMenu } from 'src/jlgraphic/ui/ContextMenu'; import { ContextMenu } from 'src/jlgraphic/ui/ContextMenu';
import { MenuItemOptions } from 'src/jlgraphic/ui/Menu'; import { MenuItemOptions } from 'src/jlgraphic/ui/Menu';
import { IscsFanData } from './graphics/IscsFanInteraction'; import { IscsFanData, IscsFanState } from './graphics/IscsFanInteraction';
import { LinkData } from './graphics/LinkInteraction'; import { LinkData } from './graphics/LinkInteraction';
import { RectData } from './graphics/RectInteraction'; import { RectData } from './graphics/RectInteraction';
import { PlatformData } from './graphics/PlatformInteraction'; import { PlatformData } from './graphics/PlatformInteraction';
@ -103,15 +103,12 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
const app = drawApp; const app = drawApp;
app.setOptions({ app.setOptions({
drawAssistants: [ drawAssistants: [
new LinkDraw(app, () => { new LinkDraw(app, new LinkTemplate(new LinkData())),
return new LinkData(); new IscsFanDraw(
}), app,
new IscsFanDraw(app, () => { new IscsFanTemplate(new IscsFanData(), new IscsFanState())
return new IscsFanData(); ),
}), new SignalDraw(app, new SignalTemplate(new SignalData())),
new SignalDraw(app, () => {
return new SignalData();
}),
new TrainDraw(app, () => { new TrainDraw(app, () => {
return new TrainData(); return new TrainData();
}), }),
@ -197,8 +194,8 @@ export function initDrawApp(dom: HTMLElement): JlDrawApp {
value: '1', value: '1',
onPress: () => { onPress: () => {
app.queryStore.queryByType<IscsFan>(IscsFan.Type).forEach((fan) => { app.queryStore.queryByType<IscsFan>(IscsFan.Type).forEach((fan) => {
fan.__state = fan.__state + 1; fan.states.state = fan.states.state + 1;
fan.__state = fan.__state % 5; fan.states.state = fan.states.state % 5;
fan.repaint(); fan.repaint();
}); });
}, },

View File

@ -0,0 +1,191 @@
/**
* Generated by the protoc-gen-ts. DO NOT EDIT!
* compiler version: 4.22.2
* source: graphic_states.proto
* git: https://github.com/thesayyn/protoc-gen-ts */
import * as pb_1 from "google-protobuf";
export namespace graphicStates {
export class CommonState extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
code?: string;
graphicType?: string;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("code" in data && data.code != undefined) {
this.code = data.code;
}
if ("graphicType" in data && data.graphicType != undefined) {
this.graphicType = data.graphicType;
}
}
}
get code() {
return pb_1.Message.getFieldWithDefault(this, 1, "") as string;
}
set code(value: string) {
pb_1.Message.setField(this, 1, value);
}
get graphicType() {
return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
}
set graphicType(value: string) {
pb_1.Message.setField(this, 2, value);
}
static fromObject(data: {
code?: string;
graphicType?: string;
}): CommonState {
const message = new CommonState({});
if (data.code != null) {
message.code = data.code;
}
if (data.graphicType != null) {
message.graphicType = data.graphicType;
}
return message;
}
toObject() {
const data: {
code?: string;
graphicType?: string;
} = {};
if (this.code != null) {
data.code = this.code;
}
if (this.graphicType != null) {
data.graphicType = this.graphicType;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.code.length)
writer.writeString(1, this.code);
if (this.graphicType.length)
writer.writeString(2, this.graphicType);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): CommonState {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new CommonState();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
message.code = reader.readString();
break;
case 2:
message.graphicType = reader.readString();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): CommonState {
return CommonState.deserialize(bytes);
}
}
export class IscsFan extends pb_1.Message {
#one_of_decls: number[][] = [];
constructor(data?: any[] | {
common?: CommonState;
state?: number;
}) {
super();
pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
if (!Array.isArray(data) && typeof data == "object") {
if ("common" in data && data.common != undefined) {
this.common = data.common;
}
if ("state" in data && data.state != undefined) {
this.state = data.state;
}
}
}
get common() {
return pb_1.Message.getWrapperField(this, CommonState, 1) as CommonState;
}
set common(value: CommonState) {
pb_1.Message.setWrapperField(this, 1, value);
}
get has_common() {
return pb_1.Message.getField(this, 1) != null;
}
get state() {
return pb_1.Message.getFieldWithDefault(this, 2, 0) as number;
}
set state(value: number) {
pb_1.Message.setField(this, 2, value);
}
static fromObject(data: {
common?: ReturnType<typeof CommonState.prototype.toObject>;
state?: number;
}): IscsFan {
const message = new IscsFan({});
if (data.common != null) {
message.common = CommonState.fromObject(data.common);
}
if (data.state != null) {
message.state = data.state;
}
return message;
}
toObject() {
const data: {
common?: ReturnType<typeof CommonState.prototype.toObject>;
state?: number;
} = {};
if (this.common != null) {
data.common = this.common.toObject();
}
if (this.state != null) {
data.state = this.state;
}
return data;
}
serialize(): Uint8Array;
serialize(w: pb_1.BinaryWriter): void;
serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
const writer = w || new pb_1.BinaryWriter();
if (this.has_common)
writer.writeMessage(1, this.common, () => this.common.serialize(writer));
if (this.state != 0)
writer.writeInt32(2, this.state);
if (!w)
return writer.getResultBuffer();
}
static deserialize(bytes: Uint8Array | pb_1.BinaryReader): IscsFan {
const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new IscsFan();
while (reader.nextField()) {
if (reader.isEndGroup())
break;
switch (reader.getFieldNumber()) {
case 1:
reader.readMessage(message.common, () => message.common = CommonState.deserialize(reader));
break;
case 2:
message.state = reader.readInt32();
break;
default: reader.skipField();
}
}
return message;
}
serializeBinary(): Uint8Array {
return this.serialize();
}
static deserializeBinary(bytes: Uint8Array): IscsFan {
return IscsFan.deserialize(bytes);
}
}
}

View File

@ -1,6 +1,7 @@
import { import {
GraphicAnimation, GraphicAnimation,
GraphicData, GraphicData,
GraphicState,
JlGraphic, JlGraphic,
JlGraphicTemplate, JlGraphicTemplate,
} from 'src/jlgraphic'; } from 'src/jlgraphic';
@ -23,12 +24,16 @@ export interface IIscsFanData extends GraphicData {
set code(v: string); set code(v: string);
} }
export interface IIscsFanState extends GraphicState {
get state(): number;
set state(v: number);
}
export class IscsFan extends JlGraphic { export class IscsFan extends JlGraphic {
static Type = 'IscsFan'; static Type = 'IscsFan';
_border: Sprite; _border: Sprite;
_fan: Sprite; _fan: Sprite;
fanTextures: FanTextures; fanTextures: FanTextures;
__state = 0;
constructor(fanTextures: FanTextures) { constructor(fanTextures: FanTextures) {
super(IscsFan.Type); super(IscsFan.Type);
@ -42,28 +47,31 @@ export class IscsFan extends JlGraphic {
this.addChild(this._border); this.addChild(this._border);
this.addChild(this._fan); this.addChild(this._fan);
} }
get states(): IIscsFanState {
return this.getStates<IIscsFanState>();
}
doRepaint(): void { doRepaint(): void {
if (this.__state === 0) { if (this.states.state === 0) {
// 停止 // 停止
this.stopFanRun(); this.stopFanRun();
this._fan.rotation = 0; this._fan.rotation = 0;
this._fan.texture = this.fanTextures.gray; this._fan.texture = this.fanTextures.gray;
} else if (this.__state === 1) { } else if (this.states.state === 1) {
// 正常运行 // 正常运行
this._fan.texture = this.fanTextures.green; this._fan.texture = this.fanTextures.green;
// 动画 // 动画
this.initFanRun(); this.initFanRun();
} else if (this.__state === 2) { } else if (this.states.state === 2) {
// 报警运行 // 报警运行
this._fan.texture = this.fanTextures.yellow; this._fan.texture = this.fanTextures.yellow;
// 动画 // 动画
this.initFanRun(); this.initFanRun();
} else if (this.__state === 3) { } else if (this.states.state === 3) {
// 故障 // 故障
this.stopFanRun(); this.stopFanRun();
this._fan.rotation = 0; this._fan.rotation = 0;
this._fan.texture = this.fanTextures.red; this._fan.texture = this.fanTextures.red;
} else if (this.__state === 4) { } else if (this.states.state === 4) {
// 通信故障 // 通信故障
// 停止 // 停止
this.stopFanRun(); this.stopFanRun();
@ -99,12 +107,18 @@ export class IscsFan extends JlGraphic {
export class IscsFanTemplate extends JlGraphicTemplate<IscsFan> { export class IscsFanTemplate extends JlGraphicTemplate<IscsFan> {
fanTextures?: FanTextures; fanTextures?: FanTextures;
constructor() { constructor(dataTemplate: IIscsFanData, stateTemplate: IIscsFanState) {
super(IscsFan.Type); super(IscsFan.Type, {
dataTemplate,
stateTemplate,
});
} }
new(): IscsFan { new(): IscsFan {
if (this.fanTextures) { if (this.fanTextures) {
return new IscsFan(this.fanTextures); const g = new IscsFan(this.fanTextures);
g.loadData(this.datas);
g.loadState(this.states);
return g;
} }
throw new Error('资源未加载/加载失败'); throw new Error('资源未加载/加载失败');
} }

View File

@ -16,9 +16,8 @@ export class IscsFanDraw extends GraphicDrawAssistant<
> { > {
_iscsFan: IscsFan | null = null; _iscsFan: IscsFan | null = null;
constructor(app: JlDrawApp, createData: () => IIscsFanData) { constructor(app: JlDrawApp, template: IscsFanTemplate) {
const template = new IscsFanTemplate(); super(app, template, IscsFan.Type, '风机');
super(app, template, createData, IscsFan.Type, '风机');
IscsFanInteraction.init(app); IscsFanInteraction.init(app);
} }

View File

@ -89,8 +89,10 @@ export class LinkTemplate extends JlGraphicTemplate<Link> {
lineWidth: number; lineWidth: number;
lineColor: string; lineColor: string;
segmentsCount: number; segmentsCount: number;
constructor() { constructor(dataTemplate: ILinkData) {
super(Link.Type); super(Link.Type, {
dataTemplate,
});
this.lineWidth = 2; this.lineWidth = 2;
this.lineColor = '#000000'; this.lineColor = '#000000';
this.curve = false; this.curve = false;

View File

@ -68,8 +68,8 @@ export class LinkDraw extends GraphicDrawAssistant<LinkTemplate, ILinkData> {
}, },
}); });
constructor(app: JlDrawApp, createData: () => ILinkData) { constructor(app: JlDrawApp, template: LinkTemplate) {
super(app, new LinkTemplate(), createData, Link.Type, '轨道Link'); super(app, template, Link.Type, '轨道Link');
this.container.addChild(this.graphic); this.container.addChild(this.graphic);
this.graphicTemplate.curve = true; this.graphicTemplate.curve = true;

View File

@ -91,8 +91,10 @@ export class Signal extends JlGraphic {
} }
export class SignalTemplate extends JlGraphicTemplate<Signal> { export class SignalTemplate extends JlGraphicTemplate<Signal> {
constructor() { constructor(dataTemplate: ISignalData) {
super(Signal.Type); super(Signal.Type, {
dataTemplate,
});
} }
new(): Signal { new(): Signal {
return new Signal(); return new Signal();

View File

@ -17,11 +17,10 @@ export class SignalDraw extends GraphicDrawAssistant<
> { > {
_signal: Signal | null = null; _signal: Signal | null = null;
constructor(app: JlDrawApp, createData: () => ISignalData) { constructor(app: JlDrawApp, template: SignalTemplate) {
super( super(
app, app,
new SignalTemplate(), template,
createData,
'svguse: ../../drawIcon.svg#icon-signal', 'svguse: ../../drawIcon.svg#icon-signal',
'信号机Signal' '信号机Signal'
); );
@ -32,7 +31,7 @@ export class SignalDraw extends GraphicDrawAssistant<
public get signal(): Signal { public get signal(): Signal {
if (!this._signal) { if (!this._signal) {
this._signal = this.graphicTemplate.new(); this._signal = this.graphicTemplate.new();
this.signal.loadData(this.createGraphicData()); this.signal.loadData(this.graphicTemplate.datas);
this.container.addChild(this.signal); this.container.addChild(this.signal);
} }
return this._signal; return this._signal;

View File

@ -45,7 +45,6 @@ export abstract class GraphicDrawAssistant<
icon: string; // 界面显示的图标 icon: string; // 界面显示的图标
container: Container = new Container(); container: Container = new Container();
graphicTemplate: GT; graphicTemplate: GT;
createGraphicData: () => GD;
escListener: KeyListener = new KeyListener({ escListener: KeyListener = new KeyListener({
value: 'Escape', value: 'Escape',
@ -61,7 +60,6 @@ export abstract class GraphicDrawAssistant<
constructor( constructor(
graphicApp: JlDrawApp, graphicApp: JlDrawApp,
graphicTemplate: GT, graphicTemplate: GT,
createGraphicData: () => GD,
icon: string, icon: string,
description: string description: string
) { ) {
@ -69,7 +67,6 @@ export abstract class GraphicDrawAssistant<
this.app = graphicApp; this.app = graphicApp;
this.type = graphicTemplate.type; this.type = graphicTemplate.type;
this.graphicTemplate = graphicTemplate; this.graphicTemplate = graphicTemplate;
this.createGraphicData = createGraphicData;
this.icon = icon; this.icon = icon;
this.description = description; this.description = description;
this.app.registerGraphicTemplates(this.graphicTemplate); this.app.registerGraphicTemplates(this.graphicTemplate);
@ -163,7 +160,7 @@ export abstract class GraphicDrawAssistant<
* App * App
*/ */
createAndStore(finish: boolean): JlGraphic | null { createAndStore(finish: boolean): JlGraphic | null {
const data = this.createGraphicData(); const data = this.graphicTemplate.datas as GD;
data.id = this.nextId(); data.id = this.nextId();
data.graphicType = this.graphicTemplate.type; data.graphicType = this.graphicTemplate.type;
if (!this.prepareData(data)) { if (!this.prepareData(data)) {

View File

@ -923,15 +923,47 @@ export abstract class JlGraphic extends Container {
} }
} }
export type CreateData = () => GraphicData;
export type CreateState = () => GraphicState;
export interface IGraphicTemplateOptions {
dataTemplate?: GraphicData;
stateTemplate?: GraphicState;
}
/** /**
* *
*/ */
export abstract class JlGraphicTemplate<G extends JlGraphic> { export abstract class JlGraphicTemplate<G extends JlGraphic> {
readonly type: string; readonly type: string;
options: IGraphicTemplateOptions;
constructor(type: string) { constructor(type: string, options: IGraphicTemplateOptions) {
this.type = type; this.type = type;
this.options = options;
} }
get datas(): GraphicData {
if (this.options.dataTemplate) {
return this.options.dataTemplate.clone();
}
throw new Error(`type=${this.type}的图形模板没有数据模板`);
}
get states(): GraphicState {
if (this.options.stateTemplate) {
return this.options.stateTemplate.clone();
}
throw new Error(`type=${this.type}的图形模板没有状态模板`);
}
// getDataCreator<T extends CreateData>(): T {
// return this.options.dataCreator as T;
// }
// getStateCreator<T extends CreateState>(): T {
// return this.options.stateCreator as T;
// }
/** /**
* *
*/ */

View File

@ -10,7 +10,6 @@ import {
import { JlGraphic } from '../core'; import { JlGraphic } from '../core';
import { DraggablePoint } from '../graphic'; import { DraggablePoint } from '../graphic';
import { import {
assertBezierPoints,
calculateDistanceFromPointToLine, calculateDistanceFromPointToLine,
calculateFootPointFromPointToLine, calculateFootPointFromPointToLine,
calculateLineSegmentingPoint, calculateLineSegmentingPoint,