Compare commits

...

3 Commits

Author SHA1 Message Date
barsdeveloper
74edd2b9d8 More tests 2025-02-04 23:53:45 +02:00
barsdeveloper
72057d6c4b Shorting repetitive bits 2025-02-04 23:22:17 +02:00
barsdeveloper
2f357818f4 Refactoring WIP 2025-02-04 23:11:46 +02:00
30 changed files with 1145 additions and 567 deletions

16
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Launch Blueprintue",
"type": "firefox",
"request": "launch",
"reAttach": true,
"url": "http://127.0.0.1:8080/debug.html",
"tmpDir": "~/.tmp/"
},
]
}

648
dist/ueblueprint.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -85,7 +85,6 @@ export default class Blueprint extends IElement {
nodesNames = new Map()
/** @type {Coordinates} */
mousePosition = [0, 0]
waitingExpandUpdate = false
constructor() {
super()

View File

@@ -93,9 +93,9 @@ export default class Configuration {
static mouseWheelZoomThreshold = 80
static nodeDragEventName = "ueb-node-drag"
static nodeDragGeneralEventName = "ueb-node-drag-general"
static nodeTitle = (name, counter) => `${name}_${counter}`
static nodeRadius = 8 // px
static nodeReflowEventName = "ueb-node-reflow"
static nodeTitle = (name, counter) => `${name}_${counter}`
static nodeUpdateEventName = "ueb-node-update"
static paths = {
actorBoundEvent: "/Script/BlueprintGraph.K2Node_ActorBoundEvent",
addDelegate: "/Script/BlueprintGraph.K2Node_AddDelegate",
@@ -215,6 +215,7 @@ export default class Configuration {
timeline: "/Script/BlueprintGraph.K2Node_Timeline",
timeManagementBlueprintLibrary: "/Script/TimeManagement.TimeManagementBlueprintLibrary",
transform: "/Script/CoreUObject.Transform",
typedElementHandleLibrary: "/Script/TypedElementFramework.TypedElementHandleLibrary",
userDefinedEnum: "/Script/Engine.UserDefinedEnum",
variableGet: "/Script/BlueprintGraph.K2Node_VariableGet",
variableSet: "/Script/BlueprintGraph.K2Node_VariableSet",
@@ -226,6 +227,7 @@ export default class Configuration {
whileLoop: "/Engine/EditorBlueprintResources/StandardMacros.StandardMacros:WhileLoop",
}
static pinInputWrapWidth = 145 // px
static pinUpdateEventName = "ueb-pin-update"
static removeEventName = "ueb-element-delete"
static scale = {
[-12]: 0.133333,

View File

@@ -1,26 +1,28 @@
import Configuration from "../Configuration.js"
import LinearColorEntity from "../entity/LinearColorEntity.js"
const p = Configuration.paths
/** @param {ObjectEntity} entity */
export default function nodeColor(entity) {
switch (entity.getType()) {
case Configuration.paths.materialExpressionConstant2Vector:
case Configuration.paths.materialExpressionConstant3Vector:
case Configuration.paths.materialExpressionConstant4Vector:
case p.materialExpressionConstant2Vector:
case p.materialExpressionConstant3Vector:
case p.materialExpressionConstant4Vector:
return Configuration.nodeColors.yellow
case Configuration.paths.materialExpressionFunctionInput:
case Configuration.paths.materialExpressionTextureCoordinate:
case Configuration.paths.materialExpressionWorldPosition:
case Configuration.paths.pcgEditorGraphNodeInput:
case Configuration.paths.pcgEditorGraphNodeOutput:
case p.materialExpressionFunctionInput:
case p.materialExpressionTextureCoordinate:
case p.materialExpressionWorldPosition:
case p.pcgEditorGraphNodeInput:
case p.pcgEditorGraphNodeOutput:
return Configuration.nodeColors.red
case Configuration.paths.makeStruct:
case p.makeStruct:
return Configuration.nodeColors.darkBlue
case Configuration.paths.materialExpressionMaterialFunctionCall:
case p.materialExpressionMaterialFunctionCall:
return Configuration.nodeColors.blue
case Configuration.paths.materialExpressionTextureSample:
case p.materialExpressionTextureSample:
return Configuration.nodeColors.darkTurquoise
case Configuration.paths.niagaraNodeInput:
case p.niagaraNodeInput:
switch (entity["Usage"]?.toString()) {
case "Attribute": return Configuration.nodeColors.intenseGreen
case "Parameter": return Configuration.nodeColors.red
@@ -31,29 +33,29 @@ export default function nodeColor(entity) {
}
}
switch (entity.getClass()) {
case Configuration.paths.niagaraNodeFunctionCall:
case p.niagaraNodeFunctionCall:
return Configuration.nodeColors.darkerBlue
case Configuration.paths.dynamicCast:
case p.dynamicCast:
return Configuration.nodeColors.turquoise
case Configuration.paths.inputDebugKey:
case Configuration.paths.inputKey:
case p.inputDebugKey:
case p.inputKey:
return Configuration.nodeColors.red
case Configuration.paths.createDelegate:
case Configuration.paths.enumLiteral:
case Configuration.paths.makeArray:
case Configuration.paths.makeMap:
case Configuration.paths.materialGraphNode:
case Configuration.paths.select:
case p.createDelegate:
case p.enumLiteral:
case p.makeArray:
case p.makeMap:
case p.materialGraphNode:
case p.select:
return Configuration.nodeColors.green
case Configuration.paths.executionSequence:
case Configuration.paths.ifThenElse:
case Configuration.paths.macro:
case Configuration.paths.multiGate:
case p.executionSequence:
case p.ifThenElse:
case p.macro:
case p.multiGate:
return Configuration.nodeColors.gray
case Configuration.paths.functionEntry:
case Configuration.paths.functionResult:
case p.functionEntry:
case p.functionResult:
return Configuration.nodeColors.violet
case Configuration.paths.timeline:
case p.timeline:
return Configuration.nodeColors.yellow
}
if (entity.switchTarget()) {

View File

@@ -2,50 +2,52 @@ import Configuration from "../Configuration.js"
import SVGIcon from "../SVGIcon.js"
import nodeTitle from "./nodeTitle.js"
const p = Configuration.paths
/** @param {ObjectEntity} entity */
export default function nodeIcon(entity) {
if (entity.isMaterial() || entity.isPcg() || entity.isNiagara()) {
return null
}
switch (entity.getType()) {
case Configuration.paths.addDelegate:
case Configuration.paths.asyncAction:
case Configuration.paths.callDelegate:
case Configuration.paths.clearDelegate:
case Configuration.paths.createDelegate:
case Configuration.paths.functionEntry:
case Configuration.paths.functionResult:
case Configuration.paths.removeDelegate:
case p.addDelegate:
case p.asyncAction:
case p.callDelegate:
case p.clearDelegate:
case p.createDelegate:
case p.functionEntry:
case p.functionResult:
case p.removeDelegate:
return SVGIcon.node
case Configuration.paths.customEvent: return SVGIcon.event
case Configuration.paths.doN: return SVGIcon.doN
case Configuration.paths.doOnce: return SVGIcon.doOnce
case Configuration.paths.dynamicCast: return SVGIcon.cast
case Configuration.paths.enumLiteral: return SVGIcon.enum
case Configuration.paths.event: return SVGIcon.event
case Configuration.paths.executionSequence:
case Configuration.paths.multiGate:
case p.customEvent: return SVGIcon.event
case p.doN: return SVGIcon.doN
case p.doOnce: return SVGIcon.doOnce
case p.dynamicCast: return SVGIcon.cast
case p.enumLiteral: return SVGIcon.enum
case p.event: return SVGIcon.event
case p.executionSequence:
case p.multiGate:
return SVGIcon.sequence
case Configuration.paths.flipflop:
case p.flipflop:
return SVGIcon.flipflop
case Configuration.paths.forEachElementInEnum:
case Configuration.paths.forLoop:
case Configuration.paths.forLoopWithBreak:
case Configuration.paths.whileLoop:
case p.forEachElementInEnum:
case p.forLoop:
case p.forLoopWithBreak:
case p.whileLoop:
return SVGIcon.loop
case Configuration.paths.forEachLoop:
case Configuration.paths.forEachLoopWithBreak:
case p.forEachLoop:
case p.forEachLoopWithBreak:
return SVGIcon.forEachLoop
case Configuration.paths.ifThenElse: return SVGIcon.branchNode
case Configuration.paths.isValid: return SVGIcon.questionMark
case Configuration.paths.makeArray: return SVGIcon.makeArray
case Configuration.paths.makeMap: return SVGIcon.makeMap
case Configuration.paths.makeSet: return SVGIcon.makeSet
case Configuration.paths.makeStruct: return SVGIcon.makeStruct
case Configuration.paths.metasoundEditorGraphExternalNode: return SVGIcon.metasoundFunction
case Configuration.paths.select: return SVGIcon.select
case Configuration.paths.spawnActorFromClass: return SVGIcon.spawnActor
case Configuration.paths.timeline: return SVGIcon.timer
case p.ifThenElse: return SVGIcon.branchNode
case p.isValid: return SVGIcon.questionMark
case p.makeArray: return SVGIcon.makeArray
case p.makeMap: return SVGIcon.makeMap
case p.makeSet: return SVGIcon.makeSet
case p.makeStruct: return SVGIcon.makeStruct
case p.metasoundEditorGraphExternalNode: return SVGIcon.metasoundFunction
case p.select: return SVGIcon.select
case p.spawnActorFromClass: return SVGIcon.spawnActor
case p.timeline: return SVGIcon.timer
}
if (entity.switchTarget()) {
return SVGIcon.switch
@@ -53,7 +55,7 @@ export default function nodeIcon(entity) {
if (nodeTitle(entity).startsWith("Break")) {
return SVGIcon.breakStruct
}
if (entity.getClass() === Configuration.paths.macro) {
if (entity.getClass() === p.macro) {
return SVGIcon.macro
}
const hidValue = entity.getHIDAttribute()?.toString()
@@ -73,7 +75,7 @@ export default function nodeIcon(entity) {
if (entity.getDelegatePin()) {
return SVGIcon.event
}
if (entity.ObjectRef?.type === Configuration.paths.ambientSound) {
if (entity.ObjectRef?.type === p.ambientSound) {
return SVGIcon.sound
}
return SVGIcon.functionSymbol

View File

@@ -2,16 +2,18 @@ import Configuration from "../Configuration.js"
import Utility from "../Utility.js"
import pinTitle from "./pinTitle.js"
const p = Configuration.paths
/**
* @param {ObjectEntity} entity
* @returns {String?}
*/
export default function nodeSubtitle(entity) {
switch (entity.getType()) {
case Configuration.paths.addDelegate:
case Configuration.paths.clearDelegate:
case Configuration.paths.callDelegate:
case Configuration.paths.removeDelegate:
case p.addDelegate:
case p.clearDelegate:
case p.callDelegate:
case p.removeDelegate:
return null
}
const targetPin = entity

View File

@@ -71,7 +71,7 @@ const niagaraOperationNodes = [
"Vector3::Cross",
]
const paths = Configuration.paths
const p = Configuration.paths
/**
* @param {ObjectEntity} nodeEntity
@@ -80,17 +80,18 @@ const paths = Configuration.paths
export default function nodeTemplateClass(nodeEntity) {
const className = nodeEntity.getClass()
if (
className === paths.callFunction
|| className === paths.commutativeAssociativeBinaryOperator
|| className === paths.callArrayFunction
className === p.callFunction
|| className === p.commutativeAssociativeBinaryOperator
|| className === p.callArrayFunction
) {
const memberParent = nodeEntity.FunctionReference?.MemberParent?.path ?? ""
const memberName = nodeEntity.FunctionReference?.MemberName?.toString()
if (
memberName && (
memberParent === paths.kismetMathLibrary
|| memberParent === paths.kismetArrayLibrary
|| memberParent === paths.kismetStringLibrary
memberParent === p.kismetArrayLibrary
|| memberParent === p.kismetMathLibrary
|| memberParent === p.kismetStringLibrary
|| memberParent === p.typedElementHandleLibrary
)) {
if (memberName.startsWith("Conv_")) {
return VariableConversionNodeTemplate
@@ -117,6 +118,7 @@ export default function nodeTemplateClass(nodeEntity) {
case "BMin":
case "CrossProduct2D":
case "DotProduct2D":
case "Equal":
case "Exp":
case "FMax":
case "FMin":
@@ -143,37 +145,37 @@ export default function nodeTemplateClass(nodeEntity) {
return VariableOperationNodeTemplate
}
}
if (memberParent === paths.blueprintSetLibrary) {
if (memberParent === p.blueprintSetLibrary) {
return VariableOperationNodeTemplate
}
if (memberParent === paths.blueprintMapLibrary) {
if (memberParent === p.blueprintMapLibrary) {
return VariableOperationNodeTemplate
}
}
switch (className) {
case paths.comment:
case paths.materialGraphNodeComment:
case p.comment:
case p.materialGraphNodeComment:
return CommentNodeTemplate
case paths.createDelegate:
case p.createDelegate:
return NodeTemplate
case paths.metasoundEditorGraphExternalNode:
case p.metasoundEditorGraphExternalNode:
if (nodeEntity["ClassName"]?.["Name"] == "Add") {
return MetasoundOperationTemplate
}
return MetasoundNodeTemplate
case paths.niagaraNodeOp:
case p.niagaraNodeOp:
if (niagaraOperationNodes.includes(nodeEntity.OpName?.toString())) {
return VariableOperationNodeTemplate
}
break
case paths.promotableOperator:
case p.promotableOperator:
return VariableOperationNodeTemplate
case paths.knot:
case p.knot:
return KnotNodeTemplate
case paths.literal:
case paths.self:
case paths.variableGet:
case paths.variableSet:
case p.literal:
case p.self:
case p.variableGet:
case p.variableSet:
return VariableAccessNodeTemplate
}
if (nodeEntity.isEvent()) {

View File

@@ -5,7 +5,6 @@ import LinearColorEntity from "../entity/LinearColorEntity.js"
import MirroredEntity from "../entity/MirroredEntity.js"
import VectorEntity from "../entity/VectorEntity.js"
const paths = Configuration.paths
const sequencerScriptingNameRegex = /\/Script\/SequencerScripting\.MovieSceneScripting(.+)Channel/
const keyNameValue = {
"A_AccentGrave": "à",
@@ -95,6 +94,8 @@ const niagaraNodeNames = {
"TWO_PI": `2 ${String.fromCharCode(0x03C0)}`,
}).map(([k, v]) => ["Numeric::" + k, v])),
}
const p = Configuration.paths
const format = Utility.formatStringName
/** @param {String} value */
function numberFromText(value = "") {
@@ -139,58 +140,58 @@ function keyName(value) {
export default function nodeTitle(entity) {
let value
switch (entity.getType()) {
case paths.addDelegate:
case p.addDelegate:
value ??= "Bind Event to "
case paths.clearDelegate:
case p.clearDelegate:
value ??= "Unbind all Events from "
case paths.removeDelegate:
case p.removeDelegate:
value ??= "Unbind Event from "
return value + Utility.formatStringName(
return value + format(
entity.DelegateReference?.MemberName?.toString().replace(/Delegate$/, "") ?? "None"
)
case paths.asyncAction:
case p.asyncAction:
if (entity.ProxyFactoryFunctionName) {
return Utility.formatStringName(entity.ProxyFactoryFunctionName?.toString())
return format(entity.ProxyFactoryFunctionName?.toString())
}
case paths.actorBoundEvent:
case paths.componentBoundEvent:
return `${Utility.formatStringName(entity.DelegatePropertyName?.toString())} (${entity.ComponentPropertyName?.toString() ?? "Unknown"})`
case paths.callDelegate:
case p.actorBoundEvent:
case p.componentBoundEvent:
return `${format(entity.DelegatePropertyName?.toString())} (${entity.ComponentPropertyName?.toString() ?? "Unknown"})`
case p.callDelegate:
return `Call ${entity.DelegateReference?.MemberName?.toString() ?? "None"}`
case paths.createDelegate:
case p.createDelegate:
return "Create Event"
case paths.customEvent:
case p.customEvent:
if (entity.CustomFunctionName) {
return entity.CustomFunctionName?.toString()
}
case paths.dynamicCast:
case p.dynamicCast:
if (!entity.TargetType) {
return "Bad cast node" // Target type not found
}
return `Cast To ${entity.TargetType?.getName()}`
case paths.enumLiteral:
case p.enumLiteral:
return `Literal enum ${entity.Enum?.getName()}`
case paths.event:
case p.event:
return `Event ${(entity.EventReference?.MemberName?.toString() ?? "").replace(/^Receive/, "")}`
case paths.executionSequence:
case p.executionSequence:
return "Sequence"
case paths.forEachElementInEnum:
case p.forEachElementInEnum:
return `For Each ${entity.Enum?.getName()}`
case paths.forEachLoopWithBreak:
case p.forEachLoopWithBreak:
return "For Each Loop with Break"
case paths.functionEntry:
case p.functionEntry:
return entity.FunctionReference?.MemberName?.toString() === "UserConstructionScript"
? "Construction Script"
: entity.FunctionReference?.MemberName?.toString()
case paths.functionResult:
case p.functionResult:
return "Return Node"
case paths.ifThenElse:
case p.ifThenElse:
return "Branch"
case paths.makeStruct:
case p.makeStruct:
if (entity.StructType) {
return `Make ${entity.StructType.getName()}`
}
case paths.materialExpressionComponentMask: {
case p.materialExpressionComponentMask: {
const materialObject = entity.getMaterialSubobject()
if (materialObject) {
return `Mask ( ${Configuration.rgba
@@ -199,15 +200,15 @@ export default function nodeTitle(entity) {
.join("")})`
}
}
case paths.materialExpressionConstant:
case p.materialExpressionConstant:
value ??= [entity.getCustomproperties().find(pinEntity => pinEntity.PinName.toString() == "Value")?.DefaultValue]
case paths.materialExpressionConstant2Vector:
case p.materialExpressionConstant2Vector:
value ??= [
entity.getCustomproperties().find(pinEntity => pinEntity.PinName?.toString() == "X")?.DefaultValue,
entity.getCustomproperties().find(pinEntity => pinEntity.PinName?.toString() == "Y")?.DefaultValue,
]
case paths.materialExpressionConstant3Vector:
case paths.materialExpressionConstant4Vector:
case p.materialExpressionConstant3Vector:
case p.materialExpressionConstant4Vector:
if (!value) {
const vector = entity.getCustomproperties()
.find(pinEntity => pinEntity.PinName?.toString() == "Constant")
@@ -221,32 +222,32 @@ export default function nodeTitle(entity) {
}
value = undefined
break
case paths.materialExpressionFunctionInput: {
case p.materialExpressionFunctionInput: {
const materialObject = entity.getMaterialSubobject()
const inputName = materialObject?.InputName ?? "In"
const inputType = materialObject?.InputType?.value.match(/^.+?_(\w+)$/)?.[1] ?? "Vector3"
return `Input ${inputName} (${inputType})`
}
case paths.materialExpressionLogarithm:
case p.materialExpressionLogarithm:
return "Ln"
case paths.materialExpressionLogarithm10:
case p.materialExpressionLogarithm10:
return "Log10"
case paths.materialExpressionLogarithm2:
case p.materialExpressionLogarithm2:
return "Log2"
case paths.materialExpressionMaterialFunctionCall:
case p.materialExpressionMaterialFunctionCall:
const materialFunction = entity.getMaterialSubobject()?.MaterialFunction
if (materialFunction) {
return materialFunction.getName()
}
break
case paths.materialExpressionSquareRoot:
case p.materialExpressionSquareRoot:
return "Sqrt"
case paths.materialExpressionSubtract:
case p.materialExpressionSubtract:
const materialObject = entity.getMaterialSubobject()
if (materialObject) {
return `Subtract(${materialObject.ConstA ?? "1"},${materialObject.ConstB ?? "1"})`
}
case paths.metasoundEditorGraphExternalNode: {
case p.metasoundEditorGraphExternalNode: {
const name = entity["ClassName"]?.["Name"]
if (name) {
switch (name) {
@@ -255,7 +256,7 @@ export default function nodeTitle(entity) {
}
}
}
case paths.niagaraNodeConvert:
case p.niagaraNodeConvert:
/** @type {String} */
const targetType = (entity["AutowireMakeType"]?.["ClassStructOrEnum"] ?? "")
.toString()
@@ -263,11 +264,11 @@ export default function nodeTitle(entity) {
?.[1]
?? ""
return `Make ${targetType}`
case paths.pcgEditorGraphNodeInput:
case p.pcgEditorGraphNodeInput:
return "Input"
case paths.pcgEditorGraphNodeOutput:
case p.pcgEditorGraphNodeOutput:
return "Output"
case paths.spawnActorFromClass:
case p.spawnActorFromClass:
let className = entity.getCustomproperties()
.find(pinEntity => pinEntity.PinName.toString() == "ReturnValue")
?.PinType
@@ -276,21 +277,21 @@ export default function nodeTitle(entity) {
if (className === "Actor") {
className = null
}
return `SpawnActor ${Utility.formatStringName(className ?? "NONE")}`
case paths.switchEnum:
return `SpawnActor ${format(className ?? "NONE")}`
case p.switchEnum:
return `Switch on ${entity.Enum?.getName() ?? "Enum"}`
case paths.switchInteger:
case p.switchInteger:
return `Switch on Int`
case paths.variableGet:
case p.variableGet:
return ""
case paths.variableSet:
case p.variableSet:
return "SET"
}
const className = entity.getClass()
let switchTarget = entity.switchTarget()
if (switchTarget) {
if (switchTarget[0] !== "E") {
switchTarget = Utility.formatStringName(switchTarget)
switchTarget = format(switchTarget)
}
return `Switch on ${switchTarget}`
}
@@ -300,16 +301,16 @@ export default function nodeTitle(entity) {
const keyNameSymbol = entity.getHIDAttribute()
if (keyNameSymbol) {
const name = keyNameSymbol.toString()
let title = keyName(name) ?? Utility.formatStringName(name)
if (className === paths.inputDebugKey) {
let title = keyName(name) ?? format(name)
if (className === p.inputDebugKey) {
title = "Debug Key " + title
} else if (className === paths.getInputAxisKeyValue) {
} else if (className === p.getInputAxisKeyValue) {
title = "Get " + title
}
return title
}
if (className === paths.macro) {
return Utility.formatStringName(entity.MacroGraphReference?.getMacroName())
if (className === p.macro) {
return format(entity.MacroGraphReference?.getMacroName())
}
const materialSubobject = entity.getMaterialSubobject()
if (materialSubobject) {
@@ -328,19 +329,19 @@ export default function nodeTitle(entity) {
}
const settingsObject = entity.getSettingsObject()
if (settingsObject) {
if (settingsObject.ExportPath?.valueOf()?.type === paths.pcgHiGenGridSizeSettings) {
if (settingsObject.ExportPath?.valueOf()?.type === p.pcgHiGenGridSizeSettings) {
return `Grid Size: ${(
settingsObject.HiGenGridSize?.toString().match(/\d+/)?.[0]?.concat("00")
?? settingsObject.HiGenGridSize?.toString().match(/^\w+$/)?.[0]
) ?? "256"}`
}
if (settingsObject.BlueprintElementInstance) {
return Utility.formatStringName(settingsObject.BlueprintElementType.getName())
return format(settingsObject.BlueprintElementType.getName())
}
if (settingsObject.Operation) {
const match = settingsObject.Name?.toString().match(/PCGMetadata(\w+)Settings_\d+/)
if (match) {
return Utility.formatStringName(match[1] + ": " + settingsObject.Operation)
return format(match[1] + ": " + settingsObject.Operation)
}
}
const settingsSubgraphObject = settingsObject.getSubgraphObject()
@@ -355,7 +356,7 @@ export default function nodeTitle(entity) {
case "AddKey":
let result = memberParent.match(sequencerScriptingNameRegex)
if (result) {
return `Add Key (${Utility.formatStringName(result[1])})`
return `Add Key (${format(result[1])})`
}
case "Concat_StrStr":
return "Append"
@@ -366,15 +367,16 @@ export default function nodeTitle(entity) {
+ (memberNameTraceLineMatch[1] === "Multi" ? " Multi " : " ")
+ (memberNameTraceLineMatch[2] === ""
? "By Channel"
: Utility.formatStringName(memberNameTraceLineMatch[2])
: format(memberNameTraceLineMatch[2])
)
}
switch (memberParent) {
case paths.blueprintGameplayTagLibrary:
case paths.kismetMathLibrary:
case paths.kismetStringLibrary:
case paths.slateBlueprintLibrary:
case paths.timeManagementBlueprintLibrary:
case p.blueprintGameplayTagLibrary:
case p.kismetMathLibrary:
case p.kismetStringLibrary:
case p.slateBlueprintLibrary:
case p.timeManagementBlueprintLibrary:
case p.typedElementHandleLibrary:
const leadingLetter = memberName.match(/[BF]([A-Z]\w+)/)
if (leadingLetter) {
// Some functions start with B or F (Like FCeil, FMax, BMin)
@@ -385,6 +387,7 @@ export default function nodeTitle(entity) {
case "BooleanAND": return "AND"
case "BooleanNAND": return "NAND"
case "BooleanOR": return "OR"
case "Equal": return "=="
case "Exp": return "e"
case "LineTraceSingle": return "Line Trace By Channel"
case "Max": return "MAX"
@@ -458,23 +461,23 @@ export default function nodeTitle(entity) {
return "^"
}
break
case paths.blueprintSetLibrary:
case p.blueprintSetLibrary:
{
const setOperationMatch = memberName.match(/Set_(\w+)/)
if (setOperationMatch) {
return Utility.formatStringName(setOperationMatch[1]).toUpperCase()
return format(setOperationMatch[1]).toUpperCase()
}
}
break
case paths.blueprintMapLibrary:
case p.blueprintMapLibrary:
{
const setOperationMatch = memberName.match(/Map_(\w+)/)
if (setOperationMatch) {
return Utility.formatStringName(setOperationMatch[1]).toUpperCase()
return format(setOperationMatch[1]).toUpperCase()
}
}
break
case paths.kismetArrayLibrary:
case p.kismetArrayLibrary:
{
const arrayOperationMath = memberName.match(/Array_(\w+)/)
if (arrayOperationMath) {
@@ -483,14 +486,14 @@ export default function nodeTitle(entity) {
}
break
}
return Utility.formatStringName(memberName)
return format(memberName)
}
if (entity.OpName) {
return niagaraNodeNames[entity.OpName.toString()]
?? Utility.formatStringName(entity.OpName.toString().replaceAll(/(?:^\w+(?<!^Matrix))?::/g, " "))
?? format(entity.OpName.toString().replaceAll(/(?:^\w+(?<!^Matrix))?::/g, " "))
}
if (entity.FunctionDisplayName) {
return Utility.formatStringName(entity.FunctionDisplayName.toString())
return format(entity.FunctionDisplayName.toString())
}
if (entity.ObjectRef) {
return entity.ObjectRef.getName()
@@ -500,10 +503,10 @@ export default function nodeTitle(entity) {
className.startsWith(prefix = "/Script/NiagaraEditor.NiagaraNodeParameter")
|| className.startsWith(prefix = "/Script/NiagaraEditor.NiagaraNode")
) {
return entity["Input"]?.["Name"]?.toString() ?? Utility.formatStringName(className.substring(prefix.length))
return entity["Input"]?.["Name"]?.toString() ?? format(className.substring(prefix.length))
}
if (entity.ParameterName) {
return entity.ParameterName.toString()
}
return Utility.formatStringName(entity.getNameAndCounter()[0])
return format(entity.getNameAndCounter()[0])
}

View File

@@ -8,6 +8,7 @@ import StringEntity from "../entity/StringEntity.js"
/** @param {PinEntity} pinEntity */
const indexFromUpperCaseLetterName = pinEntity =>
pinEntity.PinName?.toString().match(/^\s*([A-Z])\s*$/)?.[1]?.charCodeAt(0) - "A".charCodeAt(0)
const p = Configuration.paths
/** @param {ObjectEntity} entity */
export default function nodeVariadic(entity) {
@@ -21,8 +22,8 @@ export default function nodeVariadic(entity) {
let prefix
let name
switch (type) {
case Configuration.paths.commutativeAssociativeBinaryOperator:
case Configuration.paths.promotableOperator:
case p.commutativeAssociativeBinaryOperator:
case p.promotableOperator:
name = entity.FunctionReference?.MemberName?.toString()
switch (name) {
default:
@@ -60,9 +61,9 @@ export default function nodeVariadic(entity) {
break
}
break
case Configuration.paths.executionSequence:
case p.executionSequence:
prefix ??= "Then"
case Configuration.paths.multiGate:
case p.multiGate:
prefix ??= "Out"
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isOutput())
pinIndexFromEntity ??= pinEntity => Number(
@@ -71,7 +72,7 @@ export default function nodeVariadic(entity) {
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) =>
`${prefix} ${index >= 0 ? index : min > 0 ? `${prefix} 0` : max + 1}`
break
// case Configuration.paths.niagaraNodeOp:
// case p.niagaraNodeOp:
// pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isInput())
// pinIndexFromEntity ??= indexFromUpperCaseLetterName
// pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => {
@@ -81,12 +82,12 @@ export default function nodeVariadic(entity) {
// return result
// }
// break
case Configuration.paths.switchInteger:
case p.switchInteger:
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isOutput())
pinIndexFromEntity ??= pinEntity => Number(pinEntity.PinName?.toString().match(/^\s*(\d+)\s*$/)?.[1])
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => (index < 0 ? max + 1 : index).toString()
break
case Configuration.paths.switchGameplayTag:
case p.switchGameplayTag:
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => {
const result = `Case_${index >= 0 ? index : min > 0 ? "0" : max + 1}`
entity.PinNames ??= new ArrayEntity()
@@ -95,8 +96,8 @@ export default function nodeVariadic(entity) {
entity.PinTags.valueOf()[entity.PinTags.length] = null
return result
}
case Configuration.paths.switchName:
case Configuration.paths.switchString:
case p.switchName:
case p.switchString:
pinEntities ??= () => entity.getPinEntities().filter(pinEntity => pinEntity.isOutput())
pinIndexFromEntity ??= pinEntity => Number(pinEntity.PinName.toString().match(/^\s*Case[_\s]+(\d+)\s*$/i)?.[1])
pinNameFromIndex ??= (index, min = -1, max = -1, newPin) => {

View File

@@ -1,6 +1,7 @@
import { css } from "lit"
import Configuration from "../Configuration.js"
const p = Configuration.paths
const colors = {
"Any": css`132, 132, 132`,
"Any[]": css`132, 132, 132`,
@@ -36,21 +37,21 @@ const colors = {
"Volume": css`230, 69, 188`,
"Volume[]": css`230, 69, 188`,
"wildcard": css`128, 120, 120`,
[Configuration.paths.linearColor]: css`0, 88, 200`,
[Configuration.paths.niagaraBool]: css`146, 0, 0`,
[Configuration.paths.niagaraDataInterfaceCollisionQuery]: css`0, 168, 242`,
[Configuration.paths.niagaraDataInterfaceCurlNoise]: css`0, 168, 242`,
[Configuration.paths.niagaraDataInterfaceVolumeTexture]: css`0, 168, 242`,
[Configuration.paths.niagaraFloat]: css`160, 250, 68`,
[Configuration.paths.niagaraInt32]: css`30, 224, 172`,
[Configuration.paths.niagaraPosition]: css`251, 146, 251`,
[Configuration.paths.quat4f]: css`0, 88, 200`,
[Configuration.paths.rotator]: css`157, 177, 251`,
[Configuration.paths.transform]: css`227, 103, 0`,
[Configuration.paths.vector]: css`251, 198, 34`,
[Configuration.paths.vector2f]: css`0, 88, 200`,
[Configuration.paths.vector3f]: css`250, 200, 36`,
[Configuration.paths.vector4f]: css`0, 88, 200`,
[p.linearColor]: css`0, 88, 200`,
[p.niagaraBool]: css`146, 0, 0`,
[p.niagaraDataInterfaceCollisionQuery]: css`0, 168, 242`,
[p.niagaraDataInterfaceCurlNoise]: css`0, 168, 242`,
[p.niagaraDataInterfaceVolumeTexture]: css`0, 168, 242`,
[p.niagaraFloat]: css`160, 250, 68`,
[p.niagaraInt32]: css`30, 224, 172`,
[p.niagaraPosition]: css`251, 146, 251`,
[p.quat4f]: css`0, 88, 200`,
[p.rotator]: css`157, 177, 251`,
[p.transform]: css`227, 103, 0`,
[p.vector]: css`251, 198, 34`,
[p.vector2f]: css`0, 88, 200`,
[p.vector3f]: css`250, 200, 36`,
[p.vector4f]: css`0, 88, 200`,
}
const pinColorMaterial = css`120, 120, 120`

View File

@@ -17,6 +17,7 @@ import Vector4DPinTemplate from "../template/pin/Vector4DPinTemplate.js"
import VectorPinTemplate from "../template/pin/VectorPinTemplate.js"
import pinTitle from "./pinTitle.js"
const p = Configuration.paths
const inputPinTemplates = {
"bool": BoolPinTemplate,
"byte": IntPinTemplate,
@@ -29,17 +30,17 @@ const inputPinTemplates = {
"real": RealPinTemplate,
"rg": Vector2DPinTemplate,
"string": StringPinTemplate,
[Configuration.paths.linearColor]: LinearColorPinTemplate,
[Configuration.paths.niagaraBool]: BoolPinTemplate,
[Configuration.paths.niagaraFloat]: RealPinTemplate,
[Configuration.paths.niagaraInt32]: IntPinTemplate,
[Configuration.paths.niagaraPosition]: VectorPinTemplate,
[Configuration.paths.rotator]: RotatorPinTemplate,
[Configuration.paths.vector]: VectorPinTemplate,
[Configuration.paths.vector2D]: Vector2DPinTemplate,
[Configuration.paths.vector2f]: Vector2DPinTemplate,
[Configuration.paths.vector3f]: VectorPinTemplate,
[Configuration.paths.vector4f]: Vector4DPinTemplate,
[p.linearColor]: LinearColorPinTemplate,
[p.niagaraBool]: BoolPinTemplate,
[p.niagaraFloat]: RealPinTemplate,
[p.niagaraInt32]: IntPinTemplate,
[p.niagaraPosition]: VectorPinTemplate,
[p.rotator]: RotatorPinTemplate,
[p.vector]: VectorPinTemplate,
[p.vector2D]: Vector2DPinTemplate,
[p.vector2f]: Vector2DPinTemplate,
[p.vector3f]: VectorPinTemplate,
[p.vector4f]: Vector4DPinTemplate,
}
/** @param {PinEntity<IEntity>} entity */

View File

@@ -5,6 +5,7 @@ import Utility from "../Utility.js"
import BooleanEntity from "../entity/BooleanEntity.js"
import LinkTemplate from "../template/LinkTemplate.js"
import IFromToPositionedElement from "./IFromToPositionedElement.js"
import LinearColorEntity from "../entity/LinearColorEntity.js"
/** @extends {IFromToPositionedElement<Object, LinkTemplate>} */
export default class LinkElement extends IFromToPositionedElement {
@@ -43,6 +44,9 @@ export default class LinkElement extends IFromToPositionedElement {
converter: BooleanEntity.booleanConverter,
reflect: true,
},
color: {
type: LinearColorEntity,
},
svgPathD: {
type: String,
attribute: false,
@@ -75,6 +79,29 @@ export default class LinkElement extends IFromToPositionedElement {
this.#setPin(pin, true)
}
/** @param {UEBNodeUpdateEvent} e */
#nodeUpdateHandler = e => {
if (this.#origin.nodeElement === e.target) {
if (this.originNode != this.#origin.nodeElement.nodeTitle) {
this.originNode = this.#origin.nodeElement.nodeTitle
}
this.setOriginLocation()
} else if (this.#target.nodeElement === e.target) {
if (this.targetNode != this.#target.nodeElement.nodeTitle) {
this.targetNode = this.#target.nodeElement.nodeTitle
}
this.setTargetLocation()
} else {
throw new Error("Unexpected node update")
}
}
/** @param {UEBNodeUpdateEvent} e */
#pinUpdateHandler = e => {
const colorReferencePin = this.getOutputPin(true)
if (!this.color?.equals(colorReferencePin.color)) {
this.color = colorReferencePin.color
}
}
#nodeDeleteHandler = () => this.remove()
/** @param {UEBDragEvent} e */
#nodeDragOriginHandler = e => this.addOriginLocation(...e.detail.value)
@@ -104,6 +131,7 @@ export default class LinkElement extends IFromToPositionedElement {
this.targetNode = ""
this.targetPin = ""
this.originatesFromInput = false
this.color = new LinearColorEntity()
this.startPercentage = 0
this.svgPathD = ""
this.startPixels = 0
@@ -153,15 +181,13 @@ export default class LinkElement extends IFromToPositionedElement {
}
if (getCurrentPin()) {
const nodeElement = getCurrentPin().getNodeElement()
nodeElement.removeEventListener(Configuration.nodeUpdateEventName, this.#nodeUpdateHandler)
nodeElement.removeEventListener(Configuration.removeEventName, this.#nodeDeleteHandler)
nodeElement.removeEventListener(
Configuration.nodeDragEventName,
isTargetPin ? this.#nodeDragTargetHandler : this.#nodeDragOriginHandler
)
nodeElement.removeEventListener(
Configuration.nodeReflowEventName,
isTargetPin ? this.#nodeReflowTargetHandler : this.#nodeReflowOriginHandler
)
getCurrentPin().removeEventListener(Configuration.pinUpdateEventName, this.#pinUpdateHandler)
this.#unlinkPins()
}
if (isTargetPin) {
@@ -175,20 +201,20 @@ export default class LinkElement extends IFromToPositionedElement {
}
if (getCurrentPin()) {
const nodeElement = getCurrentPin().getNodeElement()
nodeElement.addEventListener(Configuration.nodeUpdateEventName, this.#nodeUpdateHandler)
nodeElement.addEventListener(Configuration.pinUpdateEventName, this.#pinUpdateHandler)
nodeElement.addEventListener(Configuration.removeEventName, this.#nodeDeleteHandler)
nodeElement.addEventListener(
Configuration.nodeDragEventName,
isTargetPin ? this.#nodeDragTargetHandler : this.#nodeDragOriginHandler
)
nodeElement.addEventListener(
Configuration.nodeReflowEventName,
isTargetPin ? this.#nodeReflowTargetHandler : this.#nodeReflowOriginHandler
)
getCurrentPin().addEventListener(Configuration.pinUpdateEventName, this.#pinUpdateHandler)
isTargetPin
? this.setTargetLocation()
: (this.setOriginLocation(), this.originatesFromInput = this.origin.isInputVisually())
this.#linkPins()
}
this.color = this.getOutputPin(true)?.color
}
#linkPins() {

View File

@@ -138,18 +138,11 @@ export default class NodeElement extends ISelectableDraggableElement {
this.#redirectLinksBeforeRename(newName?.toString())
this.nodeTitle = newName?.toString()
this.nodeDisplayName = nodeTitle(entity)
this.acknowledgeUpdate()
}
)
}
async getUpdateComplete() {
let result = await super.getUpdateComplete()
for (const pin of this.getPinElements()) {
result &&= await pin.updateComplete
}
return result
}
/** @param {NodeElement} commentNode */
bindToComment(commentNode) {
if (commentNode != this && !this.boundComments.includes(commentNode)) {
@@ -192,14 +185,14 @@ export default class NodeElement extends ISelectableDraggableElement {
setNodeWidth(value) {
this.entity.setNodeWidth(value)
this.sizeX = value
this.acknowledgeReflow()
this.acknowledgeUpdate(true)
}
/** @param {Number} value */
setNodeHeight(value) {
this.entity.setNodeHeight(value)
this.sizeY = value
this.acknowledgeReflow()
this.acknowledgeUpdate(true)
}
/** @param {IElement[]} nodesWhitelist */
@@ -222,11 +215,13 @@ export default class NodeElement extends ISelectableDraggableElement {
super.setLocation(x, y, acknowledge)
}
acknowledgeReflow() {
this.requestUpdate()
this.updateComplete.then(() => this.computeSizes())
let reflowEvent = new CustomEvent(Configuration.nodeReflowEventName)
this.dispatchEvent(reflowEvent)
acknowledgeUpdate(resize = false) {
const event = new CustomEvent(Configuration.nodeUpdateEventName)
if (resize) {
this.requestUpdate()
this.updateComplete.then(() => this.computeSizes())
}
this.dispatchEvent(event)
}
setShowAdvancedPinDisplay(value) {

View File

@@ -44,7 +44,8 @@ export default class PinElement extends IElement {
fromAttribute: (value, type) => value
? LinearColorEntity.getLinearColorFromAnyFormat().parse(value)
: null,
toAttribute: (value, type) => value ? LinearColorEntity.printLinearColor(value) : null,
/** @param {LinearColorEntity} value */
toAttribute: (value, type) => value?.toString() ?? "",
},
attribute: "data-color",
reflect: true,
@@ -96,10 +97,11 @@ export default class PinElement extends IElement {
this.connectable = !entity.bNotConnectable?.valueOf()
super.initialize(entity, template)
this.pinId = this.entity.PinId
this.pinType = this.entity.getType()
this.updateType()
this.defaultValue = this.entity.getDefaultValue()
this.pinDirection = entity.isInput() ? "input" : entity.isOutput() ? "output" : "hidden"
this.updateColor()
/** @type {LinearColorEntity} */
this.color = PinElement.properties.color.converter.fromAttribute(this.entity.pinColor().toString())
}
setup() {
@@ -107,8 +109,13 @@ export default class PinElement extends IElement {
this.nodeElement = this.closest("ueb-node")
}
updateColor() {
this.color = PinElement.properties.color.converter.fromAttribute(this.entity.pinColor().toString())
updateType() {
this.pinType = this.entity.getType()
const newColor = PinElement.properties.color.converter.fromAttribute(this.entity.pinColor().toString())
if (!this.color?.equals(newColor)) {
this.color = newColor
this.acknowledgeUpdate()
}
}
createPinReference() {
@@ -289,4 +296,9 @@ export default class PinElement extends IElement {
}
return false
}
acknowledgeUpdate() {
let event = new CustomEvent(Configuration.pinUpdateEventName)
this.dispatchEvent(event)
}
}

View File

@@ -34,6 +34,8 @@ import Vector2DEntity from "./Vector2DEntity.js"
import Vector4DEntity from "./Vector4DEntity.js"
import VectorEntity from "./VectorEntity.js"
const paths = Configuration.paths
/** @template {IEntity} T */
export default class PinEntity extends IEntity {
@@ -49,24 +51,24 @@ export default class PinEntity extends IEntity {
"name": StringEntity,
"real": NumberEntity,
"string": StringEntity,
[Configuration.paths.linearColor]: LinearColorEntity,
[Configuration.paths.niagaraBool]: BooleanEntity,
[Configuration.paths.niagaraFloat]: NumberEntity,
[Configuration.paths.niagaraPosition]: VectorEntity,
[Configuration.paths.rotator]: RotatorEntity,
[Configuration.paths.vector]: VectorEntity,
[Configuration.paths.vector2D]: Vector2DEntity,
[Configuration.paths.vector4f]: Vector4DEntity,
[paths.linearColor]: LinearColorEntity,
[paths.niagaraBool]: BooleanEntity,
[paths.niagaraFloat]: NumberEntity,
[paths.niagaraPosition]: VectorEntity,
[paths.rotator]: RotatorEntity,
[paths.vector]: VectorEntity,
[paths.vector2D]: Vector2DEntity,
[paths.vector4f]: Vector4DEntity,
}
static #alternativeTypeEntityMap = {
"enum": EnumDisplayValueEntity,
"rg": RBSerializationVector2DEntity,
[Configuration.paths.niagaraPosition]: SimpleSerializationVectorEntity.flagAllowShortSerialization(),
[Configuration.paths.rotator]: SimpleSerializationRotatorEntity,
[Configuration.paths.vector]: SimpleSerializationVectorEntity,
[Configuration.paths.vector2D]: SimpleSerializationVector2DEntity,
[Configuration.paths.vector3f]: SimpleSerializationVectorEntity,
[Configuration.paths.vector4f]: SimpleSerializationVector4DEntity,
[paths.niagaraPosition]: SimpleSerializationVectorEntity.flagAllowShortSerialization(),
[paths.rotator]: SimpleSerializationRotatorEntity,
[paths.vector]: SimpleSerializationVectorEntity,
[paths.vector2D]: SimpleSerializationVector2DEntity,
[paths.vector3f]: SimpleSerializationVectorEntity,
[paths.vector4f]: SimpleSerializationVector4DEntity,
}
static attributes = {
PinId: GuidEntity.withDefault(),
@@ -216,9 +218,9 @@ export default class PinEntity extends IEntity {
case "rg":
return "rg"
case "rgb":
return Configuration.paths.vector
return paths.vector
case "rgba":
return Configuration.paths.linearColor
return paths.linearColor
default:
return subCategory
}
@@ -254,14 +256,14 @@ export default class PinEntity extends IEntity {
isEnum() {
const type = this.PinType.PinSubCategoryObject?.type
return type === Configuration.paths.enum
|| type === Configuration.paths.userDefinedEnum
return type === paths.enum
|| type === paths.userDefinedEnum
|| type?.toLowerCase() === "enum"
}
isExecution() {
return this.PinType.PinCategory.toString() === "exec"
|| this.getType() === Configuration.paths.niagaraParameterMap
|| this.getType() === paths.niagaraParameterMap
}
isHidden() {

View File

@@ -1,7 +1,6 @@
import { html, nothing } from "lit"
import Configuration from "../Configuration.js"
import ElementFactory from "../element/ElementFactory.js"
import LinearColorEntity from "../entity/LinearColorEntity.js"
import KnotEntity from "../entity/objects/KnotEntity.js"
import KeyboardShortcut from "../input/keyboard/KeyboardShortcut.js"
import MouseClick from "../input/mouse/MouseClick.js"
@@ -53,8 +52,6 @@ export default class LinkTemplate extends IFromToPositionedTemplate {
this.blueprint.addGraphElement(knot) // Important: keep it before changing existing links
const inputPin = this.element.getInputPin()
const outputPin = this.element.getOutputPin()
this.element.origin = null
this.element.target = null
const link = /** @type {LinkElementConstructor} */(ElementFactory.getConstructor("ueb-link"))
.newObject(outputPin, knotTemplate.inputPin)
this.blueprint.addGraphElement(link)
@@ -181,24 +178,28 @@ export default class LinkTemplate extends IFromToPositionedTemplate {
/** @param {PropertyValues} changedProperties */
update(changedProperties) {
super.update(changedProperties)
const referencePin = this.element.getOutputPin(true)
if (referencePin) {
this.element.style.setProperty("--ueb-link-color-rgb", LinearColorEntity.printLinearColor(referencePin.color))
const style = this.element.style
if (changedProperties.has("color")) {
style.setProperty("--ueb-link-color-rgb", this.element.color?.toString() ?? "255, 255, 255")
}
this.element.style.setProperty("--ueb-start-percentage", `${Math.round(this.element.startPercentage)}%`)
this.element.style.setProperty("--ueb-link-start", `${Math.round(this.element.startPixels)}`)
style.setProperty("--ueb-start-percentage", `${Math.round(this.element.startPercentage)}%`)
style.setProperty("--ueb-link-start", `${Math.round(this.element.startPixels)}`)
const mirrorV = (this.element.originY > this.element.targetY ? -1 : 1) // If from is below to => mirror
* (this.element.originatesFromInput ? -1 : 1) // Unless fro refers to an input pin
* (this.element.origin?.isInputVisually() && this.element.target?.isInputVisually() ? -1 : 1)
const mirrorH = (this.element.origin?.isInputVisually() && this.element.target?.isInputVisually() ? -1 : 1)
this.element.style.setProperty("--ueb-link-scale-y", `${mirrorV}`)
this.element.style.setProperty("--ueb-link-scale-x", `${mirrorH}`)
style.setProperty("--ueb-link-scale-y", `${mirrorV}`)
style.setProperty("--ueb-link-scale-x", `${mirrorH}`)
}
render() {
return html`
<svg version="1.2" baseProfile="tiny" width="100%" height="100%" viewBox="0 0 100 100" preserveAspectRatio="none">
<path id="${this.#uniqueId}" fill="none" vector-effect="non-scaling-stroke" d="${this.element.svgPathD}" />
<svg version="1.2" baseProfile="tiny" width="100%" height="100%" viewBox="0 0 100 100"
preserveAspectRatio="none"
>
<path id="${this.#uniqueId}" fill="none" vector-effect="non-scaling-stroke"
d="${this.element.svgPathD}"
/>
<use href="#${this.#uniqueId}" class="ueb-link-area" pointer-events="all" />
<use href="#${this.#uniqueId}" class="ueb-link-path" pointer-events="none" />
</svg>

View File

@@ -14,7 +14,7 @@ export default class KnotNodeTemplate extends NodeTemplate {
return
}
this.#switchDirectionsVisually = value
this.element.acknowledgeReflow()
this.element.acknowledgeUpdate()
}
/** @type {PinElement} */
@@ -35,17 +35,6 @@ export default class KnotNodeTemplate extends NodeTemplate {
this.element.classList.add("ueb-node-style-minimal")
}
/** @param {PropertyValues} changedProperties */
update(changedProperties) {
super.update(changedProperties)
if (!this.#inputPin.isLinked && !this.#outputPin.isLinked) {
this.#inputPin.entity.PinType.PinCategory.value = "wildcard"
this.#inputPin.updateColor()
this.#outputPin.entity.PinType.PinCategory.value = "wildcard"
this.#inputPin.updateColor()
}
}
render() {
return html`
<div class="ueb-node-border"></div>

View File

@@ -31,14 +31,14 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
} else {
(pin.isInput() ? this.inputContainer : this.outputContainer).appendChild(this.createPinElement(pin))
}
this.element.acknowledgeReflow()
this.element.acknowledgeUpdate()
}
}
toggleAdvancedDisplayHandler = () => {
this.element.toggleShowAdvancedPinDisplay()
this.element.requestUpdate()
this.element.updateComplete.then(() => this.element.acknowledgeReflow())
this.element.updateComplete.then(() => this.element.acknowledgeUpdate())
}
/** @param {PinEntity<IEntity>} pinEntity */
@@ -125,7 +125,7 @@ export default class NodeTemplate extends ISelectableDraggableTemplate {
this.inputContainer = this.element.querySelector(".ueb-node-inputs")
this.outputContainer = this.element.querySelector(".ueb-node-outputs")
this.setupPins()
this.element.updateComplete.then(() => this.element.acknowledgeReflow())
this.element.updateComplete.then(() => this.element.acknowledgeUpdate())
}
setupPins() {

View File

@@ -78,13 +78,13 @@ export default class IInputPinTemplate extends PinTemplate {
}
if (Self.canWrapInput && this.isInputRendered()) {
this.element.addEventListener("input", this.#checkWrapHandler)
this.element.nodeElement.addEventListener(Configuration.nodeReflowEventName, this.#checkWrapHandler)
this.element.nodeElement.addEventListener(Configuration.nodeUpdateEventName, this.#checkWrapHandler)
}
}
cleanup() {
super.cleanup()
this.element.nodeElement.removeEventListener(Configuration.nodeReflowEventName, this.#checkWrapHandler)
this.element.nodeElement.removeEventListener(Configuration.nodeUpdateEventName, this.#checkWrapHandler)
this.element.removeEventListener("input", this.#checkWrapHandler)
this.element.removeEventListener("input", this.#setInput)
this.element.removeEventListener("focusout", this.#setInput)
@@ -112,7 +112,7 @@ export default class IInputPinTemplate extends PinTemplate {
this.setDefaultValue(values.map(v => IInputPinTemplate.stringFromInputToUE(v)), values)
}
this.element.requestUpdate()
this.element.nodeElement.acknowledgeReflow()
this.element.updateComplete.then(() => this.element.nodeElement.acknowledgeUpdate())
}
setDefaultValue(values = [], rawValues = values) {

View File

@@ -1,13 +1,68 @@
import { html } from "lit"
import FunctionReferenceEntity from "../../entity/FunctionReferenceEntity.js"
import ObjectReferenceEntity from "../../entity/ObjectReferenceEntity.js"
import PinTypeEntity from "../../entity/PinTypeEntity.js"
import StringEntity from "../../entity/StringEntity.js"
import MinimalPinTemplate from "./MinimalPinTemplate.js"
/** @extends MinimalPinTemplate<KnotEntity> */
export default class KnotPinTemplate extends MinimalPinTemplate {
static #wildcardPinType = new PinTypeEntity({
PinCategory: new StringEntity("wildcard"),
PinSubCategoryObject: ObjectReferenceEntity.createNoneInstance(),
PinSubCategoryMemberReference: new FunctionReferenceEntity(),
})
/** @param {PinTypeEntity} type */
#setType(type) {
const oppositePin = this.getoppositePin()
this.element.entity.PinType.copyTypeFrom(type)
oppositePin.entity.PinType.copyTypeFrom(type)
this.element.updateType()
oppositePin.updateType()
}
render() {
return this.element.isOutput() ? super.render() : html``
}
/** @param {PropertyValues} changedProperties */
update(changedProperties) {
super.update(changedProperties)
if (changedProperties.has("isLinked")) {
const oppositePin = this.getoppositePin()
if (!this.element.isLinked && !oppositePin.isLinked) {
this.#setType(KnotPinTemplate.#wildcardPinType)
} else if (this.element.isLinked && this.element.pinType == "wildcard") {
const type = this.element
.getLinks()
.map(r => this.blueprint.getPin(r))
.find(p => p && p.pinType != "wildcard")
?.entity
.PinType
if (type) {
/** @type {KnotPinTemplate[]} */
const propagated = [this]
for (let i = 0; i < propagated.length; ++i) {
let current = propagated[i]
current.#setType(type)
current = /** @type {KnotPinTemplate} */(current.getoppositePin().template)
current.#setType(type)
propagated.push(
...current.element.getLinks().map(r => (
/** @type {KnotPinTemplate} */(
this.blueprint.getPin(r).template
)
))
)
}
}
}
}
}
getoppositePin() {
const nodeTemplate = /** @type {KnotNodeTemplate} */(this.element.nodeElement.template)
return this.element.isOutput() ? nodeTemplate.inputPin : nodeTemplate.outputPin

View File

@@ -159,14 +159,16 @@ export default class PinTemplate extends ITemplate {
// When connected, an input may drop its input fields which means the node has to reflow
const node = this.element.nodeElement
this.element.requestUpdate()
this.element.updateComplete.then(() => node.acknowledgeReflow())
this.element.updateComplete.then(() => node.acknowledgeUpdate())
}
if (changedProperties.has("color")) {
this.element.style.setProperty("--ueb-pin-color-rgb", this.element.color.toString())
}
}
/** @param {PropertyValues} changedProperties */
firstUpdated(changedProperties) {
super.firstUpdated(changedProperties)
this.element.style.setProperty("--ueb-pin-color-rgb", this.element.entity.pinColor().cssText)
this.#iconElement = this.element.querySelector(".ueb-pin-icon svg") ?? this.element
this.#wrapperElement = this.element.querySelector(".ueb-pin-wrapper")
}

View File

@@ -93,7 +93,7 @@ export default class BlueprintFixture {
})
webserver.listen(this.#port, "127.0.0.1", async () => {
console.log(`Server started on http://127.0.0.1:${this.#port}`)
const url = `http://127.0.0.1:${this.#port}/empty.html`
const url = `http://127.0.0.1:${this.#port}/debug.html`
try {
await this.checkServerReady(url)
BlueprintFixture.server = webserver
@@ -111,7 +111,7 @@ export default class BlueprintFixture {
}
async setup() {
const url = `http://127.0.0.1:${this.#port}/empty.html`
const url = `http://127.0.0.1:${this.#port}/debug.html`
for (let i = 0; i < 1E4; ++i) {
try {
await this.page.goto(url, { waitUntil: "domcontentloaded" })

View File

@@ -62,11 +62,9 @@ export function testNode(testData) {
if (testData.color) {
test(
`${testData.name}: Has correct color`,
async ({ blueprintPage }) => {
expect(
await blueprintPage.node.evaluate(node => node.entity.nodeColor().toString())
).toBe(testData.color.toString())
}
async ({ blueprintPage }) =>
expect(await blueprintPage.node.evaluate(node => node.entity.nodeColor().toString()))
.toBe(testData.color.toString())
)
}

135
tests/linking3.spec.js Executable file
View File

@@ -0,0 +1,135 @@
import { expect, test } from "./fixtures/test.js"
test("Linking 3", async ({ blueprintPage }) => {
const source = String.raw`
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_25" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_25'"
NodePosX=976
NodePosY=288
NodeGuid=CF9256F15B564DB0B289FDB4704A2290
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_8 47E4D9AF4CD414564F484A96E876E80B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_27" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_27'"
NodePosX=1232
NodePosY=288
NodeGuid=43A2EF73BD644DD382666D7AC1FB6075
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_8 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_35 47E4D9AF4CD414564F484A96E876E80B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_8" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_8'"
NodePosX=1120
NodePosY=288
NodeGuid=E3B195FA61CC499A9B34F07F5F5A6CCE
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_25 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_27 47E4D9AF4CD414564F484A96E876E80B,K2Node_Knot_38 47E4D9AF4CD414564F484A96E876E80B,K2Node_Knot_40 47E4D9AF4CD414564F484A96E876E80B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_35" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_35'"
NodePosX=1376
NodePosY=288
NodeGuid=60EA1A96C0B544C1A23FE8E43E93C5A9
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_27 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_38" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_38'"
NodePosX=1232
NodePosY=336
NodeGuid=C85E3544423E44F4A7097FB732C2EA9F
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_8 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_39 47E4D9AF4CD414564F484A96E876E80B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_39" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_39'"
NodePosX=1376
NodePosY=336
NodeGuid=EBFD7E66E2564FB6B72CD6B9609F2584
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_38 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_40" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_40'"
NodePosX=1232
NodePosY=384
NodeGuid=DE79DE02C598433FA7F3ED8EB016E9E2
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_8 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_41 47E4D9AF4CD414564F484A96E876E80B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_41" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_41'"
NodePosX=1376
NodePosY=384
NodeGuid=033ED30A27A7469CA482FDE433792DD8
CustomProperties Pin (PinId=47E4D9AF4CD414564F484A96E876E80B,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,LinkedTo=(K2Node_Knot_40 009095D54E2C15EBBB57DC9098EC7D8B,),PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=009095D54E2C15EBBB57DC9098EC7D8B,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class="/Script/BlueprintGraph.K2Node_VariableGet" Name="K2Node_VariableGet_131" ExportPath=/Script/BlueprintGraph.K2Node_VariableGet'"/Game/StarterContent/Blueprints/Blueprint_WallSconce.Blueprint_WallSconce:UserConstructionScript.K2Node_VariableGet_131"'
VariableReference=(MemberName="Color",MemberGuid=AAEC3E9C476A2187972DDE8D142A814B,bSelfContext=True)
NodePosX=768
NodePosY=272
NodeGuid=5BE70A964537A1F13BE2489B0DC06370
CustomProperties Pin (PinId=E11890DA93464F48A6221977085C4549,PinName="Color",Direction="EGPD_Output",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/CoreUObject.ScriptStruct'"/Script/CoreUObject.LinearColor"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=506366A2BD594C01A714D4B3A4B67508,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject=/Script/Engine.BlueprintGeneratedClass'"/Game/StarterContent/Blueprints/Blueprint_WallSconce.Blueprint_WallSconce_C"',PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
`
const nodes = blueprintPage.blueprintLocator.locator("ueb-node")
const knots = blueprintPage.blueprintLocator.locator('ueb-node[data-type="/Script/BlueprintGraph.K2Node_Knot"]')
const links = blueprintPage.blueprintLocator.locator("ueb-link")
const mouse = blueprintPage.page.mouse
const grayColor = "128, 120, 120"
const blueColor = "0, 88, 200"
/** @type {(i: Number) => Locator<NodeElement>} */
const getNode = i => blueprintPage.blueprintLocator.locator("ueb-node").nth(i)
const link = async (origin, target) => {
await origin.hover()
await mouse.down()
await mouse.move(100, 100, { steps: 4 })
await target.hover()
await mouse.up()
}
/** @param {NodeElement} n */
const getKnotColors = n => {
const template = /** @type {KnotNodeTemplate} */(n.template)
return [
template.inputPin.entity.pinColor().toString(),
template.inputPin.color.toString(),
template.outputPin.entity.pinColor().toString(),
template.outputPin.color.toString(),
]
}
await expect(nodes).toHaveCount(0)
await expect(knots).toHaveCount(0)
await expect(links).toHaveCount(0)
await blueprintPage.paste(source)
await blueprintPage.blueprintLocator.evaluate(b => b.template.centerContentInViewport(false))
await expect(nodes).toHaveCount(9)
await expect(knots).toHaveCount(8)
await expect(links).toHaveCount(7)
const knotsCount = await knots.count()
for (let i = 0; i < knotsCount; ++i) {
expect(await knots.nth(i).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
}
const linksCount = await links.count()
for (let i = 0; i < linksCount; ++i) {
/** @type {Locator<LinkElement>} */
const link = links.nth(i)
expect(await link.evaluate(l => l.color.toString())).toEqual(grayColor)
}
await link(blueprintPage.blueprintLocator.locator("ueb-pin").getByText("Color", { exact: true }), knots.nth(0))
await expect(links).toHaveCount(8)
for (let i = 0; i < knotsCount; ++i) {
expect(await knots.nth(i).evaluate(getKnotColors)).toEqual(Array(4).fill(blueColor))
}
for (let i = 0; i < linksCount; ++i) {
/** @type {Locator<LinkElement>} */
const link = links.nth(i)
expect(await link.evaluate(l => l.color.toString())).toEqual(blueColor)
}
await links.evaluateAll(ls => ls.forEach(l => l.remove()))
for (let i = 0; i < knotsCount; ++i) {
expect(await knots.nth(i).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
}
await expect(links).toHaveCount(0)
})

208
tests/linking4.spec.js Executable file
View File

@@ -0,0 +1,208 @@
import { expect, test } from "./fixtures/test.js"
test("Linking 4", async ({ blueprintPage }) => {
const source = String.raw`
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_31" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_31'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=2064
NodePosY=512
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=1D701CAA2E0740A7AB1126924B4F9895
CustomProperties Pin (PinId=C213898047FB4EE388496E786C75A377,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=AE2D76AC152348E290EE202FE4386D4D,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=0BDB25D0DB3143D3A7BFB4262D4E0697,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4913ACB8B9944AB3A07F0B0B4DE95820,PinName="WorldContextObject",PinToolTip="World Context Object\nRiferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=94D39DE61C4140DFA0058E45E8FD65EF,PinName="InString",PinToolTip="In String\nStringa\n\nLa stringa per il logout",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=8B64D3035BB04AF7AF7CAAC4E6F6452E,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBooleano\n\nDetermina se stampare o meno l\'output sullo schermo",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C2A16B109D2949D99DF6ACE44C693641,PinName="bPrintToLog",PinToolTip="Print to Log\nBooleano\n\nDetermina se stampare o meno l\'output nel registro",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=292140479AE849EFAB4550A6218484F7,PinName="TextColor",PinToolTip="Text Color\nLinear Color Struttura\n\nIl colore del testo da visualizzare",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=AF23F8B9D0EA40698AD5A912155BBBD8,PinName="Duration",PinToolTip="Duration\nFloat (precisione singola)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=D56DDC28C51544B7BDD1D8E38348AD44,PinName="Key",PinToolTip="Key\nNome",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_32" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_32'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=2080
NodePosY=704
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=F6899A2106DA453C893893CC42284666
CustomProperties Pin (PinId=C213898047FB4EE388496E786C75A377,PinName="execute",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=AE2D76AC152348E290EE202FE4386D4D,PinName="then",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=0BDB25D0DB3143D3A7BFB4262D4E0697,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4913ACB8B9944AB3A07F0B0B4DE95820,PinName="WorldContextObject",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=94D39DE61C4140DFA0058E45E8FD65EF,PinName="InString",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=8B64D3035BB04AF7AF7CAAC4E6F6452E,PinName="bPrintToScreen",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C2A16B109D2949D99DF6ACE44C693641,PinName="bPrintToLog",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=292140479AE849EFAB4550A6218484F7,PinName="TextColor",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=AF23F8B9D0EA40698AD5A912155BBBD8,PinName="Duration",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=D56DDC28C51544B7BDD1D8E38348AD44,PinName="Key",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_33" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_33'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=2064
NodePosY=864
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=C6E18A63A7D14480951E047585646A16
CustomProperties Pin (PinId=C213898047FB4EE388496E786C75A377,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=AE2D76AC152348E290EE202FE4386D4D,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=0BDB25D0DB3143D3A7BFB4262D4E0697,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4913ACB8B9944AB3A07F0B0B4DE95820,PinName="WorldContextObject",PinToolTip="World Context Object\nRiferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=94D39DE61C4140DFA0058E45E8FD65EF,PinName="InString",PinToolTip="In String\nStringa\n\nLa stringa per il logout",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=8B64D3035BB04AF7AF7CAAC4E6F6452E,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBooleano\n\nDetermina se stampare o meno l\'output sullo schermo",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C2A16B109D2949D99DF6ACE44C693641,PinName="bPrintToLog",PinToolTip="Print to Log\nBooleano\n\nDetermina se stampare o meno l\'output nel registro",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=292140479AE849EFAB4550A6218484F7,PinName="TextColor",PinToolTip="Text Color\nLinear Color Struttura\n\nIl colore del testo da visualizzare",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=AF23F8B9D0EA40698AD5A912155BBBD8,PinName="Duration",PinToolTip="Duration\nFloat (precisione singola)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=D56DDC28C51544B7BDD1D8E38348AD44,PinName="Key",PinToolTip="Key\nNome",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_34" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_34'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=2080
NodePosY=1040
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=4C237BCECEE348DC81DAC37FC0627348
CustomProperties Pin (PinId=C213898047FB4EE388496E786C75A377,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=AE2D76AC152348E290EE202FE4386D4D,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=0BDB25D0DB3143D3A7BFB4262D4E0697,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4913ACB8B9944AB3A07F0B0B4DE95820,PinName="WorldContextObject",PinToolTip="World Context Object\nRiferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=94D39DE61C4140DFA0058E45E8FD65EF,PinName="InString",PinToolTip="In String\nStringa\n\nLa stringa per il logout",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=8B64D3035BB04AF7AF7CAAC4E6F6452E,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBooleano\n\nDetermina se stampare o meno l\'output sullo schermo",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C2A16B109D2949D99DF6ACE44C693641,PinName="bPrintToLog",PinToolTip="Print to Log\nBooleano\n\nDetermina se stampare o meno l\'output nel registro",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=292140479AE849EFAB4550A6218484F7,PinName="TextColor",PinToolTip="Text Color\nLinear Color Struttura\n\nIl colore del testo da visualizzare",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=AF23F8B9D0EA40698AD5A912155BBBD8,PinName="Duration",PinToolTip="Duration\nFloat (precisione singola)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=D56DDC28C51544B7BDD1D8E38348AD44,PinName="Key",PinToolTip="Key\nNome",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_30" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_30'"
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",MemberName="PrintString")
NodePosX=2512
NodePosY=608
AdvancedPinDisplay=Hidden
EnabledState=DevelopmentOnly
NodeGuid=D102FE881EF5463F8309034683650841
CustomProperties Pin (PinId=C213898047FB4EE388496E786C75A377,PinName="execute",PinToolTip="\nExec",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=AE2D76AC152348E290EE202FE4386D4D,PinName="then",PinToolTip="\nExec",Direction="EGPD_Output",PinType.PinCategory="exec",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=0BDB25D0DB3143D3A7BFB4262D4E0697,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nKismet System Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/Engine.KismetSystemLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/Engine.Default__KismetSystemLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=4913ACB8B9944AB3A07F0B0B4DE95820,PinName="WorldContextObject",PinToolTip="World Context Object\nRiferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/CoreUObject.Object'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=94D39DE61C4140DFA0058E45E8FD65EF,PinName="InString",PinToolTip="In String\nStringa\n\nLa stringa per il logout",PinType.PinCategory="string",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="Hello",AutogeneratedDefaultValue="Hello",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=8B64D3035BB04AF7AF7CAAC4E6F6452E,PinName="bPrintToScreen",PinToolTip="Print to Screen\nBooleano\n\nDetermina se stampare o meno l\'output sullo schermo",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=C2A16B109D2949D99DF6ACE44C693641,PinName="bPrintToLog",PinToolTip="Print to Log\nBooleano\n\nDetermina se stampare o meno l\'output nel registro",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="true",AutogeneratedDefaultValue="true",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=292140479AE849EFAB4550A6218484F7,PinName="TextColor",PinToolTip="Text Color\nLinear Color Struttura\n\nIl colore del testo da visualizzare",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/CoreUObject.LinearColor'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",AutogeneratedDefaultValue="(R=0.000000,G=0.660000,B=1.000000,A=1.000000)",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=AF23F8B9D0EA40698AD5A912155BBBD8,PinName="Duration",PinToolTip="Duration\nFloat (precisione singola)",PinType.PinCategory="real",PinType.PinSubCategory="float",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="2.000000",AutogeneratedDefaultValue="2.000000",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
CustomProperties Pin (PinId=D56DDC28C51544B7BDD1D8E38348AD44,PinName="Key",PinToolTip="Key\nNome",PinType.PinCategory="name",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="None",AutogeneratedDefaultValue="None",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=True,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_26" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_26'"
NodePosX=2432
NodePosY=800
NodeGuid=09E4717EEE2144249972101FD6D89319
CustomProperties Pin (PinId=115CA6C68D99441783881018A83AE02D,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=94C0E1EE1D9244099DDC7E655BF22E5F,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
Begin Object Class=/Script/BlueprintGraph.K2Node_Knot Name="K2Node_Knot_37" ExportPath="/Script/BlueprintGraph.K2Node_Knot'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_Knot_37'"
NodePosX=2400
NodePosY=944
NodeGuid=E2CADFEE08AE4EBC8AEAA52233270744
CustomProperties Pin (PinId=C496819F4BF84B59A41D2145202E0EC8,PinName="InputPin",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=2C9D6F2E7B154F9DA1165AD88057A898,PinName="OutputPin",Direction="EGPD_Output",PinType.PinCategory="wildcard",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
`
const nodes = blueprintPage.blueprintLocator.locator("ueb-node")
const knots = blueprintPage.blueprintLocator.locator('ueb-node[data-type="/Script/BlueprintGraph.K2Node_Knot"]')
const links = blueprintPage.blueprintLocator.locator("ueb-link")
const mouse = blueprintPage.page.mouse
const grayColor = "128, 120, 120"
const whiteColor = "240, 240, 240"
/** @type {(i: Number) => Locator<NodeElement>} */
const getNode = i => blueprintPage.blueprintLocator.locator("ueb-node").nth(i)
const link = async (origin, target) => {
await origin.hover()
await mouse.down()
await mouse.move(100, 100, { steps: 4 })
await target.hover()
await mouse.up()
}
/** @param {NodeElement} n */
const getKnotColors = n => {
const template = /** @type {KnotNodeTemplate} */(n.template)
return [
template.inputPin.entity.pinColor().toString(),
template.inputPin.color.toString(),
template.outputPin.entity.pinColor().toString(),
template.outputPin.color.toString(),
]
}
await expect(nodes).toHaveCount(0)
await expect(knots).toHaveCount(0)
await expect(links).toHaveCount(0)
await blueprintPage.paste(source)
await blueprintPage.blueprintLocator.evaluate(b => b.template.centerContentInViewport(false))
await expect(nodes).toHaveCount(7)
await expect(knots).toHaveCount(2)
await expect(links).toHaveCount(0)
expect(await knots.nth(0).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
expect(await knots.nth(1).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
const knotsCount = await knots.count()
for (let i = 0; i < knotsCount; ++i) {
expect(await knots.nth(i).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
}
await link(
nodes.nth(0).locator('ueb-pin[data-type="exec"][data-direction="output"]'),
nodes.nth(4).locator('ueb-pin[data-type="exec"][data-direction="input"]'),
)
await expect(links).toHaveCount(1)
await link(
nodes.nth(1).locator('ueb-pin[data-type="exec"][data-direction="output"]'),
knots.nth(0),
)
await expect(links).toHaveCount(2)
expect(await knots.nth(0).evaluate(getKnotColors)).toEqual(Array(4).fill(whiteColor))
expect(await knots.nth(1).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
await link(
knots.nth(0).locator('ueb-pin[data-direction="output"]'),
nodes.nth(4).locator('ueb-pin[data-type="exec"][data-direction="input"]'),
)
await expect(links).toHaveCount(3)
await link(
nodes.nth(2).locator('ueb-pin[data-type="exec"][data-direction="output"]'),
knots.nth(0),
)
await expect(links).toHaveCount(4)
expect(await knots.nth(0).evaluate(getKnotColors)).toEqual(Array(4).fill(whiteColor))
expect(await knots.nth(1).evaluate(getKnotColors)).toEqual(Array(4).fill(grayColor))
await link(
nodes.nth(2).locator('ueb-pin[data-type="exec"][data-direction="output"]'),
knots.nth(1),
)
await expect(links).toHaveCount(4) // This replaced the previous link
expect(await knots.nth(0).evaluate(getKnotColors)).toEqual(Array(4).fill(whiteColor))
expect(await knots.nth(1).evaluate(getKnotColors)).toEqual(Array(4).fill(whiteColor))
await link(
nodes.nth(3).locator('ueb-pin[data-type="exec"][data-direction="output"]'),
knots.nth(1),
)
await expect(links).toHaveCount(5)
await link(
knots.nth(1),
nodes.nth(4).locator('ueb-pin[data-type="exec"][data-direction="input"]'),
)
await expect(links).toHaveCount(6)
await link(
knots.nth(1),
knots.nth(0),
)
await expect(links).toHaveCount(6) // This replaced the previous link
})

View File

@@ -0,0 +1,31 @@
import { expect, testNode } from "./fixtures/test.js"
testNode({
name: "Equal",
title: "==",
value: String.raw`
Begin Object Class=/Script/BlueprintGraph.K2Node_CallFunction Name="K2Node_CallFunction_14" ExportPath="/Script/BlueprintGraph.K2Node_CallFunction'/Game/NewWorld.NewWorld:PersistentLevel.NewWorld.EventGraph.K2Node_CallFunction_14'"
bDefaultsToPureFunc=True
FunctionReference=(MemberParent="/Script/CoreUObject.Class'/Script/TypedElementFramework.TypedElementHandleLibrary'",MemberName="Equal")
NodePosX=3632
NodePosY=-2288
NodeGuid=A103141723D244F581A0A9F8E92896F8
CustomProperties Pin (PinId=39C4587583EA4432932FA978AA918C44,PinName="self",PinFriendlyName=NSLOCTEXT("K2Node", "Target", "Target"),PinToolTip="Target\nTyped Element Handle Library Riferimento Oggetto",PinType.PinCategory="object",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.Class'/Script/TypedElementFramework.TypedElementHandleLibrary'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultObject="/Script/TypedElementFramework.Default__TypedElementHandleLibrary",PersistentGuid=00000000000000000000000000000000,bHidden=True,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=5159BBDAFA644C7DA8AAEC25138286AB,PinName="LHS",PinToolTip="LHS\nScript Typed Element Handle Struttura (by ref)",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/TypedElementFramework.ScriptTypedElementHandle'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=8E09436509C24857B9593EBAA9420160,PinName="RHS",PinToolTip="RHS\nScript Typed Element Handle Struttura (by ref)",PinType.PinCategory="struct",PinType.PinSubCategory="",PinType.PinSubCategoryObject="/Script/CoreUObject.ScriptStruct'/Script/TypedElementFramework.ScriptTypedElementHandle'",PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=True,PinType.bIsConst=True,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=True,bAdvancedView=False,bOrphanedPin=False,)
CustomProperties Pin (PinId=BEACF29085B844F0B99626653E16673D,PinName="ReturnValue",PinToolTip="Return Value\nBooleano\n\nQuesti due handle sono uguali?",Direction="EGPD_Output",PinType.PinCategory="bool",PinType.PinSubCategory="",PinType.PinSubCategoryObject=None,PinType.PinSubCategoryMemberReference=(),PinType.PinValueType=(),PinType.ContainerType=None,PinType.bIsReference=False,PinType.bIsConst=False,PinType.bIsWeakPointer=False,PinType.bIsUObjectWrapper=False,PinType.bSerializeAsSinglePrecisionFloat=False,DefaultValue="false",AutogeneratedDefaultValue="false",PersistentGuid=00000000000000000000000000000000,bHidden=False,bNotConnectable=False,bDefaultValueIsReadOnly=False,bDefaultValueIsIgnored=False,bAdvancedView=False,bOrphanedPin=False,)
End Object
`,
size: [9, 4],
pins: 3,
delegate: false,
development: false,
variadic: false,
additionalTest: async (node, pins) => {
expect(await pins[0].evaluate(pin => pin.color.toString())).toEqual("0, 88, 200")
expect(await pins[1].evaluate(pin => pin.color.toString())).toEqual("0, 88, 200")
expect(await pins[2].evaluate(pin => pin.color.toString())).toEqual("146, 0, 0")
expect(await node.evaluate(node => node.classList.contains("ueb-node-style-glass"))).toBeTruthy()
expect(await node.evaluate(node => node.classList.contains("ueb-node-style-default"))).toBeFalsy()
}
})

View File

@@ -7,6 +7,7 @@
*/
/**
* @typedef {CustomEvent<{ value: Coordinates }>} UEBDragEvent
* @typedef {CustomEvent} UEBNodeUpdateEvent
*/
/** @typedef {typeof import("./js/entity/IEntity.js").default} IEntityConstructor */
/**