فهرست منبع

Moved Controls to Network library.
Fixed async scene loading.
Fixed crashes if two scene nodes were created with the same ID.

Lasse Öörni 14 سال پیش
والد
کامیت
6531fa08d5

+ 2 - 38
Engine/Engine/InputAPI.cpp

@@ -23,12 +23,9 @@
 
 #include "Precompiled.h"
 #include "APITemplates.h"
-#include "Controls.h"
 #include "Input.h"
 
-#include <angelscript.h>
-
-static void RegisterKeyCodes(asIScriptEngine* engine)
+static void RegisterInputConstants(asIScriptEngine* engine)
 {
     engine->RegisterGlobalProperty("const int MOUSEB_LEFT", (void*)&MOUSEB_LEFT);
     engine->RegisterGlobalProperty("const int MOUSEB_RIGHT", (void*)&MOUSEB_RIGHT);
@@ -121,38 +118,6 @@ static void RegisterKeyCodes(asIScriptEngine* engine)
     engine->RegisterGlobalProperty("const int KEY_OEM_8", (void*)&KEY_OEM_8);
 }
 
-static void ConstructControls(Controls* ptr)
-{
-    new(ptr) Controls();
-}
-
-static void ConstructControlsCopy(const Controls& controls, Controls* ptr)
-{
-    new(ptr) Controls(controls);
-}
-
-static void DestructControls(Controls* ptr)
-{
-    ptr->~Controls();
-}
-
-static void RegisterControls(asIScriptEngine* engine)
-{
-    engine->RegisterObjectType("Controls", sizeof(Controls), asOBJ_VALUE | asOBJ_APP_CLASS_CDA);
-    engine->RegisterObjectBehaviour("Controls", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructControls), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Controls", asBEHAVE_CONSTRUCT, "void f(const Controls&in)", asFUNCTION(ConstructControlsCopy), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectBehaviour("Controls", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructControls), asCALL_CDECL_OBJLAST);
-    engine->RegisterObjectMethod("Controls", "Controls &opAssign(const Controls&in)", asMETHOD(Controls, operator =), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Controls", "void Reset()", asMETHOD(Controls, Reset), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Controls", "void Set(uint, bool)", asMETHOD(Controls, Set), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Controls", "bool IsDown(uint)", asMETHOD(Controls, IsDown), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Controls", "bool IsPressed(uint, const Controls&in)", asMETHOD(Controls, IsPressed), asCALL_THISCALL);
-    engine->RegisterObjectProperty("Controls", "uint buttons", offsetof(Controls, buttons_));
-    engine->RegisterObjectProperty("Controls", "float yaw", offsetof(Controls, yaw_));
-    engine->RegisterObjectProperty("Controls", "float pitch", offsetof(Controls, pitch_));
-    engine->RegisterObjectProperty("Controls", "VariantMap extraData", offsetof(Controls, extraData_));
-}
-
 static Input* GetInput()
 {
     return GetScriptContext()->GetSubsystem<Input>();
@@ -187,7 +152,6 @@ static void RegisterInput(asIScriptEngine* engine)
 
 void RegisterInputAPI(asIScriptEngine* engine)
 {
-    RegisterKeyCodes(engine);
-    RegisterControls(engine);
+    RegisterInputConstants(engine);
     RegisterInput(engine);
 }

+ 34 - 0
Engine/Engine/NetworkAPI.cpp

@@ -23,9 +23,42 @@
 
 #include "Precompiled.h"
 #include "APITemplates.h"
+#include "Controls.h"
 #include "Network.h"
 #include "Peer.h"
 
+static void ConstructControls(Controls* ptr)
+{
+    new(ptr) Controls();
+}
+
+static void ConstructControlsCopy(const Controls& controls, Controls* ptr)
+{
+    new(ptr) Controls(controls);
+}
+
+static void DestructControls(Controls* ptr)
+{
+    ptr->~Controls();
+}
+
+static void RegisterControls(asIScriptEngine* engine)
+{
+    engine->RegisterObjectType("Controls", sizeof(Controls), asOBJ_VALUE | asOBJ_APP_CLASS_CDA);
+    engine->RegisterObjectBehaviour("Controls", asBEHAVE_CONSTRUCT, "void f()", asFUNCTION(ConstructControls), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Controls", asBEHAVE_CONSTRUCT, "void f(const Controls&in)", asFUNCTION(ConstructControlsCopy), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectBehaviour("Controls", asBEHAVE_DESTRUCT, "void f()", asFUNCTION(DestructControls), asCALL_CDECL_OBJLAST);
+    engine->RegisterObjectMethod("Controls", "Controls &opAssign(const Controls&in)", asMETHOD(Controls, operator =), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Controls", "void Reset()", asMETHOD(Controls, Reset), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Controls", "void Set(uint, bool)", asMETHOD(Controls, Set), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Controls", "bool IsDown(uint)", asMETHOD(Controls, IsDown), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Controls", "bool IsPressed(uint, const Controls&in)", asMETHOD(Controls, IsPressed), asCALL_THISCALL);
+    engine->RegisterObjectProperty("Controls", "uint buttons", offsetof(Controls, buttons_));
+    engine->RegisterObjectProperty("Controls", "float yaw", offsetof(Controls, yaw_));
+    engine->RegisterObjectProperty("Controls", "float pitch", offsetof(Controls, pitch_));
+    engine->RegisterObjectProperty("Controls", "VariantMap extraData", offsetof(Controls, extraData_));
+}
+
 void RegisterPeer(asIScriptEngine* engine)
 {
     engine->RegisterGlobalProperty("const uint8 CHANNEL_ANY", (void*)&CHANNEL_ANY);
@@ -90,6 +123,7 @@ void RegisterNetwork(asIScriptEngine* engine)
 
 void RegisterNetworkAPI(asIScriptEngine* engine)
 {
+    RegisterControls(engine);
     RegisterPeer(engine);
     RegisterNetwork(engine);
 }

+ 4 - 2
Engine/Engine/SceneAPI.cpp

@@ -89,10 +89,12 @@ static void RegisterScene(asIScriptEngine* engine)
     engine->RegisterObjectMethod("Scene", "Component@+ GetComponentByID(uint)", asMETHOD(Scene, GetComponentByID), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "Node@+ GetNodeByID(uint)", asMETHOD(Scene, GetNodeByID), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void Update(float)", asMETHOD(Scene, Update), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Scene", "void set_active(bool)", asMETHOD(Scene, SetActive), asCALL_THISCALL);
-    engine->RegisterObjectMethod("Scene", "bool get_active() const", asMETHOD(Scene, IsActive), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "void set_networkMode(NetworkMode)", asMETHOD(Scene, SetNetworkMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "NetworkMode get_networkMode() const", asMETHOD(Scene, GetNetworkMode), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Scene", "void set_active(bool)", asMETHOD(Scene, SetActive), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Scene", "bool get_active() const", asMETHOD(Scene, IsActive), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Scene", "bool get_asyncLoading() const", asMETHOD(Scene, IsAsyncLoading), asCALL_THISCALL);
+    engine->RegisterObjectMethod("Scene", "float get_asyncProgress() const", asMETHOD(Scene, GetAsyncProgress), asCALL_THISCALL);
     engine->RegisterObjectMethod("Node", "Scene@+ get_scene() const", asMETHOD(Node, GetScene), asCALL_THISCALL);
     engine->RegisterGlobalFunction("Scene@+ get_scene()", asFUNCTION(GetScriptContextScene), asCALL_CDECL);
     

+ 2 - 2
Engine/Graphics/View.cpp

@@ -93,8 +93,8 @@ bool View::Define(RenderSurface* renderTarget, const Viewport& viewport)
         return false;
     
     // If scene is loading asynchronously, it is incomplete and should not be rendered
-    //if (viewport.scene_->isAsyncLoading())
-    //    return false;
+    if (viewport.scene_->IsAsyncLoading())
+        return false;
     
     Octree* octree = viewport.scene_->GetComponent<Octree>();
     if (!octree)

+ 1 - 0
Engine/Input/Controls.cpp → Engine/Network/Controls.cpp

@@ -21,6 +21,7 @@
 // THE SOFTWARE.
 //
 
+#include "Precompiled.h"
 #include "Controls.h"
 
 Controls::Controls()

+ 0 - 0
Engine/Input/Controls.h → Engine/Network/Controls.h


+ 0 - 1
Engine/Network/Precompiled.h

@@ -26,6 +26,5 @@
 #include <cstdio>
 #include <cstdlib>
 #include <map>
-#include <stdexcept>
 #include <string>
 #include <vector>

+ 8 - 8
Engine/Scene/Node.cpp

@@ -392,12 +392,6 @@ void Node::RemoveAllChildren()
         RemoveChild(children_.end() - 1);
 }
 
-void Node::SetParent(Node* parent)
-{
-    if (parent)
-        parent->AddChild(this);
-}
-
 Component* Node::CreateComponent(ShortStringHash type, bool local)
 {
     return CreateComponent(type, 0, local);
@@ -487,6 +481,12 @@ void Node::Remove()
         parent_->RemoveChild(this);
 }
 
+void Node::SetParent(Node* parent)
+{
+    if (parent)
+        parent->AddChild(this);
+}
+
 unsigned Node::GetNumChildren(bool recursive) const
 {
     if (!recursive)
@@ -665,7 +665,7 @@ bool Node::LoadXML(const XMLElement& source, bool readChildren)
     XMLElement childElem = source.GetChildElement("node");
     while (childElem)
     {
-        Node* newNode = CreateChild(compElem.GetInt("id"), false);
+        Node* newNode = CreateChild(childElem.GetInt("id"), false);
         if (!newNode->LoadXML(childElem))
             return false;
         
@@ -766,7 +766,7 @@ void Node::SetID(unsigned id)
     id_ = id;
 }
 
-void Node::setScene(Scene* scene)
+void Node::SetScene(Scene* scene)
 {
     scene_ = scene;
 }

+ 5 - 5
Engine/Scene/Node.h

@@ -105,10 +105,6 @@ public:
     void RemoveChild(Node* node);
     /// Remove all child scene nodes
     void RemoveAllChildren();
-    /// Remove from the parent node. If no other shared pointer references exist, causes immediate deletion
-    void Remove();
-    /// Set parent scene node. Same as parent->AddChild(this)
-    void SetParent(Node* parent);
     /// Create a component to this node
     Component* CreateComponent(ShortStringHash type, bool local = false);
     /// Create a component to this node if it does not exist already
@@ -121,6 +117,10 @@ public:
     void AddListener(Component* component);
     /// Remove listener component
     void RemoveListener(Component* component);
+    /// Remove from the parent node. If no other shared pointer references exist, causes immediate deletion
+    void Remove();
+    /// Set parent scene node. Same as parent->AddChild(this)
+    void SetParent(Node* parent);
     /// Template version of creating a component
     template <class T> T* CreateComponent(bool local = false);
     /// Template version of getting or creating a component
@@ -258,7 +258,7 @@ private:
     /// Set ID. Called by Scene
     void SetID(unsigned id);
     /// Set scene. Called by Scene
-    void setScene(Scene* scene);
+    void SetScene(Scene* scene);
     
     /// Unique ID within the scene
     unsigned id_;

+ 30 - 13
Engine/Scene/Scene.cpp

@@ -30,11 +30,12 @@
 #include "Profiler.h"
 #include "Scene.h"
 #include "SceneEvents.h"
+#include "StringUtils.h"
 #include "XMLFile.h"
 
 OBJECTTYPESTATIC(Scene);
 
-static const int ASYNC_LOAD_MIN_FPS = 60;
+static const int ASYNC_LOAD_MIN_FPS = 50;
 static const int ASYNC_LOAD_MAX_MSEC = (int)(1000.0f / ASYNC_LOAD_MIN_FPS);
 
 Scene::Scene(Context* context) :
@@ -58,7 +59,7 @@ Scene::~Scene()
 {
     // Remove scene reference from all nodes that still exist
     for (std::map<unsigned, Node*>::iterator i = allNodes_.begin(); i != allNodes_.end(); ++i)
-        i->second->setScene(0);
+        i->second->SetScene(0);
 }
 
 void Scene::RegisterObject(Context* context)
@@ -149,7 +150,7 @@ bool Scene::LoadAsync(File* file)
         return false;
     }
     
-    // Load the root level components first
+    // Clear the previous scene and load the root level components first
     if (!Node::Load(*file, false))
         return false;
     
@@ -176,14 +177,13 @@ bool Scene::LoadAsyncXML(File* file)
     if (!xmlFile->Load(*file))
         return false;
     
-    // Load the root level components first
+    // Clear the previous scene and load the root level components first
     XMLElement rootElement = xmlFile->GetRootElement();
-    if (!Node::LoadXML(rootElement))
+    if (!Node::LoadXML(rootElement, false))
         return false;
     
-    XMLElement childNodeElement = rootElement.GetChildElement("node");
-    
     // Then prepare for loading all root level child nodes in the async update
+    XMLElement childNodeElement = rootElement.GetChildElement("node");
     asyncLoading_ = true;
     asyncProgress_.file_.Reset();
     asyncProgress_.xmlFile_ = xmlFile;
@@ -255,6 +255,14 @@ Component* Scene::GetComponentByID(unsigned id) const
         return 0;
 }
 
+float Scene::GetAsyncProgress() const
+{
+    if ((!asyncLoading_) || (!asyncProgress_.totalNodes_))
+        return 1.0f;
+    else
+        return (float)asyncProgress_.loadedNodes_ / (float)asyncProgress_.totalNodes_;
+}
+
 unsigned Scene::GetFreeNodeID(bool local)
 {
     if (!local)
@@ -321,8 +329,18 @@ void Scene::NodeAdded(Node* node)
     if ((!node) || (node->GetScene()))
         return;
     
-    node->setScene(this);
-    allNodes_[node->GetID()] = node;
+    node->SetScene(this);
+    
+    // If we already have an existing node with the same ID, must remove the scene reference from it
+    unsigned id = node->GetID();
+    std::map<unsigned, Node*>::iterator i = allNodes_.find(id);
+    if ((i != allNodes_.end()) && (i->second != node))
+    {
+        LOGWARNING("Overwriting node with ID " + ToString(id));
+        i->second->SetScene(0);
+    }
+    
+    allNodes_[id] = node;
 }
 
 void Scene::NodeRemoved(Node* node)
@@ -332,7 +350,7 @@ void Scene::NodeRemoved(Node* node)
     
     allNodes_.erase(node->GetID());
     node->SetID(0);
-    node->setScene(0);
+    node->SetScene(0);
 }
 
 void Scene::ComponentAdded(Component* component)
@@ -368,7 +386,6 @@ void Scene::UpdateAsyncLoad()
     
     for (;;)
     {
-        // Check if everything loaded
         if (asyncProgress_.loadedNodes_ >= asyncProgress_.totalNodes_)
         {
             FinishAsyncLoad();
@@ -376,12 +393,12 @@ void Scene::UpdateAsyncLoad()
         }
         
         // Read one child node either from binary or XML
-        if (asyncProgress_.file_)
+        if ((asyncProgress_.file_) && (!asyncProgress_.file_->IsEof()))
         {
             Node* newNode = CreateChild(asyncProgress_.file_->ReadUInt(), false);
             newNode->Load(*asyncProgress_.file_);
         }
-        else
+        if (asyncProgress_.xmlElement_)
         {
             Node* newNode = CreateChild(asyncProgress_.xmlElement_.GetInt("id"), false);
             newNode->LoadXML(asyncProgress_.xmlElement_);

+ 4 - 0
Engine/Scene/Scene.h

@@ -105,6 +105,10 @@ public:
     NetworkMode GetNetworkMode() const { return networkMode_; }
     /// Return active flag
     bool IsActive() const { return active_; }
+    /// Return async loading flag
+    bool IsAsyncLoading() const { return asyncLoading_; }
+    /// Return async loading progress between 0.0 and 1.0, or 1.0 if not async loading
+    float GetAsyncProgress() const;
     
     /// Get free node ID, either non-local or local
     unsigned GetFreeNodeID(bool local);