Browse Source

Fixed Node::Clone() to respect the local mode of child nodes & components.
Added convenience functions for saving & instantiating nodes directly from a XMLFile.
Added the Scenes & Objects directories to GetPreferredResourceDir() check.

Lasse Öörni 14 năm trước cách đây
mục cha
commit
30430d24ad

+ 1 - 6
Bin/Data/Scripts/Editor/EditorScene.as

@@ -279,12 +279,7 @@ void SaveNode(const String&in fileName)
         if (extension != ".xml")
             selectedNodes[0].Save(file);
         else
-        {
-            XMLFile xml;
-            XMLElement root = xml.CreateRoot("node");
-            selectedNodes[0].SaveXML(root);
-            xml.Save(file);
-        }
+            selectedNodes[0].SaveXML(file);
 
         instantiateFileName = fileName;
     }

+ 2 - 2
Bin/Data/Scripts/NinjaSnowWar.as

@@ -270,7 +270,7 @@ void SpawnPlayer(Connection@ connection)
     Node@ playerNode = SpawnObject(spawnPosition, Quaternion(), "Ninja");
     // Set owner connection. Owned nodes are always updated to the owner at full frequency
     playerNode.owner = connection;
-    playerNode.name = "Player";    
+    playerNode.name = "Player";
 
     // Initialize variables
     Ninja@ playerNinja = cast<Ninja>(playerNode.scriptObject);
@@ -619,7 +619,7 @@ void SendHiscores(int playerIndex)
 Node@ SpawnObject(const Vector3&in position, const Quaternion&in rotation, const String&in className)
 {
     XMLFile@ xml = cache.GetResource("XMLFile", "Objects/" + className + ".xml");
-    return gameScene.InstantiateXML(xml.root, position, rotation);
+    return gameScene.InstantiateXML(xml, position, rotation);
 }
 
 void SpawnObjects(float timeStep)

+ 1 - 1
Bin/Data/Scripts/NinjaSnowWar/GameObject.as

@@ -82,7 +82,7 @@ class GameObject : ScriptObject
     Node@ SpawnObject(const Vector3&in position, const Quaternion&in rotation, const String&in className)
     {
         XMLFile@ xml = cache.GetResource("XMLFile", "Objects/" + className + ".xml");
-        return scene.InstantiateXML(xml.root, position, rotation);
+        return scene.InstantiateXML(xml, position, rotation);
     }
 
     Node@ SpawnParticleEffect(const Vector3&in position, const String&in effectName, float duration)

+ 18 - 0
Engine/Engine/SceneAPI.cpp

@@ -38,6 +38,14 @@ static void RegisterSerializable(asIScriptEngine* engine)
     RegisterSerializable<Serializable>(engine, "Serializable");
 }
 
