Browse Source

Made internal event handling functions private in Object & Context.
Refactored NinjaSnowWar game object classes to use Start() function for initialization.

Lasse Öörni 14 years ago
parent
commit
7a45a5b33a

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

@@ -309,13 +309,13 @@ void SpawnPlayer(Connection@ connection)
     // Set owner connection. Owned nodes are always updated to the owner at full frequency
     Node@ playerNode = gameScene.CreateChild("Player");
     playerNode.owner = connection;
+    if (singlePlayer)
+        playerNode.position = Vector3(0, 90, 0);
+    else
+        playerNode.position = Vector3(Random(spawnAreaSize) - spawnAreaSize * 0.5, 90, Random(spawnAreaSize) - spawnAreaSize);
 
      // Create the logic object as local, as it only needs to run on server
     Ninja@ playerNinja = cast<Ninja>(playerNode.CreateScriptObject(scriptFile, "Ninja", LOCAL));
-    if (singlePlayer)
-        playerNinja.Create(Vector3(0, 90, 0), Quaternion());
-    else
-        playerNinja.Create(Vector3(Random(spawnAreaSize) - spawnAreaSize * 0.5, 90, Random(spawnAreaSize) - spawnAreaSize), Quaternion());
     playerNinja.health = playerNinja.maxHealth = playerHealth;
     playerNinja.side = SIDE_PLAYER;
     // Make sure the player can not shoot on first frame by holding the button down
@@ -680,10 +680,9 @@ void SpawnObjects(float timeStep)
             float xOffset = Random(maxOffset * 2.0f) - maxOffset;
             float zOffset = Random(maxOffset * 2.0f) - maxOffset;
 
-            Vector3 position(xOffset, 5000, zOffset);
             Node@ crateNode = gameScene.CreateChild();
+            crateNode.position = Vector3(xOffset, 5000, zOffset);
             GameObject@ crateObject = cast<GameObject>(crateNode.CreateScriptObject(scriptFile, "SnowCrate", LOCAL));
-            crateObject.Create(position, Quaternion());
         }
     }
 
@@ -708,16 +707,17 @@ void SpawnObjects(float timeStep)
             // Random north/east/south/west direction
             int dir = RandomInt() & 3;
             dir *= 90;
-            Quaternion q(dir, Vector3(0, 1, 0));
-            Vector3 position(q * Vector3(offset, 1000, -12000));
+            Quaternion rotation(0, dir, 0);
 
             Node@ enemyNode = gameScene.CreateChild();
+            enemyNode.position = rotation * Vector3(offset, 1000, -12000);
+            enemyNode.rotation = rotation;
+
             Ninja@ enemyNinja = cast<Ninja>(enemyNode.CreateScriptObject(scriptFile, "Ninja", LOCAL));
-            enemyNinja.Create(position, q);
             enemyNinja.side = SIDE_ENEMY;
             @enemyNinja.controller = AIController();
             RigidBody@ enemyBody = enemyNode.GetComponent("RigidBody");
-            enemyBody.linearVelocity = (q * Vector3(0, 1000, 3000));
+            enemyBody.linearVelocity = rotation * Vector3(0, 1000, 3000);
         }
     }
 }

+ 3 - 7
Bin/Data/Scripts/NinjaSnowWar/GameObject.as

@@ -38,10 +38,6 @@ class GameObject : ScriptObject
             Print("Warning! Logic object created on client!");
     }
 
