webstudio/ui/src/core/model/skill_model.ts

393 lines
9 KiB
TypeScript
Raw Normal View History

2024-05-29 15:38:36 +03:00
import { IsArray, IsOptional, IsString, ValidateNested } from "class-validator";
2024-04-23 15:56:52 +03:00
import { Type } from "class-transformer";
import { ISkillView } from "../../features/behavior_tree_builder/presentation/ui/skill_tree/skill_tree";
import { v4 } from "uuid";
2024-05-29 15:38:36 +03:00
import { Result } from "../helper/result";
import clone from "just-clone";
2024-04-23 15:56:52 +03:00
2024-05-29 15:38:36 +03:00
export interface IDependency {
skills: ISkillDependency[];
}
export interface ISkillDependency {
sid: string;
dependency: Object;
}
export interface ISkill {
sid?: string;
2024-04-23 15:56:52 +03:00
SkillPackage: ISkillPackage;
Module: IModule;
Launch: ILaunch;
ROS2: IRos2;
BTAction: IBTAction[];
Interface: IInterface;
Settings: ISetting[];
xxx: IXxx;
}
2024-05-13 20:43:11 +03:00
export interface IWeightsDependency {
2024-05-29 15:38:36 +03:00
weights_name:string;
object_name: string;
weights_file: string;
dimensions: number[];
2024-05-13 20:43:11 +03:00
}
2024-04-23 15:56:52 +03:00
2024-05-13 20:43:11 +03:00
export interface IParam {
type: string;
2024-05-29 15:38:36 +03:00
dependency: Object;
2024-05-13 20:43:11 +03:00
}
2024-04-23 15:56:52 +03:00
export interface IBTAction {
name: string;
format: string;
2024-05-29 15:38:36 +03:00
// TODO: Нужно выпилить его отсюда
// sid?: string;
2024-04-23 15:56:52 +03:00
type: string;
2024-05-13 20:43:11 +03:00
param: IParam[];
2024-04-23 15:56:52 +03:00
result: string[];
}
export interface IInterface {
Input: IPut[];
Output: IPut[];
}
export interface IPut {
name: string;
type: string;
}
export interface ILaunch {
executable: string;
}
export interface IModule {
name: string;
description: string;
}
export interface IRos2 {
node_name: string;
}
export interface ISetting {
name: string;
value: number | string;
}
export interface ISkillPackage {
name: string;
version: string;
format: string;
}
export interface IXxx {
cameraLink: string;
topicImage: string;
topicCameraInfo: string;
}
export class SkillPackage implements ISkillPackage {
@IsString()
name: string;
@IsString()
version: string;
@IsString()
format: string;
}
export class Module implements IModule {
@IsString()
name: string;
@IsString()
description: string;
}
export class BTAction implements IBTAction {
@IsString()
name: string;
@IsString()
format: string;
@IsString()
type: string;
2024-05-29 15:38:36 +03:00
sid?: string;
2024-04-23 15:56:52 +03:00
@IsArray()
2024-05-13 20:43:11 +03:00
param: IParam[];
2024-04-23 15:56:52 +03:00
@IsArray()
result: string[];
}
export class Launch implements ILaunch {
@IsString()
executable: string;
}
export class Ros2 implements IRos2 {
@IsString()
node_name: string;
}
export class Put implements IPut {
@IsString()
name: string;
@IsString()
type: string;
}
export class Interface implements IInterface {
@ValidateNested()
@Type(() => Put)
Input: IPut[];
@ValidateNested()
@Type(() => Put)
Output: IPut[];
}
export class Setting implements ISetting {
name: string;
value: string | number;
}
export class Xxx implements IXxx {
cameraLink: string;
topicImage: string;
topicCameraInfo: string;
}
2024-05-29 15:38:36 +03:00
export class SkillModel implements ISkill {
@IsOptional()
@IsString()
sid?: string;
2024-04-23 15:56:52 +03:00
@ValidateNested()
@Type(() => SkillPackage)
SkillPackage: ISkillPackage;
@ValidateNested()
@Type(() => Module)
Module: IModule;
@ValidateNested()
@Type(() => Launch)
Launch: ILaunch;
@ValidateNested()
@Type(() => Ros2)
ROS2: IRos2;
@ValidateNested()
@IsArray()
@Type(() => BTAction)
BTAction: IBTAction[];
@ValidateNested()
@Type(() => Interface)
Interface: IInterface;
@ValidateNested()
@IsArray()
@Type(() => Setting)
Settings: ISetting[];
@ValidateNested()
@Type(() => Xxx)
xxx: IXxx;
2024-05-29 15:38:36 +03:00
static empty() {
const skillModel = new SkillModel();
skillModel.BTAction = [];
return skillModel;
}
public static isEmpty(skill: SkillModel): Result<void, SkillModel> {
if (skill.BTAction.isEmpty()) {
return Result.error(undefined);
}
return Result.ok(Object.assign(skill, {}));
}
public getSid = () => this.sid;
public setSid = (sid: string) => {
const result = clone(this);
result.sid = sid;
return result;
};
}
export class SkillDependency implements IDependency {
constructor(public skills: ISkillDependency[]) {}
static empty() {
return new SkillDependency([]);
}
static isEmpty = (skill: SkillDependency) => {
if (skill.skills.isEmpty()) {
return Result.error(undefined);
}
return Result.ok(skill);
};
2024-04-23 15:56:52 +03:00
}
export class Skills {
@IsArray()
2024-05-29 15:38:36 +03:00
@Type(() => SkillModel)
skills: SkillModel[];
validation = (): Result<string[], void> => {
const errors: string[] = [];
this.skills.forEach((skill) => {
skill.BTAction.forEach((action) => {
if (action.param.isNotEmpty()) {
action.param.forEach((param) => {
if (Object.keys(param.dependency).isEmpty()) {
errors.push(param.type);
}
});
}
});
});
if (errors.isNotEmpty()) {
return Result.error(errors);
}
return Result.ok(undefined);
};
skillBySid = (sid: string) =>
SkillModel.isEmpty(
this.skills.reduce<SkillModel>((acc, el) => {
if (el.sid?.isEqual(sid)) {
acc = el;
}
return acc;
}, SkillModel.empty())
);
2024-05-13 20:43:11 +03:00
toSkillView = (): ISkillView[] =>
this.skills.map((el) => {
2024-04-23 15:56:52 +03:00
return {
name: el.Module.name,
children: el.BTAction.map((act) => {
return { name: act.name, uuid: v4() };
}),
};
});
2024-05-29 15:38:36 +03:00
getSkill = (name: string) =>
SkillModel.isEmpty(
this.skills.reduce<SkillModel>((acc, el) => {
if (el.BTAction.find((el) => el.name.isEqual(name))) {
el.BTAction.map((action) => {
action.param.map((param) => {
return param;
});
});
acc = el;
}
return acc;
}, SkillModel.empty())
);
2024-05-13 20:43:11 +03:00
getSkilsOut = (name: string) =>
this.skills
.reduce<string[][]>((acc, el) => {
if (el.BTAction.find((el) => el.name.isEqual(name))) {
acc = el.BTAction.filter((f) => f.name.isEqual(name)).map((z) => z.result);
}
return acc;
}, [])
.flat(1);
getSkillParams = (name: string) =>
this.skills
.reduce<IParam[][]>((acc, el) => {
if (el.BTAction.find((el) => el.name.isEqual(name))) {
acc = el.BTAction.filter((f) => f.name.isEqual(name)).map((z) => z.param);
}
return acc;
}, [])
.flat(1);
getSkillDo = (name: string) =>
this.skills.reduce((acc, el) => {
2024-04-23 15:56:52 +03:00
if (el.BTAction.find((el) => el.name.isEqual(name))) {
acc = el.Module.name;
}
return acc;
}, "error");
2024-05-13 20:43:11 +03:00
getSkillsNames = () =>
this.skills
2024-04-23 15:56:52 +03:00
.map((el) => {
return el.BTAction.map((act) => {
return { name: act.name };
});
})
.flat(1);
2024-05-13 20:43:11 +03:00
getForms = (skillLabel: string) =>
this.skills
2024-05-29 15:38:36 +03:00
.reduce<SkillModel[]>((acc, el) => {
2024-05-13 20:43:11 +03:00
if (el.BTAction.find((el) => el.name.isEqual(skillLabel))) {
acc.push(el);
}
return acc;
}, [])
.map((el) => el.BTAction.map((act) => act.param.map((el) => el.type).flat(1)))
.flat(1)
.flat(1)
.filter((el) => el !== "");
2024-05-29 15:38:36 +03:00
getDependencyBySkillLabelAndType = <T>(skillType: string, sid: string) =>
2024-05-13 20:43:11 +03:00
this.skills
2024-05-29 15:38:36 +03:00
.reduce<Object[]>((acc, skill) => {
if (skill.sid?.isEqual(sid)) {
skill.BTAction.map((action) => {
action.param.map((param) => {
if (param.type.isEqual(skillType)) {
acc.push(param.dependency);
}
return param;
});
return action;
});
2024-05-13 20:43:11 +03:00
}
2024-05-29 15:38:36 +03:00
2024-05-13 20:43:11 +03:00
return acc;
}, [])
.at(0) as T;
2024-05-29 15:38:36 +03:00
static isEmpty(model: Skills): Result<void, void> {
if (model.skills.isEmpty()) {
return Result.error(undefined);
}
return Result.ok(undefined);
}
static empty() {
const skills = new Skills();
skills.skills = [];
return skills;
}
public dependencyIsFilled = (skillType: string, sid: string) =>
this.skills.reduce((acc, skill) => {
if (skill.sid?.isEqual(sid)) {
skill.BTAction.forEach((action) => {
action.param.forEach((param) => {
if (param.type.isEqual(skillType)) {
// console.log('SKILL TYPE')
// console.log(skillType);
// console.log("SID")
// console.log(sid)
// console.log("DEPENDENCY")
// console.log(param.dependency)
acc = Object.keys(param.dependency).isNotEmpty();
}
});
});
}
return acc;
}, false);
getAllSids = () =>
this.skills.reduce((acc, skill) => {
skill.BTAction.forEach((action) =>
action.param.forEach((param) => {
// acc.incrementValue(param.sid ?? "empty");
return param;
})
);
return acc;
}, new Map<string, number>());
deleteSid(sid: string): SkillModel[] {
return this.skills.filter((skill) => !skill.sid?.isEqual(sid));
}
updateSkill = (skill: SkillModel) => {
console.log(skill);
this.skills = this.skills.map((el) => {
if (el.sid?.isEqual(skill.sid ?? "")) {
el = skill;
}
return el;
});
};
skillHasForm = (label: string): boolean => {
// TODO:NEED IMPLEMENTS
return true;
};
2024-04-23 15:56:52 +03:00
}