Browse Source

More work on prefabs

Josh Engebretson 10 years ago
parent
commit
8a1da37032

+ 1 - 0
Script/AtomicEditor/ui/ProjectFrame.ts

@@ -126,6 +126,7 @@ class ProjectFrame extends ScriptWidget {
 
             var file = new Atomic.File(destFilename, Atomic.FILE_WRITE);
             node.saveXML(file);
+            file.close();
 
             this.rescan(asset);
 

+ 1 - 0
Script/AtomicEditor/ui/inspector/InspectorFrame.ts

@@ -47,6 +47,7 @@ class InspectorFrame extends ScriptWidget {
         var node = <Atomic.Node> data.node;
 
         if (!node) {
+          
             return;
         }
 

+ 26 - 1
Script/AtomicEditor/ui/inspector/NodeInspector.ts

@@ -92,6 +92,8 @@ class NodeInspector extends ScriptWidget {
 
 
     inspect(node: Atomic.Node) {
+      
+        this.bindings = new Array();
 
         this.node = node;
 
@@ -196,7 +198,13 @@ class NodeInspector extends ScriptWidget {
             var prefabComponent = this.getPrefabComponent(this.node);
 
             if (prefabComponent) {
+
               prefabComponent.savePrefab();
+
+              this.sendEvent("EditorActiveNodeChange", {node:this.node});
+
+              return true;
+
             }
 
           }.bind(this);
@@ -205,6 +213,23 @@ class NodeInspector extends ScriptWidget {
           undoButton.text = "Undo";
           undoButton.fontDescription = fd;
 
+          undoButton.onClick = function() {
+
+            var prefabComponent = this.getPrefabComponent(this.node);
+
+            if (prefabComponent) {
+
+              prefabComponent.undoPrefab();
+
+              this.sendEvent("EditorActiveNodeChange", {node:this.node});
+
+              return true;
+
+            }
+
+          }.bind(this);
+
+
           prefabLayout.addChild(name);
           prefabLayout.addChild(saveButton);
           prefabLayout.addChild(undoButton);
@@ -243,7 +268,7 @@ class NodeInspector extends ScriptWidget {
     isPrefab:boolean;
     node: Atomic.Node;
     nodeLayout: Atomic.UILayout;
-    bindings: Array<DataBinding> = new Array();
+    bindings: Array<DataBinding>;
 
 
 }

+ 1 - 0
Script/TypeScript/Atomic.d.ts

@@ -1818,6 +1818,7 @@ declare module Atomic {
       setPrefabGUID(guid: string): void;
       getPrefabGUID(): string;
       savePrefab(): boolean;
+      undoPrefab(): void;
       getPrefabNode(): Node;
 
    }

+ 34 - 14
Source/Atomic/Scene/PrefabComponent.cpp

@@ -5,6 +5,8 @@
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceEvents.h>
 
+#include <Atomic/Physics/RigidBody.h>
+
 #include "PrefabEvents.h"
 #include "PrefabComponent.h"
 
@@ -15,7 +17,7 @@ namespace Atomic
 PrefabComponent::PrefabComponent(Context* context) :
     Component(context)
 {
-
+    SubscribeToEvent(E_PREFABCHANGED, HANDLER(PrefabComponent, HandlePrefabChanged));
 }
 
 PrefabComponent::~PrefabComponent()
@@ -32,6 +34,11 @@ bool PrefabComponent::SavePrefab()
     return true;
 }
 
+void PrefabComponent::UndoPrefab()
+{
+    LoadPrefabNode();
+}
+
 void PrefabComponent::RegisterObject(Context* context)
 {
     context->RegisterFactory<PrefabComponent>();
@@ -39,14 +46,38 @@ void PrefabComponent::RegisterObject(Context* context)
     ACCESSOR_ATTRIBUTE("PrefabGUID", GetPrefabGUID, SetPrefabGUID, String, String::EMPTY, AM_FILE | AM_NOEDIT);
 }
 
-void PrefabComponent::HandleReloadFinished(StringHash eventType, VariantMap& eventData)
+void PrefabComponent::LoadPrefabNode()
 {
     ResourceCache* cache = GetSubsystem<ResourceCache>();
     XMLFile* xmlfile = cache->GetResource<XMLFile>(prefabGUID_);
 
     prefabNode_->LoadXML(xmlfile->GetRoot());
+    prefabNode_->SetPosition(Vector3::ZERO);
+    prefabNode_->SetRotation(Quaternion::IDENTITY);
+    prefabNode_->SetScale(Vector3::ONE);
     prefabNode_->SetTemporary(true);
 
+    PODVector<RigidBody*> bodies;
+    prefabNode_->GetComponents<RigidBody>(bodies, true);
+    for (unsigned i = 0; i < bodies.Size(); i++)
+    {
+        RigidBody* body = bodies[i];
+
+        body->SetPosition(body->GetNode()->GetWorldPosition());
+        body->SetRotation(body->GetNode()->GetWorldRotation());
+    }
+
+}
+
+void PrefabComponent::HandlePrefabChanged(StringHash eventType, VariantMap& eventData)
+{
+    using namespace PrefabChanged;
+
+    if (prefabGUID_ != eventData[P_GUID].GetString())
+        return;
+
+    LoadPrefabNode();
+
 }
 
 void PrefabComponent::SetPrefabGUID(const String& guid)
@@ -62,20 +93,9 @@ void PrefabComponent::SetPrefabGUID(const String& guid)
 
     if (prefabGUID_.Length())
     {
-        ResourceCache* cache = GetSubsystem<ResourceCache>();
-        XMLFile* xmlfile = cache->GetResource<XMLFile>(prefabGUID_);
-
-        SubscribeToEvent(xmlfile, E_RELOADFINISHED, HANDLER(PrefabComponent, HandleReloadFinished));
-
-        if (xmlfile)
-        {
-            prefabNode_->LoadXML(xmlfile->GetRoot());
-        }
+        LoadPrefabNode();
     }
 
-    prefabNode_->SetName(prefabNode_->GetName() + "_Prefab");
-    prefabNode_->SetTemporary(true);
-
 }
 
 void PrefabComponent::OnNodeSet(Node* node)

+ 4 - 1
Source/Atomic/Scene/PrefabComponent.h

@@ -26,6 +26,7 @@ public:
     const String& GetPrefabGUID() const { return prefabGUID_; }
 
     bool SavePrefab();
+    void UndoPrefab();
 
     Node* GetPrefabNode() { return prefabNode_; }
 
@@ -37,7 +38,9 @@ protected:
 
 private:
 
-    void HandleReloadFinished(StringHash eventType, VariantMap& eventData);
+    void HandlePrefabChanged(StringHash eventType, VariantMap& eventData);
+
+    void LoadPrefabNode();
 
     SharedPtr<Node> prefabNode_;
     String prefabGUID_;

+ 2 - 2
Source/Atomic/Scene/PrefabEvents.h

@@ -10,10 +10,10 @@ EVENT(E_PREFABSAVE, PrefabSave)
     PARAM(P_PREFABCOMPONENT, PrefabComponent); // PrefabComponent Pointer
 }
 
+/// Instead of using resource reload system which can be delayed due to file watchers, we explicitly send prefab changes
 EVENT(E_PREFABCHANGED, PrefabChanged)
 {
-    PARAM(P_PREFABCOMPONENT, PrefabComponent); // PrefabComponent Pointer
-    PARAM(P_NODE, Node); // Node Pointer
+    PARAM(P_GUID, GUID); // String
 }
 
 }

+ 9 - 1
Source/AtomicEditorWork/Editors/SceneEditor3D/SceneView3D.cpp

@@ -287,7 +287,15 @@ void SceneView3D::HandlePostRenderUpdate(StringHash eventType, VariantMap& event
                 {
 
                     VariantMap neventData;
-                    neventData[EditorActiveNodeChange::P_NODE] = r.drawable_->GetNode();
+                    Node* node = r.drawable_->GetNode();
+
+                    // if temporary, this is a prefab
+                    // TODO: if we use temporary for other stuff
+                    // fix this to look for prefab
+                    if (node->IsTemporary())
+                        node = node->GetParent();
+
+                    neventData[EditorActiveNodeChange::P_NODE] = node;
                     SendEvent(E_EDITORACTIVENODECHANGE, neventData);
 
                 }

+ 15 - 1
Source/ToolCore/Assets/PrefabImporter.cpp

@@ -1,6 +1,6 @@
 
 #include <Atomic/Resource/ResourceCache.h>
-#include <Atomic/Resource/Image.h>
+#include <Atomic/Resource/XMLFile.h>
 #include <Atomic/Scene/Scene.h>
 #include <Atomic/Scene/PrefabEvents.h>
 #include <Atomic/Scene/PrefabComponent.h>
@@ -51,6 +51,10 @@ void PrefabImporter::HandlePrefabSave(StringHash eventType, VariantMap& eventDat
 
     Node* node = component->GetPrefabNode();
 
+    node->SetPosition(Vector3::ZERO);
+    node->SetRotation(Quaternion::IDENTITY);
+    node->SetScale(Vector3::ONE);
+
     SharedPtr<File> file(new File(context_, asset_->GetPath(), FILE_WRITE));
     node->SaveXML(*file);
     file->Close();
@@ -58,6 +62,16 @@ void PrefabImporter::HandlePrefabSave(StringHash eventType, VariantMap& eventDat
     FileSystem* fs = GetSubsystem<FileSystem>();
     fs->Copy(asset_->GetPath(), asset_->GetCachePath());
 
+    // reload it immediately so it is ready for use
+    // TODO: The resource cache is reloading after this reload due to catching the file cache
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    XMLFile* xmlfile = cache->GetResource<XMLFile>(asset_->GetGUID());
+    cache->ReloadResource(xmlfile);
+
+    VariantMap changedData;
+    changedData[PrefabChanged::P_GUID] = asset_->GetGUID();
+    SendEvent(E_PREFABCHANGED, changedData);
+
 }
 
 bool PrefabImporter::Import(const String& guid)