Browse Source

Working on serialization for action manager (actions & conditions)

moreau-mathis 9 năm trước cách đây
mục cha
commit
ffd1d421c6

+ 49 - 0
src/Actions/babylon.action.ts

@@ -89,5 +89,54 @@
         public _getEffectiveTarget(target: any, propertyPath: string): any {
             return this._actionManager._getEffectiveTarget(target, propertyPath);
         }
+        
+        public serialize(parent: any): any {
+        }
+        
+        // Called by BABYLON.Action objects in serialize(...). Internal use
+        protected _serialize(serializedAction: any, parent?: any, target?: Node | Scene): any {
+            var serializationObject: any = { 
+                type: 1,
+                children: [],
+                name: serializedAction.name,
+                properties: serializedAction.properties || []
+            };
+            
+            // If target, auto-complete
+            if (target) {
+                var targetObject = {
+                    name: "target",
+                    targetType: target instanceof Mesh ? "MeshProperties"
+                              : target instanceof Light ? "LightProperties"
+                              : target instanceof Camera ? "CameraProperties"
+                              : "Scene",
+                    value: target instanceof Scene ? "Scene" : target.name
+                }
+                
+                // Concat action's properties
+                serializationObject.properties = [targetObject].concat(serializationObject.properties);
+            }
+            
+            // Serialize child
+            if (this._child) {
+                this._child.serialize(serializationObject);
+            }
+            
+            // Check if "this" has a condition
+            if (this._condition) {
+                var serializedCondition = this._condition.serialize();
+                serializedCondition.children.push(serializationObject);
+                
+                if (parent) {
+                    parent.children.push(serializedCondition);
+                }
+                return serializedCondition;
+            }
+            
+            if (parent) {
+                parent.children.push(serializationObject);
+            }
+            return serializationObject;
+        }
     }
 }

+ 48 - 0
src/Actions/babylon.actionManager.ts

@@ -291,6 +291,54 @@
 
             return properties[properties.length - 1];
         }
+        
+        public serialize(name: string): any {
+            var root = {
+                children: [],
+                name: name,
+                type: 3, // Root node
+                properties: [] // Empty for root but required
+            };
+            
+            for (var i = 0; i < this.actions.length; i++) {
+                var triggerObject = { 
+                    type: 0, // Trigger
+                    children: [],
+                    name: ActionManager.GetTriggerName(this.actions[i].trigger),
+                    properties: []
+                };
+                
+                // Serialize child action, recursively
+                this.actions[i].serialize(triggerObject);
+                
+                // Add serialized trigger
+                root.children.push(triggerObject);
+            }
+            
+            return root;
+        }
+        
+        public static GetTriggerName(trigger: number): string {
+            switch (trigger) {
+                case 0:  return "NothingTrigger";
+                case 1:  return "OnPickTrigger";
+                case 2:  return "OnLeftPickTrigger";
+                case 3:  return "OnRightPickTrigger";
+                case 4:  return "OnCenterPickTrigger";
+                case 5:  return "OnPickDownTrigger";
+                case 6:  return "OnPickUpTrigger";
+                case 7:  return "OnLongPressTrigger";
+                case 8:  return "OnPointerOverTrigger";
+                case 9:  return "OnPointerOutTrigger";
+                case 10: return "OnEveryFrameTrigger";
+                case 11: return "OnIntersectionEnterTrigger";
+                case 12: return "OnIntersectionExitTrigger";
+                case 13: return "OnKeyDownTrigger";
+                case 14: return "OnKeyUpTrigger";
+                case 15: return "OnPickOutTrigger";
+                default: return "";
+            }
+        }
 
         public static Parse(parsedActions: any, object: AbstractMesh, scene: Scene) {
             var actionManager = new BABYLON.ActionManager(scene);

+ 36 - 0
src/Actions/babylon.condition.ts

@@ -20,6 +20,35 @@
         public _getEffectiveTarget(target: any, propertyPath: string): any {
             return this._actionManager._getEffectiveTarget(target, propertyPath);
         }
+        
+        public serialize(): any {
+        }
+        
+        protected _serialize(serializedCondition: any, target?: Node | Scene): any {
+            var serializationObject = { 
+                type: 3, // Condition
+                children: [],
+                name: serializedCondition.name,
+                properties: serializedCondition.properties
+            };
+            
+            // If target, auto-complete
+            if (target) {
+                var targetObject = {
+                    name: "target",
+                    targetType: target instanceof Mesh ? "MeshProperties"
+                              : target instanceof Light ? "LightProperties"
+                              : target instanceof Camera ? "CameraProperties"
+                              : "Scene",
+                    value: target instanceof Scene ? "Scene" : target.name
+                }
+                
+                // Concat action's properties
+                serializationObject.properties = [targetObject].concat(serializationObject.properties);
+            }
+            
+            return serializationObject;
+        }
     }
 
     export class ValueCondition extends Condition {
@@ -111,6 +140,13 @@
         public isValid(): boolean {
             return this._target.state === this.value;
         }
+        
+        public serialize(): any {
+            return this._serialize({
+               name: "StateCondition",
+               properties: [{ name: "value", value: this.value }]
+            }, this._target);
+        }
     }
 
 }

+ 7 - 0
src/Actions/babylon.directActions.ts

@@ -16,6 +16,13 @@
         public execute(): void {
             this._target[this._property] = !this._target[this._property];
         }
+        
+        public serialize(parent: any): any {
+            return super._serialize({
+                name: "SwitchBooleanAction",
+                properties: [{ name: "propertyPath", value: this.propertyPath }]
+            }, parent, this._target);
+        }
     }
 
     export class SetStateAction extends Action {

+ 10 - 0
src/Tools/babylon.sceneSerializer.ts

@@ -147,6 +147,11 @@
 
         // Layer mask
         serializationObject.layerMask = mesh.layerMask;
+        
+        // Action Manager
+        if (mesh.actionManager) {
+            serializationObject.actions = mesh.actionManager.serialize(mesh.name);
+        }
 
         return serializationObject;
     };
@@ -333,6 +338,11 @@
                     serializationObject.shadowGenerators.push(light.getShadowGenerator().serialize());
                 }
             }
+            
+            // Action Manager
+            if (scene.actionManager) {
+                serializationObject.actions = scene.actionManager.serialize("scene");
+            }
 
             return serializationObject;
         }