Sfoglia il codice sorgente

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

Lasse Öörni 14 anni fa
parent
commit
6531fa08d5

+ 2 - 38
Engine/Engine/InputAPI.cpp

@@ -23,12 +23,9 @@
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "APITemplates.h"
 #include "APITemplates.h"
-#include "Controls.h"
 #include "Input.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_LEFT", (void*)&MOUSEB_LEFT);
     engine->RegisterGlobalProperty("const int MOUSEB_RIGHT", (void*)&MOUSEB_RIGHT);
     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);
     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()
 static Input* GetInput()
 {
 {
     return GetScriptContext()->GetSubsystem<Input>();
     return GetScriptContext()->GetSubsystem<Input>();
@@ -187,7 +152,6 @@ static void RegisterInput(asIScriptEngine* engine)
 
 
 void RegisterInputAPI(asIScriptEngine* engine)
 void RegisterInputAPI(asIScriptEngine* engine)
 {
 {
-    RegisterKeyCodes(engine);
-    RegisterControls(engine);
+    RegisterInputConstants(engine);
     RegisterInput(engine);
     RegisterInput(engine);
 }
 }

+ 34 - 0
Engine/Engine/NetworkAPI.cpp

@@ -23,9 +23,42 @@
 
 
 #include "Precompiled.h"
 #include "Precompiled.h"
 #include "APITemplates.h"
 #include "APITemplates.h"
+#include "Controls.h"
 #include "Network.h"
 #include "Network.h"
 #include "Peer.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)
 void RegisterPeer(asIScriptEngine* engine)
 {
 {
     engine->RegisterGlobalProperty("const uint8 CHANNEL_ANY", (void*)&CHANNEL_ANY);
     engine->RegisterGlobalProperty("const uint8 CHANNEL_ANY", (void*)&CHANNEL_ANY);
@@ -90,6 +123,7 @@ void RegisterNetwork(asIScriptEngine* engine)
 
 
 void RegisterNetworkAPI(asIScriptEngine* engine)
 void RegisterNetworkAPI(asIScriptEngine* engine)
 {
 {
+    RegisterControls(engine);
     RegisterPeer(engine);
     RegisterPeer(engine);
     RegisterNetwork(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", "Component@+ GetComponentByID(uint)", asMETHOD(Scene, GetComponentByID), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "Node@+ GetNodeByID(uint)", asMETHOD(Scene, GetNodeByID), 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 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", "void set_networkMode(NetworkMode)", asMETHOD(Scene, SetNetworkMode), asCALL_THISCALL);
     engine->RegisterObjectMethod("Scene", "NetworkMode get_networkMode() const", asMETHOD(Scene, GetNetworkMode), 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->RegisterObjectMethod("Node", "Scene@+ get_scene() const", asMETHOD(Node, GetScene), asCALL_THISCALL);
     engine->RegisterGlobalFunction("Scene@+ get_scene()", asFUNCTION(GetScriptContextScene), asCALL_CDECL);
     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;
         return false;
     
     
     // If scene is loading asynchronously, it is incomplete and should not be rendered
     // 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>();
     Octree* octree = viewport.scene_->GetComponent<Octree>();
     if (!octree)
     if (!octree)

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

@@ -21,6 +21,7 @@
 // THE SOFTWARE.
 // THE SOFTWARE.
 //
 //
 
 
+#include "Precompiled.h"
 #include "Controls.h"
 #include "Controls.h"
 
 
 Controls::Controls()
 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 <cstdio>
 #include <cstdlib>
 #include <cstdlib>
 #include <map>
 #include <map>
-#include <stdexcept>
 #include <string>
 #include <string>
 #include <vector>
 #include <vector>

+ 8 - 8
Engine/Scene/Node.cpp

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

+ 5 - 5
Engine/Scene/Node.h

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

+ 30 - 13
Engine/Scene/Scene.cpp

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

+ 4 - 0
Engine/Scene/Scene.h

@@ -105,6 +105,10 @@ public:
     NetworkMode GetNetworkMode() const { return networkMode_; }
     NetworkMode GetNetworkMode() const { return networkMode_; }
     /// Return active flag
     /// Return active flag
     bool IsActive() const { return active_; }
     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
     /// Get free node ID, either non-local or local
     unsigned GetFreeNodeID(bool local);
     unsigned GetFreeNodeID(bool local);