-    void Create(const Vector3&in position, const Quaternion&in rotation)
-    {
-    }
-
     void FixedUpdate(float timeStep)
     {
         // Disappear when duration expired
@@ -86,11 +82,11 @@ class GameObject : ScriptObject
     Node@ SpawnObject(const Vector3&in position, const Quaternion&in rotation, const String&in className)
     {
         Node@ newNode = scene.CreateChild();
+        newNode.position = position;
+        newNode.rotation = rotation;
 
         // Create the script object with specified class
-        GameObject@ object = cast<GameObject>(newNode.CreateScriptObject(scriptFile, className, LOCAL));
-        if (object !is null)
-            object.Create(position, rotation);
+        newNode.CreateScriptObject(scriptFile, className, LOCAL);
 
         return newNode;
     }

+ 3 - 10
Bin/Data/Scripts/NinjaSnowWar/LightFlash.as

@@ -6,11 +6,8 @@ class LightFlash : GameObject
     {
     }
 
-    void Create(const Vector3&in position, const Quaternion&in rotation)
+    void Start()
     {
-        node.position = position;
-        node.rotation = rotation;
-
         Light@ light = node.CreateComponent("Light");
         light.lightType = LIGHT_POINT;
         light.range = 500.0;
@@ -26,11 +23,7 @@ class LightFlash : GameObject
         Light@ light = node.GetComponent("Light");
         light.color = light.color * Max(1.0 - timeStep * 10.0, 0.0);
 
-        if (duration >= 0)
-        {
-            duration -= timeStep;
-            if (duration <= 0)
-                node.Remove();
-        }
+        // Call superclass to handle lifetime
+        GameObject::FixedUpdate(timeStep);
     }
 }

+ 1 - 7
Bin/Data/Scripts/NinjaSnowWar/Ninja.as

@@ -53,12 +53,6 @@ class Ninja : GameObject
     void Start()
     {
         SubscribeToEvent("NodeCollision", "HandleNodeCollision");
-    }
-
-    void Create(const Vector3&in position, const Quaternion&in rotation)
-    {
-        node.position = position;
-        node.rotation = rotation;
 
         // Setup interest management for networking
         NetworkPriority@ priority = node.CreateComponent("NetworkPriority", LOCAL);
@@ -94,7 +88,7 @@ class Ninja : GameObject
         body.mass = ninjaMass;
         body.angularMaxVelocity = 0;
 
-        aimX = rotation.yaw;
+        aimX = node.rotation.yaw;
     }
 
     void SetControls(const Controls&in newControls)

+ 0 - 6
Bin/Data/Scripts/NinjaSnowWar/Potion.as

