@esengine/behavior-tree 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.umd.js DELETED
@@ -1,2 +0,0 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@esengine/ecs-framework")):"function"==typeof define&&define.amd?define(["exports","@esengine/ecs-framework"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).BehaviorTree={},e.ECS)}(this,(function(e,t){"use strict";var a;e.TaskStatus=void 0,(a=e.TaskStatus||(e.TaskStatus={}))[a.Invalid=0]="Invalid",a[a.Success=1]="Success",a[a.Failure=2]="Failure",a[a.Running=3]="Running";const r={Composite:"composite",Decorator:"decorator",Action:"action",Condition:"condition"};var n,o,s,i;function c(){return{status:e.TaskStatus.Invalid,currentChildIndex:0}}function d(e,t,a,r){var n,o=arguments.length,s=o<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,a):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,a,r);else for(var i=e.length-1;i>=0;i--)(n=e[i])&&(s=(o<3?n(s):o>3?n(t,a,s):n(t,a))||s);return o>3&&s&&Object.defineProperty(t,a,s),s}function l(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}e.CompositeType=void 0,(n=e.CompositeType||(e.CompositeType={})).Sequence="sequence",n.Selector="selector",n.Parallel="parallel",n.ParallelSelector="parallel-selector",n.RandomSequence="random-sequence",n.RandomSelector="random-selector",e.DecoratorType=void 0,(o=e.DecoratorType||(e.DecoratorType={})).Inverter="inverter",o.Repeater="repeater",o.UntilSuccess="until-success",o.UntilFail="until-fail",o.AlwaysSucceed="always-succeed",o.AlwaysFail="always-fail",o.Conditional="conditional",o.Cooldown="cooldown",o.Timeout="timeout",e.AbortType=void 0,(s=e.AbortType||(e.AbortType={})).None="none",s.Self="self",s.LowerPriority="lower-priority",s.Both="both",e.BlackboardValueType=void 0,(i=e.BlackboardValueType||(e.BlackboardValueType={})).String="string",i.Number="number",i.Boolean="boolean",i.Vector2="vector2",i.Vector3="vector3",i.Object="object",i.Array="array","function"==typeof SuppressedError&&SuppressedError,e.BehaviorTreeRuntimeComponent=class extends t.Component{constructor(){super(...arguments),this.treeAssetId="",this.autoStart=!0,this.isRunning=!1,this.nodeStates=new Map,this.blackboard=new Map,this.blackboardObservers=new Map,this.activeNodeIds=new Set,this.needsReset=!1,this.nodesToAbort=new Set}getNodeState(e){return this.nodeStates.has(e)||this.nodeStates.set(e,c()),this.nodeStates.get(e)}resetNodeState(t){const a=this.getNodeState(t);a.status=e.TaskStatus.Invalid,a.currentChildIndex=0,delete a.startTime,delete a.lastExecutionTime,delete a.repeatCount,delete a.cachedResult,delete a.shuffledIndices,delete a.isAborted,delete a.lastConditionResult,delete a.observedKeys}resetAllStates(){this.nodeStates.clear(),this.activeNodeIds.clear()}getBlackboardValue(e){return this.blackboard.get(e)}setBlackboardValue(e,t){const a=this.blackboard.get(e);this.blackboard.set(e,t),a!==t&&this.notifyBlackboardChange(e,t,a)}hasBlackboardKey(e){return this.blackboard.has(e)}initializeBlackboard(e){e&&e.forEach(((e,t)=>{this.blackboard.has(t)||this.blackboard.set(t,e)}))}clearBlackboard(){this.blackboard.clear()}start(){this.isRunning=!0,this.resetAllStates()}stop(){this.isRunning=!1,this.activeNodeIds.clear()}pause(){this.isRunning=!1}resume(){this.isRunning=!0}observeBlackboard(e,t,a){const r={nodeId:e,keys:new Set(t),callback:a};for(const e of t)this.blackboardObservers.has(e)||this.blackboardObservers.set(e,[]),this.blackboardObservers.get(e).push(r)}unobserveBlackboard(e){for(const t of this.blackboardObservers.values()){const a=t.findIndex((t=>t.nodeId===e));-1!==a&&t.splice(a,1)}}notifyBlackboardChange(e,t,a){const r=this.blackboardObservers.get(e);if(r)for(const n of r)try{n.callback(e,t,a)}catch(e){console.error(`黑板观察者回调错误 (节点: ${n.nodeId}):`,e)}}requestAbort(e){this.nodesToAbort.add(e)}shouldAbort(e){return this.nodesToAbort.has(e)}clearAbortRequest(e){this.nodesToAbort.delete(e)}clearAllAbortRequests(){this.nodesToAbort.clear()}},d([t.Serialize(),l("design:type",String)],e.BehaviorTreeRuntimeComponent.prototype,"treeAssetId",void 0),d([t.Serialize(),l("design:type",Boolean)],e.BehaviorTreeRuntimeComponent.prototype,"autoStart",void 0),d([t.IgnoreSerialization(),l("design:type",Boolean)],e.BehaviorTreeRuntimeComponent.prototype,"isRunning",void 0),d([t.IgnoreSerialization(),l("design:type",Map)],e.BehaviorTreeRuntimeComponent.prototype,"nodeStates",void 0),d([t.IgnoreSerialization(),l("design:type",Map)],e.BehaviorTreeRuntimeComponent.prototype,"blackboard",void 0),d([t.IgnoreSerialization(),l("design:type",Map)],e.BehaviorTreeRuntimeComponent.prototype,"blackboardObservers",void 0),d([t.IgnoreSerialization(),l("design:type",Set)],e.BehaviorTreeRuntimeComponent.prototype,"activeNodeIds",void 0),d([t.IgnoreSerialization(),l("design:type",Boolean)],e.BehaviorTreeRuntimeComponent.prototype,"needsReset",void 0),d([t.IgnoreSerialization(),l("design:type",Set)],e.BehaviorTreeRuntimeComponent.prototype,"nodesToAbort",void 0),e.BehaviorTreeRuntimeComponent=d([t.ECSComponent("BehaviorTreeRuntime"),t.Serializable({version:1})],e.BehaviorTreeRuntimeComponent);const u=t.createLogger("BehaviorTreeAssetManager");class h{constructor(){this.assets=new Map}loadAsset(e){this.assets.has(e.id)&&u.warn(`行为树资产已存在,将被覆盖: ${e.id}`),this.assets.set(e.id,e),u.info(`行为树资产已加载: ${e.name} (${e.nodes.size}个节点)`)}getAsset(e){return this.assets.get(e)}hasAsset(e){return this.assets.has(e)}unloadAsset(e){const t=this.assets.delete(e);return t&&u.info(`行为树资产已卸载: ${e}`),t}clearAll(){this.assets.clear(),u.info("所有行为树资产已清空")}getAssetCount(){return this.assets.size}getAllAssetIds(){return Array.from(this.assets.keys())}dispose(){this.clearAll()}}class p{static getValue(e,t,a){const{nodeData:r,runtime:n}=e;if(r.bindings&&r.bindings[t]){const e=r.bindings[t],o=n.getBlackboardValue(e);return void 0!==o?o:a}const o=r.config[t];return void 0!==o?o:a}static hasBinding(e,t){return!(!e.nodeData.bindings||!e.nodeData.bindings[t])}static getBindingKey(e,t){return e.nodeData.bindings?.[t]}}class m{constructor(){this.executors=new Map}register(e,t){this.executors.has(e)&&console.warn(`执行器已存在,将被覆盖: ${e}`),this.executors.set(e,t)}get(e){return this.executors.get(e)}has(e){return this.executors.has(e)}unregister(e){return this.executors.delete(e)}clear(){this.executors.clear()}}class g{static register(e,t){this.metadataMap.set(t.implementationType,t),this.executorClassMap.set(e,t.implementationType),this.executorConstructors.set(t.implementationType,e)}static getMetadata(e){return this.metadataMap.get(e)}static getAllMetadata(){return Array.from(this.metadataMap.values())}static getByCategory(e){return this.getAllMetadata().filter((t=>t.category===e))}static getByNodeType(e){return this.getAllMetadata().filter((t=>t.nodeType===e))}static getImplementationType(e){return this.executorClassMap.get(e)}static getExecutorConstructor(e){return this.executorConstructors.get(e)}static getAllExecutorConstructors(){return new Map(this.executorConstructors)}}function y(e){return function(t){g.register(t,e)}}g.metadataMap=new Map,g.executorClassMap=new Map,g.executorConstructors=new Map,e.SequenceExecutor=class{execute(t){const{nodeData:a,state:r}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Success;for(;r.currentChildIndex<a.children.length;){const n=a.children[r.currentChildIndex],o=t.executeChild(n);if(o===e.TaskStatus.Running)return e.TaskStatus.Running;if(o===e.TaskStatus.Failure)return r.currentChildIndex=0,e.TaskStatus.Failure;r.currentChildIndex++}return r.currentChildIndex=0,e.TaskStatus.Success}reset(e){e.state.currentChildIndex=0}},e.SequenceExecutor=d([y({implementationType:"Sequence",nodeType:r.Composite,displayName:"序列",description:"按顺序执行子节点,全部成功才成功",category:"Composite"})],e.SequenceExecutor),e.SelectorExecutor=class{execute(t){const{nodeData:a,state:r}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;for(;r.currentChildIndex<a.children.length;){const n=a.children[r.currentChildIndex],o=t.executeChild(n);if(o===e.TaskStatus.Running)return e.TaskStatus.Running;if(o===e.TaskStatus.Success)return r.currentChildIndex=0,e.TaskStatus.Success;r.currentChildIndex++}return r.currentChildIndex=0,e.TaskStatus.Failure}reset(e){e.state.currentChildIndex=0}},e.SelectorExecutor=d([y({implementationType:"Selector",nodeType:r.Composite,displayName:"选择器",description:"按顺序执行子节点,任一成功则成功",category:"Composite"})],e.SelectorExecutor),e.ParallelExecutor=class{execute(t){const{nodeData:a}=t,r=p.getValue(t,"successPolicy","all"),n=p.getValue(t,"failurePolicy","one");if(!a.children||0===a.children.length)return e.TaskStatus.Success;let o=!1,s=0,i=0;for(const r of a.children){const a=t.executeChild(r);a===e.TaskStatus.Running?o=!0:a===e.TaskStatus.Success?s++:a===e.TaskStatus.Failure&&i++}return"one"===r&&s>0?(this.stopAllChildren(t),e.TaskStatus.Success):"all"===r&&s===a.children.length?e.TaskStatus.Success:"one"===n&&i>0?(this.stopAllChildren(t),e.TaskStatus.Failure):"all"===n&&i===a.children.length?e.TaskStatus.Failure:o?e.TaskStatus.Running:e.TaskStatus.Success}stopAllChildren(e){const{nodeData:t,runtime:a}=e;if(t.children)for(const e of t.children)a.activeNodeIds.delete(e),a.resetNodeState(e)}reset(e){const{nodeData:t,runtime:a}=e;if(t.children)for(const e of t.children)a.resetNodeState(e)}},e.ParallelExecutor=d([y({implementationType:"Parallel",nodeType:r.Composite,displayName:"并行",description:"同时执行所有子节点",category:"Composite",configSchema:{successPolicy:{type:"string",default:"all",description:"成功策略",options:["all","one"]},failurePolicy:{type:"string",default:"one",description:"失败策略",options:["all","one"]}}})],e.ParallelExecutor),e.ParallelSelectorExecutor=class{execute(t){const{nodeData:a}=t,r=p.getValue(t,"failurePolicy","all");if(!a.children||0===a.children.length)return e.TaskStatus.Failure;let n=!1,o=0,s=0;for(const r of a.children){const a=t.executeChild(r);a===e.TaskStatus.Running?n=!0:a===e.TaskStatus.Success?o++:a===e.TaskStatus.Failure&&s++}return o>0?(this.stopAllChildren(t),e.TaskStatus.Success):"one"===r&&s>0?(this.stopAllChildren(t),e.TaskStatus.Failure):"all"===r&&s===a.children.length?e.TaskStatus.Failure:n?e.TaskStatus.Running:e.TaskStatus.Failure}stopAllChildren(e){const{nodeData:t,runtime:a}=e;if(t.children)for(const e of t.children)a.activeNodeIds.delete(e),a.resetNodeState(e)}reset(e){const{nodeData:t,runtime:a}=e;if(t.children)for(const e of t.children)a.resetNodeState(e)}},e.ParallelSelectorExecutor=d([y({implementationType:"ParallelSelector",nodeType:r.Composite,displayName:"并行选择器",description:"并行执行子节点,任一成功则成功",category:"Composite",configSchema:{failurePolicy:{type:"string",default:"all",description:"失败策略",options:["all","one"]}}})],e.ParallelSelectorExecutor),e.RandomSequenceExecutor=class{execute(t){const{nodeData:a,state:r}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Success;for(r.shuffledIndices&&0!==r.shuffledIndices.length||(r.shuffledIndices=this.shuffleIndices(a.children.length));r.currentChildIndex<r.shuffledIndices.length;){const n=r.shuffledIndices[r.currentChildIndex],o=a.children[n],s=t.executeChild(o);if(s===e.TaskStatus.Running)return e.TaskStatus.Running;if(s===e.TaskStatus.Failure)return r.currentChildIndex=0,delete r.shuffledIndices,e.TaskStatus.Failure;r.currentChildIndex++}return r.currentChildIndex=0,delete r.shuffledIndices,e.TaskStatus.Success}shuffleIndices(e){const t=Array.from({length:e},((e,t)=>t));for(let e=t.length-1;e>0;e--){const a=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[a],t[a]=r}return t}reset(e){e.state.currentChildIndex=0,delete e.state.shuffledIndices}},e.RandomSequenceExecutor=d([y({implementationType:"RandomSequence",nodeType:r.Composite,displayName:"随机序列",description:"随机顺序执行子节点,全部成功才成功",category:"Composite"})],e.RandomSequenceExecutor),e.RandomSelectorExecutor=class{execute(t){const{nodeData:a,state:r}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;for(r.shuffledIndices&&0!==r.shuffledIndices.length||(r.shuffledIndices=this.shuffleIndices(a.children.length));r.currentChildIndex<r.shuffledIndices.length;){const n=r.shuffledIndices[r.currentChildIndex],o=a.children[n],s=t.executeChild(o);if(s===e.TaskStatus.Running)return e.TaskStatus.Running;if(s===e.TaskStatus.Success)return r.currentChildIndex=0,delete r.shuffledIndices,e.TaskStatus.Success;r.currentChildIndex++}return r.currentChildIndex=0,delete r.shuffledIndices,e.TaskStatus.Failure}shuffleIndices(e){const t=Array.from({length:e},((e,t)=>t));for(let e=t.length-1;e>0;e--){const a=Math.floor(Math.random()*(e+1)),r=t[e];t[e]=t[a],t[a]=r}return t}reset(e){e.state.currentChildIndex=0,delete e.state.shuffledIndices}},e.RandomSelectorExecutor=d([y({implementationType:"RandomSelector",nodeType:r.Composite,displayName:"随机选择器",description:"随机顺序执行子节点,任一成功则成功",category:"Composite"})],e.RandomSelectorExecutor),e.InverterExecutor=class{execute(t){const{nodeData:a}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const r=a.children[0],n=t.executeChild(r);return n===e.TaskStatus.Running?e.TaskStatus.Running:n===e.TaskStatus.Success?e.TaskStatus.Failure:n===e.TaskStatus.Failure?e.TaskStatus.Success:e.TaskStatus.Failure}reset(e){e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.InverterExecutor=d([y({implementationType:"Inverter",nodeType:r.Decorator,displayName:"反转",description:"反转子节点的执行结果",category:"Decorator"})],e.InverterExecutor),e.RepeaterExecutor=class{execute(t){const{nodeData:a,state:r,runtime:n}=t,o=p.getValue(t,"repeatCount",1),s=p.getValue(t,"endOnFailure",!1);if(!a.children||0===a.children.length)return e.TaskStatus.Success;const i=a.children[0];r.repeatCount||(r.repeatCount=0);const c=t.executeChild(i);if(c===e.TaskStatus.Running)return e.TaskStatus.Running;if(c===e.TaskStatus.Failure&&s)return r.repeatCount=0,e.TaskStatus.Failure;r.repeatCount++,n.resetNodeState(i);return-1===o||r.repeatCount<o?e.TaskStatus.Running:(r.repeatCount=0,e.TaskStatus.Success)}reset(e){delete e.state.repeatCount,e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.RepeaterExecutor=d([y({implementationType:"Repeater",nodeType:r.Decorator,displayName:"重复",description:"重复执行子节点指定次数",category:"Decorator",configSchema:{repeatCount:{type:"number",default:1,description:"重复次数(-1表示无限循环)",supportBinding:!0},endOnFailure:{type:"boolean",default:!1,description:"子节点失败时是否结束"}}})],e.RepeaterExecutor),e.AlwaysSucceedExecutor=class{execute(t){const{nodeData:a}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Success;const r=a.children[0];return t.executeChild(r)===e.TaskStatus.Running?e.TaskStatus.Running:e.TaskStatus.Success}reset(e){e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.AlwaysSucceedExecutor=d([y({implementationType:"AlwaysSucceed",nodeType:r.Decorator,displayName:"总是成功",description:"无论子节点结果如何都返回成功",category:"Decorator"})],e.AlwaysSucceedExecutor),e.AlwaysFailExecutor=class{execute(t){const{nodeData:a}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const r=a.children[0];return t.executeChild(r)===e.TaskStatus.Running?e.TaskStatus.Running:e.TaskStatus.Failure}reset(e){e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.AlwaysFailExecutor=d([y({implementationType:"AlwaysFail",nodeType:r.Decorator,displayName:"总是失败",description:"无论子节点结果如何都返回失败",category:"Decorator"})],e.AlwaysFailExecutor),e.UntilSuccessExecutor=class{execute(t){const{nodeData:a,runtime:r}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const n=a.children[0],o=t.executeChild(n);return o===e.TaskStatus.Running?e.TaskStatus.Running:o===e.TaskStatus.Success?e.TaskStatus.Success:(r.resetNodeState(n),e.TaskStatus.Running)}reset(e){e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.UntilSuccessExecutor=d([y({implementationType:"UntilSuccess",nodeType:r.Decorator,displayName:"直到成功",description:"重复执行子节点直到成功",category:"Decorator"})],e.UntilSuccessExecutor),e.UntilFailExecutor=class{execute(t){const{nodeData:a,runtime:r}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Success;const n=a.children[0],o=t.executeChild(n);return o===e.TaskStatus.Running?e.TaskStatus.Running:o===e.TaskStatus.Failure?e.TaskStatus.Failure:(r.resetNodeState(n),e.TaskStatus.Running)}reset(e){e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.UntilFailExecutor=d([y({implementationType:"UntilFail",nodeType:r.Decorator,displayName:"直到失败",description:"重复执行子节点直到失败",category:"Decorator"})],e.UntilFailExecutor),e.ConditionalExecutor=class{execute(t){const{nodeData:a,runtime:r,state:n}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const o=p.getValue(t,"blackboardKey",""),s=p.getValue(t,"expectedValue"),i=p.getValue(t,"operator","equals"),c=a.abortType||e.AbortType.None;if(!o)return e.TaskStatus.Failure;const d=r.getBlackboardValue(o),l=this.evaluateCondition(d,s,i),u=n.status===e.TaskStatus.Running;if(c!==e.AbortType.None&&(n.observedKeys&&0!==n.observedKeys.length||(n.observedKeys=[o],this.setupObserver(t,o,s,i,c)),void 0!==n.lastConditionResult&&n.lastConditionResult!==l&&(l?this.handleConditionBecameTrue(t,c):u&&this.handleConditionBecameFalse(t,c))),n.lastConditionResult=l,!l)return e.TaskStatus.Failure;const h=a.children[0];return t.executeChild(h)}evaluateCondition(e,t,a){switch(a){case"equals":return e===t;case"notEquals":return e!==t;case"greaterThan":return e>t;case"lessThan":return e<t;case"greaterOrEqual":return e>=t;case"lessOrEqual":return e<=t;default:return!1}}setupObserver(e,t,a,r,n){const{nodeData:o,runtime:s}=e;s.observeBlackboard(o.id,[t],((t,o)=>{const s=this.evaluateCondition(o,a,r),i=e.state.lastConditionResult;void 0!==i&&i!==s&&(s?this.handleConditionBecameTrue(e,n):this.handleConditionBecameFalse(e,n)),e.state.lastConditionResult=s}))}handleConditionBecameTrue(t,a){a!==e.AbortType.LowerPriority&&a!==e.AbortType.Both||this.requestAbortLowerPriority(t)}handleConditionBecameFalse(t,a){const{nodeData:r,runtime:n}=t;a!==e.AbortType.Self&&a!==e.AbortType.Both||r.children&&r.children.length>0&&n.requestAbort(r.children[0])}requestAbortLowerPriority(e){const{runtime:t}=e;t.requestAbort("__lower_priority__")}reset(e){const{nodeData:t,runtime:a,state:r}=e;r.observedKeys&&r.observedKeys.length>0&&(a.unobserveBlackboard(t.id),delete r.observedKeys),delete r.lastConditionResult,t.children&&t.children.length>0&&a.resetNodeState(t.children[0])}},e.ConditionalExecutor=d([y({implementationType:"Conditional",nodeType:r.Decorator,displayName:"条件",description:"根据条件决定是否执行子节点",category:"Decorator",configSchema:{blackboardKey:{type:"string",default:"",description:"黑板变量名"},expectedValue:{type:"object",description:"期望值",supportBinding:!0},operator:{type:"string",default:"equals",description:"比较运算符",options:["equals","notEquals","greaterThan","lessThan","greaterOrEqual","lessOrEqual"]},abortType:{type:"string",default:"none",description:"中止类型",options:["none","self","lower-priority","both"]}}})],e.ConditionalExecutor),e.CooldownExecutor=class{execute(t){const{nodeData:a,state:r,totalTime:n}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const o=p.getValue(t,"cooldownTime",1);if(void 0!==r.lastExecutionTime){if(n-r.lastExecutionTime<o)return e.TaskStatus.Failure}const s=a.children[0],i=t.executeChild(s);return i===e.TaskStatus.Running?e.TaskStatus.Running:i===e.TaskStatus.Success?(r.lastExecutionTime=n,e.TaskStatus.Success):e.TaskStatus.Failure}reset(e){delete e.state.lastExecutionTime,e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.CooldownExecutor=d([y({implementationType:"Cooldown",nodeType:r.Decorator,displayName:"冷却",description:"子节点执行成功后进入冷却时间",category:"Decorator",configSchema:{cooldownTime:{type:"number",default:1,description:"冷却时间(秒)",min:0,supportBinding:!0}}})],e.CooldownExecutor),e.TimeoutExecutor=class{execute(t){const{nodeData:a,state:r,totalTime:n}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const o=p.getValue(t,"timeout",1);void 0===r.startTime&&(r.startTime=n);if(n-r.startTime>=o)return delete r.startTime,e.TaskStatus.Failure;const s=a.children[0],i=t.executeChild(s);return i===e.TaskStatus.Running?e.TaskStatus.Running:(delete r.startTime,i)}reset(e){delete e.state.startTime,e.nodeData.children&&e.nodeData.children.length>0&&e.runtime.resetNodeState(e.nodeData.children[0])}},e.TimeoutExecutor=d([y({implementationType:"Timeout",nodeType:r.Decorator,displayName:"超时",description:"限制子节点的执行时间",category:"Decorator",configSchema:{timeout:{type:"number",default:1,description:"超时时间(秒)",min:0,supportBinding:!0}}})],e.TimeoutExecutor);class f{static register(e,t){this.services.set(e,t)}static get(e){return this.services.get(e)}static has(e){return this.services.has(e)}static unregister(e){return this.services.delete(e)}}f.services=new Map,e.ServiceDecorator=class{execute(t){const{nodeData:a,state:r,totalTime:n}=t;if(!a.children||0===a.children.length)return e.TaskStatus.Failure;const o=p.getValue(t,"serviceName",""),s=p.getValue(t,"tickInterval",0);if(!o)return e.TaskStatus.Failure;const i=f.get(o);if(!i)return console.warn(`未找到Service: ${o}`),e.TaskStatus.Failure;r.status!==e.TaskStatus.Running&&(r.startTime=n,r.lastExecutionTime=n,i.onServiceStart&&i.onServiceStart(t));(0===s||void 0!==r.lastExecutionTime&&n-r.lastExecutionTime>=s)&&(i.onServiceTick(t),r.lastExecutionTime=n);const c=a.children[0],d=t.executeChild(c);return d!==e.TaskStatus.Running&&i.onServiceEnd&&i.onServiceEnd(t),d}reset(e){const{nodeData:t,runtime:a,state:r}=e,n=p.getValue(e,"serviceName","");if(n){const t=f.get(n);t&&t.onServiceEnd&&t.onServiceEnd(e)}delete r.startTime,delete r.lastExecutionTime,t.children&&t.children.length>0&&a.resetNodeState(t.children[0])}},e.ServiceDecorator=d([y({implementationType:"Service",nodeType:r.Decorator,displayName:"Service",description:"在子节点执行期间持续运行后台逻辑",category:"Decorator",configSchema:{serviceName:{type:"string",default:"",description:"Service名称"},tickInterval:{type:"number",default:0,description:"Service更新间隔(秒,0表示每帧更新)",supportBinding:!0}}})],e.ServiceDecorator),e.WaitAction=class{execute(t){const{state:a,totalTime:r}=t,n=p.getValue(t,"duration",1);return a.startTime?r-a.startTime>=n?e.TaskStatus.Success:e.TaskStatus.Running:(a.startTime=r,e.TaskStatus.Running)}reset(e){delete e.state.startTime}},e.WaitAction=d([y({implementationType:"Wait",nodeType:r.Action,displayName:"等待",description:"等待指定时间后返回成功",category:"Action",configSchema:{duration:{type:"number",default:1,description:"等待时长(秒)",min:0,supportBinding:!0}}})],e.WaitAction),e.LogAction=class{execute(t){const{runtime:a}=t,r=p.getValue(t,"message",""),n=p.getValue(t,"logLevel","info"),o=this.replaceBlackboardVariables(r,a);return this.log(o,n),e.TaskStatus.Success}replaceBlackboardVariables(e,t){return e.includes("{")&&e.includes("}")?e.replace(/\{([\w.]{1,100})\}/g,((e,a)=>{const r=t.getBlackboardValue(a.trim());return void 0!==r?String(r):`{${a}}`})):e}log(e,t){switch(t){case"error":console.error(e);break;case"warn":console.warn(e);break;default:console.log(e)}}},e.LogAction=d([y({implementationType:"Log",nodeType:r.Action,displayName:"日志",description:"输出日志信息",category:"Action",configSchema:{message:{type:"string",default:"",description:"日志消息,支持{key}占位符引用黑板变量",supportBinding:!0},logLevel:{type:"string",default:"info",description:"日志级别",options:["info","warn","error"]}}})],e.LogAction),e.SetBlackboardValue=class{execute(t){const{runtime:a}=t,r=p.getValue(t,"key",""),n=p.getValue(t,"value");return r?(a.setBlackboardValue(r,n),e.TaskStatus.Success):e.TaskStatus.Failure}},e.SetBlackboardValue=d([y({implementationType:"SetBlackboardValue",nodeType:r.Action,displayName:"设置黑板值",description:"设置黑板中的变量值",category:"Action",configSchema:{key:{type:"string",default:"",description:"黑板变量名"},value:{type:"object",description:"要设置的值",supportBinding:!0}}})],e.SetBlackboardValue),e.ModifyBlackboardValue=class{execute(t){const{runtime:a}=t,r=p.getValue(t,"key",""),n=p.getValue(t,"operation","add"),o=p.getValue(t,"value",0);if(!r)return e.TaskStatus.Failure;const s=a.getBlackboardValue(r)||0;let i;switch(n){case"add":i=s+o;break;case"subtract":i=s-o;break;case"multiply":i=s*o;break;case"divide":i=0!==o?s/o:s;break;case"set":i=o;break;default:return e.TaskStatus.Failure}return a.setBlackboardValue(r,i),e.TaskStatus.Success}},e.ModifyBlackboardValue=d([y({implementationType:"ModifyBlackboardValue",nodeType:r.Action,displayName:"修改黑板值",description:"对黑板中的数值进行运算",category:"Action",configSchema:{key:{type:"string",default:"",description:"黑板变量名"},operation:{type:"string",default:"add",description:"运算类型",options:["add","subtract","multiply","divide","set"]},value:{type:"number",default:0,description:"操作数",supportBinding:!0}}})],e.ModifyBlackboardValue),e.ExecuteAction=class{execute(t){const{runtime:a,entity:r}=t,n=p.getValue(t,"actionName","");if(!n)return e.TaskStatus.Failure;const o=a.getBlackboardValue(`action_${n}`);if(!o||"function"!=typeof o)return e.TaskStatus.Failure;try{return o(r)}catch(t){return console.error(`ExecuteAction failed: ${t}`),e.TaskStatus.Failure}}},e.ExecuteAction=d([y({implementationType:"ExecuteAction",nodeType:r.Action,displayName:"执行动作",description:"执行自定义动作逻辑",category:"Action",configSchema:{actionName:{type:"string",default:"",description:"动作名称(黑板中action_前缀的函数)"}}})],e.ExecuteAction),e.SubTreeExecutor=class{constructor(){this.assetManager=null}getAssetManager(){return this.assetManager||(this.assetManager=t.Core.services.resolve(h)),this.assetManager}execute(t){const{runtime:a,state:r,entity:n}=t,o=p.getValue(t,"treeAssetId",""),s=p.getValue(t,"shareBlackboard",!0);if(!o)return e.TaskStatus.Failure;const i=this.getAssetManager().getAsset(o);if(!i)return console.warn(`未找到子树资产: ${o}`),e.TaskStatus.Failure;const c=i.nodes.get(i.rootNodeId);if(!c)return console.warn(`子树根节点未找到: ${i.rootNodeId}`),e.TaskStatus.Failure;if(!s&&r.status!==e.TaskStatus.Running&&i.blackboardVariables)for(const[e,t]of i.blackboardVariables.entries())a.hasBlackboardKey(e)||a.setBlackboardValue(e,t);const d={entity:n,nodeData:c,state:a.getNodeState(c.id),runtime:a,treeData:i,deltaTime:t.deltaTime,totalTime:t.totalTime,executeChild:r=>{const o=i.nodes.get(r);if(!o)return console.warn(`子树节点未找到: ${r}`),e.TaskStatus.Failure;const s={entity:n,nodeData:o,state:a.getNodeState(r),runtime:a,treeData:i,deltaTime:t.deltaTime,totalTime:t.totalTime,executeChild:d.executeChild};return this.executeSubTreeNode(s)}};return this.executeSubTreeNode(d)}executeSubTreeNode(t){const{nodeData:a,runtime:r}=t,n=r.getNodeState(a.id);if(!a.children||0===a.children.length)return e.TaskStatus.Success;const o=a.children[n.currentChildIndex],s=t.executeChild(o);return s===e.TaskStatus.Running?e.TaskStatus.Running:s===e.TaskStatus.Failure?(n.currentChildIndex=0,e.TaskStatus.Failure):(n.currentChildIndex++,n.currentChildIndex>=a.children.length?(n.currentChildIndex=0,e.TaskStatus.Success):e.TaskStatus.Running)}reset(e){const t=p.getValue(e,"treeAssetId","");if(t){const a=this.getAssetManager().getAsset(t);if(a){const t=a.nodes.get(a.rootNodeId);if(t&&(e.runtime.resetNodeState(t.id),t.children))for(const a of t.children)e.runtime.resetNodeState(a)}}}},e.SubTreeExecutor=d([y({implementationType:"SubTree",nodeType:r.Action,displayName:"子树",description:"引用并执行其他行为树",category:"Special",configSchema:{treeAssetId:{type:"string",default:"",description:"要执行的行为树资产ID",supportBinding:!0},shareBlackboard:{type:"boolean",default:!0,description:"是否共享黑板数据"}}})],e.SubTreeExecutor),e.BlackboardCompare=class{execute(t){const{runtime:a}=t,r=p.getValue(t,"key",""),n=p.getValue(t,"compareValue"),o=p.getValue(t,"operator","equals");if(!r)return e.TaskStatus.Failure;const s=a.getBlackboardValue(r);return this.compare(s,n,o)?e.TaskStatus.Success:e.TaskStatus.Failure}compare(e,t,a){switch(a){case"equals":return e===t;case"notEquals":return e!==t;case"greaterThan":return e>t;case"lessThan":return e<t;case"greaterOrEqual":return e>=t;case"lessOrEqual":return e<=t;default:return!1}}},e.BlackboardCompare=d([y({implementationType:"BlackboardCompare",nodeType:r.Condition,displayName:"黑板比较",description:"比较黑板中的值",category:"Condition",configSchema:{key:{type:"string",default:"",description:"黑板变量名"},compareValue:{type:"object",description:"比较值",supportBinding:!0},operator:{type:"string",default:"equals",description:"比较运算符",options:["equals","notEquals","greaterThan","lessThan","greaterOrEqual","lessOrEqual"]}}})],e.BlackboardCompare),e.BlackboardExists=class{execute(t){const{runtime:a}=t,r=p.getValue(t,"key",""),n=p.getValue(t,"checkNull",!1);if(!r)return e.TaskStatus.Failure;const o=a.getBlackboardValue(r);return void 0===o||n&&null===o?e.TaskStatus.Failure:e.TaskStatus.Success}},e.BlackboardExists=d([y({implementationType:"BlackboardExists",nodeType:r.Condition,displayName:"黑板存在",description:"检查黑板中是否存在指定的键",category:"Condition",configSchema:{key:{type:"string",default:"",description:"黑板变量名"},checkNull:{type:"boolean",default:!1,description:"检查是否为null"}}})],e.BlackboardExists),e.RandomProbability=class{execute(t){const a=p.getValue(t,"probability",.5),r=Math.max(0,Math.min(1,a));return Math.random()<r?e.TaskStatus.Success:e.TaskStatus.Failure}},e.RandomProbability=d([y({implementationType:"RandomProbability",nodeType:r.Condition,displayName:"随机概率",description:"根据概率返回成功或失败",category:"Condition",configSchema:{probability:{type:"number",default:.5,description:"成功概率(0-1)",min:0,max:1,supportBinding:!0}}})],e.RandomProbability),e.ExecuteCondition=class{execute(t){const{runtime:a,entity:r}=t,n=p.getValue(t,"conditionName","");if(!n)return e.TaskStatus.Failure;const o=a.getBlackboardValue(`condition_${n}`);if(!o||"function"!=typeof o)return e.TaskStatus.Failure;try{return o(r)?e.TaskStatus.Success:e.TaskStatus.Failure}catch(t){return console.error(`ExecuteCondition failed: ${t}`),e.TaskStatus.Failure}}},e.ExecuteCondition=d([y({implementationType:"ExecuteCondition",nodeType:r.Condition,displayName:"执行条件",description:"执行自定义条件逻辑",category:"Condition",configSchema:{conditionName:{type:"string",default:"",description:"条件名称(黑板中condition_前缀的函数)"}}})],e.ExecuteCondition),e.BehaviorTreeExecutionSystem=class extends t.EntitySystem{constructor(){super(t.Matcher.empty().all(e.BehaviorTreeRuntimeComponent)),this.assetManager=t.Core.services.resolve(h),this.executorRegistry=new m,this.registerBuiltInExecutors()}registerBuiltInExecutors(){const e=g.getAllExecutorConstructors();for(const[t,a]of e)try{const e=new a;this.executorRegistry.register(t,e)}catch(e){this.logger.error(`注册执行器失败: ${t}`,e)}}getExecutorRegistry(){return this.executorRegistry}process(t){for(const a of t){const t=a.getComponent(e.BehaviorTreeRuntimeComponent);if(!t.isRunning)continue;const r=this.assetManager.getAsset(t.treeAssetId);r?(t.needsReset&&(t.resetAllStates(),t.needsReset=!1),this.executeTree(a,t,r)):this.logger.warn(`未找到行为树资产: ${t.treeAssetId}`)}}executeTree(t,a,r){const n=r.nodes.get(r.rootNodeId);if(!n)return void this.logger.error(`未找到根节点: ${r.rootNodeId}`);this.executeNode(t,a,n,r)!==e.TaskStatus.Running?a.needsReset=!0:a.needsReset=!1}executeNode(t,a,r,n){const o=a.getNodeState(r.id);if(a.shouldAbort(r.id)){a.clearAbortRequest(r.id),o.isAborted=!0;const s=this.executorRegistry.get(r.implementationType);if(s&&s.reset){const e=this.createContext(t,a,r,n);s.reset(e)}return a.activeNodeIds.delete(r.id),o.status=e.TaskStatus.Failure,e.TaskStatus.Failure}a.activeNodeIds.add(r.id),o.isAborted=!1;const s=this.executorRegistry.get(r.implementationType);if(!s)return this.logger.error(`未找到执行器: ${r.implementationType}`),o.status=e.TaskStatus.Failure,e.TaskStatus.Failure;const i=this.createContext(t,a,r,n);try{const t=s.execute(i);return o.status=t,t!==e.TaskStatus.Running&&(a.activeNodeIds.delete(r.id),s.reset&&s.reset(i)),t}catch(t){return this.logger.error(`执行节点时发生错误: ${r.name}`,t),o.status=e.TaskStatus.Failure,a.activeNodeIds.delete(r.id),e.TaskStatus.Failure}}createContext(a,r,n,o){return{entity:a,nodeData:n,state:r.getNodeState(n.id),runtime:r,treeData:o,deltaTime:t.Time.deltaTime,totalTime:t.Time.totalTime,executeChild:t=>{const n=o.nodes.get(t);return n?this.executeNode(a,r,n,o):(this.logger.warn(`未找到子节点: ${t}`),e.TaskStatus.Failure)}}}executeChildren(t,a){const{nodeData:r,treeData:n,entity:o,runtime:s}=t;if(!r.children||0===r.children.length)return[];const i=[],c=a||Array.from({length:r.children.length},((e,t)=>t));for(const t of c){if(t>=r.children.length)continue;const a=r.children[t],c=n.nodes.get(a);if(!c){this.logger.warn(`未找到子节点: ${a}`),i.push(e.TaskStatus.Failure);continue}const d=this.executeNode(o,s,c,n);i.push(d)}return i}},e.BehaviorTreeExecutionSystem=d([t.ECSSystem("BehaviorTreeExecution"),l("design:paramtypes",[])],e.BehaviorTreeExecutionSystem);class S{constructor(e){this.nodeStack=[],this.nodeIdCounter=0,this.treeData={id:`tree_${Date.now()}`,name:e,rootNodeId:"",nodes:new Map,blackboardVariables:new Map}}static create(e="BehaviorTree"){return new S(e)}defineBlackboardVariable(e,t){return this.treeData.blackboardVariables||(this.treeData.blackboardVariables=new Map),this.treeData.blackboardVariables.set(e,t),this}sequence(e){return this.addCompositeNode("Sequence",e||"Sequence")}selector(e){return this.addCompositeNode("Selector",e||"Selector")}parallel(e,t){return this.addCompositeNode("Parallel",e||"Parallel",t)}parallelSelector(e,t){return this.addCompositeNode("ParallelSelector",e||"ParallelSelector",t)}randomSequence(e){return this.addCompositeNode("RandomSequence",e||"RandomSequence")}randomSelector(e){return this.addCompositeNode("RandomSelector",e||"RandomSelector")}inverter(e){return this.addDecoratorNode("Inverter",e||"Inverter")}repeater(e,t){return this.addDecoratorNode("Repeater",t||"Repeater",{repeatCount:e})}alwaysSucceed(e){return this.addDecoratorNode("AlwaysSucceed",e||"AlwaysSucceed")}alwaysFail(e){return this.addDecoratorNode("AlwaysFail",e||"AlwaysFail")}untilSuccess(e){return this.addDecoratorNode("UntilSuccess",e||"UntilSuccess")}untilFail(e){return this.addDecoratorNode("UntilFail",e||"UntilFail")}conditional(e,t,a,r){return this.addDecoratorNode("Conditional",r||"Conditional",{blackboardKey:e,expectedValue:t,operator:a||"equals"})}cooldown(e,t){return this.addDecoratorNode("Cooldown",t||"Cooldown",{cooldownTime:e})}timeout(e,t){return this.addDecoratorNode("Timeout",t||"Timeout",{timeout:e})}wait(e,t){return this.addActionNode("Wait",t||"Wait",{duration:e})}log(e,t){return this.addActionNode("Log",t||"Log",{message:e})}setBlackboardValue(e,t,a){return this.addActionNode("SetBlackboardValue",a||"SetBlackboardValue",{key:e,value:t})}modifyBlackboardValue(e,t,a,r){return this.addActionNode("ModifyBlackboardValue",r||"ModifyBlackboardValue",{key:e,operation:t,value:a})}executeAction(e,t){return this.addActionNode("ExecuteAction",t||"ExecuteAction",{actionName:e})}blackboardCompare(e,t,a,r){return this.addConditionNode("BlackboardCompare",r||"BlackboardCompare",{key:e,compareValue:t,operator:a||"equals"})}blackboardExists(e,t){return this.addConditionNode("BlackboardExists",t||"BlackboardExists",{key:e})}randomProbability(e,t){return this.addConditionNode("RandomProbability",t||"RandomProbability",{probability:e})}executeCondition(e,t){return this.addConditionNode("ExecuteCondition",t||"ExecuteCondition",{conditionName:e})}end(){return this.nodeStack.length>0&&this.nodeStack.pop(),this}build(){if(!this.treeData.rootNodeId)throw new Error("No root node defined. Add at least one node to the tree.");return this.treeData}addCompositeNode(e,t,a={}){const n=this.generateNodeId(),o={id:n,name:t,nodeType:r.Composite,implementationType:e,children:[],config:a};if(this.treeData.nodes.set(n,o),this.treeData.rootNodeId||(this.treeData.rootNodeId=n),this.nodeStack.length>0){const e=this.nodeStack[this.nodeStack.length-1],t=this.treeData.nodes.get(e);t&&t.children&&t.children.push(n)}return this.nodeStack.push(n),this}addDecoratorNode(e,t,a={}){const n=this.generateNodeId(),o={id:n,name:t,nodeType:r.Decorator,implementationType:e,children:[],config:a};if(this.treeData.nodes.set(n,o),this.treeData.rootNodeId||(this.treeData.rootNodeId=n),this.nodeStack.length>0){const e=this.nodeStack[this.nodeStack.length-1],t=this.treeData.nodes.get(e);t&&t.children&&t.children.push(n)}return this.nodeStack.push(n),this}addActionNode(e,t,a={}){const n=this.generateNodeId(),o={id:n,name:t,nodeType:r.Action,implementationType:e,config:a};if(this.treeData.nodes.set(n,o),this.treeData.rootNodeId||(this.treeData.rootNodeId=n),this.nodeStack.length>0){const e=this.nodeStack[this.nodeStack.length-1],t=this.treeData.nodes.get(e);t&&t.children&&t.children.push(n)}return this}addConditionNode(e,t,a={}){const n=this.generateNodeId(),o={id:n,name:t,nodeType:r.Condition,implementationType:e,config:a};if(this.treeData.nodes.set(n,o),this.treeData.rootNodeId||(this.treeData.rootNodeId=n),this.nodeStack.length>0){const e=this.nodeStack[this.nodeStack.length-1],t=this.treeData.nodes.get(e);t&&t.children&&t.children.push(n)}return this}generateNodeId(){return"node_"+this.nodeIdCounter++}}const T={String:"string",Number:"number",Boolean:"boolean",Select:"select",Blackboard:"blackboard",Code:"code",Variable:"variable",Asset:"asset"};class b{static validate(e){const t=[],a=[];if(e.version||t.push("Missing version field"),e.metadata&&e.metadata.name||t.push("Missing or invalid metadata"),e.rootNodeId||t.push("Missing rootNodeId"),e.nodes&&Array.isArray(e.nodes)){const r=new Set;e.nodes.find((t=>t.id===e.rootNodeId))||t.push(`Root node '${e.rootNodeId}' not found in nodes array`);for(const a of e.nodes)if(a.id){if(r.has(a.id)&&t.push(`Duplicate node id: ${a.id}`),r.add(a.id),a.nodeType||t.push(`Node ${a.id} missing nodeType`),a.children)for(const r of a.children)e.nodes.find((e=>e.id===r))||t.push(`Node ${a.id} references non-existent child: ${r}`)}else t.push("Node missing id field");const n=new Set([e.rootNodeId]),o=t=>{const a=e.nodes.find((e=>e.id===t));if(a&&a.children)for(const e of a.children)n.add(e),o(e)};o(e.rootNodeId);for(const t of e.nodes)n.has(t.id)||a.push(`Orphaned node detected: ${t.id} (${t.name})`)}else t.push("Missing or invalid nodes array");if(e.blackboard&&Array.isArray(e.blackboard)){const a=new Set;for(const r of e.blackboard)r.name?(a.has(r.name)&&t.push(`Duplicate blackboard variable: ${r.name}`),a.add(r.name),r.type||t.push(`Blackboard variable ${r.name} missing type`)):t.push("Blackboard variable missing name")}if(e.propertyBindings&&Array.isArray(e.propertyBindings)){const a=new Set(e.nodes.map((e=>e.id))),r=new Set(e.blackboard?.map((e=>e.name))||[]);for(const n of e.propertyBindings)a.has(n.nodeId)||t.push(`Property binding references non-existent node: ${n.nodeId}`),r.has(n.variableName)||t.push(`Property binding references non-existent variable: ${n.variableName}`),n.propertyName||t.push("Property binding missing propertyName")}const r={valid:0===t.length};return t.length>0&&(r.errors=t),a.length>0&&(r.warnings=a),r}static getStats(e){let t=0,a=0,n=0,o=0;for(const s of e.nodes)switch(s.nodeType){case r.Action:t++;break;case r.Condition:a++;break;case r.Composite:n++;break;case r.Decorator:o++}const s=(t,a=0)=>{const r=e.nodes.find((e=>e.id===t));if(!r||!r.children||0===r.children.length)return a;let n=a;for(const e of r.children){const t=s(e,a+1);n=Math.max(n,t)}return n};return{nodeCount:e.nodes.length,actionCount:t,conditionCount:a,compositeCount:n,decoratorCount:o,blackboardVariableCount:e.blackboard?.length||0,propertyBindingCount:e.propertyBindings?.length||0,maxDepth:s(e.rootNodeId)}}}const k=t.createLogger("EditorFormatConverter");class C{static toAsset(e,t){k.info("开始转换编辑器格式到资产格式");const a=this.findRootNode(e.nodes);if(!a)throw new Error("未找到根节点");const r={name:t?.name||e.metadata?.name||"Untitled Behavior Tree",version:t?.version||e.version||"1.0.0"},n=t?.description||e.metadata?.description;n&&(r.description=n);const o=t?.createdAt||e.metadata?.createdAt;o&&(r.createdAt=o);const s=t?.modifiedAt||(new Date).toISOString();s&&(r.modifiedAt=s);const i=this.convertNodes(e.nodes),c=this.convertBlackboard(e.blackboard),d=this.convertPropertyBindings(e.connections,e.nodes,c),l={version:"1.0.0",metadata:r,rootNodeId:a.id,nodes:i,blackboard:c};return d.length>0&&(l.propertyBindings=d),k.info(`转换完成: ${i.length}个节点, ${c.length}个黑板变量, ${d.length}个属性绑定`),l}static findRootNode(e){return e.find((e=>"根节点"===e.template.category||"root"===e.data.nodeType))||null}static convertNodes(e){return e.map((e=>this.convertNode(e)))}static convertNode(e){const t={...e.data};return delete t.nodeType,e.template.className&&(t.className=e.template.className),{id:e.id,name:e.template.displayName||e.data.name||"Node",nodeType:e.template.type,data:t,children:e.children||[]}}static convertBlackboard(e){const t=[];for(const[a,r]of Object.entries(e)){const e=this.inferBlackboardType(r);t.push({name:a,type:e,defaultValue:r})}return t}static inferBlackboardType(t){return"number"==typeof t?e.BlackboardValueType.Number:"string"==typeof t?e.BlackboardValueType.String:"boolean"==typeof t?e.BlackboardValueType.Boolean:e.BlackboardValueType.Object}static convertPropertyBindings(e,t,a){const r=[],n=new Set(a.map((e=>e.name))),o=e.filter((e=>"property"===e.connectionType));for(const e of o){const a=t.find((t=>t.id===e.from)),o=t.find((t=>t.id===e.to));if(!a||!o||!e.toProperty){k.warn(`跳过无效的属性连接: from=${e.from}, to=${e.to}`);continue}let s;"blackboard-variable"===a.data.nodeType?s=a.data.variableName:e.fromProperty&&(s=e.fromProperty),s?n.has(s)?r.push({nodeId:o.id,propertyName:e.toProperty,variableName:s}):k.warn(`属性绑定引用了不存在的黑板变量: ${s}`):k.warn(`无法确定变量名: from节点=${a.template.displayName}`)}return r}static fromAsset(e){k.info("开始转换资产格式到编辑器格式");const t=this.convertNodesFromAsset(e.nodes),a={};for(const t of e.blackboard)a[t.name]=t.defaultValue;const r=this.convertPropertyBindingsToConnections(e.propertyBindings||[]),n=this.buildNodeConnections(e.nodes);r.push(...n);const o={name:e.metadata.name};e.metadata.description&&(o.description=e.metadata.description),e.metadata.createdAt&&(o.createdAt=e.metadata.createdAt),e.metadata.modifiedAt&&(o.modifiedAt=e.metadata.modifiedAt);const s={version:e.metadata.version,metadata:o,nodes:t,connections:r,blackboard:a,canvasState:{offset:{x:0,y:0},scale:1}};return k.info(`转换完成: ${t.length}个节点, ${r.length}个连接`),s}static convertNodesFromAsset(e){return e.map(((e,t)=>{const a={x:100+t%5*250,y:100+150*Math.floor(t/5)},r={displayName:e.name,category:this.inferCategory(e.nodeType),type:e.nodeType};return e.data.className&&(r.className=e.data.className),{id:e.id,template:r,data:{...e.data},position:a,children:e.children}}))}static inferCategory(e){switch(e){case r.Action:return"动作";case r.Condition:return"条件";case r.Composite:return"组合";case r.Decorator:return"装饰器";default:return"其他"}}static convertPropertyBindingsToConnections(e){const t=[];for(const a of e)t.push({from:"blackboard",to:a.nodeId,toProperty:a.propertyName,connectionType:"property"});return t}static buildNodeConnections(e){const t=[];for(const a of e)for(const e of a.children)t.push({from:a.id,to:e,connectionType:"node"});return t}}const v=t.createLogger("BehaviorTreeAssetSerializer");class x{constructor(){this.variables=new Map}dispose(){this.variables.clear()}defineVariable(e,t,a,r){const n={name:e,type:t,value:a,readonly:r?.readonly??!1};void 0!==r?.description&&(n.description=r.description),this.variables.set(e,n)}getValue(e){const t=this.variables.get(e);return t?.value}setValue(e,t,a=!1){const r=this.variables.get(e);return!!r&&(!(r.readonly&&!a)&&(r.value=t,!0))}hasVariable(e){return this.variables.has(e)}removeVariable(e){return this.variables.delete(e)}getVariableNames(){return Array.from(this.variables.keys())}getAllVariables(){return Array.from(this.variables.values())}clear(){this.variables.clear()}setVariables(e){for(const[t,a]of Object.entries(e)){const e=this.variables.get(t);e&&!e.readonly&&(e.value=a)}}getVariables(e){const t={};for(const a of e){const e=this.getValue(a);void 0!==e&&(t[a]=e)}return t}exportConfig(){return{version:"1.0",variables:Array.from(this.variables.values())}}importConfig(e){this.variables.clear();for(const t of e.variables)this.variables.set(t.name,t)}toJSON(){return JSON.stringify(this.exportConfig(),null,2)}static fromJSON(e){return JSON.parse(e)}}e.BehaviorTreeAssetManager=h,e.BehaviorTreeAssetSerializer=class{static serialize(e,t={format:"json",pretty:!0}){if(!1!==t.validate){const t=b.validate(e);if(!t.valid){const e=t.errors?.join(", ")||"Unknown error";throw new Error(`资产验证失败: ${e}`)}t.warnings&&t.warnings.length>0&&v.warn(`资产验证警告: ${t.warnings.join(", ")}`)}return"json"===t.format?this.serializeToJSON(e,t.pretty):this.serializeToBinary(e)}static serializeToJSON(e,t=!0){try{const a=t?JSON.stringify(e,null,2):JSON.stringify(e);return v.info(`已序列化为JSON: ${a.length} 字符`),a}catch(e){throw new Error(`JSON序列化失败: ${e}`)}}static serializeToBinary(e){try{const a=t.BinarySerializer.encode(e);return v.info(`已序列化为二进制: ${a.length} 字节`),a}catch(e){throw new Error(`二进制序列化失败: ${e}`)}}static deserialize(e,t={validate:!0,strict:!0}){let a;try{a="string"==typeof e?this.deserializeFromJSON(e):this.deserializeFromBinary(e)}catch(e){throw new Error(`反序列化失败: ${e}`)}if(!1!==t.validate){const e=b.validate(a);if(!e.valid){const a=e.errors?.join(", ")||"Unknown error";if(t.strict)throw new Error(`资产验证失败: ${a}`);v.error(`资产验证失败: ${a}`)}e.warnings&&e.warnings.length>0&&v.warn(`资产验证警告: ${e.warnings.join(", ")}`)}return a}static deserializeFromJSON(e){try{const t=JSON.parse(e);if(!t.rootNodeId&&t.nodes&&t.connections){v.info("检测到编辑器格式,正在转换为运行时资产格式...");const e=t,a=C.toAsset(e);return v.info(`已从编辑器格式转换: ${a.nodes.length} 个节点`),a}{const e=t;return v.info(`已从运行时资产格式反序列化: ${e.nodes.length} 个节点`),e}}catch(e){throw new Error(`JSON解析失败: ${e}`)}}static deserializeFromBinary(e){try{const a=t.BinarySerializer.decode(e);return v.info(`已从二进制反序列化: ${a.nodes.length} 个节点`),a}catch(e){throw new Error(`二进制解码失败: ${e}`)}}static detectFormat(e){return"string"==typeof e?"json":"binary"}static getInfo(e){try{const a=this.detectFormat(e);let r;r="json"===a?JSON.parse(e):t.BinarySerializer.decode(e);const n=e.length;return{format:a,name:r.metadata.name,version:r.version,nodeCount:r.nodes.length,blackboardVariableCount:r.blackboard.length,size:n}}catch(e){return v.error(`获取资产信息失败: ${e}`),null}}static convert(e,t,a=!0){const r=this.deserialize(e,{validate:!1});return this.serialize(r,{format:t,pretty:a,validate:!1})}static compareSize(e,t){const a=e.length,r=t.length,n=a-r;return{jsonSize:a,binarySize:r,compressionRatio:n/a*100,savedBytes:n}}},e.BehaviorTreeAssetValidator=b,e.BehaviorTreeBuilder=S,e.BehaviorTreePlugin=class{constructor(){this.name="@esengine/behavior-tree",this.version="1.0.0",this.worldManager=null,this.services=null}async install(e,a){this.services=a,a.registerSingleton(x),a.registerSingleton(h),this.worldManager=a.resolve(t.WorldManager)}async uninstall(){this.services&&(this.services.unregister(x),this.services.unregister(h)),this.worldManager=null,this.services=null}setupScene(t){t.addSystem(new e.BehaviorTreeExecutionSystem)}setupAllScenes(){if(!this.worldManager)throw new Error("Plugin not installed");const e=this.worldManager.getAllWorlds();for(const t of e)for(const e of t.getAllScenes())this.setupScene(e)}},e.BehaviorTreeStarter=class{static start(a,r,n=!0){t.Core.services.resolve(h).loadAsset(r);let o=a.getComponent(e.BehaviorTreeRuntimeComponent);if(o||(o=new e.BehaviorTreeRuntimeComponent,a.addComponent(o)),o.treeAssetId=r.id,o.autoStart=n,r.blackboardVariables)for(const[e,t]of r.blackboardVariables.entries())o.setBlackboardValue(e,t);n&&(o.isRunning=!0)}static stop(t){const a=t.getComponent(e.BehaviorTreeRuntimeComponent);a&&(a.isRunning=!1,a.resetAllStates())}static pause(t){const a=t.getComponent(e.BehaviorTreeRuntimeComponent);a&&(a.isRunning=!1)}static resume(t){const a=t.getComponent(e.BehaviorTreeRuntimeComponent);a&&(a.isRunning=!0)}static restart(t){const a=t.getComponent(e.BehaviorTreeRuntimeComponent);a&&(a.resetAllStates(),a.isRunning=!0)}},e.BindingHelper=p,e.EditorFormatConverter=C,e.GlobalBlackboardService=x,e.NodeExecutorMetadata=y,e.NodeExecutorRegistry=m,e.NodeMetadataRegistry=g,e.NodeTemplates=class{static getAllTemplates(){return g.getAllMetadata().map((e=>this.convertMetadataToTemplate(e)))}static getTemplate(e,t){return this.getAllTemplates().find((a=>{if(a.type!==e)return!1;const n=a.defaultConfig;switch(e){case r.Composite:return n.compositeType===t;case r.Decorator:return n.decoratorType===t;case r.Action:return n.actionType===t;case r.Condition:return n.conditionType===t;default:return!1}}))}static convertMetadataToTemplate(e){const t=this.convertConfigSchemaToProperties(e.configSchema||{}),a={nodeType:this.nodeTypeToString(e.nodeType)};switch(e.nodeType){case r.Composite:a.compositeType=e.implementationType;break;case r.Decorator:a.decoratorType=e.implementationType;break;case r.Action:a.actionType=e.implementationType;break;case r.Condition:a.conditionType=e.implementationType}if(e.configSchema)for(const[t,r]of Object.entries(e.configSchema)){const e=r;void 0!==e.default&&(a[t]=e.default)}const{icon:n,color:o}=this.getIconAndColorByType(e.nodeType,e.category||"");return{type:e.nodeType,displayName:e.displayName,category:e.category||this.getCategoryByNodeType(e.nodeType),description:e.description||"",className:e.implementationType,icon:n,color:o,defaultConfig:a,properties:t}}static convertConfigSchemaToProperties(e){const t=[];for(const[a,r]of Object.entries(e)){const e={name:a,type:this.mapFieldTypeToPropertyType(r),label:a};void 0!==r.description&&(e.description=r.description),void 0!==r.default&&(e.defaultValue=r.default),void 0!==r.min&&(e.min=r.min),void 0!==r.max&&(e.max=r.max),void 0!==r.allowMultipleConnections&&(e.allowMultipleConnections=r.allowMultipleConnections),r.options&&(e.options=r.options.map((e=>({label:e,value:e})))),r.supportBinding&&(e.renderConfig={component:"BindableInput",props:{supportBinding:!0}}),t.push(e)}return t}static mapFieldTypeToPropertyType(e){if(e.options&&e.options.length>0)return T.Select;switch(e.type){case"string":case"array":case"object":default:return T.String;case"number":return T.Number;case"boolean":return T.Boolean}}static nodeTypeToString(e){switch(e){case r.Composite:return"composite";case r.Decorator:return"decorator";case r.Action:return"action";case r.Condition:return"condition";default:return"unknown"}}static getCategoryByNodeType(e){switch(e){case r.Composite:return"组合";case r.Decorator:return"装饰器";case r.Action:return"动作";case r.Condition:return"条件";default:return"其他"}}static getIconAndColorByType(e,t){switch(e){case r.Composite:return{icon:"GitBranch",color:"#1976d2"};case r.Decorator:return{icon:"Settings",color:"#fb8c00"};case r.Action:return{icon:"Play",color:"#388e3c"};case r.Condition:return{icon:"HelpCircle",color:"#d32f2f"};default:return{icon:"Circle",color:"#757575"}}}},e.NodeType=r,e.PropertyType=T,e.ServiceRegistry=f,e.createDefaultRuntimeState=c}));
2
- //# sourceMappingURL=index.umd.js.map