Selaa lähdekoodia

Component loading updates

Josh Engebretson 9 vuotta sitten
vanhempi
sitoutus
c45d722c83

+ 4 - 0
Script/AtomicNET/AtomicNET/Core/NativeCore.cs

@@ -356,6 +356,10 @@ namespace AtomicEngine
                 throw new InvalidOperationException("NativeCore.WrapNative - Attempting to wrap unknown native class id");
             }
 
+            // TODO: make CSComponent abstract and have general abstract logic here?
+            if (nativeType.Type == typeof(CSComponent))
+                return null;
+
             r = nativeType.managedConstructor(native);
 
             w = new WeakReference<RefCounted>(r);

+ 33 - 0
Script/AtomicNET/AtomicNET/Player/Player.cs

@@ -0,0 +1,33 @@
+
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+using AtomicEngine;
+
+namespace AtomicPlayer
+{
+    public partial class Player : AObject
+    {
+        static List<Scene> loadedScenes = new List<Scene>();
+
+        internal override void PostNativeUpdate()
+        {
+            SubscribeToEvent<PlayerSceneLoadBeginEvent>(e =>
+            {
+                loadedScenes.Add(e.Scene);
+            });
+
+            SubscribeToEvent<PlayerSceneLoadEndEvent>(e =>
+            {
+                if (!e.Success)
+                    loadedScenes.Remove(e.Scene);
+            });
+
+        }
+
+
+    }
+
+}
+

+ 1 - 28
Script/AtomicNET/AtomicNET/Scene/CSComponentCore.cs

@@ -144,32 +144,6 @@ namespace AtomicEngine
 
     public class CSComponentCore : NETScriptObject
     {
-
-        void HandleComponentLoad(uint eventType, ScriptVariantMap eventData)
-        {
-            var className = eventData["ClassName"];
-
-            IntPtr csnative = eventData.GetVoidPtr("NativeInstance");
-            IntPtr fieldValues = IntPtr.Zero;
-
-            if (eventData.Contains("FieldValues"))
-                fieldValues = eventData.GetVoidPtr("FieldValues");
-
-            CSComponentInfo csinfo;
-
-            if (!componentCache.TryGetValue(className, out csinfo))
-            {
-                return;
-            }
-
-            NativeCore.NativeContructorOverride = csnative;
-            var component = (CSComponent)Activator.CreateInstance(csinfo.Type);
-            NativeCore.VerifyNativeContructorOverrideConsumed();
-
-            if (fieldValues != IntPtr.Zero)
-                csinfo.ApplyFieldValues(component, fieldValues);
-        }
-
         [Obsolete("Method HandleComponentAssemblyReference is deprecated (loading component assemblies at runtime, will be changed to preload them)")]
         void HandleComponentAssemblyReference(uint eventType, ScriptVariantMap eventData)
         {
@@ -223,12 +197,11 @@ namespace AtomicEngine
             instance.ParseComponents();
 
             instance.SubscribeToEvent("CSComponentAssemblyReference", instance.HandleComponentAssemblyReference);
-            instance.SubscribeToEvent("CSComponentLoad", instance.HandleComponentLoad);
 
         }
 
         // type name -> CSComponentInfo lookup TODO: store with namespace to solve ambiguities
-        Dictionary<string, CSComponentInfo> componentCache = new Dictionary<string, CSComponentInfo>();
+        internal static Dictionary<string, CSComponentInfo> componentCache = new Dictionary<string, CSComponentInfo>();
 
         [Obsolete("Member parsedAssemblies is temporarily required for runtime component assemblies loading")]
         Dictionary<Assembly, bool> parsedAssemblies = new Dictionary<Assembly, bool>();

+ 81 - 40
Script/AtomicNET/AtomicNET/Scene/Scene.cs

@@ -1,4 +1,5 @@
 using System;
+using System.Linq;
 using System.Collections.Generic;
 using System.Runtime.InteropServices;
 using static System.Reflection.IntrospectionExtensions;
@@ -21,6 +22,8 @@ namespace AtomicEngine
 
             });
 
+            SubscribeToEvent<CSComponentLoadEvent>(this, HandleCSComponentLoad);
+
             SubscribeToEvent<ComponentAddedEvent>(this, HandleComponentAdded);
             SubscribeToEvent<ComponentRemovedEvent>(this, HandleComponentRemoved);
 
