Browse Source

C# updates

Josh Engebretson 9 years ago
parent
commit
95249b16d0

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

@@ -428,37 +428,6 @@ namespace AtomicEngine
             return ancestorType;
         }
 
-        static public IntPtr NativeContructorOverride
-        {
-            get
-            {
-                IntPtr value = nativeContructorOverride;
-                nativeContructorOverride = IntPtr.Zero;
-                return value;
-            }
-
-            set
-            {
-                if (nativeContructorOverride != IntPtr.Zero)
-                {
-                    throw new InvalidOperationException("NativeCore.NativeContructorOverride - Previous nativeContructorOverride not consumed");
-                }
-
-                nativeContructorOverride = value;
-            }
-        }
-
-        static public void VerifyNativeContructorOverrideConsumed()
-        {
-            if (nativeContructorOverride != IntPtr.Zero)
-            {
-                throw new InvalidOperationException("NativeCore.VerifyNativeContructorOverrideConsumed -  NativeContructorOverride not consumed");
-            }
-        }
-
-
-        private static IntPtr nativeContructorOverride = IntPtr.Zero;
-
         // weak references here, hold a ref native side
         internal static Dictionary<IntPtr, WeakReference<RefCounted>> nativeLookup = new Dictionary<IntPtr, WeakReference<RefCounted>>();
 

+ 25 - 0
Script/AtomicNET/AtomicNET/Graphics/Material.cs

@@ -0,0 +1,25 @@
+
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace AtomicEngine
+{
+    public partial class Material : Resource
+    {
+
+        public void SetShaderParameter(string name, ScriptVariant variant)
+        {
+            csi_Atomic_Material_SetShaderParameter(nativeInstance, name, variant.nativeInstance);
+        }
+      
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern void csi_Atomic_Material_SetShaderParameter(IntPtr self, string name, IntPtr variant);
+
+    };
+
+}
+
+
+
+

+ 64 - 0
Script/AtomicNET/AtomicNET/Scene/CSComponent.cs

@@ -1,4 +1,6 @@
 using System;
