Move entities decode methods to entities

This commit is contained in:
barsdeveloper
2023-01-28 23:33:08 +01:00
parent daf6abf038
commit 2ccb0dc519
15 changed files with 538 additions and 520 deletions

View File

@@ -1,6 +1,4 @@
import { css } from "lit"
import SVGIcon from "./SVGIcon"
import Utility from "./Utility"
/**
* @typedef {import("./element/NodeElement").default} NodeElement
@@ -9,28 +7,6 @@ import Utility from "./Utility"
*/
export default class Configuration {
static #pinColor = {
"/Script/CoreUObject.Rotator": css`157, 177, 251`,
"/Script/CoreUObject.Transform": css`227, 103, 0`,
"/Script/CoreUObject.Vector": css`251, 198, 34`,
"bool": css`147, 0, 0`,
"byte": css`0, 109, 99`,
"class": css`88, 0, 186`,
"default": css`255, 255, 255`,
"delegate": css`255, 56, 56`,
"enum": css`0, 109, 99`,
"exec": css`240, 240, 240`,
"int": css`31, 224, 172`,
"int64": css`169, 223, 172`,
"interface": css`238, 252, 168`,
"name": css`201, 128, 251`,
"object": css`0, 167, 240`,
"real": css`54, 208, 0`,
"string": css`251, 0, 209`,
"struct": css`0, 88, 201`,
"text": css`226, 121, 167`,
"wildcard": css`128, 120, 120`,
}
static nodeColors = {
blue: css`84, 122, 156`,
gray: css`150,150,150`,
@@ -38,18 +14,6 @@ export default class Configuration {
red: css`151, 33, 32`,
turquoise: css`46, 104, 106`,
}
static #keyName = {
"A_AccentGrave": "à",
"E_AccentGrave": "è",
"E_AccentAigu": "é",
"Add": "Num +",
"Decimal": "Num .",
"Divide": "Num /",
"Multiply": "Num *",
"Subtract": "Num -",
"Section": "§",
"C_Cedille": "ç",
}
static alphaPattern = "repeating-conic-gradient(#7c8184 0% 25%, #c2c3c4 0% 50%) 50% / 10px 10px"
static colorDragEventName = "ueb-color-drag"
static colorPickEventName = "ueb-color-pick"
@@ -80,28 +44,6 @@ export default class Configuration {
static gridShrinkThreshold = 4 // exceding size factor threshold to cause a shrink event
static gridSize = 16 // px
static hexColorRegex = /^\s*#(?<r>[0-9a-fA-F]{2})(?<g>[0-9a-fA-F]{2})(?<b>[0-9a-fA-F]{2})([0-9a-fA-F]{2})?|#(?<rs>[0-9a-fA-F])(?<gs>[0-9a-fA-F])(?<bs>[0-9a-fA-F])\s*$/
/** @param {String} value */
static keyName(value) {
let result = Configuration.#keyName[value]
if (result) {
return result
}
result = Utility.numberFromText(value)?.toString()
if (result) {
return result
}
const match = value.match(/NumPad([a-zA-Z]+)/)
if (match) {
result = Utility.numberFromText(match[1])
if (result) {
return "Num " + result
}
}
}
/** @param {NodeElement} node */
static hidAttribute(node) {
return node.entity.InputKey ?? node.entity.AxisKey ?? node.entity.InputAxisKey
}
static keysSeparator = "+"
static linkCurveHeight = 15 // px
static linkCurveWidth = 80 // px
@@ -120,156 +62,7 @@ export default class Configuration {
static mouseWheelFactor = 0.2
static nodeDragGeneralEventName = "ueb-node-drag-general"
static nodeDragEventName = "ueb-node-drag"
/** @param {NodeElement} node */
static nodeIcon(node) {
switch (node.getType()) {
case Configuration.nodeType.doN: return SVGIcon.doN
case Configuration.nodeType.dynamicCast: return SVGIcon.cast
case Configuration.nodeType.event:
case Configuration.nodeType.customEvent:
return SVGIcon.event
case Configuration.nodeType.executionSequence: return SVGIcon.sequence
case Configuration.nodeType.forEachElementInEnum: return SVGIcon.loop
case Configuration.nodeType.forEachLoop: return SVGIcon.forEachLoop
case Configuration.nodeType.forEachLoopWithBreak: return SVGIcon.forEachLoop
case Configuration.nodeType.forLoop: return SVGIcon.loop
case Configuration.nodeType.forLoopWithBreak: return SVGIcon.loop
case Configuration.nodeType.ifThenElse: return SVGIcon.branchNode
case Configuration.nodeType.makeArray: return SVGIcon.makeArray
case Configuration.nodeType.makeMap: return SVGIcon.makeMap
case Configuration.nodeType.makeSet: return SVGIcon.makeSet
case Configuration.nodeType.select: return SVGIcon.select
case Configuration.nodeType.whileLoop: return SVGIcon.loop
}
if (node.getNodeDisplayName().startsWith("Break")) {
return SVGIcon.breakStruct
}
if (node.entity.getClass() === Configuration.nodeType.macro) {
return SVGIcon.macro
}
const hidValue = Configuration.hidAttribute(node)
if (hidValue) {
if (hidValue.toString().includes("Mouse")) {
return SVGIcon.mouse
} else {
return SVGIcon.keyboard
}
}
return SVGIcon.functionSymbol
}
/** @param {NodeElement} node */
static nodeColor(node) {
switch (node.entity.getClass()) {
case Configuration.nodeType.callFunction:
return node.entity.bIsPureFunc
? Configuration.nodeColors.green
: Configuration.nodeColors.blue
case Configuration.nodeType.event:
case Configuration.nodeType.customEvent:
case Configuration.nodeType.inputKey:
case Configuration.nodeType.inputAxisKeyEvent:
case Configuration.nodeType.inputDebugKey:
return Configuration.nodeColors.red
case Configuration.nodeType.makeArray:
case Configuration.nodeType.makeMap:
case Configuration.nodeType.select:
return Configuration.nodeColors.green
case Configuration.nodeType.executionSequence:
case Configuration.nodeType.ifThenElse:
case Configuration.nodeType.macro:
return Configuration.nodeColors.gray
case Configuration.nodeType.dynamicCast:
return Configuration.nodeColors.turquoise
}
if (node.entity.bIsPureFunc) {
return Configuration.nodeColors.green
}
if (node.isEvent()) {
return Configuration.nodeColors.red
}
return Configuration.nodeColors.blue
}
static nodeName = (name, counter) => `${name}_${counter}`
/** @param {NodeElement} node */
static nodeDisplayName(node) {
switch (node.getType()) {
case Configuration.nodeType.callFunction:
case Configuration.nodeType.commutativeAssociativeBinaryOperator:
let memberName = node.entity.FunctionReference.MemberName ?? ""
const memberParent = node.entity.FunctionReference.MemberParent?.path ?? ""
if (memberName === "AddKey") {
const sequencerScriptingNameRegex = /\/Script\/SequencerScripting\.MovieSceneScripting(.+)Channel/
let result = memberParent.match(sequencerScriptingNameRegex)
if (result) {
return `Add Key (${Utility.formatStringName(result[1])})`
}
}
if (memberParent == "/Script/Engine.KismetMathLibrary") {
if (memberName.startsWith("Conv_")) {
return "" // Conversion nodes do not have visible names
}
if (memberName.startsWith("Percent_")) {
return "%"
}
const leadingLetter = memberName.match(/[BF]([A-Z]\w+)/)
if (leadingLetter) {
// Some functions start with B or F (Like FCeil, FMax, BMin)
memberName = leadingLetter[1]
}
switch (memberName) {
case "Abs": return "ABS"
case "Exp": return "e"
case "Max": return "MAX"
case "MaxInt64": return "MAX"
case "Min": return "MIN"
case "MinInt64": return "MIN"
}
}
if (memberParent === "/Script/Engine.BlueprintSetLibrary") {
const setOperationMatch = memberName.match(/Set_(\w+)/)
if (setOperationMatch) {
return Utility.formatStringName(setOperationMatch[1]).toUpperCase()
}
}
if (memberParent === "/Script/Engine.BlueprintMapLibrary") {
const setOperationMatch = memberName.match(/Map_(\w+)/)
if (setOperationMatch) {
return Utility.formatStringName(setOperationMatch[1]).toUpperCase()
}
}
return Utility.formatStringName(memberName)
case Configuration.nodeType.dynamicCast:
return `Cast To ${node.entity.TargetType.getName()}`
case Configuration.nodeType.event:
return `Event ${(node.entity.EventReference?.MemberName ?? "").replace(/^Receive/, "")}`
case Configuration.nodeType.executionSequence:
return "Sequence"
case Configuration.nodeType.forEachElementInEnum:
return `For Each ${node.entity.Enum.getName()}`
case Configuration.nodeType.forEachLoopWithBreak:
return "For Each Loop with Break"
case Configuration.nodeType.ifThenElse:
return "Branch"
case Configuration.nodeType.variableGet:
return ""
case Configuration.nodeType.variableSet:
return "SET"
}
const keyNameSymbol = Configuration.hidAttribute(node)
if (keyNameSymbol) {
const keyName = keyNameSymbol.toString()
let title = Configuration.keyName(keyName) ?? Utility.formatStringName(keyName)
if (node.entity.getClass() === Configuration.nodeType.inputDebugKey) {
title = "Debug Key " + title
}
return title
}
if (node.entity.getClass() === Configuration.nodeType.macro) {
return Utility.formatStringName(node.entity.MacroGraphReference.getMacroName())
} else {
return Utility.formatStringName(node.entity.getNameAndCounter()[0])
}
}
static nodeRadius = 8 // px
static nodeReflowEventName = "ueb-node-reflow"
static nodeType = {
@@ -306,14 +99,27 @@ export default class Configuration {
variableSet: "/Script/BlueprintGraph.K2Node_VariableSet",
whileLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:WhileLoop",
}
/**
* @param {PinElement} pin
* @return {CSSResult}
*/
static pinColor(pin) {
return Configuration.#pinColor[pin.entity.getType()]
?? Configuration.#pinColor[pin.entity.PinType.PinCategory]
?? Configuration.#pinColor["default"]
static pinColor = {
"/Script/CoreUObject.Rotator": css`157, 177, 251`,
"/Script/CoreUObject.Transform": css`227, 103, 0`,
"/Script/CoreUObject.Vector": css`251, 198, 34`,
"bool": css`147, 0, 0`,
"byte": css`0, 109, 99`,
"class": css`88, 0, 186`,
"default": css`255, 255, 255`,
"delegate": css`255, 56, 56`,
"enum": css`0, 109, 99`,
"exec": css`240, 240, 240`,
"int": css`31, 224, 172`,
"int64": css`169, 223, 172`,
"interface": css`238, 252, 168`,
"name": css`201, 128, 251`,
"object": css`0, 167, 240`,
"real": css`54, 208, 0`,
"string": css`251, 0, 209`,
"struct": css`0, 88, 201`,
"text": css`226, 121, 167`,
"wildcard": css`128, 120, 120`,
}
static removeEventName = "ueb-element-delete"
static scale = {

View File

@@ -225,7 +225,7 @@ export default class NodeElement extends ISelectableDraggableElement {
}
getNodeDisplayName() {
return Configuration.nodeDisplayName(this)
return this.entity.nodeDisplayName()
}
/** @param {Number} value */
@@ -279,10 +279,6 @@ export default class NodeElement extends ISelectableDraggableElement {
super.setLocation(x, y, acknowledge)
}
isEvent() {
return this.template instanceof EventNodeTemplate
}
acknowledgeReflow() {
this.requestUpdate()
this.updateComplete.then(() => this.computeSizes())

View File

@@ -1,5 +1,4 @@
import BoolPinTemplate from "../template/pin/BoolPinTemplate"
import Configuration from "../Configuration"
import ElementFactory from "./ElementFactory"
import ExecPinTemplate from "../template/pin/ExecPinTemplate"
import GuidEntity from "../entity/GuidEntity"
@@ -175,7 +174,7 @@ export default class PinElement extends IElement {
/** @return {CSSResult} */
getColor() {
return Configuration.pinColor(this)
return this.entity.pinColor()
}
isInput() {

View File

@@ -8,7 +8,9 @@ import LinearColorEntity from "./LinearColorEntity"
import MacroGraphReferenceEntity from "./MacroGraphReferenceEntity"
import ObjectReferenceEntity from "./ObjectReferenceEntity"
import PinEntity from "./PinEntity"
import SVGIcon from "../SVGIcon"
import SymbolEntity from "./SymbolEntity"
import Utility from "../Utility"
import VariableReferenceEntity from "./VariableReferenceEntity"
export default class ObjectEntity extends IEntity {
@@ -186,11 +188,42 @@ export default class ObjectEntity extends IEntity {
static nameRegex = /^(\w+?)(?:_(\d+))?$/
static sequencerScriptingNameRegex = /\/Script\/SequencerScripting\.MovieSceneScripting(.+)Channel/
static #keyName = {
"A_AccentGrave": "à",
"E_AccentGrave": "è",
"E_AccentAigu": "é",
"Add": "Num +",
"Decimal": "Num .",
"Divide": "Num /",
"Multiply": "Num *",
"Subtract": "Num -",
"Section": "§",
"C_Cedille": "ç",
}
static {
this.cleanupAttributes(this.attributes)
}
/** @param {String} value */
static keyName(value) {
let result = ObjectEntity.#keyName[value]
if (result) {
return result
}
result = Utility.numberFromText(value)?.toString()
if (result) {
return result
}
const match = value.match(/NumPad([a-zA-Z]+)/)
if (match) {
result = Utility.numberFromText(match[1])
if (result) {
return "Num " + result
}
}
}
constructor(values, suppressWarns = false) {
super(values, suppressWarns)
/** @type {ObjectReferenceEntity} */ this.Class
@@ -315,13 +348,178 @@ export default class ObjectEntity extends IEntity {
this.NodePosY.value = Math.round(value)
}
isEvent() {
if (
this.getClass() === Configuration.nodeType.event
|| this.getClass() === Configuration.nodeType.customEvent
) {
return true
}
if (this.getDelegatePin()) {
return true
}
return false
}
isDevelopmentOnly() {
const nodeClass = this.getClass()
return this.EnabledState?.toString() === "DevelopmentOnly"
|| nodeClass.includes("Debug", Math.max(0, nodeClass.lastIndexOf(".")))
}
hasHIDAttribute() {
return this.InputKey ?? this.AxisKey ?? this.InputAxisKey
}
getDelegatePin() {
return this.CustomProperties?.find(pin => pin.PinType.PinCategory === "delegate")
}
nodeDisplayName() {
switch (this.getType()) {
case Configuration.nodeType.callFunction:
case Configuration.nodeType.commutativeAssociativeBinaryOperator:
let memberName = this.FunctionReference.MemberName ?? ""
const memberParent = this.FunctionReference.MemberParent?.path ?? ""
if (memberName === "AddKey") {
let result = memberParent.match(ObjectEntity.sequencerScriptingNameRegex)
if (result) {
return `Add Key (${Utility.formatStringName(result[1])})`
}
}
if (memberParent == "/Script/Engine.KismetMathLibrary") {
if (memberName.startsWith("Conv_")) {
return "" // Conversion nodes do not have visible names
}
if (memberName.startsWith("Percent_")) {
return "%"
}
const leadingLetter = memberName.match(/[BF]([A-Z]\w+)/)
if (leadingLetter) {
// Some functions start with B or F (Like FCeil, FMax, BMin)
memberName = leadingLetter[1]
}
switch (memberName) {
case "Abs": return "ABS"
case "Exp": return "e"
case "Max": return "MAX"
case "MaxInt64": return "MAX"
case "Min": return "MIN"
case "MinInt64": return "MIN"
}
}
if (memberParent === "/Script/Engine.BlueprintSetLibrary") {
const setOperationMatch = memberName.match(/Set_(\w+)/)
if (setOperationMatch) {
return Utility.formatStringName(setOperationMatch[1]).toUpperCase()
}
}
if (memberParent === "/Script/Engine.BlueprintMapLibrary") {
const setOperationMatch = memberName.match(/Map_(\w+)/)
if (setOperationMatch) {
return Utility.formatStringName(setOperationMatch[1]).toUpperCase()
}
}
return Utility.formatStringName(memberName)
case Configuration.nodeType.dynamicCast:
return `Cast To ${this.TargetType.getName()}`
case Configuration.nodeType.event:
return `Event ${(this.EventReference?.MemberName ?? "").replace(/^Receive/, "")}`
case Configuration.nodeType.executionSequence:
return "Sequence"
case Configuration.nodeType.forEachElementInEnum:
return `For Each ${this.Enum.getName()}`
case Configuration.nodeType.forEachLoopWithBreak:
return "For Each Loop with Break"
case Configuration.nodeType.ifThenElse:
return "Branch"
case Configuration.nodeType.variableGet:
return ""
case Configuration.nodeType.variableSet:
return "SET"
}
const keyNameSymbol = this.hasHIDAttribute()
if (keyNameSymbol) {
const keyName = keyNameSymbol.toString()
let title = ObjectEntity.keyName(keyName) ?? Utility.formatStringName(keyName)
if (this.getClass() === Configuration.nodeType.inputDebugKey) {
title = "Debug Key " + title
}
return title
}
if (this.getClass() === Configuration.nodeType.macro) {
return Utility.formatStringName(this.MacroGraphReference.getMacroName())
} else {
return Utility.formatStringName(this.getNameAndCounter()[0])
}
}
nodeColor() {
switch (this.getClass()) {
case Configuration.nodeType.callFunction:
return this.bIsPureFunc
? Configuration.nodeColors.green
: Configuration.nodeColors.blue
case Configuration.nodeType.event:
case Configuration.nodeType.customEvent:
case Configuration.nodeType.inputKey:
case Configuration.nodeType.inputAxisKeyEvent:
case Configuration.nodeType.inputDebugKey:
return Configuration.nodeColors.red
case Configuration.nodeType.makeArray:
case Configuration.nodeType.makeMap:
case Configuration.nodeType.select:
return Configuration.nodeColors.green
case Configuration.nodeType.executionSequence:
case Configuration.nodeType.ifThenElse:
case Configuration.nodeType.macro:
return Configuration.nodeColors.gray
case Configuration.nodeType.dynamicCast:
return Configuration.nodeColors.turquoise
}
if (this.bIsPureFunc) {
return Configuration.nodeColors.green
}
if (this.isEvent()) {
return Configuration.nodeColors.red
}
return Configuration.nodeColors.blue
}
nodeIcon() {
switch (this.getType()) {
case Configuration.nodeType.doN: return SVGIcon.doN
case Configuration.nodeType.dynamicCast: return SVGIcon.cast
case Configuration.nodeType.event:
case Configuration.nodeType.customEvent:
return SVGIcon.event
case Configuration.nodeType.executionSequence: return SVGIcon.sequence
case Configuration.nodeType.forEachElementInEnum: return SVGIcon.loop
case Configuration.nodeType.forEachLoop: return SVGIcon.forEachLoop
case Configuration.nodeType.forEachLoopWithBreak: return SVGIcon.forEachLoop
case Configuration.nodeType.forLoop: return SVGIcon.loop
case Configuration.nodeType.forLoopWithBreak: return SVGIcon.loop
case Configuration.nodeType.ifThenElse: return SVGIcon.branchNode
case Configuration.nodeType.makeArray: return SVGIcon.makeArray
case Configuration.nodeType.makeMap: return SVGIcon.makeMap
case Configuration.nodeType.makeSet: return SVGIcon.makeSet
case Configuration.nodeType.select: return SVGIcon.select
case Configuration.nodeType.whileLoop: return SVGIcon.loop
}
if (this.nodeDisplayName().startsWith("Break")) {
return SVGIcon.breakStruct
}
if (this.getClass() === Configuration.nodeType.macro) {
return SVGIcon.macro
}
const hidValue = this.hasHIDAttribute()
if (hidValue) {
if (hidValue.toString().includes("Mouse")) {
return SVGIcon.mouse
} else {
return SVGIcon.keyboard
}
}
return SVGIcon.functionSymbol
}
}

View File

@@ -22,7 +22,10 @@ import Utility from "../Utility"
import Vector2DEntity from "./Vector2DEntity"
import VectorEntity from "./VectorEntity"
/** @typedef {import("./IEntity").AnyValue} AnyValue */
/**
* @typedef {import("./IEntity").AnyValue} AnyValue
* @typedef {import("lit").CSSResult} CSSResult
*/
/** @template {AnyValue} T */
export default class PinEntity extends IEntity {
@@ -278,4 +281,11 @@ export default class PinEntity extends IEntity {
getSubCategory() {
return this.PinType.PinSubCategoryObject.path
}
/** @return {CSSResult} */
pinColor() {
return Configuration.pinColor[this.getType()]
?? Configuration.pinColor[this.PinType.PinCategory]
?? Configuration.pinColor["default"]
}
}

View File

@@ -1,5 +1,4 @@
import { html, nothing } from "lit"
import Configuration from "../../Configuration"
import ElementFactory from "../../element/ElementFactory"
import ISelectableDraggableTemplate from "../ISelectableDraggableTemplate"
import SVGIcon from "../../SVGIcon"
@@ -34,7 +33,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
}
getColor() {
return Configuration.nodeColor(this.element)
return this.element.entity.nodeColor()
}
render() {
@@ -62,7 +61,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
}
renderNodeIcon() {
return Configuration.nodeIcon(this.element)
return this.element.entity.nodeIcon()
}
renderNodeName() {

View File

@@ -1,5 +1,4 @@
import { html, nothing } from "lit"
import Configuration from "../../Configuration"
import ITemplate from "../ITemplate"
import MouseCreateLink from "../../input/mouse/MouseCreateLink"
import SVGIcon from "../../SVGIcon"
@@ -103,7 +102,7 @@ export default class PinTemplate extends ITemplate {
/** @param {PropertyValues} changedProperties */
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties)
this.element.style.setProperty("--ueb-pin-color-rgb", Configuration.pinColor(this.element).cssText)
this.element.style.setProperty("--ueb-pin-color-rgb", this.element.entity.pinColor().cssText)
this.#iconElement = this.element.querySelector(".ueb-pin-icon svg") ?? this.element
}