@@ -44,17 +47,18 @@ namespace AtomicEngine
             // Handle Start
             if (cscomponentStart.Count > 0)
             {
-                var newList = new List<CSComponent>();
-                foreach (var csc in cscomponentStart)
+                var started = new List<CSComponent>();
+
+                foreach (var csc in cscomponentStart.ToList())
                 {
                     if (!csc.IsEnabled())
                     {
-                        newList.Add(csc);
                         continue;
                     }
 
                     // mark as started whether or not a Start method exists
                     csc.started = true;
+                    started.Add(csc);
 
                     CSComponentInfo info;
                     if (CSComponentCore.csinfoLookup.TryGetValue(csc.GetType(), out info))
@@ -67,7 +71,10 @@ namespace AtomicEngine
 
                 }
 
-                cscomponentStart = newList;
+                foreach (var csc in started)
+                {
+                    cscomponentStart.Remove(csc);
+                }
             }
 
             // Handle Scene Update
@@ -224,6 +231,73 @@ namespace AtomicEngine
 
         }
 
+        void HandleCSComponentLoad(CSComponentLoadEvent e)
+        {
+            var scriptMap = e.scriptMap;
+
+            // Get the NativeInstance as an IntPtr, otherwise we would be wrapping as a CSComponent
+            IntPtr csnative = scriptMap.GetVoidPtr("NativeInstance");
+
+            IntPtr fieldValues = IntPtr.Zero;
+            if (scriptMap.Contains("FieldValues"))
+                fieldValues = scriptMap.GetVoidPtr("FieldValues");
+
+            CSComponentInfo csinfo;
+
+            if (!CSComponentCore.componentCache.TryGetValue(e.ClassName, out csinfo))
+            {
+                return;
+            }
+
+            NativeCore.NativeContructorOverride = csnative;
+            var component = (CSComponent)Activator.CreateInstance(csinfo.Type);
+            NativeCore.VerifyNativeContructorOverrideConsumed();
+
+            if (fieldValues != IntPtr.Zero)
+                csinfo.ApplyFieldValues(component, fieldValues);
+
+            AddCSComponent(component);
+
+        }
+
+        void AddCSComponent(CSComponent csc)
+        {
+            CSComponentInfo info;
+
+            if (!CSComponentCore.csinfoLookup.TryGetValue(csc.GetType(), out info))
+            {
+                Log.Error("Scene.HandleComponentAdded - unable to get CSComponentInfo");
+                return;
+            }
+
+            List<CSComponent> cslist;
+
+            if (!cscomponents.TryGetValue(info, out cslist))
+            {
+                cslist = cscomponents[info] = new List<CSComponent>();
+            }
+
+            if (cslist.Contains(csc))
+            {
+                throw new InvalidOperationException("Scene.HandleComponentAdded - CSComponent already added to component list");
+            }
+
+            cslist.Add(csc);
+
+            if (cscomponentStart.Contains(csc))
+            {
+                throw new InvalidOperationException("Scene.HandleComponentAdded CSComponent already added to start list");
+            }
+
+            if (csc.started)
+            {
+                throw new InvalidOperationException("Scene.HandleComponentAdded CSComponent already started");
+            }
+
+            cscomponentStart.Add(csc);
+
+        }
+
         void HandleComponentAdded(ComponentAddedEvent e)
         {
             Component component;
@@ -239,9 +313,9 @@ namespace AtomicEngine
             }
             
 
+            // Check null (CSComponent) or other abstract component
             if (component == null)
