Add model & behavior archive function #44
@ -123,7 +123,7 @@ class HeaderWindowsAction extends Component<IMixinElectronProps> {
|
|||||||
* 头部信息栏
|
* 头部信息栏
|
||||||
*/
|
*/
|
||||||
@useSettingWithEvent("language")
|
@useSettingWithEvent("language")
|
||||||
@useStatusWithEvent("fileChange")
|
@useStatusWithEvent("fileSave")
|
||||||
class HeaderBar extends Component<IHeaderBarProps & IMixinStatusProps & IMixinSettingProps> {
|
class HeaderBar extends Component<IHeaderBarProps & IMixinStatusProps & IMixinSettingProps> {
|
||||||
|
|
||||||
public render(): ReactNode {
|
public render(): ReactNode {
|
||||||
|
@ -30,7 +30,8 @@ function randomColor(unNormal: boolean = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IStatusEvent {
|
interface IStatusEvent {
|
||||||
fileChange: void;
|
fileSave: void;
|
||||||
|
fileLoad: void;
|
||||||
renderLoop: number;
|
renderLoop: number;
|
||||||
physicsLoop: number;
|
physicsLoop: number;
|
||||||
mouseModChange: void;
|
mouseModChange: void;
|
||||||
@ -145,7 +146,19 @@ class Status extends Emitter<IStatusEvent> {
|
|||||||
this.on("behaviorAttrChange", updateBehaviorParameter);
|
this.on("behaviorAttrChange", updateBehaviorParameter);
|
||||||
|
|
||||||
// 映射文件状态改变事件
|
// 映射文件状态改变事件
|
||||||
this.archive.on("fileChange", () => this.emit("fileChange"));
|
this.archive.on("fileSave", () => this.emit("fileSave"));
|
||||||
|
|
||||||
|
// 处理存档加载事件
|
||||||
|
this.archive.on("fileLoad", () => {
|
||||||
|
|
||||||
|
// 触发对象修改
|
||||||
|
this.emit("objectChange");
|
||||||
|
this.emit("labelChange");
|
||||||
|
this.emit("behaviorChange");
|
||||||
|
|
||||||
|
// 映射
|
||||||
|
this.emit("fileLoad");
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
public bindRenderer(renderer: AbstractRenderer) {
|
public bindRenderer(renderer: AbstractRenderer) {
|
||||||
|
@ -1,22 +1,27 @@
|
|||||||
import { Emitter, EventType } from "@Model/Emitter";
|
import { Emitter, EventType } from "@Model/Emitter";
|
||||||
import { IArchiveCtrlObject } from "@Model/CtrlObject";
|
import { CtrlObject, IArchiveCtrlObject } from "@Model/CtrlObject";
|
||||||
import { Model } from "@Model/Model";
|
import { Model } from "@Model/Model";
|
||||||
import { IArchiveLabel } from "@Model/Label";
|
import { IArchiveLabel, Label } from "@Model/Label";
|
||||||
|
import { Group, IArchiveGroup } from "@Model/Group";
|
||||||
|
import { Range } from "@Model/Range";
|
||||||
|
import { IArchiveIndividual, Individual } from "@Model/Individual";
|
||||||
|
import { Behavior, IArchiveBehavior } from "@Model/Behavior";
|
||||||
|
import { getBehaviorById } from "@Behavior/Behavior";
|
||||||
|
import { IArchiveParseFn, IObjectParamArchiveType, IRealObjectType } from "@Model/Parameter";
|
||||||
|
|
||||||
interface IArchiveEvent {
|
interface IArchiveEvent {
|
||||||
fileChange: Archive;
|
fileSave: Archive;
|
||||||
|
fileLoad: Archive;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IArchiveObject {
|
interface IArchiveObject {
|
||||||
nextIndividualId: number;
|
nextIndividualId: number;
|
||||||
objectPool: IArchiveCtrlObject[];
|
objectPool: IArchiveCtrlObject[];
|
||||||
labelPool: IArchiveLabel[];
|
labelPool: IArchiveLabel[];
|
||||||
|
behaviorPool: IArchiveBehavior[];
|
||||||
}
|
}
|
||||||
|
|
||||||
class Archive<
|
class Archive<M extends any = any> extends Emitter<IArchiveEvent> {
|
||||||
M extends any = any,
|
|
||||||
E extends Record<EventType, any> = {}
|
|
||||||
> extends Emitter<E & IArchiveEvent> {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否为新文件
|
* 是否为新文件
|
||||||
@ -39,44 +44,224 @@ class Archive<
|
|||||||
public fileData?: M;
|
public fileData?: M;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存文件
|
* 将模型转换为存档对象
|
||||||
* 模型转换为文件
|
|
||||||
*/
|
*/
|
||||||
public save(model: Model): string {
|
public parseModel2Archive(model: Model): string {
|
||||||
|
|
||||||
// 存贮 CtrlObject
|
// 存贮 CtrlObject
|
||||||
const objectPool: IArchiveCtrlObject[] = [];
|
const objectPool: IArchiveCtrlObject[] = [];
|
||||||
model.objectPool.forEach(obj => {
|
model.objectPool.forEach(obj => {
|
||||||
objectPool.push(obj.toArchive());
|
let archiveObject = obj.toArchive();
|
||||||
|
|
||||||
|
// 处理每个群的个体
|
||||||
|
if (archiveObject.objectType === "G") {
|
||||||
|
const archiveGroup: IArchiveGroup = archiveObject as any;
|
||||||
|
const group: Group = obj as Group;
|
||||||
|
|
||||||
|
const individuals: IArchiveIndividual[] = [];
|
||||||
|
group.individuals.forEach((item) => {
|
||||||
|
individuals.push(item.toArchive());
|
||||||
|
});
|
||||||
|
|
||||||
|
archiveGroup.individuals = individuals;
|
||||||
|
}
|
||||||
|
|
||||||
|
objectPool.push(archiveObject);
|
||||||
})
|
})
|
||||||
|
|
||||||
// 存储 Label
|
// 存储 Label
|
||||||
const labelPool: IArchiveLabel[] = [];
|
const labelPool: IArchiveLabel[] = [];
|
||||||
model.labelPool.forEach(obj => {
|
model.labelPool.forEach(obj => {
|
||||||
labelPool.push(obj.toArchive());
|
labelPool.push(obj.toArchive());
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// 存储全部行为
|
||||||
|
const behaviorPool: IArchiveBehavior[] = [];
|
||||||
|
model.behaviorPool.forEach(obj => {
|
||||||
|
behaviorPool.push(obj.toArchive());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 生成存档对象
|
||||||
const fileData: IArchiveObject = {
|
const fileData: IArchiveObject = {
|
||||||
nextIndividualId: model.nextIndividualId,
|
nextIndividualId: model.nextIndividualId,
|
||||||
objectPool: objectPool,
|
objectPool: objectPool,
|
||||||
labelPool: labelPool
|
labelPool: labelPool,
|
||||||
|
behaviorPool: behaviorPool
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log(fileData);
|
return JSON.stringify(fileData);
|
||||||
console.log({value: JSON.stringify(fileData)});
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载存档到模型
|
||||||
|
*/
|
||||||
|
public loadArchiveIntoModel(model: Model, data: string): void {
|
||||||
|
|
||||||
|
// 解析为 JSON 对象
|
||||||
|
const archive: IArchiveObject = JSON.parse(data);
|
||||||
|
console.log(archive);
|
||||||
|
|
||||||
|
// 实例化全部对象
|
||||||
|
const objectPool: CtrlObject[] = [];
|
||||||
|
const individualPool: Individual[] = [];
|
||||||
|
archive.objectPool.forEach((obj) => {
|
||||||
|
|
||||||
|
let ctrlObject: CtrlObject | undefined = undefined;
|
||||||
|
|
||||||
|
// 处理群
|
||||||
|
if (obj.objectType === "G") {
|
||||||
|
const archiveGroup: IArchiveGroup = obj as any;
|
||||||
|
const newGroup = new Group(model);
|
||||||
|
|
||||||
|
// 实例化全部个体
|
||||||
|
const individuals: Array<Individual> = [];
|
||||||
|
archiveGroup.individuals.forEach((item) => {
|
||||||
|
const newIndividual = new Individual(newGroup);
|
||||||
|
newIndividual.id = item.id;
|
||||||
|
individuals.push(newIndividual);
|
||||||
|
individualPool.push(newIndividual);
|
||||||
|
})
|
||||||
|
|
||||||
|
newGroup.cacheIndividualsArray = individuals;
|
||||||
|
ctrlObject = newGroup;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理范围
|
||||||
|
if (obj.objectType === "R") {
|
||||||
|
ctrlObject = new Range(model);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctrlObject) {
|
||||||
|
ctrlObject.id = obj.id;
|
||||||
|
objectPool.push(ctrlObject);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 实例化全部标签
|
||||||
|
const labelPool: Label[] = [];
|
||||||
|
archive.labelPool.forEach((item) => {
|
||||||
|
const newLabel = new Label(model);
|
||||||
|
newLabel.id = item.id;
|
||||||
|
labelPool.push(newLabel);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 实例化全部行为
|
||||||
|
const behaviorPool: Behavior[] = [];
|
||||||
|
archive.behaviorPool.forEach((item) => {
|
||||||
|
const recorder = getBehaviorById(item.behaviorId);
|
||||||
|
const newBehavior = recorder.new();
|
||||||
|
newBehavior.id = item.id;
|
||||||
|
behaviorPool.push(newBehavior);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 内置标签集合
|
||||||
|
const buildInLabel = [model.allGroupLabel, model.allRangeLabel, model.currentGroupLabel]
|
||||||
|
|
||||||
|
const search: <T extends IRealObjectType>(pool: T[], archive: IObjectParamArchiveType) => T | undefined =
|
||||||
|
(pool, archive) => {
|
||||||
|
for (let i = 0; i < pool.length; i++) {
|
||||||
|
if (pool[i].id === archive.__LIVING_TOGETHER_OBJECT_ID) {
|
||||||
|
return pool[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchAll: (archive: IObjectParamArchiveType) => IRealObjectType | undefined =
|
||||||
|
(archive) => {
|
||||||
|
return void 0 ??
|
||||||
|
search(individualPool, archive) ??
|
||||||
|
search(objectPool, archive) ??
|
||||||
|
search(labelPool, archive) ??
|
||||||
|
search(buildInLabel, archive) ??
|
||||||
|
search(behaviorPool, archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 实例搜索函数
|
||||||
|
const parseFunction: IArchiveParseFn = (archive) => {
|
||||||
|
|
||||||
|
switch (archive.__LIVING_TOGETHER_OBJECT_TYPE) {
|
||||||
|
|
||||||
|
// 在个体池搜索
|
||||||
|
case "Individual":
|
||||||
|
return search(individualPool, archive) ?? searchAll(archive);
|
||||||
|
|
||||||
|
// 对象类型在对象池中搜索
|
||||||
|
case "Range":
|
||||||
|
case "Group":
|
||||||
|
return search(objectPool, archive) ?? searchAll(archive);
|
||||||
|
|
||||||
|
// 在标签池搜索
|
||||||
|
case "Label":
|
||||||
|
return search(labelPool, archive) ?? search(buildInLabel, archive) ?? searchAll(archive);
|
||||||
|
|
||||||
|
// 在标签池搜索
|
||||||
|
case "Behavior":
|
||||||
|
return search(behaviorPool, archive) ?? searchAll(archive);
|
||||||
|
|
||||||
|
// 在全部池子搜索
|
||||||
|
default:
|
||||||
|
return searchAll(archive);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载对象的属性
|
||||||
|
model.objectPool = objectPool.map((obj, index) => {
|
||||||
|
|
||||||
|
// 加载属性
|
||||||
|
obj.fromArchive(archive.objectPool[index], parseFunction);
|
||||||
|
|
||||||
|
// 加载个体属性
|
||||||
|
if (obj instanceof Group) {
|
||||||
|
|
||||||
|
const archiveGroup: IArchiveGroup = archive.objectPool[index] as any;
|
||||||
|
|
||||||
|
obj.individuals = new Set(obj.cacheIndividualsArray.map((item, i) => {
|
||||||
|
item.fromArchive(archiveGroup.individuals[i], parseFunction);
|
||||||
|
return item;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return obj;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载标签属性
|
||||||
|
model.labelPool = labelPool.map((item, index) => {
|
||||||
|
item.fromArchive(archive.labelPool[index]);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载行为属性
|
||||||
|
model.behaviorPool = behaviorPool.map((item, index) => {
|
||||||
|
item.fromArchive(archive.behaviorPool[index], parseFunction);
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存文件
|
||||||
|
* 模型转换为文件
|
||||||
|
*/
|
||||||
|
public save(model: Model): void {
|
||||||
|
|
||||||
|
console.log(this.parseModel2Archive(model));
|
||||||
|
|
||||||
this.isSaved = true;
|
this.isSaved = true;
|
||||||
this.emit( ...["fileChange", this] as any );
|
this.emit("fileSave", this);
|
||||||
|
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载文件为模型
|
* 加载文件为模型
|
||||||
* return Model
|
* @return Model
|
||||||
*/
|
*/
|
||||||
public load(model: Model, data: string) {};
|
public load(model: Model, data: string) {
|
||||||
|
|
||||||
|
this.loadArchiveIntoModel(model, data);
|
||||||
|
|
||||||
|
this.isSaved = true;
|
||||||
|
this.emit("fileLoad", this);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Archive };
|
export { Archive };
|
||||||
export default Archive;
|
|
@ -3,7 +3,11 @@ import { v4 as uuid } from "uuid";
|
|||||||
import type { Individual } from "@Model/Individual";
|
import type { Individual } from "@Model/Individual";
|
||||||
import type { Group } from "@Model/Group";
|
import type { Group } from "@Model/Group";
|
||||||
import type { Model } from "@Model/Model";
|
import type { Model } from "@Model/Model";
|
||||||
import { getDefaultValue, IParameter, IParameterOption, IParameterValue } from "@Model/Parameter";
|
import {
|
||||||
|
archiveObject2Parameter,
|
||||||
|
getDefaultValue, IArchiveParameterValue, IArchiveParseFn,
|
||||||
|
IParameter, IParameterOption, IParameterValue, parameter2ArchiveObject
|
||||||
|
} from "@Model/Parameter";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 行为构造函数类型
|
* 行为构造函数类型
|
||||||
@ -113,6 +117,17 @@ class BehaviorRecorder<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IArchiveBehavior {
|
||||||
|
behaviorId: string;
|
||||||
|
name: string;
|
||||||
|
id: string;
|
||||||
|
color: number[];
|
||||||
|
priority: number;
|
||||||
|
currentGroupKey: string[];
|
||||||
|
deleteFlag: boolean;
|
||||||
|
parameter: IArchiveParameterValue<IParameter>;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 群体的某种行为
|
* 群体的某种行为
|
||||||
*/
|
*/
|
||||||
@ -189,6 +204,33 @@ class Behavior<
|
|||||||
return this.deleteFlag;
|
return this.deleteFlag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public toArchive(): IArchiveBehavior {
|
||||||
|
return {
|
||||||
|
behaviorId: this.behaviorId,
|
||||||
|
name: this.name,
|
||||||
|
id: this.id,
|
||||||
|
color: this.color.concat([]),
|
||||||
|
priority: this.priority,
|
||||||
|
currentGroupKey: this.currentGroupKey.concat([]) as any,
|
||||||
|
deleteFlag: this.deleteFlag,
|
||||||
|
parameter: parameter2ArchiveObject(
|
||||||
|
this.parameter, this.parameterOption
|
||||||
|
)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public fromArchive(archive: IArchiveBehavior, paster: IArchiveParseFn): void {
|
||||||
|
this.name = archive.name,
|
||||||
|
this.id = archive.id,
|
||||||
|
this.color = archive.color.concat([]),
|
||||||
|
this.priority = archive.priority,
|
||||||
|
this.currentGroupKey = archive.currentGroupKey.concat([]) as any,
|
||||||
|
this.deleteFlag = archive.deleteFlag,
|
||||||
|
this.parameter = archiveObject2Parameter(
|
||||||
|
archive.parameter, paster
|
||||||
|
) as any;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 加载时调用
|
* 加载时调用
|
||||||
*/
|
*/
|
||||||
@ -241,6 +283,6 @@ class Behavior<
|
|||||||
type IRenderBehavior = BehaviorInfo | Behavior;
|
type IRenderBehavior = BehaviorInfo | Behavior;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
Behavior, BehaviorRecorder, IAnyBehavior, IAnyBehaviorRecorder, BehaviorInfo, IRenderBehavior
|
Behavior, BehaviorRecorder, IAnyBehavior, IAnyBehaviorRecorder,
|
||||||
};
|
BehaviorInfo, IRenderBehavior, IArchiveBehavior
|
||||||
export default { Behavior };
|
};
|
@ -4,16 +4,18 @@ import type { IAnyObject, Model } from "@Model/Model";
|
|||||||
import type { ObjectID } from "@Model/Model";
|
import type { ObjectID } from "@Model/Model";
|
||||||
import {
|
import {
|
||||||
parameter2ArchiveObject, archiveObject2Parameter,
|
parameter2ArchiveObject, archiveObject2Parameter,
|
||||||
IArchiveParseFn, IObjectParamArchiveType, object2ArchiveObject
|
IArchiveParseFn, IObjectParamArchiveType, object2ArchiveObject,
|
||||||
|
IArchiveParameterValue, IParameter
|
||||||
} from "@Model/Parameter";
|
} from "@Model/Parameter";
|
||||||
|
|
||||||
interface IArchiveCtrlObject {
|
interface IArchiveCtrlObject {
|
||||||
|
objectType: "R" | "G";
|
||||||
displayName: CtrlObject["displayName"];
|
displayName: CtrlObject["displayName"];
|
||||||
color: CtrlObject["color"];
|
color: CtrlObject["color"];
|
||||||
display: CtrlObject["display"];
|
display: CtrlObject["display"];
|
||||||
update: CtrlObject["update"];
|
update: CtrlObject["update"];
|
||||||
id: string;
|
id: string;
|
||||||
renderParameter: any;
|
renderParameter: IArchiveParameterValue<IParameter>;
|
||||||
deleteFlag: CtrlObject["deleteFlag"];
|
deleteFlag: CtrlObject["deleteFlag"];
|
||||||
labels: IObjectParamArchiveType[];
|
labels: IObjectParamArchiveType[];
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,11 @@ import type { Behavior, IAnyBehavior } from "@Model/Behavior";
|
|||||||
import { Label } from "@Model/Label";
|
import { Label } from "@Model/Label";
|
||||||
import { Range } from "@Model/Range";
|
import { Range } from "@Model/Range";
|
||||||
import { Model, ObjectID } from "@Model/Model";
|
import { Model, ObjectID } from "@Model/Model";
|
||||||
import { getDefaultValue, IArchiveParseFn, IObjectParamArchiveType, object2ArchiveObject } from "@Model/Parameter";
|
import { IArchiveIndividual } from "@Model/Individual";
|
||||||
|
import {
|
||||||
|
getDefaultValue, IArchiveParseFn,
|
||||||
|
IObjectParamArchiveType, object2ArchiveObject
|
||||||
|
} from "@Model/Parameter";
|
||||||
|
|
||||||
enum GenMod {
|
enum GenMod {
|
||||||
Point = "p",
|
Point = "p",
|
||||||
@ -12,6 +16,7 @@ enum GenMod {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IArchiveGroup {
|
interface IArchiveGroup {
|
||||||
|
individuals: IArchiveIndividual[];
|
||||||
genMethod: Group["genMethod"];
|
genMethod: Group["genMethod"];
|
||||||
genPoint: Group["genPoint"];
|
genPoint: Group["genPoint"];
|
||||||
genRange: IObjectParamArchiveType | undefined;
|
genRange: IObjectParamArchiveType | undefined;
|
||||||
@ -32,6 +37,11 @@ class Group extends CtrlObject<IArchiveGroup> {
|
|||||||
*/
|
*/
|
||||||
public individuals: Set<Individual> = new Set();
|
public individuals: Set<Individual> = new Set();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缓存的 individuals 数组, 用于存档加载
|
||||||
|
*/
|
||||||
|
public cacheIndividualsArray: Array<Individual> = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 个体生成方式
|
* 个体生成方式
|
||||||
*/
|
*/
|
||||||
@ -421,6 +431,7 @@ class Group extends CtrlObject<IArchiveGroup> {
|
|||||||
public override toArchive(): IArchiveCtrlObject & IArchiveGroup {
|
public override toArchive(): IArchiveCtrlObject & IArchiveGroup {
|
||||||
return {
|
return {
|
||||||
...super.toArchive(),
|
...super.toArchive(),
|
||||||
|
objectType: "G",
|
||||||
genMethod: this.genMethod,
|
genMethod: this.genMethod,
|
||||||
genPoint: this.genPoint.concat([]),
|
genPoint: this.genPoint.concat([]),
|
||||||
genRange: object2ArchiveObject(this.genRange) as IObjectParamArchiveType,
|
genRange: object2ArchiveObject(this.genRange) as IObjectParamArchiveType,
|
||||||
@ -456,4 +467,4 @@ class Group extends CtrlObject<IArchiveGroup> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Group, GenMod };
|
export { Group, GenMod, IArchiveGroup };
|
@ -234,13 +234,13 @@ class Individual {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.id = this.id,
|
this.id = archive.id,
|
||||||
this.position = this.position.concat([]),
|
this.position = archive.position.concat([]),
|
||||||
this.velocity = this.velocity.concat([]),
|
this.velocity = archive.velocity.concat([]),
|
||||||
this.acceleration = this.acceleration.concat([]),
|
this.acceleration = archive.acceleration.concat([]),
|
||||||
this.force = this.force.concat([]),
|
this.force = archive.force.concat([]),
|
||||||
this.metaData = metaData;
|
this.metaData = metaData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export { Individual };
|
export { Individual, IArchiveIndividual };
|
@ -3,10 +3,11 @@ import { Range } from "@Model/Range";
|
|||||||
import { Label } from "@Model/Label";
|
import { Label } from "@Model/Label";
|
||||||
import { Behavior, IAnyBehavior } from "@Model/Behavior";
|
import { Behavior, IAnyBehavior } from "@Model/Behavior";
|
||||||
import { Individual } from "@Model/Individual";
|
import { Individual } from "@Model/Individual";
|
||||||
|
import { CtrlObject } from "@Model/CtrlObject";
|
||||||
|
|
||||||
type IObjectParamArchiveType = {
|
type IObjectParamArchiveType = {
|
||||||
__LIVING_TOGETHER_OBJECT_ID: string;
|
__LIVING_TOGETHER_OBJECT_ID: string;
|
||||||
__LIVING_TOGETHER_OBJECT_TYPE: string;
|
__LIVING_TOGETHER_OBJECT_TYPE: "Individual" | "Range" | "Group" | "Label" | "Behavior";
|
||||||
}
|
}
|
||||||
|
|
||||||
type IObjectParamCacheType<P, Q = P> = {
|
type IObjectParamCacheType<P, Q = P> = {
|
||||||
@ -225,36 +226,36 @@ function getDefaultValue<P extends IParameter> (option: IParameterOption<P>): IP
|
|||||||
return defaultObj;
|
return defaultObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
type IRealObjectType = Range | Group | Label | IAnyBehavior;
|
type IRealObjectType = Range | Group | Label | IAnyBehavior | Individual | CtrlObject;
|
||||||
type IArchiveParseFn = (archive: IObjectParamArchiveType) => IRealObjectType | undefined;
|
type IArchiveParseFn = (archive: IObjectParamArchiveType) => IRealObjectType | undefined;
|
||||||
|
|
||||||
function object2ArchiveObject(object: IRealObjectType | IRealObjectType[] | any, testArray: boolean = true):
|
function object2ArchiveObject(object: IRealObjectType | IRealObjectType[] | any, testArray: boolean = true):
|
||||||
IObjectParamArchiveType | IObjectParamArchiveType[] | undefined {
|
IObjectParamArchiveType | IObjectParamArchiveType[] | undefined {
|
||||||
if (object instanceof Individual) {
|
if (object instanceof Individual) {
|
||||||
return {
|
return {
|
||||||
__LIVING_TOGETHER_OBJECT_ID: "Individual",
|
__LIVING_TOGETHER_OBJECT_ID: object.id,
|
||||||
__LIVING_TOGETHER_OBJECT_TYPE: object.id
|
__LIVING_TOGETHER_OBJECT_TYPE: "Individual"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (object instanceof Range) {
|
else if (object instanceof Range) {
|
||||||
return {
|
return {
|
||||||
__LIVING_TOGETHER_OBJECT_ID: "Range",
|
__LIVING_TOGETHER_OBJECT_ID: object.id,
|
||||||
__LIVING_TOGETHER_OBJECT_TYPE: object.id
|
__LIVING_TOGETHER_OBJECT_TYPE: "Range"
|
||||||
}
|
}
|
||||||
} else if (object instanceof Group) {
|
} else if (object instanceof Group) {
|
||||||
return {
|
return {
|
||||||
__LIVING_TOGETHER_OBJECT_ID: "Group",
|
__LIVING_TOGETHER_OBJECT_ID: object.id,
|
||||||
__LIVING_TOGETHER_OBJECT_TYPE: object.id
|
__LIVING_TOGETHER_OBJECT_TYPE: "Group"
|
||||||
}
|
}
|
||||||
} else if (object instanceof Label) {
|
} else if (object instanceof Label) {
|
||||||
return {
|
return {
|
||||||
__LIVING_TOGETHER_OBJECT_ID: "Label",
|
__LIVING_TOGETHER_OBJECT_ID: object.id,
|
||||||
__LIVING_TOGETHER_OBJECT_TYPE: object.id
|
__LIVING_TOGETHER_OBJECT_TYPE: "Label"
|
||||||
}
|
}
|
||||||
} else if (object instanceof Behavior) {
|
} else if (object instanceof Behavior) {
|
||||||
return {
|
return {
|
||||||
__LIVING_TOGETHER_OBJECT_ID: "Behavior",
|
__LIVING_TOGETHER_OBJECT_ID: object.id,
|
||||||
__LIVING_TOGETHER_OBJECT_TYPE: object.id
|
__LIVING_TOGETHER_OBJECT_TYPE: "Behavior"
|
||||||
}
|
}
|
||||||
} else if (Array.isArray(object) && testArray) {
|
} else if (Array.isArray(object) && testArray) {
|
||||||
const hasValue = (item: any): item is IObjectParamArchiveType => !!item;
|
const hasValue = (item: any): item is IObjectParamArchiveType => !!item;
|
||||||
@ -322,7 +323,7 @@ function archiveObject2Parameter<P extends IParameter>
|
|||||||
|
|
||||||
(parameter[key] as any) = {
|
(parameter[key] as any) = {
|
||||||
picker: picker ? parse(picker) : picker,
|
picker: picker ? parse(picker) : picker,
|
||||||
objects: objects ? parse(objects) : objects
|
objects: objects ? Array.isArray(objects) ? objects.map(item => parse(item)) : parse(objects) : objects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -358,5 +359,6 @@ export {
|
|||||||
IParamType, IParamValue, isObjectType, isVectorType, getDefaultValue,
|
IParamType, IParamValue, isObjectType, isVectorType, getDefaultValue,
|
||||||
IParameterOptionItem, IParameter, IParameterOption, IParameterValue,
|
IParameterOptionItem, IParameter, IParameterOption, IParameterValue,
|
||||||
object2ArchiveObject, parameter2ArchiveObject, archiveObject2Parameter,
|
object2ArchiveObject, parameter2ArchiveObject, archiveObject2Parameter,
|
||||||
IArchiveParseFn, IObjectParamArchiveType, isArchiveObjectType
|
IArchiveParseFn, IObjectParamArchiveType, isArchiveObjectType,
|
||||||
|
IArchiveParameterValue, IRealObjectType
|
||||||
}
|
}
|
@ -34,6 +34,7 @@ class Range extends CtrlObject<IArchiveRange> {
|
|||||||
public override toArchive(): IArchiveCtrlObject & IArchiveRange {
|
public override toArchive(): IArchiveCtrlObject & IArchiveRange {
|
||||||
return {
|
return {
|
||||||
...super.toArchive(),
|
...super.toArchive(),
|
||||||
|
objectType: "R",
|
||||||
position: this.position.concat([]),
|
position: this.position.concat([]),
|
||||||
radius: this.radius.concat([])
|
radius: this.radius.concat([])
|
||||||
};
|
};
|
||||||
|
@ -55,8 +55,10 @@ class SimulatorDesktop extends Component {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
(window as any).setting = this.setting;
|
(window as any).LT = {
|
||||||
(window as any).status = this.status;
|
status: this.status,
|
||||||
|
setting: this.setting
|
||||||
|
};
|
||||||
|
|
||||||
this.electron = {} as ISimulatorAPI;
|
this.electron = {} as ISimulatorAPI;
|
||||||
if ((window as any).API) {
|
if ((window as any).API) {
|
||||||
|
@ -76,7 +76,7 @@ class SimulatorWeb extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 鱼群模型测试
|
// 鱼群模型测试
|
||||||
if (true) {
|
if (false) {
|
||||||
let fish1 = this.status.newGroup();
|
let fish1 = this.status.newGroup();
|
||||||
let fish2 = this.status.newGroup();
|
let fish2 = this.status.newGroup();
|
||||||
let shark = this.status.newGroup();
|
let shark = this.status.newGroup();
|
||||||
|
Loading…
Reference in New Issue
Block a user