+static bool NodeSaveXML(File* file, Node* ptr)
+{
+    if (file)
+        return ptr->SaveXML(*file);
+    else
+        return false;
+}
+
 static void RegisterNode(asIScriptEngine* engine)
 {
     engine->RegisterEnum("CreateMode");
@@ -47,6 +55,7 @@ static void RegisterNode(asIScriptEngine* engine)
     // Register Component first. At this point Node is not yet registered, so can not register GetNode for Component
     RegisterComponent<Component>(engine, "Component", false);
     RegisterNode<Node>(engine, "Node");
+    engine->RegisterObjectMethod("Node", "bool SaveXML(File@+)", asFUNCTION(NodeSaveXML), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Node", "Node@+ Clone(CreateMode mode = REPLICATED)", asMETHOD(Node, Clone), asCALL_THISCALL);
     RegisterObjectConstructor<Node>(engine, "Node");
     RegisterNamedObjectConstructor<Node>(engine, "Node");
@@ -92,6 +101,14 @@ static Node* SceneInstantiateXML(File* file, const Vector3& position, const Quat
         return 0;
 }
 
+static Node* SceneInstantiateXMLFile(XMLFile* xml, const Vector3& position, const Quaternion& rotation, CreateMode mode, Scene* ptr)
+{
+    if (xml)
+        return ptr->InstantiateXML(xml->GetRoot(), position, rotation, mode);
+    else
+        return 0;
+}
+
 static CScriptArray* SceneGetRequiredPackageFiles(Scene* ptr)
 {
     return VectorToHandleArray<PackageFile>(ptr->GetRequiredPackageFiles(), "Array<PackageFile@>");
@@ -132,6 +149,7 @@ static void RegisterScene(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Scene", "void StopAsyncLoading()", asMETHOD(Scene, StopAsyncLoading), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "Node@+ Instantiate(File@+, const Vector3&in, const Quaternion&in, CreateMode mode = REPLICATED)", asFUNCTION(SceneInstantiate), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Scene", "Node@+ InstantiateXML(File@+, const Vector3&in, const Quaternion&in, CreateMode mode = REPLICATED)", asFUNCTION(SceneInstantiateXML), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("Scene", "Node@+ InstantiateXML(XMLFile@+, const Vector3&in, const Quaternion&in, CreateMode mode = REPLICATED)", asFUNCTION(SceneInstantiateXMLFile), asCALL_CDECL_OBJLAST);
     engine->RegisterObjectMethod("Scene", "Node@+ InstantiateXML(const XMLElement&in, const Vector3&in, const Quaternion&in, CreateMode mode = REPLICATED)", asMETHODPR(Scene, InstantiateXML, (const XMLElement&, const Vector3&, const Quaternion&, CreateMode), Node*), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void Clear()", asMETHOD(Scene, Clear), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void AddRequiredPackageFile(PackageFile@+)", asMETHOD(Scene, AddRequiredPackageFile), asCALL_THISCALL);

+ 2 - 0
Engine/Resource/ResourceCache.cpp

@@ -38,7 +38,9 @@ static const String checkDirs[] = {
     "Materials",
     "Models",
     "Music",
+    "Objects",
     "Particle",
+    "Scenes",
     "Scripts",
     "Sounds",
     "Shaders",

+ 14 - 3
Engine/Scene/Node.cpp

@@ -27,7 +27,7 @@
 #include "Log.h"
 #include "MemoryBuffer.h"
 #include "Scene.h"
-#include "XMLElement.h"
+#include "XMLFile.h"
 
 #include "DebugNew.h"
 
@@ -210,6 +210,16 @@ void Node::ApplyAttributes()
         children_[i]->ApplyAttributes();
 }
 
+bool Node::SaveXML(Serializer& dest)
+{
+    SharedPtr<XMLFile> xml(new XMLFile(context_));
+    XMLElement rootElem = xml->CreateRoot("node");
+    if (!SaveXML(rootElem))
+        return false;
+    
+    return xml->Save(dest);
+}
+
 void Node::SetName(const String& name)
 {
     name_ = name;
@@ -1203,7 +1213,7 @@ void Node::GetChildrenWithComponentRecursive(PODVector<Node*>& dest, ShortString
 Node* Node::CloneRecursive(Node* parent, SceneResolver& resolver, CreateMode mode)
 {
     // Create clone node
-    Node* cloneNode = parent->CreateChild(0, mode);
+    Node* cloneNode = parent->CreateChild(0, (mode == REPLICATED && id_ < FIRST_LOCAL_ID) ? REPLICATED : LOCAL);
     resolver.AddNode(id_, cloneNode);
     
     // Copy attributes
@@ -1215,7 +1225,8 @@ Node* Node::CloneRecursive(Node* parent, SceneResolver& resolver, CreateMode mod
     for (Vector<SharedPtr<Component> >::ConstIterator i = components_.Begin(); i != components_.End(); ++i)
     {
         Component* component = *i;
-        Component* cloneComponent = cloneNode->CreateComponent(component->GetType(), mode);
+        Component* cloneComponent = cloneNode->CreateComponent(component->GetType(), (mode == REPLICATED && component->GetID() <
+            FIRST_LOCAL_ID) ? REPLICATED : LOCAL);
         if (!cloneComponent)
         {
             LOGERROR("Could not clone component " + component->GetTypeName());

+ 2 - 0
Engine/Scene/Node.h

@@ -74,6 +74,8 @@ public:
     /// Apply attribute changes that can not be applied immediately recursively to child nodes and components.
     virtual void ApplyAttributes();
     
+    /// Save to an XML file. Return true if successful.
+    bool SaveXML(Serializer& dest);
     /// %Set name.
     void SetName(const String& name);
     /// %Set position.