-            {
-                Log.Error("Scene.HandleComponentAdded - null component");
+            {                
                 return;
             }
 
@@ -257,40 +331,7 @@ namespace AtomicEngine
             if (component.GetType().GetTypeInfo().IsSubclassOf(typeof(CSComponent)))
             {
                 var csc = (CSComponent)component;
-
-                CSComponentInfo info;
-
-                if (!CSComponentCore.csinfoLookup.TryGetValue(component.GetType(), out info))
-                {
-                    Log.Error("Scene.HandleComponentAdded - unable to get CSComponentInfo");
-                    return;
-                }
-
-                List<CSComponent> cslist;
-
-                if (!cscomponents.TryGetValue(info, out cslist))
-                {
-                    cslist = cscomponents[info] = new List<CSComponent>();
-                }
-
-                if (cslist.Contains(csc))
-                {
-                    throw new InvalidOperationException("Scene.HandleComponentAdded - CSComponent already added to component list");
-                }
-
-                cslist.Add(csc);
-
-                if (cscomponentStart.Contains(csc))
-                {
-                    throw new InvalidOperationException("Scene.HandleComponentAdded CSComponent already added to start list");
-                }
-
-                if (csc.started)
-                {
-                    throw new InvalidOperationException("Scene.HandleComponentAdded CSComponent already started");
-                }
-
-                cscomponentStart.Add(csc);
+                AddCSComponent(csc);
 
             }
 

+ 2 - 10
Source/AtomicNET/NETScript/CSComponent.cpp

@@ -103,26 +103,18 @@ void CSComponent::SendLoadEvent()
     if (!componentClassName_.Length())
         return;
 
-    // TODO: We need to factor out runtime loading of CSComponent assemblies
-    CSComponentAssembly*  assemblyFile = 0;
-
-#ifdef ATOMIC_PLATFORM_DESKTOP
-    assemblyFile = CSComponentAssembly::ResolveClassAssembly(componentClassName_);
-#endif
-
     using namespace CSComponentLoad;
 
     VariantMap eventData;
 
-    eventData[P_ASSEMBLYPATH] = assemblyFile ? GetFileName(assemblyFile->GetFullPath()) : String::EMPTY;
-
     eventData[P_CLASSNAME] = componentClassName_;
     eventData[P_NATIVEINSTANCE] = (void*) this;
 
     if (!fieldValues_.Empty())
         eventData[P_FIELDVALUES] = (void*) &fieldValues_;
 
-    SendEvent(E_CSCOMPONENTLOAD, eventData);
+    if (node_ && node_->GetScene())
+        node_->GetScene()->SendEvent(E_CSCOMPONENTLOAD, eventData);
 
 }
 

+ 0 - 1
Source/AtomicNET/NETScript/NETScriptEvents.h

@@ -35,7 +35,6 @@ namespace Atomic
 
     ATOMIC_EVENT(E_CSCOMPONENTLOAD, CSComponentLoad)
     {
-        ATOMIC_PARAM(P_ASSEMBLYPATH, AssemblyPath); // String
         ATOMIC_PARAM(P_CLASSNAME, ClassName); // String
         ATOMIC_PARAM(P_NATIVEINSTANCE, NativeInstance); // CSComponent as void*
         ATOMIC_PARAM(P_FIELDVALUES, FieldValues);  // VariantMap as void*

+ 14 - 0
Source/AtomicPlayer/Player.cpp

@@ -28,6 +28,7 @@
 #include <Atomic/Graphics/Renderer.h>
 #include <Atomic/Graphics/Camera.h>
 
+#include "PlayerEvents.h"
 #include "Player.h"
 
 namespace AtomicPlayer
@@ -66,12 +67,25 @@ Scene* Player::LoadScene(const String& filename, Camera *camera)
 
     Scene* scene = new Scene(context_);
 
+    VariantMap eventData;
+
+    eventData[PlayerSceneLoadBegin::P_SCENE] = scene;
+
+    scene->SendEvent(E_PLAYERSCENELOADBEGIN, eventData);
+
     if (!scene->LoadXML(*file))
     {
+        eventData[PlayerSceneLoadEnd::P_SCENE] = scene;
+        eventData[PlayerSceneLoadEnd::P_SUCCESS] = false;
+        scene->SendEvent(E_PLAYERSCENELOADEND, eventData);
         scene->ReleaseRef();
         return 0;
     }
 
+    eventData[PlayerSceneLoadEnd::P_SCENE] = scene;
+    eventData[PlayerSceneLoadEnd::P_SUCCESS] = true;
+    scene->SendEvent(E_PLAYERSCENELOADEND, eventData);
+
     if (currentScene_.Null())
     {
         currentScene_ = scene;

+ 42 - 0
Source/AtomicPlayer/PlayerEvents.h

@@ -0,0 +1,42 @@
+//
+// Copyright (c) 2014-2016, THUNDERBEAST GAMES LLC All rights reserved
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+
+#pragma once
+
+#include <Atomic/Core/Object.h>
+
+using namespace Atomic;
+
+namespace AtomicPlayer
+{
+    ATOMIC_EVENT(E_PLAYERSCENELOADBEGIN, PlayerSceneLoadBegin)
+    {
+        ATOMIC_PARAM(P_SCENE, Scene);        // Scene
+    }
+
+    ATOMIC_EVENT(E_PLAYERSCENELOADEND, PlayerSceneLoadEnd)
+    {
+        ATOMIC_PARAM(P_SCENE, Scene);       // Scene
+        ATOMIC_PARAM(P_SUCCESS, Success);   // bool
+    }
+
+}