+using System.Runtime.InteropServices;
+
 namespace AtomicEngine
 {
 
@@ -17,6 +19,68 @@ namespace AtomicEngine
 
         internal bool started = false;
 
+        // CSComponents can be instantiated from a serialized scene or from within managed code
+        protected CSComponent()
+        {
+            if (nativeLoadOverrideValidate != IntPtr.Zero)
+            {
+                // When loading CSComponents from a scene, many issues circumvented by not allowing additional components
+                // to be created (on the Node) during serialization, so this is an error state
+                throw new InvalidOperationException($"CSComponent() - Recursive CSComponent instantiation in default constructor during load type: { GetType().Name} ");
+            }
+
+            if (nativeLoadOverride == IntPtr.Zero)
+            {
+                // We are being "new'd" in script
+                nativeInstance = csi_Atomic_CSComponent_Constructor();                
+            }
+            else
+            {
+                // We are loading from a serialized CSComponent
+                nativeInstance = nativeLoadOverride;
+
+                // validation bookkeeping
+                nativeLoadOverrideValidate = nativeLoadOverride;
+                nativeLoadOverride = IntPtr.Zero;
+            }
+
+            NativeCore.RegisterNative(nativeInstance, this);
+
+
+        }
+
+        // Create an instance of a CSComponent derived class, given an existing native CSComponent
+        // This happens when loading components from serializes scene/prefab assets
+        internal static CSComponent LoadCreateInstance(Type type, IntPtr nativeCSComponent)
+        {
+            // initialize instantiation validation
+            nativeLoadOverride = nativeCSComponent;
+            nativeLoadOverrideValidate = IntPtr.Zero;
+
+            var component = (CSComponent)Activator.CreateInstance(type);
+
+            if (component == null)
+            {
+                throw new InvalidOperationException("CSComponent.CreateInstance - Unable to instantiate instance of type: " + type.Name);
+            }
+
+            // clear validation
+            nativeLoadOverride = nativeLoadOverrideValidate = IntPtr.Zero;
+
+            return component;
+        }
+
+        // When instantiating from a serialized scene, the native CSComponent instance will already exist
+        // nativeLoadOverride stores the overriden native instance to use in the default CSComponent constructor
+        internal static IntPtr nativeLoadOverride = IntPtr.Zero;
+        // Check for whether additional CSComponents were created in default constructor during serialization, this is an error condition and will throw an exception
+        internal static IntPtr nativeLoadOverrideValidate = IntPtr.Zero;
+
+        // native constructor for CSComponent
+        [DllImport(Constants.LIBNAME, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
+        private static extern IntPtr csi_Atomic_CSComponent_Constructor();
+
+
     }
 
 }

+ 8 - 3
Script/AtomicNET/AtomicNET/Scene/Scene.cs

@@ -246,12 +246,17 @@ namespace AtomicEngine
 
             if (!CSComponentCore.componentCache.TryGetValue(e.ClassName, out csinfo))
             {
+                Log.Error("Scene.HandleCSComponentLoad - unable to find CSComponent in cache for classname: " + e.ClassName );
                 return;
             }
 
-            NativeCore.NativeContructorOverride = csnative;
-            var component = (CSComponent)Activator.CreateInstance(csinfo.Type);
-            NativeCore.VerifyNativeContructorOverrideConsumed();
+            var component = CSComponent.LoadCreateInstance(csinfo.Type, csnative);
+
+            if (component == null)
+            {
+                Log.Error("Scene.HandleCSComponentLoad - unable to create CSComponent for classname: " + e.ClassName);
+                return;
+            }
 
             if (fieldValues != IntPtr.Zero)
                 csinfo.ApplyFieldValues(component, fieldValues);

+ 7 - 0
Script/AtomicNET/AtomicNETProject.json

@@ -6,6 +6,7 @@
     "projects" : [
         {
             "name": "AtomicNET.Shared",
+            "atomicNET" : true,
             "outputType" : "Shared",
             "projectGuid" : "C74A8ECC-7517-11E6-A1D7-005056C00008",
             "sources" : [
@@ -20,6 +21,7 @@
         },
         {
             "name": "AtomicNET",
+            "atomicNET" : true,
             "outputType" : "Library",
             "rootNamespace" : "AtomicEngine",
             "assemblyName" : "AtomicNET",
@@ -38,6 +40,7 @@
         },
         {
             "name": "AtomicNET.Desktop",
+            "atomicNET" : true,
             "assemblyDocFile" : true,
             "platforms" : ["desktop"],
             "outputType" : "Library",
@@ -60,6 +63,7 @@
         },
         {
             "name": "AtomicNET.Android.SDL",
+            "atomicNET" : true,
             "platforms" : ["android"],
             "outputType" : "Library",
             "rootNamespace" : "AtomicGameEngine",
@@ -80,6 +84,7 @@
         },
         {
             "name": "AtomicNET.Android",
+            "atomicNET" : true,
             "platforms" : ["android"],
             "outputType" : "Library",
             "defineConstants" : ["ATOMIC_ANDROID"],
@@ -104,6 +109,7 @@
         },
         {
             "name": "AtomicNET.iOS",
+            "atomicNET" : true,
             "platforms" : ["ios"],
             "outputType" : "Library",
             "projectTypeGuids" :[ "8FFB629D-F513-41CE-95D2-7ECE97B6EEEC", "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC" ],
@@ -130,6 +136,7 @@
         },
         {
             "name": "AtomicNETService",
+            "atomicNET" : true,
             "platforms" : ["desktop"],
             "outputType" : "Exe",
             "rootNamespace" : "AtomicTools",

+ 8 - 1
Script/Packages/AtomicNETScript/AtomicNETScript.json

@@ -1,5 +1,12 @@
 {
 	"name" : "AtomicNETScript",
 	"sources" : ["Source/AtomicNET/NETScript"],
-	"classes" : ["NETScriptObject", "CSComponent", "CSComponentAssembly"]
+	"classes" : ["NETScriptObject", "CSComponent", "CSComponentAssembly"],
+	"excludes" : {
+		"CSharp" : {
+			"CSComponent" : {
+				"CSComponent" : ["Context"]
+			}
+		}
+	}
 }

+ 4 - 0
Source/Atomic/Script/ScriptVariant.h

@@ -59,6 +59,10 @@ namespace Atomic
 
         void SetVector3(const Vector3& value) { variant_ = value; }
 
+        Vector4 GetVector4() { return variant_.GetVector4(); }
+
+        void SetVector4(const Vector4& value) { variant_ = value; }
+
         Color GetColor() { return variant_.GetColor(); }
 
         void SetColor(const Color& value) { variant_ = value; }

+ 23 - 0
Source/AtomicNET/NETNative/NETCInterop.cpp

@@ -11,6 +11,7 @@
 #include <Atomic/Graphics/Light.h>
 #include <Atomic/Graphics/Octree.h>
 #include <Atomic/Graphics/AnimatedModel.h>
+#include <Atomic/Graphics/Material.h>
 
 #include <Atomic/Navigation/NavigationMesh.h>
 #include <Atomic/Navigation/CrowdManager.h>
@@ -19,6 +20,8 @@
 
 #include <Atomic/Scene/ValueAnimation.h>
 
+#include <AtomicNET/NETScript/CSComponent.h>
+
 #include <Atomic/Input/Controls.h>
 
 
@@ -592,6 +595,26 @@ namespace Atomic
             return self->Write(bytes, size);
         }
 
+        // Material
+
+        ATOMIC_EXPORT_API void csi_Atomic_Material_SetShaderParameter(Material* self, const char* name, ScriptVariant* variant)
+        {
+
+            if (!self || !variant || !name || !strlen(name))
+                return;
+
+            self->SetShaderParameter(name, variant->GetVariant());
+        }
+
+        // CSComponent
+
+        ATOMIC_EXPORT_API CSComponent* csi_Atomic_CSComponent_Constructor()
+        {
+
+            return new CSComponent(NETCore::GetContext());
+        }
+
+
 
 #ifdef ATOMIC_PLATFORM_IOS
         ATOMIC_EXPORT_API void SDL_IOS_Init(const char *resourceDir, const char *documentsDir)

+ 1 - 3
Source/ToolCore/JSBind/CSharp/CSFunctionWriter.cpp

@@ -591,9 +591,7 @@ void CSFunctionWriter::WriteManagedConstructor(String& source)
     String callSig;
     GenPInvokeCallParameters(callSig);
 
-    source += IndentLine("IntPtr nativeInstanceOverride = NativeCore.NativeContructorOverride;\n");
-
-    line = ToString("nativeInstance = NativeCore.RegisterNative (nativeInstanceOverride != IntPtr.Zero ? nativeInstanceOverride : csb_%s_%s_Constructor_%u(%s), this);\n",
+    line = ToString("nativeInstance = NativeCore.RegisterNative (csb_%s_%s_Constructor_%u(%s), this);\n",
                      package->GetName().CString(), klass->GetName().CString(), function_->GetID(), callSig.CString());
 
     source += IndentLine(line);

+ 45 - 3
Source/ToolCore/NETTools/NETProjectGen.cpp

@@ -74,6 +74,7 @@ namespace ToolCore
     }
 
     NETCSProject::NETCSProject(Context* context, NETProjectGen* projectGen) : NETProjectBase(context, projectGen),
+        atomicNETProject_(false),
         genAssemblyDocFile_(false),
         playerApplication_(false),
         androidApplication_(false)
@@ -177,6 +178,24 @@ namespace ToolCore
 
                 compile.CreateChild("Link").SetValue(link);
 
+                // For shared projects, ensure that the folder for the link exists, otherwise VS complains 
+                // with little red x's and Resharper (potentially other tools) have issues
+                if (outputType_ == "Shared")
+                {
+                    String pathName, fileName, extension;
+
+                    SplitPath(link, pathName, fileName, extension);
+
+                    if (extension == ".cs")
+                    {                        
+                        if (!fs->Exists(projectPath_ + pathName))
+                        {
+                            fs->CreateDirs(projectPath_, pathName);
+                        }
+                    }
+
+                }
+
             }
 
         }
@@ -406,8 +425,19 @@ namespace ToolCore
 
         pgroup.CreateChild("Optimize").SetValue("true");
 
+        String config = "Release";
+
+#ifdef ATOMIC_DEV_BUILD
+
+        // If we're a core AtomicNET assembly and a project is included in solution
+        // output to Lib so that development changes will be picked up by project reference
+        if (atomicNETProject_ && projectGen_->GetAtomicProjectPath().Length())
+            config = "Lib";
+
+#endif
+
         String outputPath = assemblyOutputPath_;
-        outputPath.Replace("$ATOMIC_CONFIG$", "Release");
+        outputPath.Replace("$ATOMIC_CONFIG$", config);
 
         if (IsAbsolutePath(outputPath))
         {
@@ -510,11 +540,21 @@ namespace ToolCore
         else
             pgroup.SetAttribute("Condition", " '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ");
 
-
         pgroup.CreateChild("Optimize").SetValue("false");
 
+        String config = "Debug";
+
+#ifdef ATOMIC_DEV_BUILD
+
+        // If we're a core AtomicNET assembly and a project is included in solution
+        // output to Lib so that development changes will be picked up by project reference
+        if (atomicNETProject_ && projectGen_->GetAtomicProjectPath().Length())
+            config = "Lib";
+
+#endif
+
         String outputPath = assemblyOutputPath_;
-        outputPath.Replace("$ATOMIC_CONFIG$", "Debug");
+        outputPath.Replace("$ATOMIC_CONFIG$", config);
 
         if (IsAbsolutePath(outputPath))
         {
@@ -1307,6 +1347,8 @@ namespace ToolCore
 
         outputType_ = root["outputType"].GetString();
 
+        atomicNETProject_ = root["atomicNET"].GetBool();
+
         androidApplication_ = root["androidApplication"].GetBool();
         playerApplication_ = root["playerApplication"].GetBool();
         genAssemblyDocFile_ = root["assemblyDocFile"].GetBool();

+ 7 - 0
Source/ToolCore/NETTools/NETProjectGen.h

@@ -80,10 +80,16 @@ namespace ToolCore
         bool SupportsDesktop() const;
         bool SupportsPlatform(const String& platform, bool explicitCheck = true) const;
 
+        /// Returns true if this project is part of core AtomicNET
+        bool GetAtomicNETProject() const { return atomicNETProject_;  }
+
         bool Generate();
 
     private:
 
+        /// Returns true if this project is part of core AtomicNET
+        void SetAtomicNETProject(bool value) { atomicNETProject_ = value; }
+
         // Portable Class Library
         bool GenerateShared();
 
@@ -117,6 +123,7 @@ namespace ToolCore
         String assemblyName_;
         String assemblyOutputPath_;
         String assemblySearchPaths_;
+        bool atomicNETProject_;
 
         // project paths
         String projectPath_;