@@ -17,12 +17,6 @@ class Potion : GameObject
     void Start()
     {
         SubscribeToEvent("NodeCollision", "HandleNodeCollision");
-    }
-
-    void Create(const Vector3&in position, const Quaternion&in rotation)
-    {
-        node.position = position;
-        node.rotation = rotation;
 
         // Setup interest management for networking
         NetworkPriority@ priority = node.CreateComponent("NetworkPriority", LOCAL);

+ 0 - 6
Bin/Data/Scripts/NinjaSnowWar/SnowBall.as

@@ -23,12 +23,6 @@ class SnowBall : GameObject
     void Start()
     {
         SubscribeToEvent("NodeCollision", "HandleNodeCollision");
-    }
-
-    void Create(const Vector3&in position, const Quaternion&in rotation)
-    {
-        node.position = position;
-        node.rotation = rotation;
 
         // Setup interest management for networking
         NetworkPriority@ priority = node.CreateComponent("NetworkPriority", LOCAL);

+ 1 - 7
Bin/Data/Scripts/NinjaSnowWar/SnowCrate.as

@@ -16,13 +16,7 @@ class SnowCrate : GameObject
     void Start()
     {
         SubscribeToEvent("NodeCollision", "HandleNodeCollision");
-    }
-
-    void Create(const Vector3&in position, const Quaternion&in rotation)
-    {
-        node.position = position;
-        node.rotation = rotation;
-
+        
         // Setup interest management for networking
         NetworkPriority@ priority = node.CreateComponent("NetworkPriority", LOCAL);
         priority.basePriority = 100.0;

+ 66 - 23
Engine/Core/Context.cpp

@@ -122,6 +122,31 @@ void Context::CopyBaseAttributes(ShortStringHash baseType, ShortStringHash deriv
     }
 }
 
+Object* Context::GetSubsystem(ShortStringHash type) const
+{
+    Map<ShortStringHash, SharedPtr<Object> >::ConstIterator i = subsystems_.Find(type);
+    if (i != subsystems_.End())
+        return i->second_;
+    else
+        return 0;
+}
+
+Object* Context::GetEventSender() const
+{
+    if (!eventSenders_.Empty())
+        return eventSenders_.Back();
+    else
+        return 0;
+}
+
+const String& Context::GetTypeName(ShortStringHash type) const
+{
+    // Search factories to find the hash-to-name mapping
+    Map<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories_.Find(type);
+    return i != factories_.End() ? i->second_->GetTypeName() : noType;
+}
+
+
 void Context::AddEventReceiver(Object* receiver, StringHash eventType)
 {
     PODVector<Object*>& receivers = eventReceivers_[eventType];
@@ -162,7 +187,7 @@ void Context::RemoveEventSender(Object* sender)
 
 void Context::RemoveEventReceiver(Object* receiver, StringHash eventType)
 {
-    PODVector<Object*>* group = GetReceivers(eventType);
+    PODVector<Object*>* group = GetEventReceivers(eventType);
     if (!group)
         return;
     
@@ -182,7 +207,7 @@ void Context::RemoveEventReceiver(Object* receiver, StringHash eventType)
 
 void Context::RemoveEventReceiver(Object* receiver, Object* sender, StringHash eventType)
 {
-    PODVector<Object*>* group = GetReceivers(sender, eventType);
+    PODVector<Object*>* group = GetEventReceivers(sender, eventType);
     if (!group)
         return;
     
@@ -200,26 +225,44 @@ void Context::RemoveEventReceiver(Object* receiver, Object* sender, StringHash e
     }
 }
 
-Object* Context::GetSubsystem(ShortStringHash type) const
+void Context::EndSendEvent()
 {
-    Map<ShortStringHash, SharedPtr<Object> >::ConstIterator i = subsystems_.Find(type);
-    if (i != subsystems_.End())
-        return i->second_;
-    else
-        return 0;
-}
-
-Object* Context::GetEventSender() const
-{
-    if (!eventSenders_.Empty())
-        return eventSenders_.Back();
-    else
-        return 0;
-}
-
-const String& Context::GetTypeName(ShortStringHash type) const
-{
-    // Search factories to find the hash-to-name mapping
-    Map<ShortStringHash, SharedPtr<ObjectFactory> >::ConstIterator i = factories_.Find(type);
-    return i != factories_.End() ? i->second_->GetTypeName() : noType;
+    eventSenders_.Pop();
+    
+    // Clean up dirtied event receiver groups when event handling finishes
+    if (eventSenders_.Empty())
+    {
+        if (!dirtySpecificReceivers_.Empty())
+        {
+            for (HashSet<Pair<Object*, StringHash> >::Iterator i = dirtySpecificReceivers_.Begin();
+                i != dirtySpecificReceivers_.End(); ++i)
+            {
+                PODVector<Object*>& receivers = specificEventReceivers_[*i];
+                for (PODVector<Object*>::Iterator j = receivers.Begin(); j != receivers.End();)
+                {
+                    if (*j == 0)
+                        j = receivers.Erase(j);
+                    else
+                        ++j;
+                }
+            }
+            dirtySpecificReceivers_.Clear();
+        }
+        
+        if (!dirtyReceivers_.Empty())
+        {
+            for (HashSet<StringHash>::Iterator i = dirtyReceivers_.Begin(); i != dirtyReceivers_.End(); ++i)
+            {
+                PODVector<Object*>& receivers = eventReceivers_[*i];
+                for (PODVector<Object*>::Iterator j = receivers.Begin(); j != receivers.End();)
+                {
+                    if (*j == 0)
+                        j = receivers.Erase(j);
+                    else
+                        ++j;
+                }
+            }
+            dirtyReceivers_.Clear();
+        }
+    }
 }

+ 21 - 65
Engine/Core/Context.h

@@ -30,6 +30,8 @@
 /// Urho3D execution context. Provides access to subsystems, object factories and attributes, and event receivers.
 class Context : public RefCounted
 {
+    friend class Object;
+    
 public:
     /// Construct.
     Context();
@@ -48,65 +50,6 @@ public:
     void RemoveAttribute(ShortStringHash objectType, const String& name);
     /// Copy base class attributes to derived class.
     void CopyBaseAttributes(ShortStringHash baseType, ShortStringHash derivedType);
-    /// Add event receiver.
-    void AddEventReceiver(Object* receiver, StringHash eventType);
-    /// Add event receiver for specific event.
-    void AddEventReceiver(Object* receiver, Object* sender, StringHash eventType);
-    /// Remove an event sender from all receivers. Called on its destruction.
-    void RemoveEventSender(Object* sender);
-    /// Remove event receiver from specific events.
-    void RemoveEventReceiver(Object* receiver, Object* sender, StringHash eventType);
-    /// Remove event receiver from non-specific events.
-    void RemoveEventReceiver(Object* receiver, StringHash eventType);
-    
-    /// %Set current event handler. Called by Object.
-    void SetEventHandler(EventHandler* handler) { eventHandler_ = handler; }
-    /// Begin event send.
-    void BeginSendEvent(Object* sender) { eventSenders_.Push(sender); }
-    
-    /// End event send. Clean up event receivers removed in the meanwhile.
-    void EndSendEvent()
-    {
-        eventSenders_.Pop();
-    
-        // Clean up dirtied event receiver groups when event handling finishes
-        if (eventSenders_.Empty())
-        {
-            if (!dirtySpecificReceivers_.Empty())
-            {
-                for (HashSet<Pair<Object*, StringHash> >::Iterator i = dirtySpecificReceivers_.Begin();
-                    i != dirtySpecificReceivers_.End(); ++i)
-                {
-                    PODVector<Object*>& receivers = specificEventReceivers_[*i];
-                    for (PODVector<Object*>::Iterator j = receivers.Begin(); j != receivers.End();)
-                    {
-                        if (*j == 0)
-                            j = receivers.Erase(j);
-                        else
-                            ++j;
-                    }
-                }
-                dirtySpecificReceivers_.Clear();
-            }
-            
-            if (!dirtyReceivers_.Empty())
-            {
-                for (HashSet<StringHash>::Iterator i = dirtyReceivers_.Begin(); i != dirtyReceivers_.End(); ++i)
-                {
-                    PODVector<Object*>& receivers = eventReceivers_[*i];
-                    for (PODVector<Object*>::Iterator j = receivers.Begin(); j != receivers.End();)
-                    {
-                        if (*j == 0)
-                            j = receivers.Erase(j);
-                        else
-                            ++j;
-                    }
-                }
-                dirtyReceivers_.Clear();
-            }
-        }
-    }
-    
     /// Template version of registering an object factory.
     template <class T> void RegisterFactory();
     /// Template version of registering an object attribute.
@@ -122,10 +65,6 @@ public:
     const Map<ShortStringHash, SharedPtr<Object> >& GetSubsystems() const { return subsystems_; }
     /// Return all object factories.
     const Map<ShortStringHash, SharedPtr<ObjectFactory> >& GetObjectFactories() const { return factories_; }
-    /// Return attributes for all object types.
-    const Map<ShortStringHash, Vector<AttributeInfo> >& GetAllAttributes() const { return attributes_; }
-    /// Return network replication attributes for all object types.
-    const Map<ShortStringHash, Vector<AttributeInfo> >& GetAllNetworkAttributes() const { return networkAttributes_; }
     /// Return active event sender. Null outside event handling.
     Object* GetEventSender() const;
     /// Return active event handler. Set by Object. Null outside event handling.
@@ -150,7 +89,7 @@ public:
     }
     
     /// Return event receivers for a sender and event type, or null if they do not exist.
-    PODVector<Object*>* GetReceivers(Object* sender, StringHash eventType)
+    PODVector<Object*>* GetEventReceivers(Object* sender, StringHash eventType)
     {
         Map<Pair<Object*, StringHash>, PODVector<Object*> >::Iterator i = 
             specificEventReceivers_.Find(MakePair(sender, eventType));
@@ -158,13 +97,30 @@ public:
     }
     
     /// Return event receivers for an event type, or null if they do not exist.
-    PODVector<Object*>* GetReceivers(StringHash eventType)
+    PODVector<Object*>* GetEventReceivers(StringHash eventType)
     {
         Map<StringHash, PODVector<Object*> >::Iterator i = eventReceivers_.Find(eventType);
         return i != eventReceivers_.End() ? &i->second_ : 0;
     }
     
 private:
+    /// Add event receiver.
+    void AddEventReceiver(Object* receiver, StringHash eventType);
+    /// Add event receiver for specific event.
+    void AddEventReceiver(Object* receiver, Object* sender, StringHash eventType);
+    /// Remove an event sender from all receivers. Called on its destruction.
+    void RemoveEventSender(Object* sender);
+    /// Remove event receiver from specific events.
+    void RemoveEventReceiver(Object* receiver, Object* sender, StringHash eventType);
+    /// Remove event receiver from non-specific events.
+    void RemoveEventReceiver(Object* receiver, StringHash eventType);
+    /// %Set current event handler. Called by Object.
+    void SetEventHandler(EventHandler* handler) { eventHandler_ = handler; }
+    /// Begin event send.
+    void BeginSendEvent(Object* sender) { eventSenders_.Push(sender); }
+    /// End event send. Clean up event receivers removed in the meanwhile.
+    void EndSendEvent();
+
     /// Object factories.
     Map<ShortStringHash, SharedPtr<ObjectFactory> > factories_;
     /// Subsystems.

+ 3 - 13
Engine/Core/Object.cpp

@@ -182,7 +182,7 @@ void Object::SendEvent(StringHash eventType, VariantMap& eventData)
     context->BeginSendEvent(this);
     
     // Check first the specific event receivers
-    const PODVector<Object*>* group = context->GetReceivers(this, eventType);
+    const PODVector<Object*>* group = context->GetEventReceivers(this, eventType);
     if (group)
     {
         unsigned numReceivers = group->Size();
@@ -204,7 +204,7 @@ void Object::SendEvent(StringHash eventType, VariantMap& eventData)
     }
     
     // Then the non-specific receivers
-    group = context->GetReceivers(eventType);
+    group = context->GetEventReceivers(eventType);
     if (group)
     {
         unsigned numReceivers = group->Size();
@@ -273,12 +273,7 @@ void Object::SendEvent(Object* receiver, StringHash eventType, VariantMap& event
 
 Object* Object::GetSubsystem(ShortStringHash type) const
 {
-    const Map<ShortStringHash, SharedPtr<Object> >& subsystems = context_->GetSubsystems();
-    Map<ShortStringHash, SharedPtr<Object> >::ConstIterator i = subsystems.Find(type);
-    if (i != subsystems.End())
-        return i->second_;
-    else
-        return 0;
+    return context_->GetSubsystem(type);
 }
 
 bool Object::HasSubscribedToEvent(StringHash eventType) const
@@ -291,11 +286,6 @@ bool Object::HasSubscribedToEvent(Object* sender, StringHash eventType) const
     return eventHandlers_.Find(MakePair(sender, eventType)) != eventHandlers_.End();
 }
 
-Object* Object::GetEventSender() const
-{
-    return context_->GetEventSender();
-}
-
 void Object::RemoveEventSender(Object* sender)
 {
     for (Map<Pair<Object*, StringHash>, SharedPtr<EventHandler> >::Iterator i = eventHandlers_.Begin();

+ 5 - 5
Engine/Core/Object.h

@@ -33,6 +33,8 @@ class EventHandler;
 /// Base class for objects with type identification, subsystem access and event sending/receiving capability.
 class Object : public RefCounted
 {
+    friend class Context;
+    
 public:
     /// Construct.
     Object(Context* context);
@@ -79,19 +81,17 @@ public:
     bool HasSubscribedToEvent(StringHash eventType) const;
     /// Return whether has subscribed to a specific sender's event.
     bool HasSubscribedToEvent(Object* sender, StringHash eventType) const;
-    /// Return active event sender.
-    Object* GetEventSender() const;
     /// Template version of returning a subsystem.
     template <class T> T* GetSubsystem() const;
     
-    /// Remove event handlers related to a specific sender.
-    void RemoveEventSender(Object* sender);
-    
 protected:
     /// Execution context.
     Context* context_;
     
 private:
+    /// Remove event handlers related to a specific sender.
+    void RemoveEventSender(Object* sender);
+    
     /// Event handlers. Sender is null for non-specific handlers.
     Map<Pair<Object*, StringHash>, SharedPtr<EventHandler> > eventHandlers_;
 };