summaryrefslogtreecommitdiff
path: root/Runtime/Scripting
diff options
context:
space:
mode:
Diffstat (limited to 'Runtime/Scripting')
-rw-r--r--Runtime/Scripting/AS3Utility.cpp31
-rw-r--r--Runtime/Scripting/AS3Utility.h144
-rw-r--r--Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.cpp287
-rw-r--r--Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.h45
-rw-r--r--Runtime/Scripting/Backend/Flash/ScriptingMethodFactory_Flash.h40
-rw-r--r--Runtime/Scripting/Backend/Flash/ScriptingTypeProvider_Flash.h53
-rw-r--r--Runtime/Scripting/Backend/IScriptingTypeProvider.h16
-rw-r--r--Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.cpp280
-rw-r--r--Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.h15
-rw-r--r--Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h83
-rw-r--r--Runtime/Scripting/Backend/ScriptingArguments.cpp218
-rw-r--r--Runtime/Scripting/Backend/ScriptingArguments.h79
-rw-r--r--Runtime/Scripting/Backend/ScriptingBackendApi.h72
-rw-r--r--Runtime/Scripting/Backend/ScriptingInvocation.cpp223
-rw-r--r--Runtime/Scripting/Backend/ScriptingInvocation.h73
-rw-r--r--Runtime/Scripting/Backend/ScriptingInvocationNoArgs.cpp123
-rw-r--r--Runtime/Scripting/Backend/ScriptingInvocationNoArgs.h31
-rw-r--r--Runtime/Scripting/Backend/ScriptingMethodFactory.h18
-rw-r--r--Runtime/Scripting/Backend/ScriptingMethodRegistry.cpp165
-rw-r--r--Runtime/Scripting/Backend/ScriptingMethodRegistry.h60
-rw-r--r--Runtime/Scripting/Backend/ScriptingMethodRegistryTests.cpp237
-rw-r--r--Runtime/Scripting/Backend/ScriptingTypeRegistry.cpp214
-rw-r--r--Runtime/Scripting/Backend/ScriptingTypeRegistry.h33
-rw-r--r--Runtime/Scripting/Backend/ScriptingTypes.h202
-rw-r--r--Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.cpp35
-rw-r--r--Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.h30
-rw-r--r--Runtime/Scripting/CommonScriptingClasses.cpp268
-rw-r--r--Runtime/Scripting/CommonScriptingClasses.h206
-rw-r--r--Runtime/Scripting/DelayedCallUtility.cpp73
-rw-r--r--Runtime/Scripting/DelayedCallUtility.h16
-rw-r--r--Runtime/Scripting/GetComponent.cpp260
-rw-r--r--Runtime/Scripting/GetComponent.h16
-rw-r--r--Runtime/Scripting/ICallString.cpp40
-rw-r--r--Runtime/Scripting/ICallString.h91
-rw-r--r--Runtime/Scripting/MonoManager_Flash.cpp41
-rw-r--r--Runtime/Scripting/MonoManager_Flash.h27
-rw-r--r--Runtime/Scripting/MonoManager_WinRT.cpp105
-rw-r--r--Runtime/Scripting/MonoManager_WinRT.h27
-rw-r--r--Runtime/Scripting/ReadOnlyScriptingObjectOfType.h151
-rw-r--r--Runtime/Scripting/ScriptLanguagePortUtility.cpp11
-rw-r--r--Runtime/Scripting/ScriptLanguagePortUtility.h10
-rw-r--r--Runtime/Scripting/ScriptPopupMenus.cpp142
-rw-r--r--Runtime/Scripting/ScriptPopupMenus.h11
-rw-r--r--Runtime/Scripting/Scripting.cpp768
-rw-r--r--Runtime/Scripting/Scripting.h197
-rw-r--r--Runtime/Scripting/ScriptingExportUtility.h265
-rw-r--r--Runtime/Scripting/ScriptingManager.cpp150
-rw-r--r--Runtime/Scripting/ScriptingManager.h63
-rw-r--r--Runtime/Scripting/ScriptingObjectOfType.h142
-rw-r--r--Runtime/Scripting/ScriptingObjectWithIntPtrField.h139
-rw-r--r--Runtime/Scripting/ScriptingUtility.h48
-rw-r--r--Runtime/Scripting/Scripting_Flash.cpp176
-rw-r--r--Runtime/Scripting/Scripting_Mono.cpp247
-rw-r--r--Runtime/Scripting/Scripting_WinRT.cpp175
-rw-r--r--Runtime/Scripting/TextAsset.cpp70
-rw-r--r--Runtime/Scripting/TextAsset.h40
-rw-r--r--Runtime/Scripting/WinRTHelper.h29
-rw-r--r--Runtime/Scripting/WinRTMarshalers.cpp306
-rw-r--r--Runtime/Scripting/WinRTMarshalers.h66
59 files changed, 7183 insertions, 0 deletions
diff --git a/Runtime/Scripting/AS3Utility.cpp b/Runtime/Scripting/AS3Utility.cpp
new file mode 100644
index 0000000..8c93499
--- /dev/null
+++ b/Runtime/Scripting/AS3Utility.cpp
@@ -0,0 +1,31 @@
+#include "UnityPrefix.h"
+#include "ScriptingUtility.h"
+#include "Runtime/Utilities/LogAssert.h"
+#include "Runtime/Scripting/ScriptingManager.h"
+#include "Runtime/Scripting/Backend/ScriptingArguments.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+extern "C" bool NativeExt_SendMessage(ScriptingStringPtr path, ScriptingStringPtr method, ScriptingObjectPtr value)
+{
+ Transform* transform = FindActiveTransformWithPath( (const char*) path );
+ if( transform != NULL)
+ {
+ return Scripting::SendScriptingMessage( transform->GetGameObject(), (const char*) method, value );
+ }
+ return false;
+}
+
+bool ReadStringFromFile (TEMP_STRING* outData, const string& path)
+{
+ const char* outDataFlash = Ext_FileContainer_ReadStringFromFile(path.c_str());
+ if(outDataFlash != NULL){
+ *outData = outDataFlash;
+ return true;
+ }
+ return false;
+}
+
+ScriptingObjectPtr ScriptingInstantiateObjectFromClassName(const char* name)
+{
+ return Ext_GetNewMonoBehaviour(name);
+}
diff --git a/Runtime/Scripting/AS3Utility.h b/Runtime/Scripting/AS3Utility.h
new file mode 100644
index 0000000..31dd7fc
--- /dev/null
+++ b/Runtime/Scripting/AS3Utility.h
@@ -0,0 +1,144 @@
+#ifndef AS3UTILITY_H
+#define AS3UTILITY_H
+
+#if !defined(SCRIPTINGUTILITY_H)
+#error "Don't include AS3Utility.h, include ScriptingUtility.h instead"
+#endif
+
+typedef UInt32 AS3Handle;
+struct UTF16String;
+
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Runtime/Graphics/Transform.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+#include "Scripting.h"
+
+using namespace std;
+
+#define htons(A) (A)
+#define htonl(A) (A)
+#define ntohs htons
+#define ntohl htohl
+
+#define SCRIPTINGAPI_THREAD_CHECK(NAME)
+#define SCRIPTINGAPI_CONSTRUCTOR_CHECK(NAME)
+#define SCRIPTINGAPI_DEFINE_REF_ARG(t, n) t n
+#define SCRIPTINGAPI_FIX_REF_ARG(t, n)
+
+extern "C" void Ext_FileContainer_MakeFilesAvailable();
+extern "C" int Ext_FileContainer_GetFileLength(const char* filename);
+extern "C" char* Ext_Flash_GetNameFromClass(ScriptingType* handle);
+extern "C" void Ext_Stack_Store(void* ptr);
+extern "C" void Ext_Flash_LogCallstack();
+extern "C" void Ext_Flash_ThrowError(const char*) __attribute__((noreturn));
+
+extern "C" int Ext_MarshallTo(ScriptingObjectPtr obj, void* dest);
+extern "C" int Ext_UnmarshallFrom(ScriptingObjectPtr obj, void* src);
+//extern "C" void Ext_SetNativePtr(ScriptingObjectPtr obj, void* ptr);
+//extern "C" void* Ext_GetNativePtr(ScriptingObjectPtr obj);
+
+//ScriptingArray* MonoFindObjectsOfType (ScriptingType* reflectionTypeObject, int mode);
+
+namespace Unity { class GameObject; class Component; }
+using namespace Unity;
+
+extern "C" const char* Ext_FileContainer_ReadStringFromFile(const char* filename);
+
+//Used by MonoBehaviourSerialization
+extern "C" void Ext_SerializeMonoBehaviour(ScriptingObjectPtr behaviour);
+extern "C" UInt8* Ext_DeserializeMonoBehaviour(ScriptingObjectPtr behaviour);
+extern "C" void Ext_RemapPPtrs(ScriptingObjectPtr behaviour);
+
+extern "C" ScriptingObjectPtr Ext_Scripting_InstantiateScriptingWrapperForClassWithName(const char* name);
+
+extern "C" bool Ext_FileContainer_IsFileCreatedAt(const char* filename);
+extern "C" void Ext_WriteTextAndToolTipIntoUTF16Strings(ScriptingObject* obj, UTF16String* text, UTF16String* tooltip);
+
+extern "C" bool Ext_Trace(const char* msg);
+extern "C" ScriptingObjectPtr Ext_GetNewMonoBehaviour(const char* name);
+
+//External interface / openurl / application.
+extern "C" void Ext_OpenURL(const char* url);
+extern "C" ScriptingString* Ext_ExternalCall(const char* function, ScriptingObjectPtr args);
+
+extern "C" ScriptingObjectPtr Ext_Flash_getProperty(ScriptingObjectPtr object, const char* property);
+
+template<class T>
+ScriptingObjectPtr Flash_CreateScriptingObjectFromNativeStruct(ScriptingClass* klass, T& thestruct);
+
+template<class T> inline
+ScriptingObjectPtr CreateScriptingObjectFromNativeStruct(ScriptingClass* klass, T& thestruct)
+{
+ //printf_console("creating instance of klass: %d",klass);
+ ScriptingObjectPtr obj = scripting_object_new(klass);
+ //printf_console("populating it with native data stored at %d",&thestruct);
+ Ext_UnmarshallFrom(obj, &thestruct);
+ return obj;
+}
+
+inline void RaiseIfNull(ScriptingObjectPtr o) {}
+
+inline int GetScriptingArraySize(ScriptingArray* a)
+{
+ if(a == NULL)
+ return 0;
+
+ //POD arrays are encoded by the as3 glue as a memoryblob: one int describing the size, following the actual bytes.
+ return *(int*)(a);
+}
+
+extern "C" int Ext_MarshallTo(ScriptingObjectPtr obj, void* dest);
+extern "C" int Ext_UnmarshallFrom(ScriptingObjectPtr obj, void* src);
+
+template<class T> inline
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, T* dest)
+{
+ Ext_MarshallTo(so,(void*)dest);
+}
+
+template<class T> inline
+void MarshallNativeStructIntoManaged(T& src, ScriptingObjectPtr dest)
+{
+ Ext_UnmarshallFrom(dest,(void*)&src);
+}
+
+template<class T>
+inline T* ScriptingObjectToObject(ScriptingObjectPtr so)
+{
+ //todo: create the optimized path where we directly grab the cachedptr
+ PPtr<T> p;
+ p.SetInstanceID(Scripting::GetInstanceIDFromScriptingWrapper(so));
+ return p;
+}
+
+ScriptingObjectPtr ScriptingInstantiateObjectFromClassName(const char* name);
+
+inline
+char* ScriptingStringToAllocatedChars(const ICallString& str)
+{
+ return strdup(str.utf8stream);
+}
+
+inline void ScriptingStringToAllocatedChars_Free(const char* str)
+{
+ free((void*)str);
+}
+
+template<class T>
+inline ScriptingObjectPtr ScriptingGetObjectReference(PPtr<T> object)
+{
+ return Scripting::ScriptingWrapperFor(object);
+}
+template<class T>
+inline ScriptingObjectPtr ScriptingGetObjectReference(T* object)
+{
+ return Scripting::ScriptingWrapperFor(object);
+}
+
+#define CreateScriptingParams(VariableName, ParamCount) ScriptingParams VariableName[ParamCount];
+// Don't use if Value is ScriptingObjectPtr!!!
+#define SetScriptingParam(VariableName, Index, Value) VariableName[Index] = &Value;
+#define GetSafeString(ClassName, Getter) Getter
+
+#endif \ No newline at end of file
diff --git a/Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.cpp b/Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.cpp
new file mode 100644
index 0000000..8022f96
--- /dev/null
+++ b/Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.cpp
@@ -0,0 +1,287 @@
+#include "UnityPrefix.h"
+
+#include "../ScriptingTypes.h"
+#include "ScriptingBackendApi_Flash.h"
+#include "../ScriptingTypeRegistry.h"
+#include "../ScriptingMethodRegistry.h"
+#include <string>
+#include "../ScriptingArguments.h"
+#include "PlatformDependent\FlashSupport\cpp\FlashUtils.h"
+
+std::string scripting_cpp_string_for(ScriptingStringPtr str)
+{
+ return std::string((const char*)str);
+}
+
+//implemented in raw actionscript
+extern "C" ScriptingClass* Ext_Flash_GetBaseClassFromScriptingClass(ScriptingClass* klass);
+bool scripting_method_is_instance(ScriptingMethodPtr method)
+{
+ //not implemented on flash yet.
+ return true;
+}
+
+ScriptingStringPtr scripting_string_new(const char* str)
+{
+ __asm __volatile__("returnString = strFromPtr(%0);" : : "r" (str) );
+ return (ScriptingStringPtr)str;
+}
+
+ScriptingStringPtr scripting_string_new(const std::string& str)
+{
+ return scripting_string_new(str.c_str());
+}
+
+extern "C" int Ext_Flash_ScriptingGetMethodParamCount(ScriptingObjectPtr object, AS3String as3String);
+int scripting_method_get_argument_count(ScriptingMethodPtr method, ScriptingTypeRegistry& typeRegistry)
+{
+ ScriptingObjectPtr methodInfo = method->GetSystemReflectionMethodInfo();
+ if (methodInfo==NULL)
+ return 0;
+
+ int result;
+ FLASH_ASM_WITH_NEWSP("%0 = ScriptingMethodHelper.NumberOfArgumentsOf(marshallmap.getObjectWithId(%1));" : "=r"(result) : "r"(methodInfo));
+
+ return result;
+}
+
+ScriptingTypePtr scripting_method_get_nth_argumenttype(ScriptingMethodPtr method, int index, ScriptingTypeRegistry& typeRegistry)
+{
+ ScriptingObjectPtr methodInfo = method->GetSystemReflectionMethodInfo();
+ if (methodInfo==NULL)
+ return NULL;
+
+ ScriptingTypePtr result;
+ FLASH_ASM_WITH_NEWSP("scratch_object = ScriptingMethodHelper.NthArgumentType(marshallmap.getObjectWithId(%0), %1)" : : "r"(methodInfo), "r"(index));
+ FLASH_ASM_WITH_NEWSP("if (scratch_object!=null) %0 = marshallmap.getIdForObject(scratch_object.GetClass()); else %0 = 0;" : "=r"(result));
+ return result;
+}
+
+const char* scripting_method_get_name(ScriptingMethodPtr method)
+{
+ return method->GetName();
+}
+
+bool scripting_method_has_attribute (ScriptingMethodPtr method, ScriptingClassPtr attribute)
+{
+ //not implemented on flash yet
+ return false;
+}
+
+ScriptingTypePtr scripting_class_get_parent(ScriptingTypePtr type, ScriptingTypeRegistry& typeRegistry)
+{
+ return Ext_Flash_GetBaseClassFromScriptingClass(type);
+}
+
+bool scripting_class_is_enum(ScriptingTypePtr type)
+{
+ //todo: implement
+ return false;
+}
+
+extern "C" const char* Ext_Flash_GetNameFromClass(ScriptingClassPtr klass);
+const char* scripting_class_get_name(ScriptingClassPtr klass)
+{
+ //Horrible, we can only clean this up once we create a struct ScriptingClass for flash.
+ std::string* s = new std::string(Ext_Flash_GetNameFromClass(klass));
+ return s->c_str();
+}
+
+extern "C" const char* Ext_Flash_GetNameSpaceFromScriptingType(ScriptingType* scriptingType);
+const char* scripting_class_get_namespace(ScriptingClassPtr klass)
+{
+ //Horrible, we can only clean this up once we create a struct ScriptingClass for flash.
+ std::string* s = new std::string(Ext_Flash_GetNameSpaceFromScriptingType(klass));
+ return s->c_str();
+}
+
+extern "C" bool Ext_Flash_ScriptingClassIsSubclassOf(ScriptingTypePtr t1, ScriptingTypePtr t2);
+bool scripting_class_is_subclass_of(ScriptingTypePtr t1, ScriptingTypePtr t2)
+{
+ return Ext_Flash_ScriptingClassIsSubclassOf(t1,t2);
+}
+
+ScriptingTypePtr scripting_method_get_returntype(ScriptingMethodPtr method, ScriptingTypeRegistry& typeRegistry)
+{
+ return method->GetReturnType();
+}
+
+extern "C" ScriptingObjectPtr Ext_Flash_InvokeMethodOnObject(void* object, AS3String as3String, ScriptingException** exception);
+ScriptingObjectPtr scripting_method_invoke(ScriptingMethodPtr method, ScriptingObjectPtr object, ScriptingArguments& arguments, ScriptingExceptionPtr* exception)
+{
+ void* objectToInvokeOn = object;
+ *exception = NULL;
+ if (object==NULL)
+ {
+ objectToInvokeOn = method->m_Class;
+ if (objectToInvokeOn == NULL)
+ ErrorString("flash_invoke_method called with NULL object, and scriptmethod->m_Class is NULL too.");
+ }
+
+ __asm __volatile__("invocation_arguments.length = 0;\n");
+
+ for (int i=0; i!=arguments.GetCount(); i++)
+ {
+ switch (arguments.GetTypeAt(i))
+ {
+ case ScriptingArguments::ARGTYPE_BOOLEAN:
+ __asm __volatile__("invocation_arguments.push(%0 ? true : false);" : : "r"(arguments.GetBooleanAt(i)));
+ break;
+ case ScriptingArguments::ARGTYPE_INT:
+ __asm __volatile__("invocation_arguments.push(%0);" : : "r"(arguments.GetIntAt(i)));
+ break;
+ case ScriptingArguments::ARGTYPE_FLOAT:
+ __asm __volatile__("invocation_arguments.push(%0);" : : "f"(arguments.GetFloatAt(i)));
+ break;
+ case ScriptingArguments::ARGTYPE_STRING:
+ __asm __volatile__("invocation_arguments.push(strFromPtr(%0));" : : "r"(arguments.GetStringAt(i)));
+ break;
+ case ScriptingArguments::ARGTYPE_OBJECT:
+ __asm __volatile__("invocation_arguments.push(marshallmap.getObjectWithId(%0));" : : "r"(arguments.GetObjectAt(i)));
+ break;
+ default:
+ ErrorString(Format("Flash does not support calling managed methods with this type of argument: %d",arguments.GetTypeAt(i)));
+ break;
+ }
+ }
+ return Ext_Flash_InvokeMethodOnObject(objectToInvokeOn, method->m_As3String,exception);
+}
+
+ScriptingTypePtr scripting_class_from_systemtypeinstance(ScriptingObjectPtr systemTypeInstance, ScriptingTypeRegistry& typeRegistry)
+{
+ //todo: think about if this is actually correct.
+ return (ScriptingClassPtr)systemTypeInstance;
+}
+
+extern "C" ScriptingObjectPtr Ext_Flash_CreateInstance(ScriptingClass* klass);
+ScriptingObjectPtr scripting_object_new(ScriptingTypePtr t)
+{
+ return Ext_Flash_CreateInstance(t);
+}
+
+extern "C" ScriptingClassPtr Ext_Flash_GetScriptingTypeOfScriptingObject(ScriptingObjectPtr);
+ScriptingTypePtr scripting_object_get_class(ScriptingObjectPtr o, ScriptingTypeRegistry& typeRegistry)
+{
+ return Ext_Flash_GetScriptingTypeOfScriptingObject(o);
+}
+
+ScriptingMethodPtr scripting_object_get_virtual_method(ScriptingObjectPtr o, ScriptingMethodPtr method, ScriptingMethodRegistry& methodRegistry)
+{
+ return method;
+}
+
+void scripting_object_invoke_default_constructor(ScriptingObjectPtr o, ScriptingExceptionPtr* exc)
+{
+ *exc = NULL;
+ //todo: properly deal with exception.
+ FLASH_ASM_WITH_NEWSP("marshallmap.getObjectWithId(%0).cil2as_DefaultConstructor()" : : "r"(o));
+}
+
+int scripting_gchandle_new(ScriptingObjectPtr o)
+{
+ __asm __volatile__("marshallmap.gcHandle(%0);" : : "r" (o));
+ return (int)o;
+}
+
+int scripting_gchandle_weak_new(ScriptingObjectPtr o)
+{
+ FatalErrorMsg("ToDo");
+ return 0;
+}
+
+void scripting_gchandle_free(int handle)
+{
+ __asm __volatile__("marshallmap.gcFree(%0);" : : "r" (handle));
+}
+
+ScriptingObjectPtr scripting_gchandle_get_target(int handle)
+{
+ return (ScriptingObjectPtr) handle;
+}
+
+int scripting_gc_maxgeneration()
+{
+ return 0;
+}
+
+void scripting_gc_collect(int maxGeneration)
+{
+ FatalErrorMsg("ToDo");
+}
+
+void ScriptingMethod::Init(const char* name, const char* mappedName, const char* sig, ScriptingClass* klass)
+{
+ m_Name = strcpy(new char[strlen(name) + 1],name);
+ m_Mappedname = strcpy(new char[strlen(mappedName) + 1],mappedName);
+ __asm __volatile__("%0 = getAS3StringForPtr(%1);\n" : "=r" (m_As3String) : "r" (m_Mappedname));
+
+ m_Signature = strcpy(new char[strlen(sig) + 1],sig);
+ m_Class = klass;
+ m_MethodInfo = NULL;
+ FLASH_ASM_WITH_NEWSP("%0 = marshallmap.getIdForObject(System.Type.ForClass(marshallmap.getObjectWithId(%1)));\n" : "=r" (m_SystemType) : "r"(m_Class) );
+ scripting_gchandle_new(m_SystemType);
+}
+
+extern "C" const char* Ext_GetMappedMethodName(const char* name, ScriptingType* klass);
+ScriptingMethod::ScriptingMethod(const char* name, ScriptingClass* klass)
+{
+ const char* mappedName = Ext_GetMappedMethodName(name,klass);
+ Init(name,mappedName,"",klass);
+}
+
+ScriptingMethod::ScriptingMethod(const char* name, const char* mappedName, const char* sig, ScriptingClass* klass)
+{
+ Init(name,mappedName,sig,klass);
+}
+
+extern "C" ScriptingClass* Ext_Flash_GetMethodReturnType(const char* methodname, ScriptingClass* klass);
+ScriptingClass* ScriptingMethod::GetReturnType()
+{
+ return Ext_Flash_GetMethodReturnType(m_Mappedname, m_Class);
+}
+
+ScriptingObjectPtr ScriptingMethod::GetSystemReflectionMethodInfo()
+{
+ if (m_MethodInfo)
+ return m_MethodInfo;
+
+ FLASH_ASM_WITH_NEWSP("%0 = marshallmap.getIdForObject(ScriptingMethodHelper.GetMethodInfo(marshallmap.getObjectWithId(%1), strFromPtr(%2)));" : "=r"(m_MethodInfo) : "r"(m_SystemType),"r"(m_Name) );
+
+ scripting_gchandle_new(m_MethodInfo);
+ return m_MethodInfo;
+}
+
+ScriptingObjectPtr scripting_class_get_object(ScriptingClassPtr klass)
+{
+ FatalErrorMsg("ToDo");
+ return SCRIPTING_NULL;
+}
+
+ScriptingArrayPtr scripting_cast_object_to_array(ScriptingObjectPtr o)
+{
+ FatalErrorMsg("ToDo");
+ return SCRIPTING_NULL;
+}
+
+void scripting_stack_trace_info_for(ScriptingExceptionPtr exception, StackTraceInfo& info)
+{
+ AssertIf (exception == NULL);
+
+ __asm __volatile__("var errorStr:String = marshallmap.getObjectWithId(%0) as String;"::"r"(exception));
+ int length;
+ __asm __volatile__("%0=getStringMarshallingLength(errorStr);":"=r"(length));
+ char* errorStrPtr = (char*)alloca(length);
+ __asm __volatile__("var ptr:int = placeStringAtPtr(errorStr,%0);"::"r"(errorStrPtr));
+
+ info.condition = errorStrPtr;
+ info.strippedStacktrace = "";
+ info.stacktrace = "";
+ info.errorNum = 0;
+ info.file = "";
+ info.line = 0;
+}
+
+void* scripting_array_element_ptr(ScriptingArrayPtr array, int i, size_t element_size)
+{
+ return (UInt8*)array + sizeof(int) + i * element_size;
+} \ No newline at end of file
diff --git a/Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.h b/Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.h
new file mode 100644
index 0000000..c2372a2
--- /dev/null
+++ b/Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.h
@@ -0,0 +1,45 @@
+#ifndef _SCRIPTINGBACKENDAPI_FLASH_H_
+#define _SCRIPTINGBACKENDAPI_FLASH_H_
+
+#include <string>
+
+#include "../ScriptingTypes.h"
+#include "../ScriptingBackendApi.h"
+
+//todo: remove
+typedef ScriptingObject* (*FastMonoMethod) (void* thiz, ScriptingException** ex);
+typedef int AS3String;
+
+struct ScriptingMethod
+{
+ const char* m_Name;
+ const char* m_Mappedname;
+ const char* m_Signature;
+ AS3String m_As3String;
+
+ ScriptingClass* m_Class;
+ ScriptingObject* m_SystemType;
+ ScriptingObject* m_MethodInfo;
+
+ ScriptingMethod(const char* name, ScriptingClass* klass);
+ ScriptingMethod(const char* name, const char* mappedName, const char* sig, ScriptingClass* klass);
+ void Init(const char* name, const char* mappedName, const char* sig, ScriptingClass* klass);
+ ScriptingClass* GetReturnType();
+ const char* GetName() { return m_Name; }
+ ScriptingObjectPtr GetSystemReflectionMethodInfo();
+};
+
+struct ScriptingField
+{
+ ScriptingField(const char* name,const char* type)
+ : m_name(name)
+ , m_type(type)
+ {
+
+ }
+
+ std::string m_name;
+ std::string m_type;
+};
+
+#endif
diff --git a/Runtime/Scripting/Backend/Flash/ScriptingMethodFactory_Flash.h b/Runtime/Scripting/Backend/Flash/ScriptingMethodFactory_Flash.h
new file mode 100644
index 0000000..35b7015
--- /dev/null
+++ b/Runtime/Scripting/Backend/Flash/ScriptingMethodFactory_Flash.h
@@ -0,0 +1,40 @@
+#ifndef _SCRIPTINGMETHODFACTORY_FLASH_
+#define _SCRIPTINGMETHODFACTORY_FLASH_
+
+#include "../ScriptingMethodFactory.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "ScriptingBackendApi_Flash.h"
+
+#if UNITY_FLASH
+
+extern "C" const char* Ext_GetMappedMethodName(const char* name, ScriptingType* klass);
+
+class ScriptingMethodFactory_Flash : public IScriptingMethodFactory
+{
+public:
+ virtual ScriptingMethodPtr Produce(ScriptingTypePtr klass, const char* name, int searchFilter)
+ {
+ //todo: respect the searchfilter
+ std::string mappedName(Ext_GetMappedMethodName(name,klass));
+
+ //remove this hack when interfaces contain mapping information
+ if (mappedName.size()==0 && strcmp(name,"MoveNext")==0)
+ mappedName.assign("IEnumerator_MoveNext");
+ return new ScriptingMethod(name, mappedName.c_str(), "",klass);
+ }
+
+ virtual ScriptingMethodPtr Produce(void* nativeMethod)
+ {
+ //not implemented for flash.
+ return NULL;
+ }
+
+ virtual void Release(ScriptingMethodPtr method)
+ {
+ delete method;
+ }
+};
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/Flash/ScriptingTypeProvider_Flash.h b/Runtime/Scripting/Backend/Flash/ScriptingTypeProvider_Flash.h
new file mode 100644
index 0000000..eb2142c
--- /dev/null
+++ b/Runtime/Scripting/Backend/Flash/ScriptingTypeProvider_Flash.h
@@ -0,0 +1,53 @@
+#ifndef _SCRIPTINGTYPEPROVIDER_FLASH
+#define _SCRIPTINGTYPEPROVIDER_FLASH
+
+#include "../IScriptingTypeProvider.h"
+//#include "Runtime/Scripting/ScriptingUtility.h"
+
+#if UNITY_FLASH
+
+extern "C" ScriptingTypePtr Ext_Flash_GetScriptingTypeFromName(const char* name);
+
+class ScriptingTypeProvider_Flash : public IScriptingTypeProvider
+{
+public:
+ virtual BackendNativeType NativeTypeFor(const char* namespaze, const char* name)
+ {
+ if (strcmp(name,"Object") == 0)
+ name = "_Object";
+
+ if (strcmp(namespaze,"System")==0)
+ {
+ if (strcmp(name,"String")==0)
+ return Ext_Flash_GetScriptingTypeFromName("String");
+ if (strcmp(name,"Int32")==0)
+ return Ext_Flash_GetScriptingTypeFromName("int");
+ if (strcmp(name,"Single")==0)
+ return Ext_Flash_GetScriptingTypeFromName("Number");
+ if (strcmp(name,"Double")==0)
+ return Ext_Flash_GetScriptingTypeFromName("Number");
+ if (strcmp(name,"Byte")==0)
+ return Ext_Flash_GetScriptingTypeFromName("int");
+ }
+
+ std::string combined(namespaze);
+ if (combined.size() > 0)
+ combined+=".";
+ combined+=name;
+
+ return Ext_Flash_GetScriptingTypeFromName(combined.c_str());
+ }
+
+ virtual ScriptingTypePtr Provide(BackendNativeType nativePtr)
+ {
+ return (ScriptingTypePtr)nativePtr;
+ }
+
+ virtual void Release(ScriptingTypePtr t)
+ {
+ }
+};
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/IScriptingTypeProvider.h b/Runtime/Scripting/Backend/IScriptingTypeProvider.h
new file mode 100644
index 0000000..c8a9fe7
--- /dev/null
+++ b/Runtime/Scripting/Backend/IScriptingTypeProvider.h
@@ -0,0 +1,16 @@
+#ifndef _ISCRIPTINGTYPEPROVIDER_H_
+#define _ISCRIPTINGTYPEPROVIDER_H_
+
+#include "ScriptingTypes.h"
+#include "Runtime/Modules/ExportModules.h"
+
+class EXPORT_COREMODULE IScriptingTypeProvider
+{
+public:
+ virtual ~IScriptingTypeProvider() {}
+ virtual BackendNativeType NativeTypeFor(const char* namespaze, const char* name) = 0;
+ virtual ScriptingTypePtr Provide(BackendNativeType nativeType) = 0;
+ virtual void Release(ScriptingTypePtr t) = 0;
+};
+
+#endif
diff --git a/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.cpp b/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.cpp
new file mode 100644
index 0000000..b27269b
--- /dev/null
+++ b/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.cpp
@@ -0,0 +1,280 @@
+#include "UnityPrefix.h"
+
+#include "../ScriptingTypes.h"
+#include "Runtime/Mono/MonoIncludes.h"
+#include "ScriptingBackendApi_Mono.h"
+#include "../ScriptingMethodRegistry.h"
+#include "../ScriptingTypeRegistry.h"
+#include "Runtime/Scripting/ScriptingUtility.h" //required for ExtractMonoobjectData, todo: see if we can remove that.
+
+std::string scripting_cpp_string_for(ScriptingStringPtr str)
+{
+ return MonoStringToCpp(str);
+}
+
+bool scripting_method_is_instance(ScriptingMethodPtr method)
+{
+ return method->isInstance;
+}
+
+const char* scripting_method_get_name(ScriptingMethodPtr method)
+{
+ return mono_method_get_name(method->monoMethod);
+}
+
+int scripting_method_get_argument_count(ScriptingMethodPtr method, ScriptingTypeRegistry& typeRegistry)
+{
+ MonoMethodSignature* sig = mono_method_signature(method->monoMethod);
+ Assert(sig);
+ return mono_signature_get_param_count(sig);
+}
+
+ScriptingTypePtr scripting_method_get_returntype(ScriptingMethodPtr method, ScriptingTypeRegistry& registry)
+{
+ MonoMethodSignature* sig = mono_method_signature (method->monoMethod);
+ MonoType* returnType = mono_signature_get_return_type (sig);
+ if (returnType == NULL)
+ return NULL;
+
+ return mono_class_from_mono_type (returnType);
+}
+
+ScriptingTypePtr scripting_method_get_nth_argumenttype(ScriptingMethodPtr method, int index, ScriptingTypeRegistry& typeRegistry)
+{
+ MonoMethodSignature* sig = mono_method_signature (method->monoMethod);
+ void* iterator = NULL;
+ MonoType* type = mono_signature_get_params (sig, &iterator);
+ if (type == NULL)
+ return NULL;
+ MonoClass* methodClass = mono_class_from_mono_type (type);
+ return typeRegistry.GetType(methodClass);
+}
+
+bool scripting_method_has_attribute(ScriptingMethodPtr method, ScriptingClassPtr attribute)
+{
+ bool hasAttribute = false;
+ MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method (method->monoMethod);
+ if (attrInfo != NULL && mono_custom_attrs_has_attr (attrInfo, attribute))
+ hasAttribute = true;
+
+ if (attrInfo)
+ mono_custom_attrs_free(attrInfo);
+
+ return hasAttribute;
+}
+
+ScriptingTypePtr scripting_class_get_parent(ScriptingTypePtr t, ScriptingTypeRegistry& registry)
+{
+ return mono_class_get_parent(t);
+}
+
+void scripting_class_get_methods(ScriptingTypePtr t, ScriptingMethodRegistry& registry, std::vector<ScriptingMethodPtr>& result)
+{
+ void* iterator = NULL;
+ ScriptingMethodPtr scriptingMethod = NULL;
+ while (MonoMethod* method = mono_class_get_methods(t, &iterator))
+ if ((scriptingMethod = registry.GetMethod (method)))
+ result.push_back(scriptingMethod);
+}
+
+ScriptingTypePtr scripting_class_from_systemtypeinstance(ScriptingObjectPtr systemTypeInstance, ScriptingTypeRegistry& typeRegistry)
+{
+ if (!systemTypeInstance)
+ return NULL;
+
+ MonoClass* klass = mono_class_from_mono_type(ExtractMonoObjectData<MonoType*>(systemTypeInstance));
+ return typeRegistry.GetType(klass);
+}
+
+const char* scripting_class_get_name(ScriptingClassPtr klass)
+{
+ return mono_class_get_name(klass);
+}
+
+const char* scripting_class_get_namespace(ScriptingClassPtr klass)
+{
+ return mono_class_get_namespace(klass);
+}
+
+bool scripting_class_is_subclass_of(ScriptingClassPtr c1, ScriptingClassPtr c2)
+{
+ return mono_class_is_subclass_of(c1,c2,true);
+}
+
+bool scripting_class_is_enum(ScriptingClassPtr klass)
+{
+ return mono_class_is_enum (klass);
+}
+
+ScriptingTypePtr scripting_object_get_class(ScriptingObjectPtr t, ScriptingTypeRegistry& registry)
+{
+ return mono_object_get_class(t);
+}
+
+void scripting_object_invoke_default_constructor(ScriptingObjectPtr t, ScriptingExceptionPtr* exc)
+{
+ mono_runtime_object_init_exception(t,exc);
+}
+
+ScriptingMethodPtr scripting_object_get_virtual_method(ScriptingObjectPtr o, ScriptingMethodPtr method, ScriptingMethodRegistry& methodRegistry)
+{
+ return methodRegistry.GetMethod(mono_object_get_virtual_method(o,method->monoMethod));
+}
+
+ScriptingObjectPtr scripting_object_new(ScriptingTypePtr t)
+{
+#if UNITY_EDITOR
+ if (mono_unity_class_is_abstract (t)) {
+ // Cannot instantiate abstract class
+ return SCRIPTING_NULL;
+ }
+#endif
+ return mono_object_new(mono_domain_get(), t);
+}
+
+int scripting_gchandle_new(ScriptingObjectPtr o)
+{
+ return mono_gchandle_new(o,1);
+}
+
+int scripting_gchandle_weak_new(ScriptingObjectPtr o)
+{
+ return mono_gchandle_new_weakref(o, 1);
+}
+
+void scripting_gchandle_free(int handle)
+{
+ mono_gchandle_free(handle);
+}
+
+ScriptingObjectPtr scripting_gchandle_get_target(int handle)
+{
+ return mono_gchandle_get_target(handle);
+}
+
+int scripting_gc_maxgeneration()
+{
+ return mono_gc_max_generation();
+}
+
+void scripting_gc_collect(int maxGeneration)
+{
+ mono_gc_collect(maxGeneration);
+}
+
+ScriptingObjectPtr scripting_method_invoke(ScriptingMethodPtr method, ScriptingObjectPtr object, ScriptingArguments& arguments, ScriptingExceptionPtr* exception)
+{
+#if UNITY_EDITOR
+ bool IsStackLargeEnough ();
+ if (!IsStackLargeEnough ())
+ {
+ *exception = mono_exception_from_name_msg (mono_get_corlib (), "System", "StackOverflowException", "");
+ return NULL;
+ }
+#endif
+
+ if (method->fastMonoMethod)
+ {
+ Assert(arguments.GetCount()==0);
+ Assert(object);
+ return method->fastMonoMethod(object,exception);
+ }
+
+ return mono_runtime_invoke(method->monoMethod, object, arguments.InMonoFormat(), exception);
+}
+
+ScriptingObjectPtr scripting_class_get_object(ScriptingClassPtr klass)
+{
+ return mono_class_get_object(klass);
+}
+
+ScriptingArrayPtr scripting_cast_object_to_array(ScriptingObjectPtr o)
+{
+ return (ScriptingArrayPtr)o;
+}
+
+ScriptingStringPtr scripting_string_new(const std::string& str)
+{
+ return scripting_string_new(str.c_str());
+}
+
+ScriptingStringPtr scripting_string_new(const UnityStr& str)
+{
+ return scripting_string_new(str.c_str());
+}
+
+ScriptingStringPtr scripting_string_new(const char* str)
+{
+ return MonoStringNew(str);
+}
+
+ScriptingStringPtr scripting_string_new(const wchar_t* str)
+{
+ return MonoStringNewUTF16(str);
+}
+
+ScriptingStringPtr scripting_string_new(const char* str, unsigned int length)
+{
+ return MonoStringNewLength(str, length);
+}
+
+void scripting_stack_trace_info_for(ScriptingExceptionPtr exception, StackTraceInfo& info)
+{
+ AssertIf (exception == NULL);
+
+ MonoException* tempException = NULL;
+ MonoString* monoStringMessage = NULL;
+ MonoString* monoStringTrace = NULL;
+ void* args[] = { exception, &monoStringMessage, &monoStringTrace };
+
+ if (GetMonoManagerPtr () && GetMonoManager ().GetCommonClasses ().extractStringFromException)
+ {
+ // Call mono_runtime_invoke directly to avoid our stack size check in mono_runtime_invoke_profiled.
+ // We *should* have enough stack here to make this call, and a stack trace would be useful for the user.
+ mono_runtime_invoke (GetMonoManager ().GetCommonClasses ().extractStringFromException->monoMethod, (MonoObject*)exception, args, &tempException);
+ }
+
+ if (tempException)
+ {
+ char const* exceptionClassName = mono_class_get_name(mono_object_get_class((MonoObject*)tempException));
+ ErrorString ("Couldn't extract exception string from exception (another exception of class '"
+ + std::string (exceptionClassName) + "' was thrown while processing the stack trace)");
+ return;
+ }
+
+ // Log returned string
+ string message;
+
+ char* extractedMessage = NULL;
+ if (monoStringMessage)
+ message = extractedMessage = mono_string_to_utf8 (monoStringMessage);
+
+ char* extractedTrace = NULL;
+ if (monoStringTrace)
+ extractedTrace = mono_string_to_utf8 (monoStringTrace);
+
+ string processedStackTrace;
+ int line = -1;
+ string path;
+
+ if (extractedTrace && *extractedTrace != 0)
+ {
+ PostprocessStacktrace(extractedTrace, processedStackTrace);
+ ExceptionToLineAndPath (processedStackTrace, line, path);
+ }
+
+ info.condition = message;
+ info.strippedStacktrace = processedStackTrace;
+ info.stacktrace = extractedTrace;
+ info.errorNum = 0;
+ info.file = path;
+ info.line = line;
+
+ g_free (extractedMessage);
+ g_free (extractedTrace);
+}
+
+void* scripting_array_element_ptr(ScriptingArrayPtr array, int i, size_t element_size)
+{
+ return kMonoArrayOffset + i * element_size + (char*)array;
+} \ No newline at end of file
diff --git a/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.h b/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.h
new file mode 100644
index 0000000..e6ae12a
--- /dev/null
+++ b/Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.h
@@ -0,0 +1,15 @@
+#ifndef _SCRIPTINGBACKENDAPI_MONO_H_
+#define _SCRIPTINGBACKENDAPI_MONO_H_
+
+#include "../ScriptingTypes.h"
+
+typedef MonoObject* (*FastMonoMethod) (void* thiz, MonoException** ex);
+
+struct ScriptingMethod
+{
+ MonoMethod* monoMethod;
+ FastMonoMethod fastMonoMethod;
+ bool isInstance;
+};
+
+#endif
diff --git a/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h b/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h
new file mode 100644
index 0000000..a7519f8
--- /dev/null
+++ b/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h
@@ -0,0 +1,83 @@
+#ifndef _SCRIPTINGMETHODFACTORY_MONO_
+#define _SCRIPTINGMETHODFACTORY_MONO_
+
+#include "../ScriptingMethodFactory.h"
+#include "Runtime/Mono/MonoIncludes.h"
+#include "../ScriptingMethodRegistry.h"
+#if ENABLE_MONO
+
+
+// Flag defined in mono, when AOT libraries are built with -ficall option
+// But that is not available in mono/consoles
+extern "C" int mono_ficall_flag;
+
+FastMonoMethod FastMonoMethodPtrFor(MonoMethod* method)
+{
+#if USE_MONO_AOT && !(UNITY_XENON || UNITY_PS3)
+ return mono_ficall_flag && method ? (FastMonoMethod) mono_aot_get_method(mono_domain_get(), method) : NULL;
+#else
+ return NULL;
+#endif
+}
+
+static bool MethodMatchesSearchFilter(MonoMethod* method, int searchFilter)
+{
+ MonoMethodSignature* sig = mono_method_signature(method);
+ return MethodDescriptionMatchesSearchFilter(searchFilter, mono_signature_is_instance(sig), mono_signature_get_param_count(sig));
+}
+
+class ScriptingMethodFactory_Mono : public IScriptingMethodFactory
+{
+public:
+ virtual ScriptingMethodPtr Produce(ScriptingTypePtr klass, const char* name, int searchFilter)
+ {
+ void* iterator = NULL;
+ while (MonoMethod* method = mono_class_get_methods(klass, &iterator))
+ {
+ if (!method)
+ return NULL;
+
+ if (strcmp(mono_method_get_name(method), name)!=0)
+ continue;
+
+ if (MethodMatchesSearchFilter(method,searchFilter))
+ return Produce(method);
+ }
+ return NULL;
+ }
+
+ virtual ScriptingMethodPtr Produce(BackendNativeMethod nativeMethod)
+ {
+ ScriptingMethodPtr result = new ScriptingMethod();
+ result->monoMethod = nativeMethod;
+ MonoMethodSignature* sig = mono_method_signature(nativeMethod);
+#if UNITY_EDITOR
+ if (!sig) {
+ // Loader error - usually missing reference
+ Scripting::LogException(mono_loader_error_prepare_exception (mono_loader_get_last_error ()), 0);
+ return NULL;
+ }
+#endif
+ result->isInstance = mono_signature_is_instance(sig);
+ result->fastMonoMethod = IsSignatureSupportedForFastAotCalls(sig) ? FastMonoMethodPtrFor(nativeMethod) : NULL;
+ return result;
+ }
+
+ virtual void Release(ScriptingMethodPtr method)
+ {
+ delete method;
+ }
+
+private:
+ bool IsSignatureSupportedForFastAotCalls(MonoMethodSignature* sig)
+ {
+ if (!mono_signature_is_instance(sig))
+ return false;
+
+ return mono_signature_get_param_count(sig) == 0;
+ }
+};
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingArguments.cpp b/Runtime/Scripting/Backend/ScriptingArguments.cpp
new file mode 100644
index 0000000..9fcbaad
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingArguments.cpp
@@ -0,0 +1,218 @@
+#include "UnityPrefix.h"
+#include "ScriptingTypes.h"
+
+#if ENABLE_SCRIPTING
+
+#include "ScriptingArguments.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+
+ScriptingArguments::ScriptingArguments()
+ : m_Count(0)
+{
+#if UNITY_WINRT
+ m_StringArguments = ref new Platform::Array<Platform::String^>(MAXARGS);
+#else
+ memset(m_Arguments, 0, sizeof(m_Arguments));
+#endif
+ memset(&m_PrimitiveStorage, 0, sizeof(m_PrimitiveStorage));
+ memset(m_ArgumentTypes, 0, sizeof(m_ArgumentTypes));
+}
+
+void ScriptingArguments::AddBoolean(bool value)
+{
+ m_PrimitiveStorage.ints[m_Count] = value ? 1 : 0;
+#if UNITY_WINRT
+ m_Arguments[m_Count] = m_PrimitiveStorage.ints[m_Count];
+#else
+ m_Arguments[m_Count] = &m_PrimitiveStorage.ints[m_Count];
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_BOOLEAN;
+ m_Count++;
+}
+
+void ScriptingArguments::AddInt(int value)
+{
+ m_PrimitiveStorage.ints[m_Count] = value;
+#if UNITY_WINRT
+ m_Arguments[m_Count] = *(long long*)&value;
+#else
+ m_Arguments[m_Count] = &m_PrimitiveStorage.ints[m_Count];
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_INT;
+ m_Count++;
+}
+
+void ScriptingArguments::AddFloat(float value)
+{
+ m_PrimitiveStorage.floats[m_Count] = value;
+#if UNITY_WINRT
+ m_Arguments[m_Count] = *(long long*)&value;
+#else
+ m_Arguments[m_Count] = &m_PrimitiveStorage.floats[m_Count];
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_FLOAT;
+ m_Count++;
+}
+
+void ScriptingArguments::AddString(const char* str)
+{
+#if ENABLE_MONO
+ m_Arguments[m_Count] = MonoStringNew(str);
+#elif UNITY_FLASH
+ m_Arguments[m_Count] = str;
+#elif UNITY_WINRT
+ m_StringArguments[m_Count] = ConvertUtf8ToString(str);
+ m_Arguments[m_Count] = (long long)m_StringArguments[m_Count]->Data();
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_STRING;
+ m_Count++;
+}
+
+void ScriptingArguments::AddString(std::string& str)
+{
+ AddString(str.c_str());
+}
+
+void ScriptingArguments::AddObject(ScriptingObjectPtr scriptingObject)
+{
+#if UNITY_WINRT
+ m_Arguments[m_Count] = scriptingObject.GetHandle();
+#else
+ m_Arguments[m_Count] = scriptingObject;
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_OBJECT;
+ m_Count++;
+}
+
+void ScriptingArguments::AddStruct(void* pointerToStruct)
+{
+#if UNITY_WINRT
+ // We need to pass struct size, and ScriptingType here, to set the struct for metro
+ FatalErrorMsg("ToDo");
+#else
+ m_Arguments[m_Count] = pointerToStruct;
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_STRUCT;
+ m_Count++;
+}
+
+void ScriptingArguments::AddArray(ScriptingArrayPtr arr)
+{
+#if UNITY_WINRT
+ m_Arguments[m_Count] = arr.GetHandle();
+#elif UNITY_FLASH
+ FatalErrorMsg("ToDo");
+#else
+ m_Arguments[m_Count] = arr;
+#endif
+ m_ArgumentTypes[m_Count] = ARGTYPE_ARRAY;
+ m_Count++;
+}
+
+void ScriptingArguments::AddEnum(int value)
+{
+ AddInt(value);
+ m_ArgumentTypes[m_Count-1] = ARGTYPE_ENUM;
+}
+
+bool ScriptingArguments::GetBooleanAt(int index)
+{
+ return m_PrimitiveStorage.ints[index] == 1;
+}
+
+int ScriptingArguments::GetIntAt(int index)
+{
+ return m_PrimitiveStorage.ints[index];
+}
+
+float ScriptingArguments::GetFloatAt(int index)
+{
+ return m_PrimitiveStorage.floats[index];
+}
+
+const void* ScriptingArguments::GetStringAt(int index)
+{
+#if UNITY_WINRT
+ return m_StringArguments[index]->Data();
+#else
+ return m_Arguments[index];
+#endif
+}
+
+ScriptingObjectPtr ScriptingArguments::GetObjectAt(int index)
+{
+#if UNITY_WINRT
+ return ScriptingObjectPtr(safe_cast<long long>(m_Arguments[index]));
+#else
+ return (ScriptingObjectPtr) m_Arguments[index];
+#endif
+}
+
+void** ScriptingArguments::InMonoFormat()
+{
+ return (void**) &m_Arguments[0];
+}
+
+int ScriptingArguments::GetTypeAt(int index)
+{
+ return m_ArgumentTypes[index];
+}
+
+int ScriptingArguments::GetCount()
+{
+ return m_Count;
+}
+
+void ScriptingArguments::AdjustArgumentsToMatchMethod(ScriptingMethodPtr method)
+{
+#if ENABLE_MONO
+ MonoMethodSignature* sig = mono_method_signature (method->monoMethod);
+ int methodCount = mono_signature_get_param_count (sig);
+ if (methodCount < m_Count)
+ m_Count = methodCount;
+#endif
+}
+
+bool ScriptingArguments::CheckArgumentsAgainstMethod(ScriptingMethodPtr method)
+{
+#if !ENABLE_MONO
+ return true;
+#else
+
+ MonoMethodSignature* sig = mono_method_signature (method->monoMethod);
+ int argCount = mono_signature_get_param_count (sig);
+ if (argCount != GetCount())
+ return false;
+
+ void* iterator = NULL;
+ int argIndex = -1;
+ while(true)
+ {
+ argIndex++;
+ MonoType* methodType = mono_signature_get_params (sig, &iterator);
+ if (methodType == NULL)
+ return true;
+
+ if (GetTypeAt(argIndex) != ScriptingArguments::ARGTYPE_OBJECT)
+ continue;
+
+ MonoClass* invokingArgument = mono_object_get_class(GetObjectAt(argIndex));
+ MonoClass* receivingArgument = mono_class_from_mono_type (methodType);
+
+ if (!mono_class_is_subclass_of (invokingArgument, receivingArgument, false))
+ return false;
+ }
+ return true;
+#endif
+}
+
+
+#if UNITY_WINRT
+ScriptingParamsPtr ScriptingArguments::InMetroFormat()
+{
+ if (m_Count <= 0) return SCRIPTING_NULL;
+ return &m_Arguments[0];
+}
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingArguments.h b/Runtime/Scripting/Backend/ScriptingArguments.h
new file mode 100644
index 0000000..9ea823f
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingArguments.h
@@ -0,0 +1,79 @@
+#ifndef _SCRIPTINGARGUMENTS_H_
+#define _SCRIPTINGARGUMENTS_H_
+
+#if ENABLE_SCRIPTING
+#include "ScriptingTypes.h"
+#include <string>
+#include "Runtime/Modules/ExportModules.h"
+
+
+struct EXPORT_COREMODULE ScriptingArguments
+{
+ enum Constants
+ {
+ MAXARGS=10
+ };
+
+ enum ArgType
+ {
+ ARGTYPE_BOOLEAN,
+ ARGTYPE_INT,
+ ARGTYPE_FLOAT,
+ ARGTYPE_STRING,
+ ARGTYPE_OBJECT,
+ ARGTYPE_STRUCT,
+ ARGTYPE_ARRAY,
+ ARGTYPE_ENUM
+ };
+
+ //this setup is kind of weird. some types of arguments just need to be stuffed in m_Arguments,
+ //however for ints and floats, instead of stuffing them in, mono actually excepts a pointer to one.
+ //to make it happy, we store the actual int in a field, and store a pointer to it in the ScriptingParam.
+ union
+ {
+ int ints[MAXARGS];
+ float floats[MAXARGS];
+ } m_PrimitiveStorage;
+
+#if UNITY_WINRT
+ Platform::Array<Platform::String^>^ m_StringArguments;
+ ScriptingParams m_Arguments[MAXARGS];
+#else
+ const void* m_Arguments[MAXARGS];
+#endif
+ int m_ArgumentTypes[MAXARGS];
+ int m_Count;
+
+ ScriptingArguments();
+
+ void AddBoolean(bool value);
+ void AddInt(int value);
+ void AddFloat(float value);
+ void AddString(const char* str);
+ void AddString(std::string& str);
+ void AddObject(ScriptingObjectPtr scriptingObject);
+ void AddStruct(void* pointerToStruct);
+ void AddEnum(int value);
+ void AddArray(ScriptingArrayPtr arr);
+
+ bool GetBooleanAt(int index);
+ int GetIntAt(int index);
+ float GetFloatAt(int index);
+ const void* GetStringAt(int index);
+ ScriptingObjectPtr GetObjectAt(int index);
+
+ void** InMonoFormat();
+
+ void AdjustArgumentsToMatchMethod(ScriptingMethodPtr method);
+ bool CheckArgumentsAgainstMethod(ScriptingMethodPtr method);
+#if UNITY_WINRT
+ ScriptingParamsPtr InMetroFormat();
+#endif
+
+ int GetTypeAt(int index);
+ int GetCount();
+};
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingBackendApi.h b/Runtime/Scripting/Backend/ScriptingBackendApi.h
new file mode 100644
index 0000000..1e729b7
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingBackendApi.h
@@ -0,0 +1,72 @@
+#ifndef _SCRIPTINGBACKEND_API_H_
+#define _SCRIPTINGBACKEND_API_H_
+
+#include <string>
+
+#include "ScriptingTypes.h"
+class ScriptingMethodRegistry;
+class ScriptingTypeRegistry;
+struct ScriptingArguments;
+
+struct StackTraceInfo
+{
+ std::string condition;
+ std::string strippedStacktrace;
+ std::string stacktrace;
+ int errorNum;
+ std::string file;
+ int line;
+};
+
+bool scripting_method_is_instance(ScriptingMethodPtr method);
+const char* scripting_method_get_name(ScriptingMethodPtr method);
+int scripting_method_get_argument_count(ScriptingMethodPtr method, ScriptingTypeRegistry& typeRegistry);
+ScriptingTypePtr scripting_method_get_returntype(ScriptingMethodPtr method, ScriptingTypeRegistry& typeRegistry);
+bool scripting_method_has_attribute(ScriptingMethodPtr method, ScriptingClassPtr attribute);
+ScriptingTypePtr scripting_method_get_nth_argumenttype(ScriptingMethodPtr method, int index, ScriptingTypeRegistry& typeRegistry);
+ScriptingObjectPtr scripting_method_invoke(ScriptingMethodPtr method, ScriptingObjectPtr object, ScriptingArguments& arguments, ScriptingExceptionPtr* exception);
+
+ScriptingTypePtr scripting_class_get_parent(ScriptingTypePtr t, ScriptingTypeRegistry& typeRegistry);
+void scripting_class_get_methods(ScriptingTypePtr t, ScriptingMethodRegistry& registry, std::vector<ScriptingMethodPtr>& result);
+const char* scripting_class_get_name(ScriptingTypePtr t);
+const char* scripting_class_get_namespace(ScriptingTypePtr t);
+bool scripting_class_is_subclass_of(ScriptingTypePtr t1, ScriptingTypePtr t2);
+bool scripting_class_is_enum(ScriptingTypePtr t);
+ScriptingObjectPtr scripting_object_new(ScriptingTypePtr t);
+void scripting_object_invoke_default_constructor(ScriptingObjectPtr o, ScriptingExceptionPtr* exc);
+ScriptingTypePtr scripting_object_get_class(ScriptingObjectPtr t, ScriptingTypeRegistry& typeRegistry);
+ScriptingMethodPtr scripting_object_get_virtual_method(ScriptingObjectPtr o, ScriptingMethodPtr method, ScriptingMethodRegistry& methodRegistry);
+
+ScriptingTypePtr scripting_class_from_systemtypeinstance(ScriptingObjectPtr systemTypeInstance, ScriptingTypeRegistry& typeRegistry);
+
+EXPORT_COREMODULE int scripting_gchandle_new(ScriptingObjectPtr o);
+EXPORT_COREMODULE int scripting_gchandle_weak_new(ScriptingObjectPtr o);
+EXPORT_COREMODULE void scripting_gchandle_free(int handle);
+EXPORT_COREMODULE ScriptingObjectPtr scripting_gchandle_get_target(int handle);
+
+int scripting_gc_maxgeneration();
+void scripting_gc_collect(int maxGeneration);
+
+ScriptingObjectPtr scripting_class_get_object(ScriptingClassPtr klass);
+ScriptingArrayPtr scripting_cast_object_to_array(ScriptingObjectPtr o);
+
+ScriptingStringPtr scripting_string_new(const char* str);
+ScriptingStringPtr scripting_string_new(const std::string& str);
+ScriptingStringPtr scripting_string_new(const wchar_t* str);
+ScriptingStringPtr scripting_string_new(const char* str, unsigned int length);
+
+void scripting_stack_trace_info_for(ScriptingExceptionPtr exception, StackTraceInfo& info);
+EXPORT_COREMODULE std::string scripting_cpp_string_for(ScriptingStringPtr ptr);
+
+void* scripting_array_element_ptr(ScriptingArrayPtr array, int i, size_t element_size);
+
+// TODO: temporary, these includes are going to disappear very soon
+
+#if UNITY_FLASH
+#include "Runtime/Scripting/Backend/Flash/ScriptingBackendApi_Flash.h"
+#elif UNITY_WINRT
+#elif ENABLE_MONO
+#include "Runtime/Scripting/Backend/Mono/ScriptingBackendApi_Mono.h"
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingInvocation.cpp b/Runtime/Scripting/Backend/ScriptingInvocation.cpp
new file mode 100644
index 0000000..71ead05
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingInvocation.cpp
@@ -0,0 +1,223 @@
+#include "UnityPrefix.h"
+
+#if ENABLE_SCRIPTING
+
+#include "ScriptingInvocation.h"
+#include "Runtime/Utilities/LogAssert.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "ScriptingArguments.h"
+#include "ScriptingMethodRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+#include "Runtime/Profiler/Profiler.h"
+#include "Runtime/Scripting/ScriptingManager.h"
+
+#if ENABLE_MONO
+#include "Runtime/Mono/MonoIncludes.h"
+#include "Runtime/Mono/MonoManager.h"
+#include "Runtime/Mono/MonoUtility.h"
+#include "Runtime/Mono/MonoScript.h"
+#endif
+
+ScriptingInvocation::ScriptingInvocation()
+{
+}
+
+ScriptingInvocation::ScriptingInvocation(ScriptingMethodPtr in_method)
+ : ScriptingInvocationNoArgs(in_method)
+{
+}
+
+#if ENABLE_MONO || UNITY_WINRT
+ScriptingInvocation::ScriptingInvocation(const char* namespaze, const char* klassName, const char* methodName)
+{
+ method = GetScriptingMethodRegistry().GetMethod(namespaze, klassName, methodName);
+}
+
+ScriptingInvocation::ScriptingInvocation(ScriptingClassPtr klass, const char* methodName)
+{
+ method = GetScriptingMethodRegistry().GetMethod(klass, methodName);
+}
+
+ScriptingInvocation::ScriptingInvocation(BackendNativeMethod monoMethod)
+{
+ method = GetScriptingMethodRegistry().GetMethod(monoMethod);
+}
+#endif
+
+bool ScriptingInvocation::Check()
+{
+#if !ENABLE_MONO
+ return true;
+#else
+ return ScriptingInvocationNoArgs::Check() && arguments.CheckArgumentsAgainstMethod(method);
+#endif
+}
+
+template<class T>
+T ScriptingInvocation::Invoke()
+{
+ ScriptingExceptionPtr ex = NULL;
+ return Invoke<T>(&ex);
+}
+
+template<>
+ScriptingObjectPtr ScriptingInvocation::Invoke<ScriptingObjectPtr>()
+{
+ return Invoke();
+}
+
+template<>
+bool ScriptingInvocation::Invoke<bool>(ScriptingExceptionPtr* exception)
+{
+ ScriptingObjectPtr o = Invoke(exception);
+ if (*exception != NULL)
+ return false;
+
+ #if ENABLE_MONO
+ if (method->fastMonoMethod)
+ return (bool)o;
+ else
+ return ExtractMonoObjectData<char>(o);
+ #elif UNITY_FLASH
+ bool boolResult;
+ __asm __volatile__("%0 = marshallmap.getObjectWithId(%1);" : "=r"(boolResult) : "r"(o));
+ return boolResult;
+ #elif UNITY_WINRT
+ return o != SCRIPTING_NULL ? o.ToBool() : false;
+ #endif
+}
+
+ScriptingObjectPtr ScriptingInvocation::Invoke()
+{
+ ScriptingExceptionPtr ex = NULL;
+ return Invoke(&ex);
+}
+
+ScriptingObjectPtr ScriptingInvocation::Invoke(ScriptingExceptionPtr* exception)
+{
+ return Invoke(exception, false);
+}
+
+ScriptingObjectPtr ScriptingInvocation::Invoke(ScriptingExceptionPtr* exception, bool convertArguments)
+{
+ ScriptingObjectPtr returnValue;
+
+ *exception = NULL;
+
+#if ENABLE_MONO || UNITY_FLASH || UNITY_WINRT
+ MONO_PROFILER_BEGIN (method, classContextForProfiler, object)
+#if UNITY_WINRT
+ ScriptingObjectPtr metro_invoke_method(ScriptingMethodPtr method, ScriptingObjectPtr object, ScriptingArguments* arguments, ScriptingExceptionPtr* exception, bool convertArgs);
+ returnValue = metro_invoke_method(method, object, &arguments, exception, convertArguments);
+#else
+ returnValue = scripting_method_invoke(method, object, arguments, exception);
+#endif
+ MONO_PROFILER_END
+#elif !UNITY_EXTERNAL_TOOL
+ ErrorString("Invoke() not implemented on this platform");
+#else
+ return NULL;
+#endif
+
+ if (! *exception) return returnValue;
+
+ this->exception = *exception;
+#if !UNITY_EXTERNAL_TOOL
+ if (logException)
+ Scripting::LogException(*exception, objectInstanceIDContextForException );
+#endif
+
+ return SCRIPTING_NULL;
+}
+
+void ScriptingInvocation::AdjustArgumentsToMatchMethod()
+{
+ arguments.AdjustArgumentsToMatchMethod(method);
+}
+
+
+#if ENABLE_MONO
+
+MonoObject* CallStaticMonoMethod (MonoClass* klass , const char* methodName, void** parameters)
+{
+ MonoException* exception = NULL;
+ return CallStaticMonoMethod(klass, methodName, parameters, &exception);
+}
+
+
+static MonoObject* CallStaticMonoMethod (MonoMethod* method, void** parameters, MonoException** exception)
+{
+ MonoObject* returnValue = mono_runtime_invoke_profiled (method, NULL, parameters, exception);
+ if (! *exception) return returnValue;
+
+ Scripting::LogException(*exception, 0);
+ return NULL;
+}
+
+
+static MonoObject* CallStaticMonoMethod (MonoMethod* method, void** parameters)
+{
+ MonoException* exception = NULL;
+ return CallStaticMonoMethod(method, parameters, &exception);
+}
+
+MonoObject* CallStaticMonoMethod (const char* className, const char* methodName, void** parameters)
+{
+ MonoException* exception = NULL;
+ return CallStaticMonoMethod(className, methodName, parameters, &exception);
+}
+
+MonoObject* CallStaticMonoMethod (MonoClass* klass , const char* methodName, void** parameters, MonoException** exception)
+{
+ MonoMethod* method = mono_class_get_method_from_name (klass, methodName, -1);
+
+ if (!method)
+ {
+ ErrorString (Format ("Couldn't call method %s in class %s because it wasn't found.", methodName, mono_class_get_name(klass)));
+ return NULL;
+ }
+
+ return CallStaticMonoMethod(method, parameters, exception);
+}
+
+MonoObject* CallStaticMonoMethod (const char* className, const char* methodName, void** parameters, MonoException** exception)
+{
+ MonoMethod* m = FindStaticMonoMethod(className, methodName);
+ if (!m)
+ {
+ ErrorString (Format ("Couldn't call method %s because the class %s couldn't be found.", methodName, className));
+ return NULL;
+ }
+
+ return CallStaticMonoMethod(m, parameters, exception);
+}
+
+MonoObject* CallStaticMonoMethod (const char* className, const char* nameSpace, const char* methodName, void** parameters)
+{
+ MonoException* exception = NULL;
+ MonoMethod* m = FindStaticMonoMethod(nameSpace, className, methodName);
+ if (!m)
+ {
+ ErrorString (Format ("Couldn't call method %s because the class %s couldn't be found.", methodName, className));
+ return NULL;
+ }
+
+ return CallStaticMonoMethod(m, parameters, &exception);
+}
+
+MonoObject* CallStaticMonoMethod (const char* className, const char* nameSpace, const char* methodName, void** parameters, MonoException** exception)
+{
+ MonoMethod* m = FindStaticMonoMethod(nameSpace, className, methodName);
+ if (!m)
+ {
+ ErrorString (Format ("Couldn't call method %s because the class %s couldn't be found.", methodName, className));
+ return NULL;
+ }
+
+ return CallStaticMonoMethod(m, parameters, exception);
+}
+
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingInvocation.h b/Runtime/Scripting/Backend/ScriptingInvocation.h
new file mode 100644
index 0000000..2bad02c
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingInvocation.h
@@ -0,0 +1,73 @@
+#ifndef _SCRIPTINGINVOCATION_H_
+#define _SCRIPTINGINVOCATION_H_
+
+#if ENABLE_SCRIPTING
+
+#include "ScriptingInvocationNoArgs.h"
+#include "ScriptingArguments.h"
+
+
+/// ScriptingInvocation invocation (scriptingMethod); // Slow alternative (Don't use this in runtime code) ScriptingInvocation invocation ("MyNameSpace", "MyClassName", "MyMethod");
+/// invocation.AddInt(5);
+/// invocation.Invoke (); // < you are certain that the bound method accepts those exact parameters
+/// invocation.InvokeChecked(); // < you cant guarantee that the bound method has the passed parameters
+
+/// By default logs the exception (Can be turned off via invocation.logException = false;)
+/// Parameters are setup AddInt, AddFloat, AddStruct functions below
+class ScriptingInvocation : public ScriptingInvocationNoArgs
+{
+public:
+ ScriptingInvocation();
+ ScriptingInvocation(ScriptingMethodPtr in_method);
+#if ENABLE_MONO || UNITY_WINRT
+ ScriptingInvocation(const char* namespaze, const char* klass, const char* name);
+ ScriptingInvocation(ScriptingClassPtr klass, const char* name);
+ ScriptingInvocation(BackendNativeMethod method);
+#endif
+
+ //convenience forwarders to arguments
+ void AddBoolean(bool value) { arguments.AddBoolean(value); }
+ void AddInt(int value) { arguments.AddInt(value); }
+ void AddFloat(float value) { arguments.AddFloat(value); }
+ void AddString(const char* str) { arguments.AddString(str); }
+ void AddString(std::string& str) { arguments.AddString(str); }
+ void AddObject(ScriptingObjectPtr scriptingObject) { arguments.AddObject(scriptingObject); }
+ void AddStruct(void* pointerToStruct) { arguments.AddStruct(pointerToStruct); }
+ void AddEnum(int value) { arguments.AddEnum(value); }
+ void AddArray(ScriptingArrayPtr arr) { arguments.AddArray(arr); }
+
+ void AdjustArgumentsToMatchMethod();
+
+ template<class T> T Invoke();
+ template<class T> T Invoke(ScriptingException**);
+ ScriptingObjectPtr Invoke();
+ ScriptingObjectPtr Invoke(ScriptingException**);
+ ScriptingObjectPtr Invoke(ScriptingExceptionPtr*, bool);
+
+ ScriptingArguments& Arguments() { return arguments; }
+protected:
+ ScriptingArguments arguments;
+ virtual bool Check();
+};
+
+
+#if ENABLE_MONO
+
+struct MonoObject;
+struct MonoException;
+class Object;
+struct MonoMethod;
+struct MonoClass;
+class MonoScript;
+
+MonoObject* CallStaticMonoMethod (const char* className, const char* methodName, void** parameters = NULL);
+MonoObject* CallStaticMonoMethod (const char* className, const char* methodName, void** parameters, MonoException** exception);
+MonoObject* CallStaticMonoMethod (const char* className, const char* nameSpace, const char* methodName, void** paramenters = NULL);
+MonoObject* CallStaticMonoMethod (const char* className, const char* nameSpace, const char* methodName, void** paramenters, MonoException** exception);
+MonoObject* CallStaticMonoMethod (MonoClass* klass , const char* methodName, void** parameters = NULL);
+MonoObject* CallStaticMonoMethod (MonoClass* klass , const char* methodName, void** parameters, MonoException** exception);
+#endif
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingInvocationNoArgs.cpp b/Runtime/Scripting/Backend/ScriptingInvocationNoArgs.cpp
new file mode 100644
index 0000000..19ab0f0
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingInvocationNoArgs.cpp
@@ -0,0 +1,123 @@
+#include "UnityPrefix.h"
+
+#if ENABLE_SCRIPTING
+
+#include "ScriptingInvocationNoArgs.h"
+#include "Runtime/Utilities/LogAssert.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "ScriptingMethodRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+#include "Runtime/Profiler/Profiler.h"
+
+#if ENABLE_MONO
+#include "Runtime/Mono/MonoIncludes.h"
+#include "Runtime/Mono/MonoManager.h"
+#include "Runtime/Mono/MonoUtility.h"
+#include "Runtime/Mono/MonoScript.h"
+#endif
+
+ScriptingInvocationNoArgs::ScriptingInvocationNoArgs()
+{
+ SetDefaults();
+}
+
+ScriptingInvocationNoArgs::ScriptingInvocationNoArgs(ScriptingMethodPtr in_method)
+{
+ SetDefaults();
+ method = in_method;
+}
+
+void ScriptingInvocationNoArgs::SetDefaults()
+{
+ object = SCRIPTING_NULL;
+ method = SCRIPTING_NULL;
+ classContextForProfiler = NULL;
+ logException = true;
+ objectInstanceIDContextForException = 0;
+ exception = SCRIPTING_NULL;
+}
+
+bool ScriptingInvocationNoArgs::Check()
+{
+#if !ENABLE_MONO
+ return true;
+#else
+
+ // Check method
+ if (method == NULL)
+ {
+ ErrorString("Failed to call function because it was null");
+ return false;
+ }
+
+ bool methodIsInstance = mono_signature_is_instance (mono_method_signature(method->monoMethod));
+ bool invokingInstance = object != NULL;
+
+ if (methodIsInstance && !invokingInstance)
+ {
+ DebugStringToFile (Format("Failed to call instance function %s because the no object was provided", mono_method_get_name (method->monoMethod)), 0, __FILE_STRIPPED__, __LINE__,
+ kError, objectInstanceIDContextForException);
+ return false;
+ }
+
+ if (!methodIsInstance && invokingInstance)
+ {
+ DebugStringToFile (Format("Failed to call static function %s because an object was provided", mono_method_get_name (method->monoMethod)), 0, __FILE_STRIPPED__, __LINE__,
+ kError, objectInstanceIDContextForException);
+ return false;
+ }
+
+ return true;
+
+#endif
+}
+
+
+ScriptingObjectPtr ScriptingInvocationNoArgs::Invoke()
+{
+ ScriptingExceptionPtr ex = NULL;
+ return Invoke(&ex);
+}
+
+ScriptingObjectPtr ScriptingInvocationNoArgs::Invoke(ScriptingExceptionPtr* exception)
+{
+ ScriptingObjectPtr returnValue;
+
+ *exception = NULL;
+
+#if ENABLE_MONO || UNITY_FLASH || UNITY_WINRT
+ ScriptingArguments arguments;
+ MONO_PROFILER_BEGIN (method, classContextForProfiler, object)
+#if UNITY_WINRT
+ ScriptingObjectPtr metro_invoke_method(ScriptingMethodPtr method, ScriptingObjectPtr object, ScriptingArguments* arguments, ScriptingExceptionPtr* exception, bool convertArgs);
+ returnValue = metro_invoke_method(method, object, NULL, exception, false);
+#else
+ returnValue = scripting_method_invoke(method, object, arguments, exception);
+#endif
+ MONO_PROFILER_END
+#elif !UNITY_EXTERNAL_TOOL
+ ErrorString("Invoke() not implemented on this platform");
+#else
+ return NULL;
+#endif
+
+ if (! *exception) return returnValue;
+
+ this->exception = *exception;
+#if !UNITY_EXTERNAL_TOOL
+ if (logException)
+ Scripting::LogException(*exception, objectInstanceIDContextForException);
+#endif
+
+ return SCRIPTING_NULL;
+}
+
+ScriptingObjectPtr ScriptingInvocationNoArgs::InvokeChecked()
+{
+ if (!Check())
+ return SCRIPTING_NULL;
+
+ return Invoke();
+}
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingInvocationNoArgs.h b/Runtime/Scripting/Backend/ScriptingInvocationNoArgs.h
new file mode 100644
index 0000000..ece7010
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingInvocationNoArgs.h
@@ -0,0 +1,31 @@
+#ifndef _SCRIPTINGINVOCATIONNOARGS_H_
+#define _SCRIPTINGINVOCATIONNOARGS_H_
+
+#if ENABLE_SCRIPTING
+
+#include "ScriptingTypes.h"
+
+class ScriptingInvocationNoArgs
+{
+public:
+ ScriptingInvocationNoArgs();
+ ScriptingInvocationNoArgs(ScriptingMethodPtr in_method);
+
+ ScriptingMethodPtr method;
+ ScriptingObjectPtr object;
+ int objectInstanceIDContextForException;
+ ScriptingTypePtr classContextForProfiler;
+ bool logException;
+ ScriptingExceptionPtr exception;
+
+ ScriptingObjectPtr Invoke();
+ virtual ScriptingObjectPtr Invoke(ScriptingException**);
+ ScriptingObjectPtr InvokeChecked();
+protected:
+ void SetDefaults();
+ virtual bool Check();
+};
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingMethodFactory.h b/Runtime/Scripting/Backend/ScriptingMethodFactory.h
new file mode 100644
index 0000000..a497d62
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingMethodFactory.h
@@ -0,0 +1,18 @@
+#ifndef _SCRIPTINGMETHODFACTORY_H_
+#define _SCRIPTINGMETHODFACTORY_H_
+
+#include "ScriptingTypes.h"
+
+
+// !!TODO: ScriptingMethodPtr Produce(ScriptingTypePtr klass, const char* name, int searchFilter) & ScriptingMethodPtr Produce(BackendNativeMethod nativeMethod) must return the same
+// method if internally method is the same !!!
+class IScriptingMethodFactory
+{
+public:
+ virtual ~IScriptingMethodFactory() {}
+ virtual ScriptingMethodPtr Produce(ScriptingTypePtr klass, const char* name, int searchFilter) = 0;
+ virtual ScriptingMethodPtr Produce(BackendNativeMethod nativeMethod) = 0;
+ virtual void Release(ScriptingMethodPtr) = 0;
+};
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingMethodRegistry.cpp b/Runtime/Scripting/Backend/ScriptingMethodRegistry.cpp
new file mode 100644
index 0000000..e9df7fd
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingMethodRegistry.cpp
@@ -0,0 +1,165 @@
+#include "UnityPrefix.h"
+#if ENABLE_SCRIPTING
+#include "ScriptingMethodRegistry.h"
+#include "ScriptingMethodFactory.h"
+#include "ScriptingTypeRegistry.h"
+#include "Runtime/Mono/MonoIncludes.h"
+#include "ScriptingBackendApi.h"
+#include "Runtime/Scripting/ScriptingManager.h"
+
+using std::vector;
+
+
+ScriptingMethodRegistry::ScriptingMethodRegistry(IScriptingMethodFactory* scriptingMethodFactory, ScriptingTypeRegistry* scriptingTypeRegistry)
+ : m_ScriptingMethodFactory(scriptingMethodFactory),
+ m_ScriptingTypeRegistry(scriptingTypeRegistry)
+{
+}
+
+ScriptingMethodPtr ScriptingMethodRegistry::GetMethod(const char* namespaze, const char* className, const char* methodName, int searchOptions)
+{
+ ScriptingTypePtr klass = m_ScriptingTypeRegistry->GetType(namespaze,className);
+ if (klass==SCRIPTING_NULL)
+ return SCRIPTING_NULL;
+ return GetMethod(klass,methodName,searchOptions);
+}
+
+ScriptingMethodPtr ScriptingMethodRegistry::GetMethod(BackendNativeMethod nativeMethod)
+{
+ NativeMethodToScriptingMethod::iterator i = m_NativeMethodToScriptingMethod.find(nativeMethod);
+ if (i != m_NativeMethodToScriptingMethod.end())
+ return i->second;
+
+ ScriptingMethodPtr scriptingMethod = m_ScriptingMethodFactory->Produce(nativeMethod);
+ m_NativeMethodToScriptingMethod[nativeMethod] = scriptingMethod;
+ return scriptingMethod;
+}
+
+ScriptingMethodPtr ScriptingMethodRegistry::GetMethod(ScriptingTypePtr klass, const char* methodName, int searchOptions)
+{
+ bool found;
+ ScriptingMethodPtr cached = FindInCache(klass,methodName,searchOptions,&found);
+ if (found)
+ return cached;
+
+ ScriptingMethodPtr scriptingMethod = m_ScriptingMethodFactory->Produce(klass,methodName, searchOptions);
+
+ if (!scriptingMethod && (!(searchOptions & kDontSearchBaseTypes)))
+ {
+ ScriptingTypePtr baseClass = scripting_class_get_parent (klass, *m_ScriptingTypeRegistry);
+ if (baseClass)
+ scriptingMethod = GetMethod(baseClass, methodName, searchOptions);
+ }
+
+ PlaceInCache(klass,methodName,scriptingMethod);
+
+ return scriptingMethod;
+}
+
+bool MethodDescriptionMatchesSearchFilter(int searchFilter, bool isInstance, int argCount)
+{
+ if ((searchFilter & ScriptingMethodRegistry::kStaticOnly) && isInstance)
+ return false;
+
+ if ((searchFilter & ScriptingMethodRegistry::kInstanceOnly) && !isInstance)
+ return false;
+
+ if ((searchFilter & ScriptingMethodRegistry::kWithoutArguments) && argCount>0)
+ return false;
+
+ return true;
+}
+
+static bool MethodMatchesSearchFilter(ScriptingMethodPtr method, int searchFilter)
+{
+ return MethodDescriptionMatchesSearchFilter(searchFilter, scripting_method_is_instance(method), scripting_method_get_argument_count(method, GetScriptingTypeRegistry()));
+}
+
+void ScriptingMethodRegistry::AllMethodsIn(ScriptingTypePtr klass, vector<ScriptingMethodPtr>& result, int searchOptions)
+{
+ vector<ScriptingMethodPtr> methods;
+ scripting_class_get_methods(klass, *this, methods);
+ for (vector<ScriptingMethodPtr>::iterator item = methods.begin();
+ item != methods.end();
+ item++)
+ {
+ if (!MethodMatchesSearchFilter(*item, searchOptions))
+ continue;
+
+ result.push_back(*item);
+ }
+
+ if (searchOptions & kDontSearchBaseTypes)
+ return;
+
+ ScriptingTypePtr baseClass = scripting_class_get_parent(klass, *m_ScriptingTypeRegistry);
+ if (baseClass == SCRIPTING_NULL)
+ return;
+
+ return AllMethodsIn(baseClass, result, searchOptions);
+}
+
+void ScriptingMethodRegistry::InvalidateCache()
+{
+ //make sure to not delete a scriptingmethod twice, as it could be in the cache in multiple places. (in case of classes implementing interfaces & virtual methods)
+ MethodsSet todelete;
+ for (ClassToMethodsByName::iterator cci = m_Cache.begin(); cci != m_Cache.end(); cci++)
+ for (MethodsByName::iterator mbni = cci->second.begin(); mbni != cci->second.end(); mbni++)
+ for (VectorOfMethods::iterator smpi = mbni->second.begin(); smpi != mbni->second.end(); smpi++)
+ todelete.insert(*smpi);
+
+ for (NativeMethodToScriptingMethod::iterator i = m_NativeMethodToScriptingMethod.begin(); i != m_NativeMethodToScriptingMethod.end(); i++)
+ todelete.insert(i->second);
+
+ for (MethodsSet::iterator i = todelete.begin(); i != todelete.end(); i++)
+ m_ScriptingMethodFactory->Release(*i);
+
+ m_Cache.clear();
+ m_NativeMethodToScriptingMethod.clear();
+}
+
+ScriptingMethodPtr ScriptingMethodRegistry::FindInCache(ScriptingTypePtr klass, const char* name, int searchFilter, bool* found)
+{
+ *found = false;
+ MethodsByName* cc = FindMethodsByNameFor(klass);
+ if (cc == NULL)
+ return SCRIPTING_NULL;
+
+ MethodsByName::iterator mbni = cc->find(name);
+ if (mbni == cc->end())
+ return SCRIPTING_NULL;
+
+ for (VectorOfMethods::iterator i = mbni->second.begin(); i != mbni->second.end(); i++)
+ {
+ if (*i == NULL || MethodMatchesSearchFilter(*i, searchFilter))
+ {
+ *found = true;
+ return *i;
+ }
+ }
+ return SCRIPTING_NULL;
+}
+
+void ScriptingMethodRegistry::PlaceInCache(ScriptingTypePtr klass, const char* name, ScriptingMethodPtr method)
+{
+ MethodsByName* mbn = FindMethodsByNameFor(klass);
+ if (mbn == NULL)
+ {
+ m_Cache.insert(std::make_pair(klass, MethodsByName()));
+ mbn = FindMethodsByNameFor(klass);
+ }
+
+ VectorOfMethods vom;
+ vom.push_back(method);
+ mbn->insert(std::make_pair(name,vom));
+}
+
+ScriptingMethodRegistry::MethodsByName* ScriptingMethodRegistry::FindMethodsByNameFor(ScriptingTypePtr klass)
+{
+ ClassToMethodsByName::iterator cc = m_Cache.find(klass);
+ if (cc == m_Cache.end())
+ return NULL;
+ return &cc->second;
+}
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingMethodRegistry.h b/Runtime/Scripting/Backend/ScriptingMethodRegistry.h
new file mode 100644
index 0000000..82d7e40
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingMethodRegistry.h
@@ -0,0 +1,60 @@
+#ifndef _SCRIPTINGMETHODREGISTRY_H_
+#define _SCRIPTINGMETHODREGISTRY_H_
+
+#if ENABLE_SCRIPTING
+#include "ScriptingTypes.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class IScriptingMethodFactory;
+class ScriptingTypeRegistry;
+
+class ScriptingMethodRegistry
+{
+public:
+ ScriptingMethodRegistry(IScriptingMethodFactory* scriptingMethodFactory, ScriptingTypeRegistry* scriptingTypeRegistry);
+ ~ScriptingMethodRegistry() {InvalidateCache();}
+
+ enum SearchFilter
+ {
+ kNone = 0,
+ kInstanceOnly = 1,
+ kStaticOnly = 2,
+ kWithoutArguments = 4,
+ kDontSearchBaseTypes = 8,
+ };
+
+ ScriptingMethodPtr GetMethod(const char* namespaze, const char* klassName, const char* methodName, int searchOptions=kNone);
+ ScriptingMethodPtr GetMethod(ScriptingTypePtr klass, const char* methodName, int searchOptions=kNone);
+ ScriptingMethodPtr GetMethod(BackendNativeMethod nativeMathod);
+
+ void AllMethodsIn(ScriptingTypePtr klass, std::vector<ScriptingMethodPtr>& result, int searchOptions=kNone);
+
+ void InvalidateCache();
+
+private:
+ typedef std::vector<ScriptingMethodPtr> VectorOfMethods;
+ typedef std::map< std::string,VectorOfMethods > MethodsByName;
+ typedef std::map<ScriptingTypePtr, MethodsByName> ClassToMethodsByName;
+ typedef std::map<BackendNativeMethod, ScriptingMethodPtr> NativeMethodToScriptingMethod;
+ typedef std::set<ScriptingMethodPtr> MethodsSet;
+
+ ClassToMethodsByName m_Cache;
+
+
+ NativeMethodToScriptingMethod m_NativeMethodToScriptingMethod;
+
+ IScriptingMethodFactory* m_ScriptingMethodFactory;
+ ScriptingTypeRegistry* m_ScriptingTypeRegistry;
+
+ ScriptingMethodPtr FindInCache(ScriptingTypePtr klass, const char* name, int searchFilter, bool* out_found);
+ void PlaceInCache(ScriptingTypePtr klass, const char* name, ScriptingMethodPtr method);
+ MethodsByName* FindMethodsByNameFor(ScriptingTypePtr klass);
+};
+
+bool MethodDescriptionMatchesSearchFilter(int searchFilter, bool isInstance, int argCount);
+#endif
+
+#endif \ No newline at end of file
diff --git a/Runtime/Scripting/Backend/ScriptingMethodRegistryTests.cpp b/Runtime/Scripting/Backend/ScriptingMethodRegistryTests.cpp
new file mode 100644
index 0000000..e3735b0
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingMethodRegistryTests.cpp
@@ -0,0 +1,237 @@
+#include "UnityPrefix.h"
+#if DEDICATED_UNIT_TEST_BUILD
+#include "ScriptingMethodRegistry.h"
+#include "External/UnitTest++/src/UnitTest++.h"
+#include "ScriptingMethodFactory.h"
+#include "Tests/ScriptingBackendApi_Tests.h"
+#include <queue>
+#include <set>
+#include <vector>
+using std::queue;
+using std::vector;
+
+class ScriptingMethodFactory_Dummy : public IScriptingMethodFactory
+{
+public:
+ queue<ScriptingMethodPtr> produceThis;
+ ScriptingTypePtr returnNullForRequestson;
+ int produceCallCount;
+
+ ScriptingMethodFactory_Dummy() : produceCallCount(0) {}
+
+ virtual ScriptingMethodPtr Produce(ScriptingTypePtr klass, const char* name, int searchFilter)
+ {
+ produceCallCount++;
+
+ if (returnNullForRequestson == klass)
+ return NULL;
+
+ if (produceThis.size()==0)
+ return NULL;
+
+ ScriptingMethodPtr result = produceThis.front();
+
+ if (result && !MethodDescriptionMatchesSearchFilter(searchFilter, result->instance, result->args))
+ return NULL;
+
+ produceThis.pop();
+ return result;
+ }
+
+ virtual ScriptingMethodPtr Produce(void* nativePtr)
+ {
+ return Produce(NULL,NULL, 0);
+ }
+
+ virtual void Release(ScriptingMethodPtr method)
+ {
+ }
+};
+
+struct Fixture
+{
+ ScriptingMethodFactory_Dummy methodFactory;
+ ScriptingMethodRegistry registry;
+
+ ScriptingType normalType;
+
+ ScriptingMethod method1;
+ ScriptingMethod method2;
+
+ Fixture() : registry(&methodFactory,NULL)
+ {
+ }
+};
+
+TEST_FIXTURE(Fixture,RegistryProducesNullForNonExistingMethod)
+{
+ CHECK_EQUAL((ScriptingMethodPtr)NULL,registry.GetMethod(&normalType,"Method1"));
+}
+
+TEST_FIXTURE(Fixture,RegistryProducesMethod)
+{
+ methodFactory.produceThis.push(&method1);
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1"));
+}
+
+TEST_FIXTURE(Fixture,RegistryReturnsSameMethodWhenQueriedTwiceWithSameArguments)
+{
+ methodFactory.produceThis.push(&method1);
+
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1"));
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1"));
+}
+
+TEST_FIXTURE(Fixture,RegistryReturnsDifferentMethodsWhenQueriedForTwoDifferentClasses)
+{
+ methodFactory.produceThis.push(&method1);
+ methodFactory.produceThis.push(&method2);
+
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1"));
+ CHECK_EQUAL(&method2,registry.GetMethod((ScriptingTypePtr)124,"Method1"));
+}
+
+TEST_FIXTURE(Fixture,RegistryReturnsDifferentMethodsForDifferentSearchFilters)
+{
+ methodFactory.produceThis.push(&method1);
+ methodFactory.produceThis.push(&method2);
+ method1.instance = false;
+ method2.instance = true;
+
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1", ScriptingMethodRegistry::kStaticOnly));
+ CHECK_EQUAL(&method2,registry.GetMethod(&normalType,"Method1", ScriptingMethodRegistry::kInstanceOnly));
+}
+
+TEST_FIXTURE(Fixture,RegistryDoesNotFindMethodsNotMatchingSearchFilter)
+{
+ methodFactory.produceThis.push(&method1);
+ method1.instance = true;
+
+ ScriptingMethodPtr found = registry.GetMethod(&normalType,"Method1", ScriptingMethodRegistry::kStaticOnly);
+ if (found==NULL)
+ CHECK_EQUAL(1,1);
+ else
+ CHECK_EQUAL(1,0);
+}
+
+TEST_FIXTURE(Fixture,RegistryRemembersNonFoundMethods)
+{
+ methodFactory.produceThis.push(NULL);
+ methodFactory.produceThis.push(NULL);
+
+ registry.GetMethod(&normalType,"NonExisting");
+ registry.GetMethod(&normalType,"NonExisting");
+
+ CHECK_EQUAL(1,methodFactory.produceCallCount);
+}
+
+
+
+TEST_FIXTURE(Fixture,InvalidateCacheCausesNewMethodToBeProduced)
+{
+ methodFactory.produceThis.push(&method1);
+ methodFactory.produceThis.push(&method2);
+
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1"));
+ registry.InvalidateCache();
+ CHECK_EQUAL(&method2,registry.GetMethod(&normalType,"Method1"));
+}
+
+struct FixtureWithBaseTypeHavingMethod : public Fixture
+{
+ ScriptingType normalType;
+ ScriptingType baseType;
+
+ FixtureWithBaseTypeHavingMethod()
+ {
+ normalType.baseType = &baseType;
+ methodFactory.produceThis.push(&method1);
+ methodFactory.returnNullForRequestson = &normalType;
+ }
+};
+
+TEST_FIXTURE(FixtureWithBaseTypeHavingMethod,RegistryWillSearchBaseTypesIfRequested)
+{
+ CHECK_EQUAL(&method1,registry.GetMethod(&normalType,"Method1"));
+}
+
+TEST_FIXTURE(FixtureWithBaseTypeHavingMethod, RegistryWillNotSearchBaseTypesIfNotRequested)
+{
+ CHECK_EQUAL((ScriptingMethodPtr)NULL,registry.GetMethod(&normalType,"Method1", ScriptingMethodRegistry::kDontSearchBaseTypes));
+}
+
+TEST_FIXTURE(Fixture, CanGetMethodFromNativeMethodPointer)
+{
+ int nativeMethod;
+ methodFactory.produceThis.push(&method1);
+ CHECK_EQUAL(&method1,registry.GetMethod( &nativeMethod));
+}
+
+TEST_FIXTURE(Fixture, CanGetSameMethodFromNativeMethodTwice)
+{
+ int nativeMethod;
+ methodFactory.produceThis.push(&method1);
+ CHECK_EQUAL(&method1,registry.GetMethod(&nativeMethod));
+ CHECK_EQUAL(&method1,registry.GetMethod(&nativeMethod));
+}
+
+TEST_FIXTURE(Fixture, InvalidateCacheClearsNativeMethodWrappers)
+{
+ int nativeMethod;
+ methodFactory.produceThis.push(&method1);
+ methodFactory.produceThis.push(&method2);
+ CHECK_EQUAL(&method1,registry.GetMethod(&nativeMethod));
+ registry.InvalidateCache();
+ CHECK_EQUAL(&method2,registry.GetMethod(&nativeMethod));
+}
+
+TEST_FIXTURE(Fixture, AllMethodsInType)
+{
+ normalType.methods.push_back(&method1);
+
+ vector<ScriptingMethodPtr> result;
+ registry.AllMethodsIn(&normalType, result);
+ CHECK_EQUAL(1, result.size());
+ CHECK_EQUAL(&method1, result[0]);
+}
+
+TEST_FIXTURE(Fixture, AllMethodsInTypeWillSearchBaseTypes)
+{
+ ScriptingType baseType;
+ baseType.methods.push_back(&method1);
+ normalType.baseType = &baseType;
+
+ vector<ScriptingMethodPtr> result;
+ registry.AllMethodsIn(&normalType, result);
+ CHECK_EQUAL(1, result.size());
+ CHECK_EQUAL(&method1, result[0]);
+}
+
+TEST_FIXTURE(Fixture, AllMethodsInTypeCanSkipStaticMethods)
+{
+ normalType.methods.push_back(&method1);
+ normalType.methods.push_back(&method2);
+
+ method2.instance = true;
+
+ vector<ScriptingMethodPtr> result;
+ registry.AllMethodsIn(&normalType, result, ScriptingMethodRegistry::kInstanceOnly);
+ CHECK_EQUAL(1, result.size());
+ CHECK_EQUAL(&method2, result[0]);
+}
+
+TEST_FIXTURE(Fixture, SearchFilterCanSkipMethodsWithArguments)
+{
+ normalType.methods.push_back(&method1);
+ normalType.methods.push_back(&method2);
+
+ method1.args=0;
+ method2.args=2;
+
+ vector<ScriptingMethodPtr> result;
+ registry.AllMethodsIn(&normalType, result, ScriptingMethodRegistry::kWithoutArguments );
+ CHECK_EQUAL(1, result.size());
+ CHECK_EQUAL(&method1, result[0]);
+}
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingTypeRegistry.cpp b/Runtime/Scripting/Backend/ScriptingTypeRegistry.cpp
new file mode 100644
index 0000000..0e4fcbd
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingTypeRegistry.cpp
@@ -0,0 +1,214 @@
+#include "UnityPrefix.h"
+#if ENABLE_SCRIPTING
+#include "ScriptingTypeRegistry.h"
+#include "ScriptingBackendApi.h"
+
+ScriptingTypeRegistry::ScriptingTypeRegistry(IScriptingTypeProvider* scriptingTypeProvider)
+ : m_ScriptingTypeProvider(scriptingTypeProvider)
+{
+}
+
+ScriptingTypePtr ScriptingTypeRegistry::GetType(const char* namespaze, const char* name)
+{
+ NameSpaceAndNamePair key = std::make_pair(namespaze,name);
+
+ Cache::iterator i = m_Cache.find(key);
+ if (i != m_Cache.end())
+ return i->second;
+
+ BackendNativeType nativetype = m_ScriptingTypeProvider->NativeTypeFor(namespaze, name);
+ ScriptingTypePtr type = m_ScriptingTypeProvider->Provide(nativetype);
+
+ m_Cache.insert(std::make_pair(key,type));
+ return type;
+}
+
+ScriptingTypePtr ScriptingTypeRegistry::GetType(BackendNativeType nativeType)
+{
+ NativeTypeCache::iterator i = m_NativeTypeCache.find(ScriptingObjectToComPtr(nativeType));
+ if (i != m_NativeTypeCache.end())
+ return i->second;
+
+ ScriptingTypePtr type = m_ScriptingTypeProvider->Provide(nativeType);
+
+ m_NativeTypeCache.insert(std::make_pair(ScriptingObjectToComPtr(nativeType), type));
+ return type;
+}
+
+ScriptingTypePtr ScriptingTypeRegistry::GetType(ScriptingObjectPtr systemTypeInstance)
+{
+ return scripting_class_from_systemtypeinstance(systemTypeInstance, *this);
+}
+
+void ScriptingTypeRegistry::InvalidateCache()
+{
+ m_Cache.clear();
+ m_NativeTypeCache.clear();
+}
+
+#if DEDICATED_UNIT_TEST_BUILD
+#include "External/UnitTest++/src/UnitTest++.h"
+#include <queue>
+#include "Tests/ScriptingBackendApi_Tests.h"
+using std::queue;
+
+class ScriptingTypeProvider_test : public IScriptingTypeProvider
+{
+public:
+ BackendNativeType NativeTypeFor(const char* namespaze, const char* name)
+ {
+ BackendNativeType ptr = provideThis.front();
+ provideThis.pop();
+ return ptr;
+ }
+
+ ScriptingTypePtr Provide(BackendNativeType nativeType)
+ {
+ return (ScriptingTypePtr)nativeType;
+ }
+
+ void Release(ScriptingTypePtr ptr) {}
+
+ queue<BackendNativeType> provideThis;
+};
+
+struct MyFixture
+{
+ ScriptingTypeProvider_test typeProvider;
+
+ ScriptingType type1;
+ ScriptingType type2;
+ int nativeType1;
+ int nativeType2;
+ FakeSystemTypeInstance systemTypeInstance1;
+ FakeSystemTypeInstance systemTypeInstance2;
+};
+
+TEST_FIXTURE(MyFixture,ScriptingTypeRegistryReturnsSameTypeWhenAskedForSameName)
+{
+ typeProvider.provideThis.push(&type1);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+ ScriptingTypePtr t1 = registry.GetType("mynamespace","mytype");
+ ScriptingTypePtr t2 = registry.GetType("mynamespace","mytype");
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type1,t2);
+}
+
+TEST_FIXTURE(MyFixture,ScriptingTypeRegistryReturnsDifferentTypeWhenAskedForDifferentName)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+ ScriptingTypePtr t1 = registry.GetType("mynamespace", "mytype");
+ ScriptingTypePtr t2 = registry.GetType("mynamespace", "myothertype");
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+
+TEST_FIXTURE(MyFixture,ScriptingTypeRegistryReturnsDifferentTypeWhenAskedForTypesWithDifferentNamespace)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+ ScriptingTypePtr t1 = registry.GetType("mynamespace", "mytype");
+ ScriptingTypePtr t2 = registry.GetType("myothernamespace", "mytype");
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+
+TEST_FIXTURE(MyFixture,ScriptingTypeRegistryInvalidateCacheCausesNewTypeBeingProduced)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+ ScriptingTypePtr t1 = registry.GetType("mynamespace","mytype");
+ registry.InvalidateCache();
+ ScriptingTypePtr t2 = registry.GetType("mynamespace", "mytype");
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+
+TEST_FIXTURE(MyFixture,AskingForTheSameNativeTypeTwiceReturnsSameScriptingTypeTwice)
+{
+ typeProvider.provideThis.push(&type1);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+
+ ScriptingTypePtr t1 = registry.GetType(&nativeType1);
+ ScriptingTypePtr t2 = registry.GetType(&nativeType1);
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type1,t2);
+}
+
+TEST_FIXTURE(MyFixture,AskingForTwoDifferentNativeTypesReturnsDifferentScriptingTypes)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+ ScriptingTypePtr t1 = registry.GetType(&nativeType1);
+ ScriptingTypePtr t2 = registry.GetType(&nativeType2);
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+
+TEST_FIXTURE(MyFixture,InvalidateCacheCausesNewTypeToBeReturned)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+
+ ScriptingTypeRegistry registry(&typeProvider);
+
+ ScriptingTypePtr t1 = registry.GetType(&nativeType1);
+ registry.InvalidateCache();
+ ScriptingTypePtr t2 = registry.GetType(&nativeType1);
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+
+TEST_FIXTURE(MyFixture,AskingForTypeOfSystemTypeInstanceTwiceReturnsSameType)
+{
+ typeProvider.provideThis.push(&type1);
+ ScriptingTypeRegistry registry(&typeProvider);
+
+ systemTypeInstance1.nativeType = &nativeType1;
+ ScriptingTypePtr t1 = registry.GetType((ScriptingObjectPtr) &systemTypeInstance1);
+ ScriptingTypePtr t2 = registry.GetType((ScriptingObjectPtr) &systemTypeInstance1);
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type1,t2);
+}
+/*
+TEST_FIXTURE(MyFixture,AskingForDifferentSystemTypeInstancesReturnsDifferentTypes)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+ ScriptingTypeRegistry registry(&typeProvider);
+
+ systemTypeInstance1.nativeType = &nativeType1;
+ systemTypeInstance1.nativeType = &nativeType2;
+ ScriptingTypePtr t1 = registry.GetType((ScriptingObjectPtr) &systemTypeInstance1);
+ ScriptingTypePtr t2 = registry.GetType((ScriptingObjectPtr) &systemTypeInstance2);
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+*/
+TEST_FIXTURE(MyFixture,InvalidateCacheCausesSystemTypeInstanceQueryToProvideNewType)
+{
+ typeProvider.provideThis.push(&type1);
+ typeProvider.provideThis.push(&type2);
+ ScriptingTypeRegistry registry(&typeProvider);
+
+ systemTypeInstance1.nativeType = &nativeType1;
+ ScriptingTypePtr t1 = registry.GetType((ScriptingObjectPtr) &systemTypeInstance1);
+ registry.InvalidateCache();
+ ScriptingTypePtr t2 = registry.GetType((ScriptingObjectPtr) &systemTypeInstance1);
+ CHECK_EQUAL(&type1,t1);
+ CHECK_EQUAL(&type2,t2);
+}
+
+#endif
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingTypeRegistry.h b/Runtime/Scripting/Backend/ScriptingTypeRegistry.h
new file mode 100644
index 0000000..be2328f
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingTypeRegistry.h
@@ -0,0 +1,33 @@
+#ifndef _SCRIPTINGTYPEREGISTRY_Y_
+#define _SCRIPTINGTYPEREGISTRY_Y_
+
+#if ENABLE_SCRIPTING
+
+#include <map>
+#include <string>
+#include "ScriptingTypes.h"
+#include "IScriptingTypeProvider.h"
+
+class ScriptingTypeRegistry
+{
+public:
+ ScriptingTypeRegistry(IScriptingTypeProvider* scriptingTypeProvider);
+ ScriptingTypePtr GetType(const char* namespaze, const char* name);
+ ScriptingTypePtr GetType(BackendNativeType nativeType);
+ ScriptingTypePtr GetType(ScriptingObjectPtr systemTypeInstance);
+ void InvalidateCache();
+
+private:
+ typedef std::pair<std::string,std::string> NameSpaceAndNamePair;
+ typedef std::map<NameSpaceAndNamePair, ScriptingTypePtr> Cache;
+ Cache m_Cache;
+
+ typedef std::map<void*, ScriptingTypePtr> NativeTypeCache;
+ NativeTypeCache m_NativeTypeCache;
+
+ IScriptingTypeProvider* m_ScriptingTypeProvider;
+};
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/Backend/ScriptingTypes.h b/Runtime/Scripting/Backend/ScriptingTypes.h
new file mode 100644
index 0000000..45911b0
--- /dev/null
+++ b/Runtime/Scripting/Backend/ScriptingTypes.h
@@ -0,0 +1,202 @@
+#ifndef _SCRIPTINGTYPES_H_
+#define _SCRIPTINGTYPES_H_
+
+#if ENABLE_MONO
+struct MonoObject;
+struct MonoString;
+struct MonoArray;
+struct MonoType;
+struct MonoClass;
+struct MonoException;
+struct MonoMethod;
+struct MonoClassField;
+typedef MonoObject ScriptingObject;
+typedef MonoString ScriptingString;
+typedef MonoArray ScriptingArray;
+typedef MonoClass ScriptingType;
+typedef MonoClass ScriptingClass;
+typedef MonoException ScriptingException;
+typedef MonoClassField ScriptingField;
+struct ScriptingMethod;
+typedef MonoMethod* BackendNativeMethod;
+typedef MonoClass* BackendNativeType;
+
+#elif UNITY_FLASH
+struct ScriptingObject;
+struct ScriptingString;
+struct ScriptingArray;
+struct ScriptingClass;
+typedef ScriptingClass ScriptingType;
+struct ScriptingException;
+
+struct ScriptingMethod;
+struct ScriptingField;
+struct MonoImage;
+
+//hack to not have to change everything in one go.
+struct MonoMethod;
+struct MonoObject;
+typedef ScriptingType MonoClass;
+typedef void* BackendNativeType;
+typedef void* BackendNativeMethod;
+#elif UNITY_WINRT && ENABLE_SCRIPTING
+struct WinRTNullPtrImplementation
+{
+ inline operator long long()
+ {
+ return -1;
+ }
+ inline operator decltype(__nullptr)()
+ {
+ return nullptr;
+ }
+};
+
+// Implemented in WinRTUtility.cpp
+class WinRTScriptingObjectWrapper
+{
+public:
+ // Must be in sync with WinRTBridge\GCHandledObjects.cs, would be nice to somehow get those values directly...
+ static const int kMaxHandlesShift = 11;
+ static const int kMaxHandlesPerBlock = 1 << kMaxHandlesShift;
+ static const int kHandleMask = kMaxHandlesPerBlock - 1;
+public:
+ WinRTScriptingObjectWrapper();
+ WinRTScriptingObjectWrapper(decltype(__nullptr));
+ WinRTScriptingObjectWrapper(long long handleId);
+ WinRTScriptingObjectWrapper(const WinRTNullPtrImplementation& interopParam);
+ WinRTScriptingObjectWrapper(const WinRTScriptingObjectWrapper& handleId);
+ ~WinRTScriptingObjectWrapper();
+
+ const WinRTScriptingObjectWrapper &operator = (const WinRTScriptingObjectWrapper &ptr);
+ WinRTScriptingObjectWrapper& operator=(decltype(__nullptr));
+ WinRTScriptingObjectWrapper& operator=(const WinRTNullPtrImplementation& nullptrimpl);
+ inline operator bool () const
+ {
+ return m_Handle != -1;
+ }
+ inline operator long long() const
+ {
+ return m_Handle;
+ }
+ int GetReferenceCount() const;
+
+ // Converters
+ bool ToBool();
+
+ inline long long GetHandle() const { return m_Handle;}
+ inline int GetBlockId() const {return m_BlockId; }
+ inline int GetHandleInBlock() const { return m_HandleInBlock; }
+
+ void Validate();
+
+ static void FreeHandles();
+ static void ClearCache();
+ static void ValidateCache();
+private:
+ friend bool operator == (const WinRTScriptingObjectWrapper& a, decltype(__nullptr));
+ friend bool operator != (const WinRTScriptingObjectWrapper& a, decltype(__nullptr));
+ friend bool operator == (const WinRTScriptingObjectWrapper& a, const WinRTNullPtrImplementation& b);
+ friend bool operator != (const WinRTScriptingObjectWrapper& a, const WinRTNullPtrImplementation& b);
+ static int* GetPtrToReferences(int blockId);
+
+ void Init(long long handleId);
+ void InternalAddRef();
+ void InternalRelease();
+
+ long long m_Handle;
+ int m_BlockId;
+ int m_HandleInBlock;
+ int* m_PtrToReferences;
+
+ static const int kMaxCachedPtrToReferences = 4096;
+ static int* m_CachedPtrToReferences[kMaxCachedPtrToReferences];
+ static int m_CachedBlockCount;
+};
+
+bool operator == (const WinRTScriptingObjectWrapper& a, decltype(__nullptr));
+bool operator != (const WinRTScriptingObjectWrapper& a, decltype(__nullptr));
+bool operator == (const WinRTScriptingObjectWrapper& a, const WinRTNullPtrImplementation& b);
+bool operator != (const WinRTScriptingObjectWrapper& a, const WinRTNullPtrImplementation& b);
+// Don't implement this, as same objects can have different handle ids, so currently there's no way of effectively comparing them
+//bool operator == (const WinRTScriptingObjectWrapper& a, const WinRTScriptingObjectWrapper& b);
+
+struct ScriptingObject;
+struct ScriptingString;
+typedef Platform::Object ScriptingArray;
+//struct ScriptingArray;
+struct ScriptingType;
+typedef ScriptingType ScriptingClass;
+struct ScriptingException;
+
+typedef int BackendNativeMethod;
+typedef BridgeInterface::IScriptingClassWrapper^ BackendNativeType;
+
+struct ScriptingMethod;
+struct ScriptingField;
+struct MonoImage;
+
+//hack to not have to change everything in one go.
+struct MonoMethod;
+struct MonoObject;
+typedef ScriptingType MonoClass;
+#else
+struct ScriptingObject;
+struct ScriptingString;
+struct ScriptingException;
+struct ScriptingMethod;
+struct ScriptingField;
+struct ScriptingString;
+struct ScriptingClass;
+struct ScriptingType;
+struct ScriptingArray;
+struct ScriptingString;
+struct MonoMethod;
+struct MonoObject;
+struct MonoClass;
+typedef void* BackendNativeType;
+typedef void* BackendNativeMethod;
+#endif
+
+
+#if UNITY_WINRT && ENABLE_SCRIPTING
+typedef WinRTScriptingObjectWrapper ScriptingObjectPtr;
+typedef Platform::Object^ ScriptingStringPtr;
+typedef WinRTScriptingObjectWrapper ScriptingArrayPtr;
+typedef WinRTScriptingObjectWrapper ScriptingPinnedArrayPtr;
+typedef WinRTScriptingObjectWrapper const ScriptingArrayConstPtr;
+typedef WinRTScriptingObjectWrapper ScriptingPinnedArrayConstPtr;
+typedef ScriptingType* ScriptingTypePtr;
+typedef ScriptingClass* ScriptingClassPtr;
+typedef ScriptingException* ScriptingExceptionPtr;
+typedef ScriptingMethod* ScriptingMethodPtr;
+typedef ScriptingField* ScriptingFieldPtr;
+//typedef Platform::Array<Platform::Object^> ScriptingParams;
+//typedef ScriptingParams^ ScriptingParamsPtr;
+typedef long long ScriptingParams;
+typedef long long* ScriptingParamsPtr;
+#define ScriptingBool bool
+#define SCRIPTING_NULL WinRTNullPtrImplementation()
+#define ScriptingObjectComPtr(Type) Microsoft::WRL::ComPtr<IInspectable>
+#define ScriptingObjectToComPtr(Object) reinterpret_cast<IInspectable*>(Object)
+#define ScriptingComPtrToObject(Type, Object) reinterpret_cast<Type>((Object).Get())
+#else
+typedef ScriptingObject* ScriptingObjectPtr;
+typedef ScriptingString* ScriptingStringPtr;
+typedef ScriptingArray* ScriptingArrayPtr;
+typedef ScriptingType* ScriptingTypePtr;
+typedef ScriptingClass* ScriptingClassPtr;
+typedef ScriptingException* ScriptingExceptionPtr;
+typedef ScriptingMethod* ScriptingMethodPtr;
+typedef ScriptingField* ScriptingFieldPtr;
+typedef void* ScriptingParams;
+typedef ScriptingParams* ScriptingParamsPtr;
+#define ScriptingBool short
+#define SCRIPTING_NULL NULL
+#define ScriptingObjectComPtr(Type) Type
+#define ScriptingObjectToComPtr(Object) Object
+#define ScriptingComPtrToObject(Type, Object) Object
+#endif
+
+
+#endif
diff --git a/Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.cpp b/Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.cpp
new file mode 100644
index 0000000..c8c0122
--- /dev/null
+++ b/Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.cpp
@@ -0,0 +1,35 @@
+#include "UnityPrefix.h"
+
+#if DEDICATED_UNIT_TEST_BUILD
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.h"
+#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h"
+
+bool scripting_method_is_instance(ScriptingMethodPtr method)
+{
+ return method->instance;
+}
+
+int scripting_method_get_argument_count(ScriptingMethodPtr method)
+{
+ return method->args;
+}
+
+ScriptingTypePtr scripting_class_get_parent(ScriptingTypePtr type, ScriptingTypeRegistry& typeRegistry)
+{
+ return type->baseType;
+}
+
+void scripting_class_get_methods(ScriptingTypePtr type, ScriptingMethodRegistry& registry, std::vector<ScriptingMethodPtr>& result)
+{
+ result = type->methods;
+}
+
+ScriptingTypePtr scripting_class_from_systemtypeinstance(ScriptingObjectPtr type, ScriptingTypeRegistry& typeRegistry)
+{
+ FakeSystemTypeInstance* sti = (FakeSystemTypeInstance*) type;
+ return typeRegistry.GetType(sti->nativeType);
+}
+
+#endif
diff --git a/Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.h b/Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.h
new file mode 100644
index 0000000..2ab7765
--- /dev/null
+++ b/Runtime/Scripting/Backend/Tests/ScriptingBackendApi_Tests.h
@@ -0,0 +1,30 @@
+#ifndef _SCRIPTINGBACKENDAPI_TESTS_H_
+#define _SCRIPTINGBACKENDAPI_TESTS_H_
+
+#if DEDICATED_UNIT_TEST_BUILD
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include <vector>
+
+struct ScriptingType
+{
+ ScriptingTypePtr baseType;
+ ScriptingType() : baseType(NULL) {}
+
+ std::vector<ScriptingMethodPtr> methods;
+};
+
+struct ScriptingMethod
+{
+ bool instance;
+ int args;
+
+ ScriptingMethod() : instance(false), args(0) {}
+};
+
+struct FakeSystemTypeInstance
+{
+ void* nativeType;
+};
+
+#endif
+#endif
diff --git a/Runtime/Scripting/CommonScriptingClasses.cpp b/Runtime/Scripting/CommonScriptingClasses.cpp
new file mode 100644
index 0000000..6a7d266
--- /dev/null
+++ b/Runtime/Scripting/CommonScriptingClasses.cpp
@@ -0,0 +1,268 @@
+#include "UnityPrefix.h"
+#if ENABLE_SCRIPTING
+#include "CommonScriptingClasses.h"
+#include "Runtime/Mono/MonoIncludes.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Mono/MonoManager.h"
+#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+static ScriptingMethodPtr OptionalMethod(const char* namespaze, const char* klass, const char* name)
+{
+ return GetScriptingManager().GetScriptingMethodRegistry().GetMethod(namespaze,klass,name);
+}
+
+static ScriptingMethodPtr RequireMethod(const char* namespaze, const char* klass, const char* name)
+{
+ ScriptingMethodPtr method = GetScriptingManager().GetScriptingMethodRegistry().GetMethod(namespaze,klass,name);
+ if (!method)
+ ErrorString(Format("Unable to find method %s in %s",name,klass));
+ return method;
+}
+
+
+static ScriptingTypePtr OptionalType(const char* namespaze, const char* name)
+{
+ return GetScriptingTypeRegistry().GetType(namespaze,name);
+}
+
+static ScriptingTypePtr RequireType(const char* namespaze, const char* name)
+{
+ ScriptingTypePtr t = OptionalType(namespaze,name);
+ if (!t)
+ ErrorString(Format("Unable to find type %s.%s",namespaze,name));
+ return t;
+}
+
+static ScriptingTypePtr RequireUnityEngineType(const char* name)
+{
+ return RequireType("UnityEngine",name);
+}
+
+static ScriptingTypePtr OptionalUnityEngineType(const char* name)
+{
+ return OptionalType("UnityEngine",name);
+}
+
+void FillCommonScriptingClasses(CommonScriptingClasses& commonScriptingClasses)
+{
+ ScriptingTypeRegistry& typeRegistry = GetScriptingManager().GetScriptingTypeRegistry();
+
+#if ENABLE_SCRIPTING
+ commonScriptingClasses.monoBehaviour = RequireUnityEngineType ("MonoBehaviour");
+ commonScriptingClasses.component = RequireUnityEngineType ("Component");
+ commonScriptingClasses.scriptableObject = RequireUnityEngineType ("ScriptableObject");
+ commonScriptingClasses.vector2 = RequireUnityEngineType ("Vector2");
+ commonScriptingClasses.vector3 = RequireUnityEngineType ("Vector3");
+ commonScriptingClasses.vector4 = RequireUnityEngineType ("Vector4");
+ commonScriptingClasses.rect = RequireUnityEngineType ("Rect");
+ commonScriptingClasses.rectOffset = RequireUnityEngineType ("RectOffset");
+ commonScriptingClasses.quaternion = RequireUnityEngineType ("Quaternion");
+ commonScriptingClasses.matrix4x4 = RequireUnityEngineType ("Matrix4x4");
+ commonScriptingClasses.bounds = RequireUnityEngineType ("Bounds");
+ commonScriptingClasses.resolution = RequireUnityEngineType ("Resolution");
+ commonScriptingClasses.particle = RequireUnityEngineType ("Particle");
+ commonScriptingClasses.color = RequireUnityEngineType ("Color");
+ commonScriptingClasses.color32 = RequireUnityEngineType ("Color32");
+ commonScriptingClasses.raycastHit = OptionalUnityEngineType ("RaycastHit");
+ commonScriptingClasses.raycastHit2D = OptionalUnityEngineType ("RaycastHit2D");
+ commonScriptingClasses.animationState = OptionalUnityEngineType ("AnimationState");
+ commonScriptingClasses.collider = OptionalUnityEngineType ("Collider");
+ commonScriptingClasses.camera = RequireUnityEngineType ("Camera");
+ commonScriptingClasses.renderTexture = RequireUnityEngineType ("RenderTexture");
+ commonScriptingClasses.layerMask = RequireUnityEngineType ("LayerMask");
+ commonScriptingClasses.waitForSeconds = RequireUnityEngineType ("WaitForSeconds");
+ commonScriptingClasses.waitForFixedUpdate = RequireUnityEngineType ("WaitForFixedUpdate");
+ commonScriptingClasses.waitForEndOfFrame = RequireUnityEngineType ("WaitForEndOfFrame");
+ commonScriptingClasses.characterInfo = RequireUnityEngineType ("CharacterInfo");
+ commonScriptingClasses.font_InvokeFontTextureRebuildCallback_Internal = RequireMethod ("UnityEngine","Font","InvokeFontTextureRebuildCallback_Internal");
+#if ENABLE_WWW
+ commonScriptingClasses.www = OptionalUnityEngineType ("WWW");
+#endif
+#if UNITY_WII
+ commonScriptingClasses.waitAsyncOperationFinish = GetBuiltinScriptingClass ("WaitAsyncOperationFinish");
+#endif
+ commonScriptingClasses.lodMesh = OptionalUnityEngineType ("Mesh");
+ commonScriptingClasses.coroutine = RequireUnityEngineType ("Coroutine");
+ commonScriptingClasses.collision = OptionalUnityEngineType ("Collision");
+ commonScriptingClasses.contactPoint = OptionalUnityEngineType ("ContactPoint");
+ commonScriptingClasses.controllerColliderHit = OptionalUnityEngineType ("ControllerColliderHit");
+ commonScriptingClasses.collision2D = OptionalUnityEngineType ("Collision2D");
+ commonScriptingClasses.contactPoint2D = OptionalUnityEngineType ("ContactPoint2D");
+ commonScriptingClasses.unityEngineObject = RequireUnityEngineType ("Object");
+ commonScriptingClasses.event = RequireUnityEngineType ("Event");
+#if ENABLE_MONO
+ commonScriptingClasses.serializeField = RequireUnityEngineType ("SerializeField");
+ commonScriptingClasses.serializePrivateVariables = GetBuiltinScriptingClass ("SerializePrivateVariables");
+ commonScriptingClasses.hideInInspector = GetBuiltinScriptingClass ("HideInInspector");
+#endif
+#if ENABLE_NETWORK
+ commonScriptingClasses.RPC = OptionalUnityEngineType ("RPC");
+ commonScriptingClasses.hostData = OptionalUnityEngineType ("HostData");
+ commonScriptingClasses.bitStream = OptionalUnityEngineType ("BitStream");
+ commonScriptingClasses.networkPlayer = OptionalUnityEngineType ("NetworkPlayer");
+ commonScriptingClasses.networkViewID = OptionalUnityEngineType ("NetworkViewID");
+ commonScriptingClasses.networkMessageInfo = OptionalUnityEngineType ("NetworkMessageInfo");
+#endif // ENABLE_NETWORK
+ commonScriptingClasses.guiStyle = RequireUnityEngineType ("GUIStyle");
+ commonScriptingClasses.animationCurve = RequireUnityEngineType ("AnimationCurve");
+ commonScriptingClasses.boneWeight = RequireUnityEngineType ("BoneWeight");
+#if ENABLE_TERRAIN
+ commonScriptingClasses.terrain = OptionalUnityEngineType("Terrain");
+ commonScriptingClasses.detailPrototype = OptionalUnityEngineType ("DetailPrototype");
+ commonScriptingClasses.treePrototype = OptionalUnityEngineType ("TreePrototype");
+ commonScriptingClasses.treeInstance = OptionalUnityEngineType ("TreeInstance");
+ commonScriptingClasses.splatPrototype = OptionalUnityEngineType ("SplatPrototype");
+#endif
+ commonScriptingClasses.animationEvent = RequireUnityEngineType ("AnimationEvent");
+ commonScriptingClasses.assetBundleRequest = RequireUnityEngineType ("AssetBundleRequest");
+ commonScriptingClasses.asyncOperation = RequireUnityEngineType ("AsyncOperation");
+#if ENABLE_WWW
+ commonScriptingClasses.assetBundleCreateRequest = RequireUnityEngineType ("AssetBundleCreateRequest");
+ // Stop scaring the customers and only load this when it's needed and available
+ commonScriptingClasses.cacheIndex = RequireUnityEngineType ("CacheIndex");
+#else
+ commonScriptingClasses.cacheIndex = SCRIPTING_NULL;
+#endif
+ commonScriptingClasses.cachedFile = OptionalUnityEngineType ("CachedFile");
+
+ commonScriptingClasses.keyframe = RequireUnityEngineType ("Keyframe");
+ commonScriptingClasses.inputEvent = RequireUnityEngineType ("Event");
+ commonScriptingClasses.imageEffectOpaque = OptionalUnityEngineType ("ImageEffectOpaque");
+ commonScriptingClasses.imageEffectTransformsToLDR = OptionalUnityEngineType ("ImageEffectTransformsToLDR");
+ commonScriptingClasses.iEnumerator = typeRegistry.GetType("System.Collections", "IEnumerator");
+ commonScriptingClasses.systemObject = typeRegistry.GetType("System","Object");
+
+
+ commonScriptingClasses.string = typeRegistry.GetType("System", "String");
+ commonScriptingClasses.int_32 = typeRegistry.GetType("System", "Int32");
+ commonScriptingClasses.floatSingle = typeRegistry.GetType("System", "Single");
+ commonScriptingClasses.floatDouble = typeRegistry.GetType("System", "Double");
+ commonScriptingClasses.byte = typeRegistry.GetType("System", "Byte");
+
+#if ENABLE_MONO || UNITY_WINRT
+ commonScriptingClasses.intptr = typeRegistry.GetType("System", "IntPtr");
+ commonScriptingClasses.uInt_16 = typeRegistry.GetType("System", "UInt16");
+ commonScriptingClasses.uInt_32 = typeRegistry.GetType("System", "UInt32");
+ commonScriptingClasses.int_16 = typeRegistry.GetType("System", "Int16");
+ commonScriptingClasses.multicastDelegate = typeRegistry.GetType("System", "MulticastDelegate");
+ commonScriptingClasses.extractRequiredComponents = RequireMethod ("UnityEngine","AttributeHelperEngine", "GetRequiredComponents");
+#endif
+
+#if ENABLE_MONO || UNITY_WP8
+ commonScriptingClasses.invokeMember = RequireMethod ("UnityEngine","SetupCoroutine", "InvokeMember");
+ commonScriptingClasses.invokeStatic = RequireMethod ("UnityEngine","SetupCoroutine", "InvokeStatic");
+#endif
+#if ENABLE_MONO
+ commonScriptingClasses.checkIsEditMode = RequireMethod ("UnityEngine","AttributeHelperEngine", "CheckIsEditorScript");
+ commonScriptingClasses.extractStacktrace = RequireMethod ("UnityEngine","StackTraceUtility", "ExtractStackTrace");
+ commonScriptingClasses.extractStringFromException = RequireMethod ("UnityEngine","StackTraceUtility", "ExtractStringFromExceptionInternal");
+ commonScriptingClasses.postprocessStacktrace = RequireMethod ("UnityEngine","StackTraceUtility", "PostprocessStacktrace");
+#endif
+
+ commonScriptingClasses.IEnumerator_MoveNext = RequireMethod("System.Collections", "IEnumerator","MoveNext");
+#if ENABLE_MONO || UNITY_WINRT
+ commonScriptingClasses.callLogCallback = RequireMethod ("UnityEngine", "Application", "CallLogCallback");
+ commonScriptingClasses.IEnumerator_Current = GetScriptingMethodRegistry().GetMethod("System.Collections", "IEnumerator","get_Current");
+ commonScriptingClasses.IDisposable_Dispose = GetScriptingMethodRegistry().GetMethod("System", "IDisposable","Dispose");
+#endif
+
+ commonScriptingClasses.beginGUI = RequireMethod ("UnityEngine", "GUIUtility", "BeginGUI");
+ commonScriptingClasses.endGUI = RequireMethod ("UnityEngine", "GUIUtility", "EndGUI");
+ commonScriptingClasses.callGUIWindowDelegate = RequireMethod ("UnityEngine", "GUI", "CallWindowDelegate");
+ commonScriptingClasses.makeMasterEventCurrent = RequireMethod ("UnityEngine", "Event", "Internal_MakeMasterEventCurrent");
+ commonScriptingClasses.doSendMouseEvents = RequireMethod ("UnityEngine", "SendMouseEvents", "DoSendMouseEvents");
+
+#if ENABLE_MONO
+ commonScriptingClasses.stackTraceUtilitySetProjectFolder = RequireMethod ("UnityEngine", "StackTraceUtility", "SetProjectFolder");
+#endif
+
+#if ENABLE_MONO
+ commonScriptingClasses.enumClass = mono_get_enum_class ();
+ commonScriptingClasses.floatSingleArray = mono_array_class_get(commonScriptingClasses.floatSingle, 1);
+#endif // ENABLE_MONO
+
+
+#if UNITY_EDITOR
+ commonScriptingClasses.monoReloadableIntPtr = GetMonoManager().GetBuiltinEditorMonoClass ("MonoReloadableIntPtr");
+ commonScriptingClasses.monoReloadableIntPtrClear = GetMonoManager().GetBuiltinEditorMonoClass ("MonoReloadableIntPtrClear");
+ commonScriptingClasses.gameViewStatsGUI = RequireMethod ("UnityEditor", "GameViewGUI", "GameViewStatsGUI");
+ commonScriptingClasses.beginHandles = RequireMethod ("UnityEditor", "HandleUtility", "BeginHandles");
+ commonScriptingClasses.endHandles = RequireMethod ("UnityEditor", "HandleUtility", "EndHandles");
+ commonScriptingClasses.setViewInfo = RequireMethod ("UnityEditor", "HandleUtility", "SetViewInfo");
+ commonScriptingClasses.handleControlID = RequireMethod ("UnityEditor","EditorGUIUtility","HandleControlID");
+ commonScriptingClasses.callGlobalEventHandler = RequireMethod ("UnityEditor", "EditorApplication", "Internal_CallGlobalEventHandler");
+ commonScriptingClasses.callAnimationClipAwake = RequireMethod ("UnityEditor", "AnimationUtility", "Internal_CallAnimationClipAwake");
+ commonScriptingClasses.statusBarChanged = RequireMethod ("UnityEditor", "AppStatusBar", "StatusChanged");
+ commonScriptingClasses.lightmappingDone = RequireMethod ("UnityEditor", "LightmappingWindow", "LightmappingDone");
+ commonScriptingClasses.consoleLogChanged = RequireMethod ("UnityEditor", "ConsoleWindow", "LogChanged");
+ commonScriptingClasses.clearUndoSnapshotTarget = RequireMethod ("UnityEditor", "Undo", "ClearSnapshotTarget");
+ commonScriptingClasses.repaintAllProfilerWindows = RequireMethod ("UnityEditor", "ProfilerWindow", "RepaintAllProfilerWindows");
+ commonScriptingClasses.getGameViewAspectRatio = RequireMethod ("UnityEditor", "CameraEditor", "GetGameViewAspectRatio");
+ commonScriptingClasses.substanceMaterialInformation = RequireType("UnityEditor", "ProceduralMaterialInformation" );
+ commonScriptingClasses.propertyModification = RequireType("UnityEditor", "PropertyModification" );
+ commonScriptingClasses.undoPropertyModification = RequireType("UnityEditor", "UndoPropertyModification" );
+ commonScriptingClasses.callbackOrderAttribute = RequireType("UnityEditor", "CallbackOrderAttribute" );
+ commonScriptingClasses.postProcessBuildAttribute = RequireType ("UnityEditor.Callbacks", "PostProcessBuildAttribute");
+ commonScriptingClasses.postProcessSceneAttribute = RequireType ("UnityEditor.Callbacks", "PostProcessSceneAttribute");
+ commonScriptingClasses.didReloadScripts = RequireType ("UnityEditor.Callbacks", "DidReloadScripts");
+ commonScriptingClasses.onOpenAssetAttribute = RequireType ("UnityEditor.Callbacks", "OnOpenAssetAttribute");
+
+ commonScriptingClasses.animationClipSettings = RequireType ("UnityEditor","AnimationClipSettings");
+ commonScriptingClasses.muscleClipQualityInfo = RequireType ("UnityEditor","MuscleClipQualityInfo");
+#endif // UNITY_EDITOR
+
+ commonScriptingClasses.gradient = RequireUnityEngineType ("Gradient");
+ commonScriptingClasses.gradientColorKey = RequireUnityEngineType ("GradientColorKey");
+ commonScriptingClasses.gradientAlphaKey = RequireUnityEngineType ("GradientAlphaKey");
+
+#if ENABLE_SUBSTANCE
+ commonScriptingClasses.substancePropertyDescription = OptionalUnityEngineType ("ProceduralPropertyDescription");
+#endif
+
+ commonScriptingClasses.animatorStateInfo= RequireUnityEngineType ("AnimatorStateInfo");
+ commonScriptingClasses.animatorTransitionInfo= RequireUnityEngineType ("AnimatorTransitionInfo");
+ commonScriptingClasses.animationInfo= RequireUnityEngineType ("AnimationInfo");
+ commonScriptingClasses.skeletonBone = RequireUnityEngineType ("SkeletonBone");
+ commonScriptingClasses.humanBone = RequireUnityEngineType ("HumanBone");
+
+#if ENABLE_GAMECENTER
+ commonScriptingClasses.gameCenter = GetMonoManager().GetMonoClass("GameCenterPlatform", "UnityEngine.SocialPlatforms.GameCenter");
+ commonScriptingClasses.gcAchievement = GetMonoManager().GetMonoClass("GcAchievementData", "UnityEngine.SocialPlatforms.GameCenter");
+ commonScriptingClasses.gcAchievementDescription = GetMonoManager().GetMonoClass("GcAchievementDescriptionData", "UnityEngine.SocialPlatforms.GameCenter");
+ commonScriptingClasses.gcScore = GetMonoManager().GetMonoClass("GcScoreData", "UnityEngine.SocialPlatforms.GameCenter");
+ commonScriptingClasses.gcUserProfile = GetMonoManager().GetMonoClass("GcUserProfileData", "UnityEngine.SocialPlatforms.GameCenter");
+#endif
+
+#if ENABLE_WEBCAM
+ // We support stripping there
+ #if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_TIZEN
+ commonScriptingClasses.webCamDevice = OptionalUnityEngineType("WebCamDevice");
+ #else
+ commonScriptingClasses.webCamDevice = RequireUnityEngineType("WebCamDevice");
+ #endif
+#endif
+
+ commonScriptingClasses.display = RequireUnityEngineType("Display");
+ commonScriptingClasses.displayRecreateDisplayList = RequireMethod("UnityEngine","Display","RecreateDisplayList");
+ commonScriptingClasses.displayFireDisplaysUpdated = RequireMethod("UnityEngine","Display","FireDisplaysUpdated");
+
+#if UNITY_IPHONE
+ commonScriptingClasses.adBannerView = OptionalUnityEngineType("ADBannerView");
+ commonScriptingClasses.adInterstitialAd = OptionalUnityEngineType("ADInterstitialAd");
+ commonScriptingClasses.adFireBannerWasClicked = OptionalMethod ("UnityEngine", "ADBannerView", "FireBannerWasClicked");
+ commonScriptingClasses.adFireBannerWasLoaded = OptionalMethod ("UnityEngine", "ADBannerView", "FireBannerWasLoaded");
+ commonScriptingClasses.adFireInterstitialWasLoaded = OptionalMethod ("UnityEngine", "ADInterstitialAd", "FireInterstitialWasLoaded");
+#endif
+
+
+#endif
+}
+
+void ClearCommonScriptingClasses(CommonScriptingClasses& commonScriptingClasses)
+{
+ memset(&commonScriptingClasses, 0, sizeof(commonScriptingClasses));
+}
+
+#endif
diff --git a/Runtime/Scripting/CommonScriptingClasses.h b/Runtime/Scripting/CommonScriptingClasses.h
new file mode 100644
index 0000000..6699706
--- /dev/null
+++ b/Runtime/Scripting/CommonScriptingClasses.h
@@ -0,0 +1,206 @@
+#pragma once
+#if ENABLE_SCRIPTING
+#include "Runtime/Mono/MonoTypes.h"
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+
+struct CommonScriptingClasses
+{
+ ScriptingClassPtr monoBehaviour;
+ ScriptingClassPtr component;
+ ScriptingClassPtr scriptableObject;
+ ScriptingClassPtr vector2;
+ ScriptingClassPtr vector3;
+ ScriptingClassPtr vector4;
+ ScriptingClassPtr rect;
+ ScriptingClassPtr rectOffset;
+ ScriptingClassPtr quaternion;
+ ScriptingClassPtr matrix4x4;
+ ScriptingClassPtr bounds;
+ ScriptingClassPtr resolution;
+ ScriptingClassPtr particle;
+ ScriptingClassPtr color;
+ ScriptingClassPtr color32;
+ ScriptingClassPtr raycastHit;
+ ScriptingClassPtr raycastHit2D;
+ ScriptingClassPtr animationState;
+ ScriptingClassPtr collider;
+ ScriptingClassPtr camera;
+ ScriptingClassPtr renderTexture;
+ ScriptingClassPtr layerMask;
+ ScriptingClassPtr serializeField;
+ ScriptingClassPtr enumClass;
+ ScriptingClassPtr iEnumerator;
+ ScriptingClassPtr systemObject;
+
+#if !UNITY_FLASH
+ ScriptingClassPtr intptr;
+ ScriptingClassPtr uInt_16;
+ ScriptingClassPtr uInt_32;
+ ScriptingClassPtr int_16;
+ ScriptingClassPtr multicastDelegate;
+#endif
+
+ ScriptingClassPtr byte;
+ ScriptingClassPtr int_32;
+ ScriptingClassPtr string;
+ ScriptingClassPtr floatSingle;
+ ScriptingClassPtr floatDouble;
+ ScriptingClassPtr waitForSeconds;
+ ScriptingClassPtr waitForFixedUpdate;
+ ScriptingClassPtr waitForEndOfFrame;
+
+ ScriptingClassPtr characterInfo;
+ ScriptingMethodPtr font_InvokeFontTextureRebuildCallback_Internal;
+#if ENABLE_WWW
+ ScriptingClassPtr assetBundleCreateRequest;
+ ScriptingClassPtr www;
+#endif
+#if UNITY_WII || UNITY_PS3 || UNITY_XENON
+ ScriptingClassPtr waitAsyncOperationFinish;
+#endif
+ ScriptingClassPtr meshData;
+ ScriptingClassPtr lodMesh;
+ ScriptingClassPtr coroutine;
+ ScriptingClassPtr collision;
+ ScriptingClassPtr contactPoint;
+ ScriptingClassPtr controllerColliderHit;
+ ScriptingClassPtr collision2D;
+ ScriptingClassPtr contactPoint2D;
+ ScriptingClassPtr event;
+ ScriptingClassPtr unityEngineObject;
+ ScriptingClassPtr hideInInspector;
+ ScriptingClassPtr serializePrivateVariables;
+#if ENABLE_NETWORK
+ ScriptingClassPtr RPC;
+ ScriptingClassPtr hostData;
+ ScriptingClassPtr bitStream;
+ ScriptingClassPtr networkPlayer;
+ ScriptingClassPtr networkViewID;
+ ScriptingClassPtr networkMessageInfo;
+#endif
+
+ ScriptingClassPtr guiStyle;
+ ScriptingClassPtr animationCurve;
+ ScriptingClassPtr keyframe;
+ ScriptingClassPtr boneWeight;
+
+#if ENABLE_MONO || UNITY_WP8
+ ScriptingMethodPtr invokeMember;
+ ScriptingMethodPtr invokeStatic;
+#endif
+#if ENABLE_MONO
+ ScriptingMethodPtr checkIsEditMode;
+ ScriptingMethodPtr extractStacktrace;
+ ScriptingMethodPtr extractStringFromException;
+ ScriptingMethodPtr postprocessStacktrace;
+#endif
+ ScriptingMethodPtr IEnumerator_MoveNext;
+#if ENABLE_MONO || UNITY_WINRT
+ ScriptingMethodPtr callLogCallback;
+ ScriptingMethodPtr IEnumerator_Current;
+ ScriptingMethodPtr IDisposable_Dispose;
+ ScriptingMethodPtr extractRequiredComponents;
+#endif
+
+ ScriptingMethodPtr beginGUI;
+ ScriptingMethodPtr endGUI;
+ ScriptingMethodPtr callGUIWindowDelegate;
+
+#if ENABLE_TERRAIN
+ ScriptingClassPtr terrain;
+ ScriptingClassPtr detailPrototype;
+ ScriptingClassPtr treePrototype;
+ ScriptingClassPtr treeInstance;
+ ScriptingClassPtr splatPrototype;
+#endif
+ ScriptingClassPtr animationEvent;
+ ScriptingClassPtr assetBundleRequest;
+ ScriptingClassPtr asyncOperation;
+ ScriptingClassPtr cacheIndex;
+ ScriptingClassPtr cachedFile;
+ ScriptingClassPtr inputEvent;
+ ScriptingClassPtr imageEffectOpaque;
+ ScriptingClassPtr muscleBoneInfo;
+ ScriptingClassPtr animationClipSettings;
+ ScriptingClassPtr muscleClipQualityInfo;
+ ScriptingClassPtr imageEffectTransformsToLDR;
+
+ ScriptingMethodPtr makeMasterEventCurrent;
+ ScriptingMethodPtr doSendMouseEvents;
+ ScriptingMethodPtr stackTraceUtilitySetProjectFolder;
+
+
+
+#if UNITY_EDITOR
+ ScriptingClassPtr monoReloadableIntPtr;
+ ScriptingClassPtr monoReloadableIntPtrClear;
+ ScriptingMethodPtr gameViewStatsGUI;
+ ScriptingMethodPtr beginHandles;
+ ScriptingMethodPtr endHandles;
+ ScriptingMethodPtr setViewInfo;
+ ScriptingMethodPtr handleControlID;
+ ScriptingMethodPtr callGlobalEventHandler;
+ ScriptingMethodPtr callAnimationClipAwake;
+ ScriptingMethodPtr statusBarChanged;
+ ScriptingMethodPtr lightmappingDone;
+ ScriptingMethodPtr consoleLogChanged;
+ ScriptingMethodPtr clearUndoSnapshotTarget;
+ ScriptingMethodPtr repaintAllProfilerWindows;
+ ScriptingMethodPtr getGameViewAspectRatio;
+ ScriptingClassPtr substanceMaterialInformation;
+ ScriptingClassPtr propertyModification;
+ ScriptingClassPtr undoPropertyModification;
+ ScriptingClassPtr exportExtensionClassAttribute;
+#endif // #if UNITY_EDITOR
+
+ ScriptingClassPtr gradient;
+ ScriptingClassPtr gradientColorKey;
+ ScriptingClassPtr gradientAlphaKey;
+ ScriptingClassPtr callbackOrderAttribute;
+ ScriptingClassPtr postProcessBuildAttribute;
+ ScriptingClassPtr postProcessSceneAttribute;
+ ScriptingClassPtr didReloadScripts;
+ ScriptingClassPtr onOpenAssetAttribute;
+
+#if ENABLE_SUBSTANCE
+ ScriptingClassPtr substancePropertyDescription;
+#endif
+
+ ScriptingClassPtr animatorStateInfo;
+ ScriptingClassPtr animatorTransitionInfo;
+ ScriptingClassPtr animationInfo;
+ ScriptingClassPtr floatSingleArray;
+ ScriptingClassPtr skeletonBone;
+ ScriptingClassPtr humanBone;
+
+#if ENABLE_GAMECENTER
+ ScriptingClassPtr gameCenter;
+ ScriptingClassPtr gcScore;
+ ScriptingClassPtr gcAchievement;
+ ScriptingClassPtr gcAchievementDescription;
+ ScriptingClassPtr gcUserProfile;
+#endif
+
+#if ENABLE_WEBCAM
+ ScriptingClassPtr webCamDevice;
+#endif
+
+ ScriptingClassPtr display;
+ ScriptingMethodPtr displayRecreateDisplayList;
+ ScriptingMethodPtr displayFireDisplaysUpdated;
+
+#if UNITY_IPHONE
+ ScriptingClassPtr adBannerView;
+ ScriptingClassPtr adInterstitialAd;
+ ScriptingMethodPtr adFireBannerWasClicked;
+ ScriptingMethodPtr adFireBannerWasLoaded;
+ ScriptingMethodPtr adFireInterstitialWasLoaded;
+#endif
+};
+
+void FillCommonScriptingClasses(CommonScriptingClasses& commonScriptingClasses);
+void ClearCommonScriptingClasses(CommonScriptingClasses& commonScriptingClasses);
+
+#define MONO_COMMON GetScriptingManager().GetCommonClasses()
+
+#endif
diff --git a/Runtime/Scripting/DelayedCallUtility.cpp b/Runtime/Scripting/DelayedCallUtility.cpp
new file mode 100644
index 0000000..5e7d9f0
--- /dev/null
+++ b/Runtime/Scripting/DelayedCallUtility.cpp
@@ -0,0 +1,73 @@
+#include "UnityPrefix.h"
+
+#if ENABLE_SCRIPTING
+
+#include "Runtime/Scripting/DelayedCallUtility.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/GameCode/CallDelayed.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#include "Runtime/Mono/MonoScript.h"
+
+static void ForwardInvokeDelayed (Object* o, void* userData)
+{
+ const char* methodName = (const char*)userData;
+ MonoBehaviour* behaviour = static_cast<MonoBehaviour*> (o);
+ if (behaviour->GetInstance ())
+ {
+ bool didCall = behaviour->CallMethodInactive (methodName);
+ #if !DEPLOY_OPTIMIZED
+ if (!didCall)
+ LogStringObject ("Trying to Invoke method: " + behaviour->GetScript ()->GetScriptClassName () + "." + methodName + " couldn't be called.", o);
+ #else
+ UNUSED(didCall);
+ #endif
+
+ }
+}
+
+static void ForwardInvokeDelayedCleanup (void* userData)
+{
+ ScriptingStringToAllocatedChars_Free ((char*)userData);
+}
+
+void InvokeDelayed (MonoBehaviour& behaviour, ICallString& monoMethodName, float time, float repeatRate)
+{
+ char* methodName = ScriptingStringToAllocatedChars (monoMethodName);
+ if (repeatRate > 0.00001F || repeatRate == 0.0F)
+ CallDelayed (&ForwardInvokeDelayed, &behaviour, time, methodName, repeatRate, &ForwardInvokeDelayedCleanup);
+ else
+ Scripting::RaiseMonoException ("Invoke repeat rate has to be larger than 0.00001F)");
+}
+
+
+static bool ShouldCancelInvoke (void* lhs, void* rhs)
+{
+ return strcmp ((char*)lhs, (char*)rhs) == 0;
+}
+
+void CancelInvoke (MonoBehaviour& behaviour, ICallString& monoMethodName)
+{
+ char* methodName = ScriptingStringToAllocatedChars (monoMethodName);
+ GetDelayedCallManager ().CancelCallDelayed (&behaviour, &ForwardInvokeDelayed, &ShouldCancelInvoke, methodName);
+ ScriptingStringToAllocatedChars_Free (methodName);
+}
+
+void CancelInvoke (MonoBehaviour& behaviour)
+{
+ GetDelayedCallManager ().CancelCallDelayed (&behaviour, &ForwardInvokeDelayed, NULL, NULL);
+}
+
+bool IsInvoking (MonoBehaviour& behaviour)
+{
+ return GetDelayedCallManager ().HasDelayedCall (&behaviour, &ForwardInvokeDelayed, NULL, NULL);
+}
+
+bool IsInvoking (MonoBehaviour& behaviour, ICallString& monoMethodName)
+{
+ char* methodName = ScriptingStringToAllocatedChars (monoMethodName);
+ bool result = GetDelayedCallManager ().HasDelayedCall (&behaviour, &ForwardInvokeDelayed, &ShouldCancelInvoke, methodName);
+ ScriptingStringToAllocatedChars_Free (methodName);
+ return result;
+}
+
+#endif
diff --git a/Runtime/Scripting/DelayedCallUtility.h b/Runtime/Scripting/DelayedCallUtility.h
new file mode 100644
index 0000000..aae493d
--- /dev/null
+++ b/Runtime/Scripting/DelayedCallUtility.h
@@ -0,0 +1,16 @@
+#ifndef _DELAYEDCALLUTILITYH_
+#define _DELAYEDCALLUTILITYH_
+
+#if ENABLE_SCRIPTING
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Runtime/Scripting/ICallString.h"
+
+class MonoBehaviour;
+
+void InvokeDelayed (MonoBehaviour& behaviour, ICallString& monoMethodName, float time, float repeatRate);
+void CancelInvoke (MonoBehaviour& behaviour, ICallString& monoMethodName);
+void CancelInvoke (MonoBehaviour& behaviour);
+bool IsInvoking (MonoBehaviour& behaviour, ICallString& monoMethodName);
+bool IsInvoking (MonoBehaviour& behaviour);
+#endif
+#endif
diff --git a/Runtime/Scripting/GetComponent.cpp b/Runtime/Scripting/GetComponent.cpp
new file mode 100644
index 0000000..d30bb41
--- /dev/null
+++ b/Runtime/Scripting/GetComponent.cpp
@@ -0,0 +1,260 @@
+#include "UnityPrefix.h"
+#if ENABLE_SCRIPTING
+#include "ScriptingUtility.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#include "Runtime/Mono/MonoManager.h"
+#include "Runtime/Graphics/Transform.h"
+#include "Runtime/Misc/GameObjectUtility.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Scripting/ScriptingExportUtility.h"
+#include "Runtime/Animation/Animation.h"
+#include "Runtime/Camera/Camera.h"
+#include "Runtime/Utilities/dense_hash_map.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Scripting/Scripting.h"
+
+inline static bool ComponentMatchesRequirement_ByScriptingClass(Unity::GameObject& go, int componentIndex, ScriptingClassPtr compareClass)
+{
+ int classID = go.GetComponentClassIDAtIndex(componentIndex);
+ if (classID != ClassID (MonoBehaviour))
+ return false;
+
+ Unity::Component& component = go.GetComponentAtIndex(componentIndex);
+ MonoBehaviour& behaviour = static_cast<MonoBehaviour&> (component);
+ ScriptingClassPtr klass = behaviour.GetClass ();
+ if (klass == SCRIPTING_NULL)
+ return false;
+
+ if (klass == compareClass)
+ return true;
+
+ return scripting_class_is_subclass_of (klass, compareClass);
+}
+
+inline static bool ComponentMatchesRequirement_ByClassID(Unity::GameObject& go, int componentIndex, int compareClassID, bool isCompareClassSealed)
+{
+ int classID = go.GetComponentClassIDAtIndex(componentIndex);
+
+ if (classID == compareClassID)
+ return true;
+
+ if (isCompareClassSealed)
+ return false;
+
+ return Object::IsDerivedFromClassID(classID,compareClassID);
+}
+
+namespace SearchMethod
+{
+ enum {
+ ByClassID,
+ ByScriptingClass,
+ DontEvenStart
+ };
+}
+
+template<bool getOnlyOne, int searchMethod>
+static bool GetComponentsImplementation (GameObject& go, bool includeInactive, void* compareData, void* output)
+{
+ if (!includeInactive && !go.IsActive())
+ return false;
+
+ bool foundAtLeastOne = false;
+
+ bool isSealed;
+ UInt64 compareClassID = (UInt64)(uintptr_t)(compareData);
+ if (searchMethod == SearchMethod::ByClassID)
+ {
+ Assert(Transform::IsSealedClass());
+ Assert(Animation::IsSealedClass());
+ Assert(Camera::IsSealedClass());
+ isSealed = compareClassID == ClassID(Transform) || compareClassID == ClassID(Animation) || compareClassID == ClassID(Camera);
+ }
+
+ int count = go.GetComponentCount ();
+ for (int i = 0; i < count; i++)
+ {
+ if (searchMethod == SearchMethod::ByClassID && !ComponentMatchesRequirement_ByClassID(go,i,compareClassID,isSealed))
+ continue;
+
+ if (searchMethod == SearchMethod::ByScriptingClass && !ComponentMatchesRequirement_ByScriptingClass(go,i, reinterpret_cast<ScriptingClassPtr>(compareData)))
+ continue;
+
+ Unity::Component* component = &go.GetComponentAtIndex(i);
+ if (getOnlyOne)
+ {
+ *((Unity::Component**) output) = component;
+ return true;
+ }
+
+ dynamic_array<Unity::Component*>* manyResults = (dynamic_array<Unity::Component*>*) output;
+ if (manyResults->empty())
+ manyResults->reserve(10);
+ manyResults->push_back(component);
+ foundAtLeastOne = true;
+ }
+
+ return foundAtLeastOne;
+}
+
+template<bool getOnlyOne, int searchMethod>
+static bool GetComponentsImplementationRecurse (GameObject& go, bool includeInactive, void* compareData, void* output)
+{
+ bool foundAtLeastOne = GetComponentsImplementation<getOnlyOne, searchMethod>(go,includeInactive,compareData,output);
+ if (foundAtLeastOne && getOnlyOne)
+ return true;
+
+ // Recurse Transform hierarchy
+ Transform& transform = go.GetComponentT<Transform> (ClassID (Transform));
+ int count = transform.GetChildrenCount();
+ for (int i = 0; i < count; i++)
+ {
+ Transform& child = transform.GetChild(i);
+ foundAtLeastOne = GetComponentsImplementationRecurse<getOnlyOne,searchMethod>(child.GetGameObject(), includeInactive, compareData,output);
+ if (foundAtLeastOne && getOnlyOne)
+ return true;
+ }
+ return false;
+}
+
+#if MONO_QUALITY_ERRORS
+static bool ScriptingClassIsValidGetComponentArgument(ScriptingClass* compareClass)
+{
+ if (mono_class_is_subclass_of(compareClass, GetMonoManager().GetCommonClasses().component, true))
+ return true;
+
+ if (mono_unity_class_is_interface(compareClass))
+ return true;
+
+ return false;
+}
+
+
+static void VerifyGetComponentsOfTypeFromGameObjectArgument(GameObject& go, ScriptingClassPtr compareKlass)
+{
+ if (compareKlass == NULL)
+ {
+ ScriptWarning("GetComponent asking for invalid type", &go);
+ return;
+ }
+
+ if (ScriptingClassIsValidGetComponentArgument(compareKlass))
+ return;
+
+ const char* klassName = mono_class_get_name (compareKlass);
+ ScriptWarning(Format("GetComponent requires that the requested component '%s' derives from MonoBehaviour or Component or is an interface.", klassName), &go);
+}
+#endif
+
+static void DetermineSearchMethod(ScriptingClassPtr klass, int* outputSearchMethod, void** outputCompareData)
+{
+ int classid = GetScriptingManager().ClassIDForScriptingClass(klass);
+ if (classid == -1)
+ {
+ *outputSearchMethod = SearchMethod::ByScriptingClass;
+ *outputCompareData = (void*)klass;
+ return;
+ }
+
+ *outputCompareData = (void*) classid;
+ *outputSearchMethod = SearchMethod::ByClassID;
+}
+
+typedef bool GetComponentsFunction (GameObject& go, bool includeInactive, void* compareData, void* output);
+
+template<bool getOnlyOne>
+static GetComponentsFunction* DetermineGetComponentsImplementationFunction(int searchMethod,bool recursive)
+{
+ if (searchMethod == SearchMethod::ByClassID && recursive)
+ return GetComponentsImplementationRecurse<getOnlyOne,SearchMethod::ByClassID>;
+
+ if (searchMethod == SearchMethod::ByClassID && !recursive)
+ return GetComponentsImplementation<getOnlyOne,SearchMethod::ByClassID>;
+
+ if (searchMethod == SearchMethod::ByScriptingClass && recursive)
+ return GetComponentsImplementationRecurse<getOnlyOne,SearchMethod::ByScriptingClass>;
+
+ if (searchMethod == SearchMethod::ByScriptingClass && !recursive)
+ return GetComponentsImplementation<getOnlyOne,SearchMethod::ByScriptingClass>;
+
+ if (searchMethod == SearchMethod::DontEvenStart)
+ return NULL;
+
+ return NULL;
+}
+
+template<bool getOnlyOne>
+static void GetComponentsOfTypeFromGameObject(GameObject& go, ScriptingClassPtr compareKlass, bool generateErrors, bool recursive, bool includeInactive, void* results)
+{
+#if MONO_QUALITY_ERRORS
+ if (generateErrors)
+ VerifyGetComponentsOfTypeFromGameObjectArgument(go,compareKlass);
+#endif
+
+ if (compareKlass == SCRIPTING_NULL)
+ return;
+
+ int searchMethod;
+ void* compareData;
+
+ DetermineSearchMethod(compareKlass,&searchMethod,&compareData);
+
+ GetComponentsFunction* getComponents = DetermineGetComponentsImplementationFunction<getOnlyOne>(searchMethod,recursive);
+ if (getComponents)
+ getComponents(go,includeInactive,compareData,results);
+}
+
+ScriptingArrayPtr ScriptingGetComponentsOfType (GameObject& go, ScriptingObjectPtr systemTypeInstance, bool useSearchTypeAsArrayReturnType, bool recursive, bool includeInactive)
+{
+ dynamic_array<Unity::Component*> components(kMemTempAlloc);
+ ScriptingClassPtr compareKlass = GetScriptingTypeRegistry().GetType (systemTypeInstance);
+ GetComponentsOfTypeFromGameObject<false>(go,compareKlass, true, recursive, includeInactive, &components);
+
+#if ENABLE_MONO || UNITY_WINRT
+ ScriptingClassPtr componentClass = GetMonoManager ().ClassIDToScriptingClass (ClassID (Component));
+ ScriptingClassPtr classForArray = useSearchTypeAsArrayReturnType ? compareKlass : componentClass;
+ // ToDo: why aren't we using useSearchTypeAsArrayReturnType for flash ?! Lucas, Ralph?
+#elif UNITY_FLASH
+ ScriptingClassPtr classForArray = compareKlass;
+#endif
+ return CreateScriptingArrayFromUnityObjects(components,classForArray);
+}
+
+ScriptingObjectPtr ScriptingGetComponentOfType (GameObject& go, ScriptingObjectPtr systemTypeInstance, bool generateErrors)
+{
+ if (systemTypeInstance == SCRIPTING_NULL)
+ {
+ Scripting::RaiseArgumentException ("Type can not be null.");
+ return SCRIPTING_NULL;
+ }
+
+ ScriptingClassPtr compareKlass = GetScriptingTypeRegistry().GetType (systemTypeInstance);
+ Unity::Component* result = NULL;
+
+ GetComponentsOfTypeFromGameObject<true>(go,compareKlass, generateErrors, false, true, &result);
+
+ if (result != NULL)
+ return Scripting::ScriptingWrapperFor(result);
+
+#if MONO_QUALITY_ERRORS
+ if(generateErrors)
+ return MonoObjectNULL(compareKlass, MissingComponentString(go,compareKlass));
+#endif
+
+ return SCRIPTING_NULL;
+}
+
+ScriptingObjectPtr ScriptingGetComponentOfType (GameObject& go, ScriptingClassPtr systemTypeInstance)
+{
+ Unity::Component* result = NULL;
+ GetComponentsOfTypeFromGameObject<true>(go, systemTypeInstance, false, false, true, &result);
+ if (result)
+ return Scripting::ScriptingWrapperFor(result);
+
+ return SCRIPTING_NULL;
+}
+
+
+#endif
diff --git a/Runtime/Scripting/GetComponent.h b/Runtime/Scripting/GetComponent.h
new file mode 100644
index 0000000..f9aff0a
--- /dev/null
+++ b/Runtime/Scripting/GetComponent.h
@@ -0,0 +1,16 @@
+#ifndef GETCOMPONENT_H
+#define GETCOMPONENT_H
+
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Runtime/BaseClasses/BaseObject.h"
+#include "Runtime/Mono/MonoIncludes.h"
+
+#if ENABLE_SCRIPTING
+
+ScriptingArrayPtr ScriptingGetComponentsOfType (Unity::GameObject& go, ScriptingObjectPtr reflectionTypeObject, bool useSearchTypeAsArrayReturnType, bool recursive, bool includeInactive);
+ScriptingObjectPtr ScriptingGetComponentOfType (Unity::GameObject& go, ScriptingObjectPtr reflectionTypeObject, bool generateErrors = true);
+ScriptingObjectPtr ScriptingGetComponentOfType (GameObject& go, ScriptingClassPtr systemTypeInstance);
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/ICallString.cpp b/Runtime/Scripting/ICallString.cpp
new file mode 100644
index 0000000..ad1cceb
--- /dev/null
+++ b/Runtime/Scripting/ICallString.cpp
@@ -0,0 +1,40 @@
+#include "UnityPrefix.h"
+
+#if ENABLE_SCRIPTING
+
+#if !UNITY_FLASH
+#include "ICallString.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+
+#if ENABLE_MONO
+std::string ICallString::AsUTF8() const
+{
+ return scripting_cpp_string_for(str).c_str();
+}
+#elif UNITY_WINRT
+#include "PlatformDependent/MetroPlayer/MetroUtils.h"
+std::string ICallString::AsUTF8() const
+{
+ return ConvertStringToUtf8(str);
+}
+#endif
+
+#if ENABLE_MONO
+// todo: remove this useless include once we figure out where to take mono_string_length from.
+#include "Runtime/Scripting/ScriptingUtility.h"
+#endif
+
+int ICallString::Length()
+{
+#if ENABLE_MONO
+ return mono_string_length(str);
+#elif UNITY_WINRT
+ return wcslen(str);
+ //return safe_cast<Platform::String^>(str)->Length();
+#endif
+}
+#endif
+
+#endif
+
diff --git a/Runtime/Scripting/ICallString.h b/Runtime/Scripting/ICallString.h
new file mode 100644
index 0000000..6c096d2
--- /dev/null
+++ b/Runtime/Scripting/ICallString.h
@@ -0,0 +1,91 @@
+#pragma once
+
+#if ENABLE_SCRIPTING
+
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include <string>
+
+#if ENABLE_MONO
+struct ICallString
+{
+ MonoString* str;
+
+ EXPORT_COREMODULE std::string AsUTF8() const;
+ operator std::string () const { return AsUTF8(); }
+ int Length();
+ bool IsNull () {return !str;}
+
+ MonoString* GetNativeString() {return str;}
+};
+#endif
+
+#if UNITY_FLASH
+struct ICallString
+{
+ const char* utf8stream;
+
+ std::string AsUTF8() const { return utf8stream; }
+ operator std::string () const { return AsUTF8(); }
+
+ int Length() { return strlen(utf8stream); }
+ bool IsNull () {return !utf8stream;}
+ const char* GetNativeString() {return utf8stream;}
+};
+#endif
+
+#if UNITY_WINRT
+struct ICallString
+{
+private:
+ const wchar_t* str;
+ //Platform::Object^ str;
+
+ ICallString(const ICallString& other){}
+ ICallString& operator = (const ICallString& rhs)
+ {
+ return *this;
+ }
+public:
+ ICallString(){}
+ ICallString(const wchar_t* _str)
+ : str(_str)
+ {
+ }
+ std::string AsUTF8() const;
+ operator std::string () const { return AsUTF8(); }
+
+ int Length();
+ bool IsNull () {return (str == SCRIPTING_NULL);}
+
+ ScriptingStringPtr GetNativeString() {return ref new Platform::String(str);}
+};
+#endif
+
+/*
+//For the next step
+
+struct structwithsomename
+{
+char buf[256];
+char* fallback;
+
+structwithsomename(ICallString& ics)
+{
+
+
+}
+
+~structwithsomename()
+{
+delete fallback;
+}
+
+const char* Get()
+{
+fastutf8into(buf);
+}
+
+const char* operator () { return Get(); }
+};*/
+
+#endif
diff --git a/Runtime/Scripting/MonoManager_Flash.cpp b/Runtime/Scripting/MonoManager_Flash.cpp
new file mode 100644
index 0000000..22cc7f4
--- /dev/null
+++ b/Runtime/Scripting/MonoManager_Flash.cpp
@@ -0,0 +1,41 @@
+#include "UnityPrefix.h"
+
+#include "MonoManager_Flash.h"
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+#include "Runtime/Mono/MonoScript.h"
+#include "Runtime/BaseClasses/ManagerContext.h"
+#include "Runtime/Scripting/CommonScriptingClasses.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+#include "Runtime/Scripting/Backend/Flash/ScriptingTypeProvider_Flash.h"
+#include "Runtime/Scripting/Backend/Flash/ScriptingMethodFactory_Flash.h"
+
+#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h"
+
+#include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h"
+
+MonoManager::MonoManager (MemLabelId label, ObjectCreationMode mode)
+ : ScriptingManager(label, mode, UNITY_NEW( ScriptingTypeProvider_Flash(), kMemManager), UNITY_NEW( ScriptingMethodFactory_Flash(), kMemManager))
+{
+ FillCommonScriptingClasses(m_CommonScriptingClasses);
+}
+
+MonoManager::~MonoManager ()
+{
+
+}
+
+template<class TransferFunction>
+void MonoManager::Transfer (TransferFunction& transfer)
+{
+ Super::Transfer (transfer);
+ transfer.SetVersion(2);
+ transfer.Transfer (m_MonoScriptManager.m_RuntimeScripts, "m_Scripts");
+}
+
+
+IMPLEMENT_OBJECT_SERIALIZE (MonoManager)
+IMPLEMENT_CLASS (MonoManager)
+GET_MANAGER (MonoManager)
+GET_MANAGER_PTR (MonoManager)
diff --git a/Runtime/Scripting/MonoManager_Flash.h b/Runtime/Scripting/MonoManager_Flash.h
new file mode 100644
index 0000000..2367fbd
--- /dev/null
+++ b/Runtime/Scripting/MonoManager_Flash.h
@@ -0,0 +1,27 @@
+#ifndef MONOMANAGER_FLASH_H
+#define MONOMANAGER_FLASH_H
+
+#include "Runtime/BaseClasses/GameManager.h"
+#include "Runtime/Mono/MonoScriptManager.h"
+#include "Runtime/Scripting/CommonScriptingClasses.h"
+#include "Runtime/Scripting/ScriptingManager.h"
+
+class MonoManager : public ScriptingManager
+{
+public:
+ REGISTER_DERIVED_CLASS (MonoManager, GlobalGameManager)
+ DECLARE_OBJECT_SERIALIZE (MonoManager)
+
+ MonoManager (MemLabelId label, ObjectCreationMode mode);
+ // virtual ~MonoManager (); declared-by-macro
+
+ ScriptingObjectPtr CreateInstance(ScriptingClassPtr klass);
+
+private:
+
+};
+
+MonoManager& GetMonoManager ();
+MonoManager* GetMonoManagerPtr ();
+
+#endif
diff --git a/Runtime/Scripting/MonoManager_WinRT.cpp b/Runtime/Scripting/MonoManager_WinRT.cpp
new file mode 100644
index 0000000..7719478
--- /dev/null
+++ b/Runtime/Scripting/MonoManager_WinRT.cpp
@@ -0,0 +1,105 @@
+#include "UnityPrefix.h"
+
+#include "MonoManager_WinRT.h"
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+#include "Runtime/Mono/MonoScript.h"
+#include "Runtime/BaseClasses/ManagerContext.h"
+#include "Runtime/Scripting/CommonScriptingClasses.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+#include "Runtime/Scripting/Backend/Metro/ScriptingTypeProvider_Metro.h"
+#include "Runtime/Scripting/Backend/Metro/ScriptingMethodFactory_Metro.h"
+
+#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h"
+
+#include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h"
+
+#include "PlatformDependent/MetroPlayer/MetroUtils.h"
+
+MonoManager::MonoManager (MemLabelId label, ObjectCreationMode mode)
+ : ScriptingManager(label, mode, UNITY_NEW( ScriptingTypeProvider_Metro(), kMemManager), UNITY_NEW( ScriptingMethodFactory_Metro(), kMemManager))
+{
+ METRO_DBG_MARK_TIME("MonoManager::ctor");
+ InputString data;
+ const char* managedAssemblies = "managedAssemblies.txt";
+ if (ReadStringFromFile(&data, PathToAbsolutePath(managedAssemblies)))
+ {
+ GetWinRTUtils()->LoadAssemblies(ConvertUtf8ToString(data.c_str()));
+ }
+ else
+ {
+ FatalErrorMsg("Failed to load %s", managedAssemblies);
+ }
+ METRO_DBG_MARK_TIME("MonoManager::FillCommonScriptingClasses begin...");
+ FillCommonScriptingClasses(m_CommonScriptingClasses);
+ METRO_DBG_MARK_TIME("MonoManager::FillCommonScriptingClasses end...");
+ SetupExceptionHandler();
+ SetupMarshalCallbacks();
+ void RegisterAllInternalCalls();
+ RegisterAllInternalCalls();
+
+# if ENABLE_SERIALIZATION_BY_CODEGENERATION
+
+ s_WinRTBridge->SetupSerializationReader(
+ (long long)(NativeExt_MonoBehaviourSerialization_ReaderAlign),
+ (long long)(NativeExt_MonoBehaviourSerialization_ReadBuffer),
+ (long long)(NativeExt_MonoBehaviourSerialization_ReadUnityEngineObject),
+ (long long)(NativeExt_MonoBehaviourSerialization_ReadGUIStyle),
+ (long long)(NativeExt_MonoBehaviourSerialization_ReadRectOffset),
+ (long long)(NativeExt_MonoBehaviourSerialization_ReadAnimationCurve),
+ (long long)(NativeExt_MonoBehaviourSerialization_ReadGradient));
+
+ s_WinRTBridge->SetupSerializationWriter(
+ (long long)(NativeExt_MonoBehaviourSerialization_WriterAlign),
+ (long long)(NativeExt_MonoBehaviourSerialization_WriteBuffer),
+ (long long)(NativeExt_MonoBehaviourSerialization_WriteUnityEngineObject),
+ (long long)(NativeExt_MonoBehaviourSerialization_WriteGUIStyle),
+ (long long)(NativeExt_MonoBehaviourSerialization_WriteRectOffset),
+ (long long)(NativeExt_MonoBehaviourSerialization_WriteAnimationCurve),
+ (long long)(NativeExt_MonoBehaviourSerialization_WriteGradient));
+
+ s_WinRTBridge->SetupSerializationRemapper(
+ (long long)(NativeExt_MonoBehaviourSerialization_GetNewInstanceToReplaceOldInstance));
+
+ ScriptingInvocation initManagedAnalysis(GetScriptingMethodRegistry().GetMethod("UnityEngine.Serialization","ManagedLivenessAnalysis","Init"));
+ initManagedAnalysis.Invoke();
+# endif
+ // It tries to get classes like LevelGameManager which doesn't exist in managed land, is this intended?
+ RebuildClassIDToScriptingClass();
+
+# if !ENABLE_WINRT_PINVOKE
+ METRO_DBG_MARK_TIME("MonoManager::SetupDelegates begin...");
+ GetWinRTUtils()->SetupDelegates();
+ METRO_DBG_MARK_TIME("MonoManager::SetupDelegates end...");
+# else
+ if (GetWinRTUtils()->IsPlatformInvokeSupported() == false)
+ FatalErrorMsg("WinRTBridge: Platform Invoke should be supported on this platform.");
+ if (UnityEngineDelegates::PlatformInvoke::IsSupported() == false)
+ FatalErrorMsg("UnityEngineDelegates: Platform Invoke should be supported on this platform.");
+# endif
+
+}
+
+MonoManager::~MonoManager ()
+{
+
+}
+
+template<class TransferFunction>
+void MonoManager::Transfer (TransferFunction& transfer)
+{
+ Super::Transfer (transfer);
+ transfer.SetVersion(2);
+ transfer.Transfer (m_MonoScriptManager.m_RuntimeScripts, "m_Scripts");
+
+ // ToDo: Temporary fix if we're deserializing for metro see MonoManager::Transfer function
+ std::vector<UnityStr> assemblyNames;
+ transfer.Transfer (assemblyNames, "m_AssemblyNames");
+}
+
+
+IMPLEMENT_OBJECT_SERIALIZE (MonoManager)
+IMPLEMENT_CLASS (MonoManager)
+GET_MANAGER (MonoManager)
+GET_MANAGER_PTR (MonoManager)
diff --git a/Runtime/Scripting/MonoManager_WinRT.h b/Runtime/Scripting/MonoManager_WinRT.h
new file mode 100644
index 0000000..cc43c8e
--- /dev/null
+++ b/Runtime/Scripting/MonoManager_WinRT.h
@@ -0,0 +1,27 @@
+#ifndef MONOMANAGER_WINRT_H
+#define MONOMANAGER_WINRT_H
+
+#include "Runtime/BaseClasses/GameManager.h"
+#include "Runtime/Mono/MonoScriptManager.h"
+#include "Runtime/Scripting/CommonScriptingClasses.h"
+#include "Runtime/Scripting/ScriptingManager.h"
+
+class MonoManager : public ScriptingManager
+{
+public:
+ REGISTER_DERIVED_CLASS (MonoManager, GlobalGameManager)
+ DECLARE_OBJECT_SERIALIZE (MonoManager)
+
+ MonoManager (MemLabelId label, ObjectCreationMode mode);
+ // virtual ~MonoManager (); declared-by-macro
+
+ ScriptingObjectPtr CreateInstance(ScriptingClassPtr klass);
+
+private:
+
+};
+
+MonoManager& GetMonoManager ();
+MonoManager* GetMonoManagerPtr ();
+
+#endif
diff --git a/Runtime/Scripting/ReadOnlyScriptingObjectOfType.h b/Runtime/Scripting/ReadOnlyScriptingObjectOfType.h
new file mode 100644
index 0000000..2a837e6
--- /dev/null
+++ b/Runtime/Scripting/ReadOnlyScriptingObjectOfType.h
@@ -0,0 +1,151 @@
+#pragma once
+
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Scripting.h"
+
+#define SUPPORT_DIRECT_CACHEDPTR_PASSING_FOR_READONLY_OBJECTS UNITY_WINRT
+
+#if !SUPPORT_DIRECT_CACHEDPTR_PASSING_FOR_READONLY_OBJECTS
+template<class T>
+struct ReadOnlyScriptingObjectOfType
+{
+private:
+ ScriptingObjectPtr object;
+public:
+ ReadOnlyScriptingObjectOfType(ScriptingObjectPtr object)
+ {
+ this->object = object;
+ }
+
+ T& GetReference () const
+ {
+ T* ptr = GetPtr();
+
+ if (ptr != NULL)
+ return *ptr;
+
+ Scripting::RaiseNullExceptionObject (object);
+ return *(T*)NULL;
+ }
+
+ T& operator * () const
+ {
+ return GetReference ();
+ }
+
+ operator T* () const
+ {
+ return GetPtr ();
+ }
+
+ T* operator -> () const
+ {
+ return &GetReference ();
+ }
+
+ bool IsNull() const
+ {
+ return object == SCRIPTING_NULL;
+ }
+
+ operator PPtr<T> () const
+ {
+ if (IsNull())
+ return PPtr<T> ();
+
+ return PPtr<T> (GetInstanceID());
+ }
+
+private:
+#if UNITY_EDITOR
+public:
+ // ToDo: Fix this later, ask TomasD or Lucas
+ inline ScriptingObjectPtr GetScriptingObject() const
+ {
+ return object;
+ }
+#endif
+
+ inline int GetInstanceID() const
+ {
+ return Scripting::GetInstanceIDFromScriptingWrapper(object);
+ }
+ T* GetPtr () const
+ {
+ if (IsNull())
+ return NULL;
+
+ void* cachedPtr = GetCachedPtr();
+ if (cachedPtr != NULL)
+ {
+ AssertIf(reinterpret_cast<Object*> (cachedPtr)->GetInstanceID() != GetInstanceID());
+ return (T*)cachedPtr;
+ }
+
+ T* temp = dynamic_instanceID_cast<T*> (GetInstanceID());
+ return temp;
+ }
+
+ inline void* GetCachedPtr() const
+ {
+ return Scripting::GetCachedPtrFromScriptingWrapper(object);
+ }
+};
+
+#else
+
+template<class T>
+struct ReadOnlyScriptingObjectOfType
+{
+private:
+ T* cachedPtr;
+public:
+ ReadOnlyScriptingObjectOfType(void* p)
+ {
+ this->cachedPtr = (T*)p;
+ }
+
+ T& GetReference () const
+ {
+ if (cachedPtr != NULL)
+ return *(T*)cachedPtr;
+
+ Scripting::RaiseNullExceptionObject (SCRIPTING_NULL);
+ return *(T*)NULL;
+ }
+
+ T& operator * () const
+ {
+ return GetReference ();
+ }
+
+ operator T* () const
+ {
+ return cachedPtr;
+ }
+
+ T* operator -> () const
+ {
+ return &GetReference ();
+ }
+
+ bool IsNull() const
+ {
+ return cachedPtr == NULL;
+ }
+
+ operator PPtr<T> () const
+ {
+ if (IsNull())
+ return PPtr<T> ();
+
+ return PPtr<T> (cachedPtr->GetInstanceID());
+ }
+
+};
+
+#endif
+
+
+
+
diff --git a/Runtime/Scripting/ScriptLanguagePortUtility.cpp b/Runtime/Scripting/ScriptLanguagePortUtility.cpp
new file mode 100644
index 0000000..7f53640
--- /dev/null
+++ b/Runtime/Scripting/ScriptLanguagePortUtility.cpp
@@ -0,0 +1,11 @@
+#include "UnityPrefix.h"
+#if UNITY_FLASH
+
+#include "ScriptLanguagePortUtility.h"
+
+bool IsFileCreated(const std::string& path)
+{
+ return Ext_FileContainer_IsFileCreatedAt(path.c_str());
+}
+
+#endif \ No newline at end of file
diff --git a/Runtime/Scripting/ScriptLanguagePortUtility.h b/Runtime/Scripting/ScriptLanguagePortUtility.h
new file mode 100644
index 0000000..913aab4
--- /dev/null
+++ b/Runtime/Scripting/ScriptLanguagePortUtility.h
@@ -0,0 +1,10 @@
+#ifndef SCRIPTLANGUAGEPORTUTILITY_H
+#define SCRIPTLANGUAGEPORTUTILITY_H
+
+#if UNITY_FLASH || UNITY_WEBGL
+
+extern "C" bool Ext_FileContainer_IsFileCreatedAt(const char* filename);
+extern "C" bool Ext_LogCallstack();
+
+#endif
+#endif
diff --git a/Runtime/Scripting/ScriptPopupMenus.cpp b/Runtime/Scripting/ScriptPopupMenus.cpp
new file mode 100644
index 0000000..fdc3c1d
--- /dev/null
+++ b/Runtime/Scripting/ScriptPopupMenus.cpp
@@ -0,0 +1,142 @@
+#include "UnityPrefix.h"
+#include "Runtime/Mono/MonoManager.h"
+#include "Runtime/Scripting/ScriptPopupMenus.h"
+#include "Runtime/Mono/tabledefs.h"
+#include "Runtime/Serialize/TypeTree.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#include "Runtime/Serialize/IterateTypeTree.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+
+using namespace std;
+
+#if UNITY_EDITOR
+
+static void ExtractPopupFromEnum (MonoClass* klass, map<string, int>& popup)
+{
+ MonoVTable * vtable = mono_class_vtable (mono_domain_get (), klass);
+ MonoClassField *field;
+ void* iter = NULL;
+
+ MonoType* enumMonoType = mono_class_enum_basetype (klass);
+ int enumType = mono_type_get_type (enumMonoType);
+
+ while ((field = mono_class_get_fields (klass, &iter)))
+ {
+ int value;
+ const char* name = mono_field_get_name (field);
+ int flags = mono_field_get_flags (field);
+ if (flags & FIELD_ATTRIBUTE_STATIC)
+ {
+ switch (enumType)
+ {
+ case MONO_TYPE_I4:
+ mono_field_static_get_value (vtable, field, &value);
+ break;
+ case MONO_TYPE_U1:
+ UInt8 byteValue;
+ mono_field_static_get_value (vtable, field, &byteValue);
+ value = byteValue;
+ break;
+ default:
+ ErrorString (Format("Unsupported enum type: %s", name));
+ break;
+ }
+ popup[name] = value;
+ }
+ }
+}
+
+const string GetFieldIdentifierForEnum(const TypeTree* typeTree)
+{
+ string identifier;
+ while (typeTree != NULL && typeTree->m_Father != NULL)
+ {
+ // Skip the extra arary type injected by the serialization system
+ if (typeTree->m_Father->m_Father && IsTypeTreeArray(*typeTree->m_Father))
+ typeTree = typeTree->m_Father->m_Father;
+
+ if (identifier.empty())
+ identifier = typeTree->m_Name;
+ else
+ identifier = Format("%s.%s", typeTree->m_Name.c_str(), identifier.c_str());
+
+ typeTree = typeTree->m_Father;
+ }
+
+ return identifier;
+}
+
+static const string AppendName(const std::string& previous, MonoClassField* field)
+{
+ const char* name = mono_field_get_name(field);
+
+ if (previous.empty())
+ return name;
+ else
+ return Format("%s.%s", previous.c_str(), name);
+}
+
+static void BuildScriptPopupMenus (MonoClass* klass, const std::string& parentName, std::map<std::string, std::map<std::string, int> >& popups, std::set<MonoClass*> collected)
+{
+ const CommonScriptingClasses& commonClasses = GetMonoManager ().GetCommonClasses ();
+ MonoClass* unityEngineObject = GetMonoManager().ClassIDToScriptingClass(ClassID(Object));
+
+ while (klass && klass != commonClasses.monoBehaviour && klass != commonClasses.scriptableObject)
+ {
+ // Only collect classes once
+ if (!collected.insert (klass).second)
+ return;
+
+ MonoClassField *field;
+ void* iter = NULL;
+ while ((field = mono_class_get_fields (klass, &iter)))
+ {
+ MonoType* monoType = mono_field_get_type (field);
+ int typeType = mono_type_get_type (monoType);
+ MonoClass* elementClass;
+
+ int flags = mono_field_get_flags (field);
+ if (flags & (FIELD_ATTRIBUTE_STATIC | FIELD_ATTRIBUTE_INIT_ONLY | FIELD_ATTRIBUTE_NOT_SERIALIZED))
+ continue;
+
+ // Extract the array field from the generic list
+ MonoClassField* arrayField = GetMonoArrayFieldFromList(typeType, monoType, field);
+ if (arrayField)
+ {
+ monoType = mono_field_get_type(arrayField);
+ typeType = mono_type_get_type (monoType);
+ }
+
+ if (typeType == MONO_TYPE_VALUETYPE || typeType == MONO_TYPE_SZARRAY)
+ {
+ elementClass = mono_type_get_class_or_element_class (monoType);
+ if (mono_class_is_enum (elementClass))
+ {
+ string name = AppendName(parentName, field);
+ map<string, int>& items = popups[name];
+ items.clear ();
+ ExtractPopupFromEnum (elementClass, items);
+ continue;
+ }
+ }
+ if (typeType == MONO_TYPE_CLASS || typeType == MONO_TYPE_SZARRAY)
+ {
+ elementClass = mono_type_get_class_or_element_class (monoType);
+ MonoImage* image = mono_class_get_image(elementClass);
+ int classflags = mono_class_get_flags(elementClass);
+
+ if ((classflags & TYPE_ATTRIBUTE_SERIALIZABLE) && image != mono_get_corlib() && GetMonoManager().GetAssemblyIndexFromImage(image) != -1 && !mono_class_is_subclass_of(elementClass, unityEngineObject, false))
+ BuildScriptPopupMenus(elementClass, AppendName(parentName, field), popups, collected);
+ }
+ }
+
+ klass = mono_class_get_parent (klass);
+ }
+}
+
+void BuildScriptPopupMenus (MonoBehaviour& behaviour, std::map<string, std::map<std::string, int> >& popups)
+{
+ std::set<MonoClass*> collected;
+ BuildScriptPopupMenus(behaviour.GetClass (), "", popups, collected);
+}
+#endif \ No newline at end of file
diff --git a/Runtime/Scripting/ScriptPopupMenus.h b/Runtime/Scripting/ScriptPopupMenus.h
new file mode 100644
index 0000000..2c2f3e0
--- /dev/null
+++ b/Runtime/Scripting/ScriptPopupMenus.h
@@ -0,0 +1,11 @@
+#ifndef __SCRIPTPOPUPMENUSH__
+#define __SCRIPTPOPUPMENUSH__
+
+#include <map>
+
+class TypeTree;
+class MonoBehaviour;
+
+void BuildScriptPopupMenus (MonoBehaviour& behaviour, std::map<std::string, std::map<std::string, int> >& popups);
+const std::string GetFieldIdentifierForEnum(const TypeTree* typeTree);
+#endif \ No newline at end of file
diff --git a/Runtime/Scripting/Scripting.cpp b/Runtime/Scripting/Scripting.cpp
new file mode 100644
index 0000000..5e01feb
--- /dev/null
+++ b/Runtime/Scripting/Scripting.cpp
@@ -0,0 +1,768 @@
+#include "UnityPrefix.h"
+
+#include "Scripting.h"
+
+#include "Runtime/BaseClasses/IsPlaying.h"
+#include "Runtime/BaseClasses/RefCounted.h"
+#include "Runtime/GameCode/DestroyDelayed.h"
+#include "Runtime/Graphics/Transform.h"
+#include "Runtime/Misc/GameObjectUtility.h"
+#include "Runtime/Mono/MonoBehaviour.h"
+#include "Runtime/Mono/MonoScriptCache.h"
+#include "Runtime/Scripting/ScriptingObjectOfType.h"
+#include "Runtime/Scripting/ScriptingManager.h"
+#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h"
+#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h"
+#include "Runtime/Scripting/ScriptingExportUtility.h"
+
+#if UNITY_EDITOR
+# include "Editor/Src/AssetPipeline/MonoCompilationPipeline.h"
+#endif
+
+namespace Scripting
+{
+
+ScriptingObjectPtr ScriptingWrapperFor(Object* o)
+{
+#if !ENABLE_SCRIPTING
+ return 0;
+#else
+ if(!o)
+ return SCRIPTING_NULL;
+
+ ScriptingObjectPtr cachedInstance = o->GetCachedScriptingObject();
+ if(cachedInstance != SCRIPTING_NULL)
+ return cachedInstance;
+
+ int classID = o->GetClassID();
+ if(classID == ClassID(MonoBehaviour))
+ {
+ AssertIf(static_cast<MonoBehaviour*> (o)->GetInstance());
+ return SCRIPTING_NULL;
+ }
+
+ ScriptingObjectPtr object = InstantiateScriptingWrapperForClassID(classID);
+ return (object != SCRIPTING_NULL) ? ConnectScriptingWrapperToObject(object, o) : SCRIPTING_NULL;
+#endif
+}
+
+ScriptingObjectPtr ConnectScriptingWrapperToObject(ScriptingObjectPtr object, Object* ptr)
+{
+#if !ENABLE_SCRIPTING
+ return 0;
+#else
+ // ConnectScriptingWrapperToObject might get called from different threads
+ // - References to objects are setup from loading thread.
+ // The Object could already be loaded in memory and in that case it is possible that the main thread might asign a MonoObject* while the loader thread is doing the same.
+ // - @TODO: If this is a performance bottleneck we could ensure that the loader thread calls ConnectScriptingWrapperToObject only during safe places.
+
+ LockObjectCreation();
+
+ AssertIf(object == SCRIPTING_NULL);
+ AssertIf(ptr == NULL);
+
+ if(ptr->GetCachedScriptingObject() != SCRIPTING_NULL)
+ {
+ ScriptingObjectPtr res = ptr->GetCachedScriptingObject();
+ UnlockObjectCreation();
+
+ return res;
+ }
+
+ ScriptingObjectOfType<Object> wrapper(object);
+
+#if DEBUGMODE && !UNITY_FLASH && !UNITY_WINRT //in flash, we do not yet initialize chachedPtr to 0
+ AssertIf(wrapper.GetCachedPtr() != NULL);
+#endif
+
+ wrapper.SetCachedPtr(ptr);
+ wrapper.SetInstanceID(ptr->GetInstanceID());
+
+#if MONO_QUALITY_ERRORS
+ wrapper.SetError(NULL);
+#endif
+
+ AssertIf(ptr->GetCachedScriptingObject() != SCRIPTING_NULL);
+ ptr->SetCachedScriptingObject(object);
+
+ UnlockObjectCreation();
+
+ return object;
+#endif
+}
+
+bool BroadcastScriptingMessage(GameObject& go, const char* name, ScriptingObjectPtr param)
+{
+ bool didSend = SendScriptingMessage(go, name, param);
+
+ Transform* transform = go.QueryComponent(Transform);
+ if(transform)
+ {
+ for(int i = 0; i < transform->GetChildrenCount(); i++ )
+ didSend |= BroadcastScriptingMessage(transform->GetChild(i).GetGameObject(), name, param);
+ }
+
+ return didSend;
+}
+
+
+bool SendScriptingMessageUpwards(GameObject& go, const char* name, ScriptingObjectPtr param)
+{
+ bool didSend = SendScriptingMessage(go, name, param);
+
+ Transform* transform = go.QueryComponent(Transform);
+ if (transform)
+ transform = transform->GetParent();
+
+ while(transform)
+ {
+ didSend |= SendScriptingMessage(transform->GetGameObject(), name, param);
+ transform = transform->GetParent();
+ }
+
+ return didSend;
+}
+
+bool SendScriptingMessage(GameObject& go, const char* name, ScriptingObjectPtr param)
+{
+ bool didSend = false;
+
+ if(!go.IsActive())
+ return false;
+
+ int instanceID = go.GetInstanceID();
+
+ for(int i = 0; i < go.GetComponentCount(); i++)
+ {
+ if(go.GetComponentClassIDAtIndex(i) == ClassID(MonoBehaviour))
+ {
+ MonoBehaviour& behaviour = static_cast<MonoBehaviour&>(go.GetComponentAtIndex(i));
+
+ ScriptingObjectPtr instance = behaviour.GetInstance();
+ if(instance)
+ {
+ ScriptingMethodPtr method = behaviour.FindMethod(name);
+ if(method == SCRIPTING_NULL)
+ continue;
+
+ behaviour.InvokeMethodOrCoroutineChecked(method, param);
+ didSend = true;
+
+ // Check if the gameObject was destroyed.
+ if(!PPtr<Object>(instanceID).IsValid())
+ return didSend;
+ }
+ }
+ }
+
+ return didSend;
+}
+
+bool BroadcastScriptingMessage(GameObject& go, const std::string& methodName, ScriptingObjectPtr param, int options)
+{
+ bool didSend = BroadcastScriptingMessage(go, methodName.c_str(), param);
+
+#if !DEPLOY_OPTIMIZED
+ if(!didSend && options == 0)
+ ErrorStringObject(Format("BroadcastMessage %s has no receiver!", methodName.c_str()), &go);
+#endif
+
+ return didSend;
+}
+
+bool SendScriptingMessageUpwards(GameObject& go, const std::string& methodName, ScriptingObjectPtr param, int options)
+{
+ bool didSend = SendScriptingMessageUpwards(go, methodName.c_str(), param);
+
+#if !DEPLOY_OPTIMIZED
+ if(!didSend && options == 0)
+ ErrorStringObject(Format("SendMessage %s has no receiver!", methodName.c_str()), &go);
+#endif
+
+ return didSend;
+}
+
+bool SendScriptingMessage(GameObject& go, const std::string& methodName, ScriptingObjectPtr param, int options)
+{
+ bool didSend = SendScriptingMessage(go, methodName.c_str(), param);
+
+#if !DEPLOY_OPTIMIZED
+ if(!didSend && options == 0)
+ ErrorStringObject(Format("SendMessage %s has no receiver!", methodName.c_str()), &go);
+#endif
+
+ return didSend;
+}
+
+/// Compares two Object classes.
+/// Returns true if both have the same instance id
+/// or both are NULL (Null can either mean that the object is gone or that the instanceID is 0)
+bool CompareBaseObjects (ScriptingObjectPtr lhs, ScriptingObjectPtr rhs)
+{
+ int lhsInstanceID = 0;
+ int rhsInstanceID = 0;
+ bool isLhsNull = true, isRhsNull = true;
+ if (lhs)
+ {
+ lhsInstanceID = GetInstanceIDFromScriptingWrapper (lhs);
+ ScriptingObjectOfType<Object> lhsRef(lhs);
+ isLhsNull = !lhsRef.IsValidObjectReference();
+ }
+ if (rhs)
+ {
+ rhsInstanceID = GetInstanceIDFromScriptingWrapper (rhs);
+ ScriptingObjectOfType<Object> rhsRef(rhs);
+ isRhsNull = !rhsRef.IsValidObjectReference();
+ }
+ if (isLhsNull || isRhsNull)
+ return isLhsNull == isRhsNull;
+ else
+ return lhsInstanceID == rhsInstanceID;
+}
+
+void DestroyObjectFromScriptingImmediate(Object* object, bool allowDestroyingAssets)
+{
+#if !DEPLOY_OPTIMIZED
+ if(object && object->IsPersistent() && !allowDestroyingAssets)
+ {
+ ErrorStringObject ("Destroying assets is not permitted to avoid data loss.\nIf you really want to remove an asset use DestroyImmediate (theObject, true);", object);
+ return;
+ }
+#endif
+
+ DestroyObjectHighLevel(object);
+}
+
+void UnloadAssetFromScripting(Object* object)
+{
+ if(object == NULL)
+ return;
+
+#if !DEPLOY_OPTIMIZED
+ if(!object->IsPersistent())
+ {
+ ErrorStringObject ("UnloadAsset can only be used on assets;", object);
+ return;
+ }
+
+ bool disallowedUnloadTypes = object->IsDerivedFrom(ClassID(Component)) || object->IsDerivedFrom(ClassID(GameObject)) || object->IsDerivedFrom(ClassID(AssetBundle));
+ if(disallowedUnloadTypes)
+ {
+ ErrorStringObject ("UnloadAsset may only be used on individual assets and can not be used on GameObject's / Components or AssetBundles", object);
+ return;
+ }
+#endif
+
+ UnloadObject(object);
+}
+
+static void DisableBehaviours( GameObject* target )
+{
+ for ( unsigned compI = 0; compI < target->GetComponentCount(); ++compI )
+ {
+ Behaviour* behaviour = dynamic_pptr_cast<Behaviour*> (&target->GetComponentAtIndex(compI));
+ if (behaviour)
+ behaviour->SetEnabled(false);
+ }
+}
+
+// @TODO: Test for DestroyImmediate from Destroy in OnDisable!
+void DestroyObjectFromScripting (PPtr<Object> object, float t)
+{
+ if (!IsWorldPlaying())
+ {
+ ErrorString("Destroy may not be called from edit mode! Use DestroyImmediate instead.\nAlso think twice if you really want to destroy something in edit mode. Since this will destroy objects permanently.");
+ return;
+ }
+
+ if (object)
+ {
+#if !DEPLOY_OPTIMIZED
+ if (object->IsPersistent ())
+ {
+ ErrorStringObject ("Destroying assets is not permitted to avoid data loss.\nIf you really want to remove an asset use DestroyImmediate (theObject, true);", object);
+ return;
+ }
+#endif
+
+ // if we want to destroy it this frame (t <= 0.0) - we need to imitate "destroy right away" behaviour
+ if (t <= 0.0)
+ {
+ Behaviour* behaviour = dynamic_pptr_cast<Behaviour*> (object);
+ if (behaviour)
+ {
+ // if this Object is some kind of Behaviour, it is already in update queue.
+ // if it was updated before we can do nothing, but if not - just disable it
+ behaviour->SetEnabled(false);
+ }
+
+ GameObject* go = dynamic_pptr_cast<GameObject*> (object);
+ if (go)
+ {
+ // if we destroy game object - disable all behaviours (children included)
+ DisableBehaviours(go);
+
+ ////@TODO: This needs to be done recursively
+
+ Transform& root = go->GetComponentT<Transform>(ClassID(Transform));
+ for ( unsigned childI = 0; childI < root.GetChildrenCount(); ++childI )
+ DisableBehaviours( root.GetChild(childI).GetGameObjectPtr() );
+ }
+ }
+
+ DestroyObjectDelayed (object, t);
+ }
+}
+
+static MonoScript* FindScriptableObjectFromClass (ScriptingTypePtr klass, bool errorOnMissingScript = true)
+{
+ if (klass == SCRIPTING_NULL)
+ {
+ ErrorString ("Instance couldn't be created because type was null.");
+ return NULL;
+ }
+
+ MonoScript* script = GetMonoScriptManager().FindRuntimeScript(klass);
+ if (script == NULL)
+ {
+ script = GetMonoScriptManager().FindEditorScript(klass);
+ if (script == NULL)
+ {
+ if (errorOnMissingScript)
+ {
+ ErrorString (Format ("Instance of %s couldn't be created because there is no script with that name.", scripting_class_get_name(klass)));
+ }
+ return NULL;
+ }
+ }
+
+ if (script->GetScriptType() != kScriptTypeScriptableObjectDerived && script->GetScriptType() != kScriptTypeEditorScriptableObjectDerived)
+ {
+ ErrorString (Format ("Instance of %s couldn't be created. The the script class needs to derive from ScriptableObject.", scripting_class_get_name(klass)));
+ return NULL;
+ }
+
+ if (script->GetClass() == SCRIPTING_NULL)
+ {
+ ErrorString (Format ("Instance of %s couldn't be created. All script needs to successfully compile first!", scripting_class_get_name(klass)));
+ return NULL;
+ }
+
+ return script;
+}
+
+ScriptingObjectPtr CreateScriptableObjectWithType (ScriptingObjectPtr systemTypeInstance)
+{
+ ScriptingTypePtr type = GetScriptingTypeRegistry().GetType(systemTypeInstance);
+ if(type == NULL)
+ return SCRIPTING_NULL;
+
+ MonoBehaviour* behaviour = 0;
+
+ bool errorOnMissingScript = UNITY_EDITOR ? false : true;
+
+ MonoScript* script = FindScriptableObjectFromClass(type, errorOnMissingScript);
+ if(script == NULL)
+ {
+#if UNITY_EDITOR
+ MonoImage* image = mono_class_get_image(type);
+ std::string imageFileName = mono_image_get_filename(image);
+
+ if (IsEditorOnlyAssembly(imageFileName, true))
+ {
+ std::string imageName = mono_image_get_name(image);
+ std::string id = BuildScriptClassId(imageName, mono_class_get_namespace(type), mono_class_get_name(type));
+
+ behaviour = NEW_OBJECT (MonoBehaviour);
+ behaviour->SetClassIdentifier(id);
+ }
+ else
+ return SCRIPTING_NULL;
+#else
+ return SCRIPTING_NULL;
+#endif
+ } else
+ {
+ behaviour = NEW_OBJECT (MonoBehaviour);
+ behaviour->SetScript(script);
+ }
+
+ ResetAndApplyDefaultReferencesOnNewMonoBehaviour(*behaviour);
+ return behaviour->GetInstance();
+}
+
+ScriptingObjectPtr CreateScriptableObject(const std::string& name)
+{
+ MonoScript* script = GetMonoScriptManager().FindRuntimeScript(name);
+
+#if UNITY_EDITOR
+ if(script == NULL)
+ script = GetMonoScriptManager().FindEditorScript(name);
+#endif
+
+ if(script == NULL)
+ {
+ ErrorString(Format("Instance of %s couldn't be created because there is no script with that name.", name.c_str()));
+ return SCRIPTING_NULL;
+ }
+
+ if(
+ script->GetScriptType() != kScriptTypeScriptableObjectDerived
+#if UNITY_EDITOR
+ && script->GetScriptType() != kScriptTypeEditorScriptableObjectDerived
+#endif
+ )
+ {
+ ErrorString(Format("Instance of %s couldn't be created. The the script class needs to derive from ScriptableObject.", name.c_str()));
+ return SCRIPTING_NULL;
+ }
+
+ if(script->GetClass() == SCRIPTING_NULL)
+ {
+ ErrorString(Format("Instance of %s couldn't be created. All script needs to successfully compile first!", name.c_str()));
+ return SCRIPTING_NULL;
+ }
+
+ MonoBehaviour* behaviour = NEW_OBJECT(MonoBehaviour);
+ behaviour->SetScript(script);
+
+ ResetAndApplyDefaultReferencesOnNewMonoBehaviour(*behaviour);
+
+ return behaviour->GetInstance();
+}
+
+void CreateEngineScriptableObject(ScriptingObjectPtr object)
+{
+ // Avoid recursive loop. This object is already created from c++
+
+ if(GetInstanceIDFromScriptingWrapper(object) != 0)
+ return;
+
+ SCRIPTINGAPI_THREAD_CHECK(ScriptableObject.ctor);
+
+ ScriptingClassPtr klass = scripting_object_get_class(object, GetScriptingTypeRegistry());
+
+ const char *classNamespace = scripting_class_get_namespace(klass);
+ const char *className = scripting_class_get_name(klass);
+
+ WarningStringMsg("%s%s%s must be instantiated using the ScriptableObject.CreateInstance method instead of new %s.", classNamespace, (classNamespace[0] ? "." : ""), className, className);
+
+ MonoScript* script = FindScriptableObjectFromClass(klass);
+ if(script == NULL)
+ return;
+
+ MonoBehaviour* behaviour = NEW_OBJECT(MonoBehaviour);
+ behaviour->SetScript(script, object);
+
+#if UNITY_EDITOR
+ if(script->GetScriptType() == kScriptTypeEditorScriptableObjectDerived)
+ behaviour->SetEditorHideFlags (MonoBehaviour::kHideScriptPPtr);
+#endif
+
+ ResetAndApplyDefaultReferencesOnNewMonoBehaviour(*behaviour);
+}
+
+ScriptingObjectPtr GetScriptingWrapperForInstanceID(int instanceID)
+{
+ if(instanceID == 0)
+ return SCRIPTING_NULL;
+
+ Object* object2 = PPtr<Object>(instanceID);
+ return ScriptingWrapperFor(object2);
+}
+
+int GetClassIDFromScriptingClass(ScriptingClassPtr klass)
+{
+ int classID = 0;
+
+ // Look up this classes classID
+ ScriptingClassPtr curClass = klass;
+
+ const char* className = scripting_class_get_name(curClass);
+ const char* nameSpace = scripting_class_get_namespace(curClass);
+ const char* kEngineNameSpace = "UnityEngine";
+
+ if(strcmp(nameSpace, kEngineNameSpace) == 0)
+ {
+ if(strcmp(className, "ScriptableObject") == 0)
+ className = "MonoBehaviour";
+
+ classID = Object::StringToClassID(className);
+ if(classID != -1)
+ return classID;
+ }
+
+ // It is not an engine class so check the parents
+ classID = -1;
+
+ ScriptingClassPtr parentClass = scripting_class_get_parent(klass, GetScriptingTypeRegistry());
+ if(parentClass)
+ classID = GetClassIDFromScriptingClass(parentClass);
+
+ return classID;
+}
+
+ScriptingTypePtr ClassIDToScriptingType(int classID)
+{
+ return GetScriptingManager().ClassIDToScriptingClass(classID);
+}
+
+ScriptingObjectPtr GetScriptingWrapperOfComponentOfGameObject (GameObject& go, const std::string& name)
+{
+ int classID = Object::StringToClassID(name);
+ if (classID != -1 && Object::IsDerivedFromClassID(classID, ClassID(Component)))
+ {
+ Unity::Component* component = go.QueryComponentT<Unity::Component> (classID);
+
+#if MONO_QUALITY_ERRORS
+ if (component == NULL)
+ return MonoObjectNULL (classID, MissingComponentString(go, classID));
+#endif
+ return ScriptingWrapperFor (component);
+ }
+
+ MonoScript* script = GetMonoScriptManager().FindRuntimeScript(name);
+ if (script == NULL)
+ {
+
+#if MONO_QUALITY_ERRORS
+ if (classID != -1)
+ ScriptWarning(Format("GetComponent requires that the requested component inherits from Component or MonoBehaviour.\nYou used GetComponent(%s) which does not inherit from Component.\n", name.c_str()), &go);
+#endif
+
+ return SCRIPTING_NULL;
+ }
+
+ ScriptingTypePtr compareKlass = script->GetClass();
+ if (compareKlass == SCRIPTING_NULL)
+ return SCRIPTING_NULL;
+
+ int count = go.GetComponentCount ();
+ for (int i=0;i<count;i++)
+ {
+ // We are looking only for MonoBehaviours
+ int clsID = go.GetComponentClassIDAtIndex (i);
+ if (!Object::IsDerivedFromClassID (clsID, ClassID (MonoBehaviour)))
+ continue;
+
+ MonoBehaviour& behaviour = static_cast<MonoBehaviour&> (go.GetComponentAtIndex (i));
+ ScriptingObjectPtr object = behaviour.GetInstance ();
+
+ if(!object)
+ continue;
+
+ ScriptingTypePtr klass = scripting_object_get_class(object, GetScriptingTypeRegistry());
+ if (scripting_class_is_subclass_of(klass, compareKlass))
+ return object;
+ }
+
+ return SCRIPTING_NULL;
+}
+
+void LogException(ScriptingExceptionPtr exception, int instanceID, const std::string& error)
+{
+ StackTraceInfo info;
+
+ scripting_stack_trace_info_for(exception, info);
+
+ if (!error.empty())
+ info.condition = error + info.condition;
+
+ DebugStringToFilePostprocessedStacktrace(info.condition.c_str(), info.strippedStacktrace.c_str(), info.stacktrace.c_str(), info.errorNum, info.file.c_str(), info.line, kLog | kScriptingError | kScriptingException, instanceID, 0);
+}
+
+static ScriptingArrayPtr CreateScriptingArrayFromScriptingObjects(ScriptingObjectPtr* objects, int size, ScriptingClassPtr typeForArray)
+{
+ // copy into array
+ ScriptingArrayPtr array = CreateScriptingArray<ScriptingObjectPtr> (typeForArray, size);
+ for (int i = 0; i < size; i++)
+ {
+ Scripting::SetScriptingArrayElement (array, i, objects[i]);
+ }
+
+ return array;
+}
+
+static bool IsActiveSceneObject (Object& o)
+{
+ if (o.IsPersistent ())
+ return false;
+
+ GameObject* go = dynamic_pptr_cast<GameObject*> (&o);
+ if (go)
+ return go->IsActive ();
+
+ Unity::Component* com = dynamic_pptr_cast<Unity::Component*> (&o);
+ if (com)
+ {
+ MonoBehaviour* behaviour = dynamic_pptr_cast<MonoBehaviour*> (&o);
+ if (behaviour)
+ {
+ MonoScript* script = behaviour->GetScript();
+ if (script && script->GetScriptType () == kScriptTypeScriptableObjectDerived)
+ return true;
+ else
+ return com->IsActive ();
+ }
+ else
+ return com->IsActive ();
+ }
+
+ return true;
+}
+
+ScriptingArrayPtr FindObjectsOfType(ScriptingObjectPtr systemTypeInstance, FindMode mode)
+{
+ ScriptingClassPtr compareKlass = GetScriptingTypeRegistry().GetType(systemTypeInstance);
+
+ if(compareKlass == SCRIPTING_NULL)
+ {
+ ErrorString("FindAllObjectsOfType: Invalid Type");
+ return SCRIPTING_NULL;
+ }
+
+ int classID = GetClassIDFromScriptingClass(compareKlass);
+ if(classID == -1)
+ {
+ string klassName = scripting_class_get_name(compareKlass);
+ ErrorString("FindAllObjectsOfType: The type has to be derived from UnityEngine.Object. Type is " + klassName + ".");
+ return SCRIPTING_NULL;
+ }
+
+ // Gather the derived objects
+ vector<SInt32> objects;
+ Object::FindAllDerivedObjects(classID, &objects);
+
+ std::sort(objects.begin(), objects.end());
+
+ // We might need to ignore some objects which are not derived from the mono class but from MonoBehaviour
+ // so we store them in a buffer and then copy them into the mono array
+
+ ScriptingObjectPtr* scriptingObjects;
+
+#if UNITY_WINRT
+ scriptingObjects = new ScriptingObjectPtr[objects.size ()];
+#else
+ ALLOC_TEMP(scriptingObjects, ScriptingObjectPtr, objects.size ());
+#endif
+
+ int count = 0;
+ for(int i = 0;i < objects.size (); i++)
+ {
+ Object& object = *PPtr<Object>(objects[i]);
+ if(object.TestHideFlag (Object::kDontSave) && mode != Scripting::kFindAnything)
+ continue;
+
+ if(mode == Scripting::kFindActiveSceneObjects && !IsActiveSceneObject (object))
+ continue;
+
+ ScriptingObjectPtr mono = ScriptingWrapperFor(&object); //Todo: this used to call ObjectToScriptingObject, but that
+ //hit a bug in the alchemy compiler
+ if(mono)
+ {
+ // Cubemap is derived from Texture2D in serialization, but not in Scripting
+ if (object.IsDerivedFrom (ClassID (MonoBehaviour)) || object.IsDerivedFrom (ClassID (Cubemap)))
+ {
+ ScriptingClassPtr klass = scripting_object_get_class (mono, GetScriptingTypeRegistry());
+ if (scripting_class_is_subclass_of (klass, compareKlass))
+ scriptingObjects[count++] = mono;
+ }
+ else
+ {
+ scriptingObjects[count++] = mono;
+ }
+ }
+ }
+
+ ScriptingArrayPtr result = CreateScriptingArrayFromScriptingObjects(scriptingObjects,count,compareKlass);
+
+#if UNITY_WINRT
+ delete[]scriptingObjects;
+#endif
+
+ return result;
+}
+
+ScriptingObjectPtr TrackedReferenceBaseToScriptingObjectImpl (TrackedReferenceBase* base, ScriptingClassPtr klass)
+{
+ if (base)
+ {
+ // In the editor a weak reference (for example animation state)
+ // might get leaked when reloading domains while in playmode
+ // in that case we just recycle it
+ #if UNITY_EDITOR
+ if (base->m_MonoObjectReference != 0 && !mono_gchandle_is_in_domain(base->m_MonoObjectReference, mono_domain_get()))
+ {
+ mono_gchandle_free(base->m_MonoObjectReference);
+ base->m_MonoObjectReference = 0;
+ }
+ #endif
+#if ENABLE_MONO && !UNITY_PEPPER
+ AssertIf(base->m_MonoObjectReference != 0 && !mono_gchandle_is_in_domain(base->m_MonoObjectReference, mono_domain_get()));
+#endif
+
+ // Get cached mono object reference
+ ScriptingObjectPtr target = SCRIPTING_NULL;
+ if (base->m_MonoObjectReference != 0)
+ {
+ target = scripting_gchandle_get_target (base->m_MonoObjectReference);
+ if (target)
+ return target;
+
+ AssertString("This should never happen");
+
+ scripting_gchandle_free(base->m_MonoObjectReference);
+ base->m_MonoObjectReference = 0;
+ }
+
+ ScriptingObjectWithIntPtrField<TrackedReferenceBase> newTarget(scripting_object_new(klass));
+
+ base->m_MonoObjectReference = scripting_gchandle_new(newTarget.object);
+ newTarget.SetPtr(base);
+
+ return newTarget.object;
+ }
+ else
+ {
+#if DEPLOY_OPTIMIZED
+ return SCRIPTING_NULL;
+#else
+ ScriptingObjectPtr object = scripting_object_new (klass);
+ void* nativePointer = 0;
+ MarshallNativeStructIntoManaged(nativePointer,object);
+ return object;
+#endif
+ }
+}
+
+template <class StringType>
+ScriptingArrayPtr StringVectorToMono (const std::vector<StringType>& source)
+{
+ ScriptingArrayPtr arr = CreateScriptingArray<ScriptingObjectPtr>(MONO_COMMON.string, source.size());
+ for (int i = 0; i < source.size();i++)
+ {
+ Scripting::SetScriptingArrayElement(arr, i, scripting_string_new(source[i]));
+ }
+ return arr;
+}
+
+template ScriptingArrayPtr StringVectorToMono (const std::vector<std::string>& source);
+template ScriptingArrayPtr StringVectorToMono (const std::vector<UnityStr>& source);
+
+ScriptingObjectPtr GetComponentObjectToScriptingObject(Unity::Component* com, Unity::GameObject& go, int classID)
+{
+
+#if MONO_QUALITY_ERRORS
+ if(com == NULL)
+ return MonoObjectNULL(classID, MissingComponentString(go, classID));
+#endif
+
+ return ScriptingWrapperFor(com);
+}
+
+ScriptingObjectPtr GetComponentObjectToScriptingObject(Object* com, Unity::GameObject& go, int classID)
+{
+ return ScriptingWrapperFor(com);
+}
+
+} // namespace Scripting
diff --git a/Runtime/Scripting/Scripting.h b/Runtime/Scripting/Scripting.h
new file mode 100644
index 0000000..bdcdc91
--- /dev/null
+++ b/Runtime/Scripting/Scripting.h
@@ -0,0 +1,197 @@
+#pragma once
+
+#include "UnityPrefix.h"
+
+#include "Runtime/Modules/ExportModules.h"
+
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+#define SCRIPTINGAPI_STACK_CHECK(NAME)
+
+#if WEBPLUG
+# undef DOES_NOT_RETURN
+# define DOES_NOT_RETURN
+#endif
+
+class Object;
+class TrackedReferenceBase;
+
+namespace Unity
+{
+ class GameObject;
+ class Component;
+}
+
+template<typename T>
+class PPtr;
+
+
+namespace Scripting
+{
+ScriptingObjectPtr ScriptingObjectNULL(ScriptingClassPtr klass);
+ScriptingObjectPtr ScriptingObjectNULL(ScriptingClassPtr klass, ScriptingStringPtr error);
+
+//Exception helpers, we'll need to move this again, later.
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(1,2) void RaiseMonoException(const char* format, ...);
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(1,2) EXPORT_COREMODULE void RaiseNullException(const char* format, ...);
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(1,2) EXPORT_COREMODULE void RaiseArgumentException(const char* format, ...);
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(1,2) void RaiseOutOfRangeException(const char* format, ...);
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(1,2) void RaiseSecurityException(const char* format, ...);
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(1,2) void RaiseInvalidOperationException(const char* format, ...);
+DOES_NOT_RETURN TAKES_PRINTF_ARGS(3,4) void RaiseManagedException(const char* ns, const char* type, const char* format, ...);
+DOES_NOT_RETURN EXPORT_COREMODULE void RaiseNullExceptionObject(ScriptingObjectPtr object);
+
+void RaiseIfNull(void* object);
+void RaiseIfNull(ScriptingObjectPtr object);
+
+EXPORT_COREMODULE int GetInstanceIDFromScriptingWrapper(ScriptingObjectPtr wrapper);
+EXPORT_COREMODULE void SetInstanceIDOnScriptingWrapper(ScriptingObjectPtr wrapper, int instanceID);
+EXPORT_COREMODULE void* GetCachedPtrFromScriptingWrapper(ScriptingObjectPtr wrapper);
+EXPORT_COREMODULE void SetCachedPtrOnScriptingWrapper(ScriptingObjectPtr wrapper, void* cachedPtr);
+void SetErrorOnScriptingWrapper(ScriptingObjectPtr wrapper, ScriptingStringPtr error);
+
+ScriptingTypePtr ClassIDToScriptingType(int classiD);
+ScriptingObjectPtr InstantiateScriptingWrapperForClassID(int classID);
+ScriptingObjectPtr ConnectScriptingWrapperToObject(ScriptingObjectPtr object, Object* ptr);
+
+/**These don't belong here either**/
+bool SendScriptingMessage(Unity::GameObject& go, const char* name, ScriptingObjectPtr param);
+bool BroadcastScriptingMessage(Unity::GameObject& go, const char* name, ScriptingObjectPtr param);
+bool SendScriptingMessageUpwards(Unity::GameObject& go, const char* name, ScriptingObjectPtr param);
+bool SendScriptingMessage(Unity::GameObject& go, const std::string& name, ScriptingObjectPtr param, int options);
+bool BroadcastScriptingMessage(Unity::GameObject& go, const std::string& name, ScriptingObjectPtr param, int options);
+bool SendScriptingMessageUpwards(Unity::GameObject& go, const std::string& name, ScriptingObjectPtr param, int options);
+/** end **/
+
+void DestroyObjectFromScripting(PPtr<Object> object, float t);
+void DestroyObjectFromScriptingImmediate(Object* object, bool allowDestroyingAssets);
+void UnloadAssetFromScripting(Object* object);
+
+ScriptingObjectPtr GetScriptingWrapperOfComponentOfGameObject (Unity::GameObject& go, const std::string& name);
+
+ScriptingObjectPtr GetScriptingWrapperForInstanceID(int instanceID);
+ScriptingObjectPtr CreateScriptableObject(const std::string& name);
+ScriptingObjectPtr CreateScriptableObjectWithType(ScriptingObjectPtr klassType);
+void CreateEngineScriptableObject(ScriptingObjectPtr object);
+int GetClassIDFromScriptingClass(ScriptingClassPtr klass);
+
+bool CompareBaseObjects(ScriptingObjectPtr lhs, ScriptingObjectPtr rhs);
+
+ScriptingObjectPtr EXPORT_COREMODULE ScriptingWrapperFor(Object* object);
+
+void LogException(ScriptingExceptionPtr exception, int instanceID, const std::string& error = std::string());
+
+enum FindMode
+{
+ kFindAssets = 0,
+ kFindActiveSceneObjects = 1,
+ kFindAnything = 2
+};
+
+ScriptingArrayPtr FindObjectsOfType(ScriptingObjectPtr reflectionTypeObject, FindMode mode);
+
+ScriptingObjectPtr GetComponentObjectToScriptingObject(Unity::Component* com, Unity::GameObject& go, int classID);
+ScriptingObjectPtr GetComponentObjectToScriptingObject(Object* com, Unity::GameObject& go, int classID);
+
+//RH / GAB : Discuss with Joe what to do with this
+/// Creates a MonoObject
+/// object is a ptr to a RefCounted class.
+/// type is the name MonoManager common classes
+/// eg. animationState -> GetScriptingManager().GetCommonClasses().animationStates
+#define TrackedReferenceBaseToScriptingObject(object, type) \
+ Scripting::TrackedReferenceBaseToScriptingObjectImpl(object, GetScriptingManager().GetCommonClasses().type)
+
+ScriptingObjectPtr TrackedReferenceBaseToScriptingObjectImpl(TrackedReferenceBase* base, ScriptingClassPtr klass);
+
+template <class StringType>
+ScriptingArrayPtr StringVectorToMono (const std::vector<StringType>& source);
+
+// Array handling
+
+void SetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i, ScriptingObjectPtr value);
+void SetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i, ScriptingStringPtr value);
+ScriptingStringPtr* GetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i);
+ScriptingObjectPtr* GetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i);
+ScriptingStringPtr* GetScriptingArrayStringStartImpl(ScriptingArrayPtr a);
+ScriptingObjectPtr* GetScriptingArrayObjectStartImpl(ScriptingArrayPtr a);
+ScriptingStringPtr GetScriptingArrayStringElementNoRefImpl(ScriptingArrayPtr a, int i);
+ScriptingObjectPtr GetScriptingArrayObjectElementNoRefImpl(ScriptingArrayPtr a, int i);
+
+template<class T>
+inline void SetScriptingArrayElement(ScriptingArrayPtr array, int i, T value)
+{
+ void* raw = scripting_array_element_ptr(array, i, sizeof(T));
+ *(T*)raw = value;
+}
+
+template<>
+inline void SetScriptingArrayElement (ScriptingArrayPtr a, int i, ScriptingObjectPtr value)
+{
+ SetScriptingArrayObjectElementImpl(a, i, value);
+}
+
+template<>
+inline void SetScriptingArrayElement (ScriptingArrayPtr a, int i, ScriptingStringPtr value)
+{
+ SetScriptingArrayStringElementImpl(a, i, value);
+}
+
+
+template<class T>
+inline T* GetScriptingArrayStart(ScriptingArrayPtr array)
+{
+ return (T*)scripting_array_element_ptr(array, 0, sizeof(T));
+}
+
+template<>
+inline ScriptingStringPtr* GetScriptingArrayStart(ScriptingArrayPtr a)
+{
+ return GetScriptingArrayStringStartImpl(a);
+}
+
+template<>
+inline ScriptingObjectPtr* GetScriptingArrayStart(ScriptingArrayPtr a)
+{
+ return GetScriptingArrayObjectStartImpl(a);
+}
+
+
+template<class T>
+inline T& GetScriptingArrayElement(ScriptingArrayPtr a, int i)
+{
+ return *((T*)scripting_array_element_ptr(a, i, sizeof(T)));
+}
+
+template<>
+inline ScriptingStringPtr& GetScriptingArrayElement(ScriptingArrayPtr a, int i)
+{
+ return *GetScriptingArrayStringElementImpl(a, i);
+}
+
+template<>
+inline ScriptingObjectPtr& GetScriptingArrayElement(ScriptingArrayPtr a, int i)
+{
+ return *GetScriptingArrayObjectElementImpl(a, i);
+}
+
+
+template<class T>
+inline T GetScriptingArrayElementNoRef(ScriptingArrayPtr a, int i)
+{
+ return *((T*)scripting_array_element_ptr(a, i, sizeof(T)));
+}
+
+template<>
+inline ScriptingStringPtr GetScriptingArrayElementNoRef(ScriptingArrayPtr a, int i)
+{
+ return GetScriptingArrayStringElementNoRefImpl(a, i);
+}
+
+template<>
+inline ScriptingObjectPtr GetScriptingArrayElementNoRef(ScriptingArrayPtr a, int i)
+{
+ return GetScriptingArrayObjectElementNoRefImpl(a, i);
+}
+
+}//namespace Scripting \ No newline at end of file
diff --git a/Runtime/Scripting/ScriptingExportUtility.h b/Runtime/Scripting/ScriptingExportUtility.h
new file mode 100644
index 0000000..3061cfb
--- /dev/null
+++ b/Runtime/Scripting/ScriptingExportUtility.h
@@ -0,0 +1,265 @@
+#ifndef _SCRIPTINGEXPORTUTILITY_H_
+#define _SCRIPTINGEXPORTUTILITY_H_
+
+#if ENABLE_SCRIPTING
+
+#include "Runtime/Scripting/ScriptingManager.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/Scripting/ICallString.h"
+#include "Runtime/Scripting/Scripting.h"
+
+
+template<class T>
+inline
+ScriptingArrayPtr CreateScriptingArray (ScriptingClassPtr klass, int count)
+{
+#if ENABLE_MONO
+ //here to force template argument being used on caller, so the callsite will be compatible
+ //with the flash version of CreateScriptingArray, which actually needs to know what will be in the array beforehand.
+ //TODO: find a cleaner way of enforcing usage:
+# if DEBUGMODE
+ int nativeSize = sizeof(T);
+ int monoSize = mono_class_array_element_size(klass);
+ DebugAssert(nativeSize == monoSize || !count);
+ (void)monoSize; // silence unused variable warning
+ nativeSize++;
+# endif
+ return mono_array_new(mono_domain_get(),klass,count);
+
+#elif UNITY_FLASH
+ UInt8* memoryblob = (UInt8*) malloc(sizeof(T) * count + sizeof(int));
+ *(int*)memoryblob = count;
+ return (ScriptingArrayPtr) memoryblob;
+#elif UNITY_WINRT
+ return ScriptingArrayPtr(GetWinRTObjectInstantiation()->CreateScriptingArrayGC(klass->metroType, count));
+#endif
+}
+
+template<class T>
+inline
+ScriptingArrayPtr CreateScriptingArray2D (ScriptingClassPtr klass, int count1, int count2)
+{
+#if ENABLE_MONO
+ return mono_array_new_2d (count1, count2, klass);
+#elif UNITY_FLASH
+ FatalErrorMsg("ToDo:CreateScriptingArray2D");
+#elif UNITY_WINRT
+ return ScriptingArrayPtr(GetWinRTObjectInstantiation()->CreateScriptingArray2DGC(klass->metroType, count1, count2));
+#endif
+}
+template<class T>
+inline
+ScriptingArrayPtr CreateScriptingArray3D (ScriptingClassPtr klass, int count1, int count2, int count3)
+{
+#if ENABLE_MONO
+ return mono_array_new_3d (count1, count2, count3, klass);
+#elif UNITY_FLASH
+ FatalErrorMsg("ToDo:CreateScriptingArray3D");
+#elif UNITY_WINRT
+ return ScriptingArrayPtr(GetWinRTObjectInstantiation()->CreateScriptingArray3DGC(klass->metroType, count1, count2, count3));
+#endif
+}
+
+
+inline
+ScriptingArrayPtr CreateEmptyStructArray (ScriptingClassPtr klass)
+{
+ return CreateScriptingArray<int>(klass,0); //using int as random template argument, as it doesn't matter, since size=0
+}
+
+template<class T>
+inline
+ScriptingArrayPtr CreateScriptingArray (const T* data, int count, ScriptingClassPtr klass)
+{
+ if (data == NULL)
+ count = 0;
+
+ ScriptingArrayPtr array = CreateScriptingArray<T>(klass,count);
+ memcpy(Scripting::GetScriptingArrayStart<T>(array), data, sizeof(T) * count );
+ return array;
+}
+
+template<class T>
+ScriptingArrayPtr CreateScriptingArrayFromUnityObjects (const T& container, int classID)
+{
+ ScriptingClassPtr klass = GetScriptingManager().ClassIDToScriptingClass (classID);
+
+ ScriptingArrayPtr array = CreateScriptingArray<ScriptingObjectPtr>(klass,container.size());
+ typename T::const_iterator j = container.begin();
+ for (int i=0;i<container.size();i++, j++)
+ {
+ Scripting::SetScriptingArrayElement(array,i, Scripting::ScriptingWrapperFor(*j));
+ }
+ return array;
+}
+
+template<class T > inline
+ScriptingArrayPtr CreateScriptingArrayFromUnityObjects(T& unityobjects,ScriptingClassPtr classForArray)
+{
+ ScriptingArrayPtr array = CreateScriptingArray<ScriptingObjectPtr> (classForArray , unityobjects.size ());
+ for (int i=0;i<unityobjects.size ();i++)
+ Scripting::SetScriptingArrayElement (array, i, Scripting::ScriptingWrapperFor (unityobjects[i]));
+ return array;
+}
+
+template<class T>
+inline
+ScriptingArrayPtr CreateScriptingArrayStride (const void* data, int count, ScriptingClassPtr klass, int inputStride)
+{
+ if (data == NULL)
+ count = 0;
+
+ ScriptingArrayPtr array = CreateScriptingArray<T> (klass, count);
+ UInt8* src = (UInt8*)data;
+ UInt8* dst = (UInt8*)Scripting::GetScriptingArrayStart<T> (array);
+ for (int i=0; i<count; ++i, src += inputStride, dst += sizeof(T))
+ memcpy(dst, src, sizeof(T));
+
+ return array;
+}
+
+template<class T, class T2, class U, class TConverter>
+void ScriptingStructArrayToVector (ScriptingArrayPtr source, U &dest, TConverter converter)
+{
+ dest.clear();
+ if (source != SCRIPTING_NULL)
+ {
+ int len = GetScriptingArraySize(source);
+ dest.resize (len);
+ for (int i = 0; i < len;i++)
+ converter (Scripting::GetScriptingArrayElement<T2>(source, i), dest[i]);
+ }
+}
+
+template<class T, class T2, class U, class TConverter>
+void ScriptingStructArrayToDynamicArray (ScriptingArrayPtr source, U &dest, TConverter converter)
+{
+ dest.clear();
+ if (source != SCRIPTING_NULL)
+ {
+ int len = GetScriptingArraySize(source);
+ dest.resize_initialized (len);
+ for (int i = 0; i < len;i++)
+ converter (Scripting::GetScriptingArrayElement<T2>(source, i), dest[i]);
+ }
+}
+
+template<class T, class T2, class U>
+void ScriptingClassArrayToVector (ScriptingArrayPtr source, U &dest, void (*converter) (T2 &source, T &dest))
+{
+ dest.clear();
+ if (source != SCRIPTING_NULL)
+ {
+ int len = GetScriptingArraySize(source);
+ dest.resize (len);
+ for (int i = 0; i < len;i++)
+ {
+ T2 nativeSourceObject;
+ ScriptingObjectPtr element = Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(source, i);
+ Scripting::RaiseIfNull(element);
+ MarshallManagedStructIntoNative<T2>(element, &nativeSourceObject);
+ converter (nativeSourceObject, dest[i]);
+ }
+ }
+}
+
+template<class T, class T2>
+std::vector<T> ScriptingClassArrayToVector (ScriptingArrayPtr source, void (*converter) (T2 &source, T &dest))
+{
+ std::vector<T> dest;
+ ScriptingClassArrayToVector (source, dest, converter);
+ return dest;
+}
+
+
+template<class T, class T2, class U>
+ScriptingArrayPtr VectorToScriptingClassArray (const U &source, ScriptingClassPtr klass, void (*converter) (const T &source, T2 &dest))
+{
+ // ToDo: if all good, remove mono pass, and use unified pass
+#if ENABLE_MONO
+ return VectorToMonoClassArray<T, T2>(source, klass, converter);
+#else
+ ScriptingArrayPtr arr = CreateScriptingArray<ScriptingObjectPtr>(klass, source.size());
+ for (int i = 0; i < source.size();i++)
+ {
+ T2 obj;
+ converter (source[i], obj);
+ ScriptingObjectPtr managedObject = CreateScriptingObjectFromNativeStruct(klass, obj);
+ Scripting::SetScriptingArrayElement(arr, i, managedObject);
+ }
+ return arr;
+#endif
+}
+
+template<class T, class T2, class U, class TConverter>
+ScriptingArrayPtr VectorToScriptingStructArray (const U &source, ScriptingClassPtr klass, TConverter converter)
+{
+ // ToDo: if all good, remove mono pass, and use unified pass
+#if ENABLE_MONO
+ return VectorToMonoStructArray<T, T2>(source, klass, converter);
+#else
+ ScriptingArrayPtr arr = CreateScriptingArray<ScriptingObjectPtr>(klass, source.size());
+ for (int i = 0; i < source.size();i++)
+ {
+ T2 obj;
+ converter (source[i], obj);
+ Scripting::SetScriptingArrayElement(arr, i, obj);
+ }
+ return arr;
+#endif
+}
+
+
+template<class T>
+void ScriptingArrayToDynamicArray(ScriptingArrayPtr a, dynamic_array<T>& dest)
+{
+ Scripting::RaiseIfNull (a);
+ int len = GetScriptingArraySize(a);
+ dest.resize_uninitialized (len);
+ for (int i = 0; i < len; i++)
+ dest[i] = Scripting::GetScriptingArrayElement<T>(a, i);
+}
+
+template<class T, class T2>
+void ScriptingArrayToDynamicArray(ScriptingArrayPtr a, dynamic_array<T>& dest, void (*converter) (T2 &source, T &dest))
+{
+ Scripting::RaiseIfNull (a);
+ int len = GetScriptingArraySize(a);
+ dest.resize_uninitialized (len);
+ for (int i = 0; i < len; i++)
+ converter (Scripting::GetScriptingArrayElement<T2> (a, i), dest[i]);
+}
+
+template<class T, class T2>
+ScriptingArrayPtr DynamicArrayToScriptingStructArray (const dynamic_array<T> &source, ScriptingClassPtr klass, void (*converter) (const T &source, T2 &dest)) {
+ ScriptingArrayPtr arr = CreateScriptingArray<T2> (klass, source.size());
+ for (int i = 0; i < source.size();i++)
+ converter (source[i], Scripting::GetScriptingArrayElement<T2> (arr, i));
+ return arr;
+}
+
+inline
+std::string GetStringFromArray(ScriptingArrayPtr a, int i)
+{
+#if UNITY_WINRT
+ return ConvertStringToUtf8(safe_cast<Platform::String^>(Scripting::GetScriptingArrayStringElementNoRefImpl(a, i)));
+#elif UNITY_FLASH
+ // not supported yet
+ return "";
+#else
+ return MonoStringToCpp(Scripting::GetScriptingArrayStringElementNoRefImpl(a, i));
+#endif
+}
+
+inline
+bool GetBoolFromArray(ScriptingArrayPtr a, int i)
+{
+#if UNITY_WINRT
+ return safe_cast<Platform::Boolean>(Scripting::GetScriptingArrayObjectElementNoRefImpl(a, i));
+#else
+ return Scripting::GetScriptingArrayObjectElementNoRefImpl(a, i);
+#endif
+}
+
+#endif
+#endif
diff --git a/Runtime/Scripting/ScriptingManager.cpp b/Runtime/Scripting/ScriptingManager.cpp
new file mode 100644
index 0000000..5dcfd5c
--- /dev/null
+++ b/Runtime/Scripting/ScriptingManager.cpp
@@ -0,0 +1,150 @@
+#include "UnityPrefix.h"
+#if ENABLE_SCRIPTING
+#include "Runtime/Scripting/ScriptingManager.h"
+#include "Runtime/BaseClasses/ManagerContext.h"
+#include <vector>
+#include <stdlib.h>
+#include "Runtime/Scripting/ScriptingUtility.h"
+#include "Runtime/IMGUI/GUIState.h"
+#include "Runtime/Scripting/Backend/ScriptingMethodFactory.h"
+#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h"
+#include "Runtime/Scripting/Backend/ScriptingBackendApi.h"
+
+const char* kEngineNameSpace = "UnityEngine";
+const char* kEditorNameSpace = "UnityEditor";
+const char* kEditorInternalNameSpace = "UnityEditorInternal";
+
+ScriptingClassPtr gClassIDToClass = SCRIPTING_NULL;
+
+using namespace std;
+
+ScriptingManager::ScriptingManager (MemLabelId label, ObjectCreationMode mode, IScriptingTypeProvider* scriptingTypeProvider, IScriptingMethodFactory* scriptingMethodFactory)
+ : GlobalGameManager(label, mode)
+{
+ m_ScriptingMethodFactory = scriptingMethodFactory;
+ m_ScriptingTypeRegistry = UNITY_NEW(ScriptingTypeRegistry(scriptingTypeProvider), kMemManager);
+ m_ScriptingMethodRegistry = UNITY_NEW(ScriptingMethodRegistry(scriptingMethodFactory, m_ScriptingTypeRegistry), kMemManager);
+
+ //Registering ourselves as the monomanager manually, so that during the execution of the constructor GetMonoManager() will work.
+ SetManagerPtrInContext(ManagerContext::kMonoManager, this);
+}
+
+ScriptingManager::~ScriptingManager ()
+{
+ UNITY_DELETE(m_ScriptingTypeRegistry, kMemManager);
+ UNITY_DELETE(m_ScriptingMethodRegistry, kMemManager);
+
+ UNITY_DELETE(m_ScriptingMethodFactory, kMemManager);
+}
+
+static ScriptingClassPtr FindScriptingClassForClassID(int classID, ScriptingClassPtr baseObject)
+{
+ const char* className_c;
+#if UNITY_FLASH
+ if(classID == ClassID(Object))
+ className_c = "_Object";
+ else
+#endif
+ className_c = Object::ClassIDToString (classID).c_str();
+
+ // Found a class?
+ // Also make sure it derives from object otherwise it's not valid (Eg. RenderSettings only has public accessors and doesn't inherit from Object)
+
+ ScriptingTypeRegistry& typeRegistry = GetScriptingManager().GetScriptingTypeRegistry();
+
+ ScriptingTypePtr result = typeRegistry.GetType(kEngineNameSpace,className_c);
+
+#if UNITY_EDITOR
+ if (result== SCRIPTING_NULL)
+ result = typeRegistry.GetType (kEditorNameSpace, className_c);
+ if (result == SCRIPTING_NULL)
+ result = typeRegistry.GetType (kEditorInternalNameSpace, className_c);
+#endif
+
+ if (result != SCRIPTING_NULL && scripting_class_is_subclass_of (result, baseObject))
+ return result;
+
+ return SCRIPTING_NULL;
+}
+
+
+static ScriptingClassPtr FindScriptingClassForClassIDRecursive (int classID, ScriptingClassPtr baseObject)
+{
+ ScriptingClassPtr result = FindScriptingClassForClassID(classID,baseObject);
+
+ if (result != SCRIPTING_NULL)
+ return result;
+
+ if (classID == ClassID (Object))
+ return SCRIPTING_NULL;
+
+ return FindScriptingClassForClassIDRecursive (Object::GetSuperClassID (classID),baseObject);
+}
+
+void ScriptingManager::RebuildClassIDToScriptingClass ()
+{
+#if ENABLE_SCRIPTING
+ // Collect all engine classes
+ vector<SInt32> allEngineClasses;
+ Object::FindAllDerivedClasses (ClassID (Object), &allEngineClasses, false);
+
+ // Resize lookup table to fit all engine classes
+ SInt32 highest = 0;
+ for (int i=0;i<allEngineClasses.size ();i++)
+ highest = max (allEngineClasses[i], highest);
+ m_ClassIDToMonoClass.clear ();
+ m_ClassIDToMonoClass.resize (highest +1, SCRIPTING_NULL);
+ gClassIDToClass = m_ClassIDToMonoClass[0];
+
+ m_ScriptingClassToClassID.clear();
+ // Get the mono class from the classID by looking up the mono class by name
+ // if a mono class can't be found check the super classes recursively
+ ScriptingClassPtr baseObject = GetScriptingTypeRegistry().GetType("UnityEngine","Object");
+ for (int i=0;i<allEngineClasses.size ();i++)
+ {
+ int classID = allEngineClasses[i];
+
+ ScriptingClassPtr klass = FindScriptingClassForClassIDRecursive (classID,baseObject);
+ AssertIf(klass == SCRIPTING_NULL);
+ m_ClassIDToMonoClass[classID] = klass;
+
+ //search again, but without searching basetypes. we need to do this because some enginetypes have no managed wrapper. (EllipsoidParticleEmitter),
+ //so they can return the baseclass type. we want that for m_ClassIDToMonoClass but we do not want that for m_ScriptingClassToClassID.
+
+ klass = FindScriptingClassForClassID (classID,baseObject);
+ if (klass)
+ m_ScriptingClassToClassID[klass] = classID;
+ }
+#endif
+}
+
+ScriptingClassPtr ScriptingManager::ClassIDToScriptingClass (int classID)
+{
+ AssertIf (classID == -1);
+ AssertIf (m_ClassIDToMonoClass.size () <= classID);
+ return m_ClassIDToMonoClass[classID];
+}
+
+int ScriptingManager::ClassIDForScriptingClass (ScriptingClassPtr klass)
+{
+ ScriptingClassMap::iterator iterator = m_ScriptingClassToClassID.find(klass);
+ if (iterator == m_ScriptingClassToClassID.end())
+ return -1;
+
+ return iterator->second;
+}
+
+ScriptingObjectPtr ScriptingManager::CreateInstance(ScriptingClassPtr klass)
+{
+ if (!klass)
+ return SCRIPTING_NULL;
+
+ return scripting_object_new (klass);
+}
+
+ScriptingManager& GetScriptingManager()
+{
+ return reinterpret_cast<ScriptingManager&> (GetManagerFromContext (ManagerContext::kMonoManager));
+}
+#endif
diff --git a/Runtime/Scripting/ScriptingManager.h b/Runtime/Scripting/ScriptingManager.h
new file mode 100644
index 0000000..4c446f2
--- /dev/null
+++ b/Runtime/Scripting/ScriptingManager.h
@@ -0,0 +1,63 @@
+#ifndef _SCRIPTINGMANAGER_H_
+#define _SCRIPTINGMANAGER_H_
+
+#if ENABLE_SCRIPTING
+
+#include "Runtime/BaseClasses/GameManager.h"
+#include "Runtime/Mono/MonoScriptManager.h"
+#include "Runtime/Scripting/CommonScriptingClasses.h"
+#include "Runtime/Utilities/vector_map.h"
+#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h"
+#include "Runtime/Modules/ExportModules.h"
+
+class IScriptingTypeProvider;
+class ScriptingMethodRegistry;
+class ScriptingTypeRegistry;
+class IScriptingMethodFactory;
+
+extern const char* kEngineNameSpace;
+extern const char* kEditorNameSpace;
+extern ScriptingClassPtr gClassIDToClass;
+
+class EXPORT_COREMODULE ScriptingManager : public GlobalGameManager
+{
+public:
+ MonoScriptManager& GetMonoScriptManager() { return m_MonoScriptManager; }
+ ScriptingMethodRegistry& GetScriptingMethodRegistry() { return *m_ScriptingMethodRegistry; }
+ ScriptingTypeRegistry& GetScriptingTypeRegistry() { return *m_ScriptingTypeRegistry; }
+ const CommonScriptingClasses& GetCommonClasses () { return m_CommonScriptingClasses; }
+ ScriptingClassPtr ClassIDToScriptingClass (int classID);
+ int ClassIDForScriptingClass(ScriptingClassPtr klass);
+ virtual void RebuildClassIDToScriptingClass ();
+ ScriptingObjectPtr CreateInstance(ScriptingClassPtr klass);
+ virtual bool IsTrustedToken (const std::string& /*publicKeyToken*/){ return false; }
+
+ ~ScriptingManager();
+protected:
+ ScriptingManager (MemLabelId label, ObjectCreationMode mode, IScriptingTypeProvider* scriptingTypeProvider, IScriptingMethodFactory* scriptingMethodFactory);
+
+ MonoScriptManager m_MonoScriptManager;
+ CommonScriptingClasses m_CommonScriptingClasses;
+ typedef std::vector<ScriptingTypePtr> ClassIDToMonoClass;
+ ClassIDToMonoClass m_ClassIDToMonoClass;
+
+ typedef vector_map<ScriptingTypePtr, int> ScriptingClassMap;
+ ScriptingClassMap m_ScriptingClassToClassID;
+
+ ScriptingMethodRegistry* m_ScriptingMethodRegistry;
+ ScriptingTypeRegistry* m_ScriptingTypeRegistry;
+ IScriptingMethodFactory* m_ScriptingMethodFactory;
+};
+
+EXPORT_COREMODULE ScriptingManager& GetScriptingManager ();
+
+inline MonoScriptManager& GetMonoScriptManager() { return GetScriptingManager().GetMonoScriptManager(); }
+
+inline ScriptingMethodRegistry& GetScriptingMethodRegistry() { return GetScriptingManager().GetScriptingMethodRegistry(); }
+inline ScriptingTypeRegistry& GetScriptingTypeRegistry() { return GetScriptingManager().GetScriptingTypeRegistry(); }
+
+#define ScriptingClassFor(x) GetScriptingManager().ClassIDToScriptingClass(CLASS_##x)
+
+#endif
+
+#endif
diff --git a/Runtime/Scripting/ScriptingObjectOfType.h b/Runtime/Scripting/ScriptingObjectOfType.h
new file mode 100644
index 0000000..cca6bde
--- /dev/null
+++ b/Runtime/Scripting/ScriptingObjectOfType.h
@@ -0,0 +1,142 @@
+#pragma once
+
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Scripting.h"
+#include "ScriptingUtility.h"//We need to go back and remove this.
+
+template<class T>
+struct ScriptingObjectOfType
+{
+private:
+ ScriptingObjectPtr object;
+public:
+ ScriptingObjectOfType(ScriptingObjectPtr object)
+ {
+ this->object = object;
+ }
+
+ T& GetReference () const
+ {
+ T* ptr = GetPtr();
+
+ if (ptr != NULL)
+ return *ptr;
+
+ Scripting::RaiseNullExceptionObject (object);
+ return *(T*)NULL;
+ }
+
+ T* GetPtr () const
+ {
+ if (IsNullPtr())
+ return NULL;
+
+ void* cachedPtr = GetCachedPtr();
+ if (cachedPtr != NULL)
+ {
+ AssertIf(reinterpret_cast<Object*> (cachedPtr)->GetInstanceID() != GetInstanceID());
+ return (T*)cachedPtr;
+ }
+
+ T* temp = dynamic_instanceID_cast<T*> (GetInstanceID());
+ return temp;
+ }
+
+ bool IsValidObjectReference () const
+ {
+ if (IsNullPtr())
+ return false;
+
+ void* cachedPtr = GetCachedPtr();
+ if (cachedPtr != NULL)
+ {
+ AssertIf(reinterpret_cast<Object*> (cachedPtr)->GetInstanceID() != GetInstanceID());
+ return (T*)cachedPtr;
+ }
+
+ T* temp = dynamic_instanceID_cast<T*> (GetInstanceID());
+ if (temp == NULL)
+ return false;
+
+ // MonoBheaviours are only allowed to be the instance themselves (cached pointer)
+ // otherwise they are dangling references who happen to have the same instanceID.
+ // Thus not a valid reference.
+ if (temp->GetClassID() == ClassID(MonoBehaviour))
+ return false;
+
+ return true;
+ }
+
+
+ operator T* () const
+ {
+ return GetPtr ();
+ }
+
+ operator PPtr<T> () const
+ {
+ if (IsNullPtr())
+ return PPtr<T> ();
+
+ return PPtr<T> (GetInstanceID());
+ }
+
+ T& operator * () const
+ {
+ return GetReference ();
+ }
+
+ T* operator -> () const
+ {
+ return &GetReference ();
+ }
+
+ bool IsNullPtr() const
+ {
+ return object == SCRIPTING_NULL;
+ }
+
+ inline int GetInstanceID() const
+ {
+ return Scripting::GetInstanceIDFromScriptingWrapper(object);
+ }
+
+ inline void SetCachedPtr (void* cachedPtr)
+ {
+ Scripting::SetCachedPtrOnScriptingWrapper(object, cachedPtr);
+ }
+
+ inline void SetInstanceID (int instanceID)
+ {
+ Scripting::SetInstanceIDOnScriptingWrapper(object, instanceID);
+ }
+
+ inline void* GetCachedPtr() const
+ {
+ return Scripting::GetCachedPtrFromScriptingWrapper(object);
+ }
+
+ #if MONO_QUALITY_ERRORS
+ inline void SetError (ScriptingStringPtr error)
+ {
+ Scripting::SetErrorOnScriptingWrapper(object, error);
+ }
+ #endif
+
+#if UNITY_WINRT
+ ScriptingObjectOfType<T>& operator = (decltype(__nullptr))
+ {
+ object = nullptr;
+ return *this;
+ }
+#endif
+
+ inline ScriptingObjectPtr GetScriptingObject() const
+ {
+ return object;
+ }
+};
+
+
+
+
diff --git a/Runtime/Scripting/ScriptingObjectWithIntPtrField.h b/Runtime/Scripting/ScriptingObjectWithIntPtrField.h
new file mode 100644
index 0000000..e4cbf99
--- /dev/null
+++ b/Runtime/Scripting/ScriptingObjectWithIntPtrField.h
@@ -0,0 +1,139 @@
+#pragma once
+
+#include "Runtime/Scripting/ScriptingUtility.h"
+
+#if 1 //!UNITY_WINRT
+#if ENABLE_MONO
+extern int* s_MonoDomainContainer;
+#endif
+template<class T>
+struct ScriptingObjectWithIntPtrField
+{
+ ScriptingObjectPtr object;
+
+ ScriptingObjectWithIntPtrField(ScriptingObjectPtr o) : object(o) {}
+
+ T& operator * () const
+ {
+ return GetReference ();
+ }
+
+ T* operator -> () const
+ {
+ return &GetReference ();
+ }
+
+ operator T* () const
+ {
+ return GetPtr ();
+ }
+
+ inline T& GetReference () const
+ {
+ void* nativePointer = GetPtr();
+
+ if (nativePointer == NULL)
+ Scripting::RaiseNullException ("");
+
+ return *reinterpret_cast<T*> (nativePointer);
+ }
+
+ typedef void ExecuteOnManagedFinalizer(void* obj);
+
+ inline void SetPtr(T* ptr, ExecuteOnManagedFinalizer* eomf = NULL)
+ {
+ #if ENABLE_MONO
+ Assert(ptr == NULL || GET_CURRENT_ALLOC_ROOT_HEADER() == NULL
+ || GET_CURRENT_ALLOC_ROOT_HEADER() == GET_ALLOC_HEADER(s_MonoDomainContainer, kMemMono));
+ ExtractMonoObjectData<T*>(object) = ptr;
+ (void)eomf;
+ #elif UNITY_FLASH
+
+ __asm __volatile__("obj_g0 = marshallmap.getObjectWithId(%0);"::"r"(object));
+ __asm __volatile__("obj_g0.m_Ptr = %0;"::"r"(ptr));
+
+ //We only insert this if we actually have a way to clean it...if we don't then there's no point in inserting it in the finalizer map.
+ if(eomf == NULL)
+ return;
+
+ __asm __volatile__("finalizePtrsMap[%0] = %1;" : : "r"(ptr),"r"(eomf));
+ __asm __volatile__("finalizeMap[obj_g0] = %0;"::"r"(ptr));
+ #elif UNITY_WINRT
+ static BridgeInterface::IMarshalling^ marshaller = s_WinRTBridge->Marshalling;
+ marshaller->MarshalNativePtrIntoFirstFieldGC(object.GetHandle(), (int)ptr);
+ //typedef void (__stdcall *TMarshalNativePtrIntoFirstField)(ScriptingObjectPtr, int);
+ //static TMarshalNativePtrIntoFirstField call = (TMarshalNativePtrIntoFirstField)GetWinRTMarshalling()->GetMarshalNativePtrIntoFirstFieldDelegatePtr();
+ //call(object, (int)ptr);
+ #endif
+ }
+
+ inline T* GetPtr() const
+ {
+ if (!object)
+ return NULL;
+
+ #if ENABLE_MONO
+ return ExtractMonoObjectData<T*>(object);
+ #elif UNITY_FLASH
+ T* result;
+ __asm __volatile__("%0 = marshallmap.getObjectWithId(%1).m_Ptr;" : "=r"(result) : "r"(object));
+ return result;
+ #elif UNITY_WINRT
+ static BridgeInterface::IMarshalling^ marshaller = s_WinRTBridge->Marshalling;
+ return (T*)marshaller->MarshalFirstFieldIntoNativePtrGC(object.GetHandle());
+ //typedef int (__stdcall *TMarshalFirstFieldIntoNativePtr)(ScriptingObjectPtr);
+ //static TMarshalFirstFieldIntoNativePtr call = (TMarshalFirstFieldIntoNativePtr)GetWinRTMarshalling()->GetMarshalFirstFieldIntoNativePtrDelegatePtr();
+ //return (T*)call(object);
+ #endif
+ }
+
+ inline ScriptingObjectPtr GetScriptingObject()
+ {
+ return object;
+ }
+};
+#else
+// THIS WON'T WORK because cachedPtr doesn't derive from Object, thus we cannot extract ScriptingObjectPtr from cachedPtr
+template<class T>
+struct ScriptingObjectWithIntPtrField
+{
+ T* cachedPtr;
+
+ ScriptingObjectWithIntPtrField(void* o) : cachedPtr((T*)o) {}
+
+ T& operator * () const
+ {
+ return *cachedPtr;
+ }
+
+ T* operator -> () const
+ {
+ return cachedPtr;
+ }
+
+ operator T* () const
+ {
+ return cachedPtr;
+ }
+
+ inline T& GetReference () const
+ {
+ return *cachedPtr;
+ }
+
+ inline T* GetPtr() const
+ {
+ return cachedPtr;
+ }
+
+ typedef void ExecuteOnManagedFinalizer(void* obj);
+
+ inline void SetPtr(T* ptr, ExecuteOnManagedFinalizer* eomf = NULL)
+ {
+ if (cachedPtr != NULL)
+ {
+ s_WinRTBridge->Marshalling->MarshalNativePtrIntoFirstField(ObjectToScriptingObjectImpl(cachedPtr), (int)ptr);
+ }
+ }
+};
+#endif
diff --git a/Runtime/Scripting/ScriptingUtility.h b/Runtime/Scripting/ScriptingUtility.h
new file mode 100644
index 0000000..7670d59
--- /dev/null
+++ b/Runtime/Scripting/ScriptingUtility.h
@@ -0,0 +1,48 @@
+#ifndef SCRIPTINGUTILITY_H
+#define SCRIPTINGUTILITY_H
+
+#if ENABLE_SCRIPTING
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+
+#include "Runtime/BaseClasses/BaseObject.h"
+
+#include "Runtime/Scripting/Backend/ScriptingArguments.h"
+#include "Runtime/Scripting/Backend/ScriptingInvocation.h"
+#include "Runtime/Scripting/ICallString.h"
+
+#if ENABLE_MONO_API_THREAD_CHECK && ENABLE_MONO
+# include "Runtime/Threads/Thread.h"
+# define SCRIPTINGAPI_CONSTRUCTOR_CHECK(NAME) \
+ if (GetMonoBehaviourInConstructor() == 0) ; else { \
+ Scripting::RaiseArgumentException("You are not allowed to call " #NAME " when declaring a variable.\nMove it to the line after without a variable declaration.\nDon't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function."); \
+ }
+
+# define SCRIPTINGAPI_THREAD_CHECK(NAME) \
+ if ( Thread::CurrentThreadIsMainThread() ) ; else \
+ {\
+ ErrorString(#NAME " can only be called from the main thread.\nConstructors and field initializers will be executed from the loading thread when loading a scene.\nDon't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function."); \
+ Scripting::RaiseArgumentException(#NAME " can only be called from the main thread.\nConstructors and field initializers will be executed from the loading thread when loading a scene.\nDon't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.");\
+ }
+
+#else
+# define SCRIPTINGAPI_THREAD_CHECK(NAME)
+# define SCRIPTINGAPI_CONSTRUCTOR_CHECK(NAME)
+#endif
+
+#if ENABLE_MONO
+# include "Runtime/Mono/MonoIncludes.h"
+# include "Runtime/Mono/MonoUtility.h"
+#elif UNITY_WINRT
+#elif UNITY_FLASH
+# include "AS3Utility.h"
+#endif
+
+#include "Scripting.h"
+
+//todo: put these back at the top when we've cleaned up the dependency mess
+#include "Runtime/Scripting/ScriptingObjectOfType.h"
+#include "Runtime/Scripting/ReadOnlyScriptingObjectOfType.h"
+
+#endif //ENABLE_SCRIPTING
+
+#endif
diff --git a/Runtime/Scripting/Scripting_Flash.cpp b/Runtime/Scripting/Scripting_Flash.cpp
new file mode 100644
index 0000000..a36a950
--- /dev/null
+++ b/Runtime/Scripting/Scripting_Flash.cpp
@@ -0,0 +1,176 @@
+#include "UnityPrefix.h"
+
+#include "Scripting.h"
+#include "ScriptingUtility.h"
+#include "Runtime/BaseClasses/BaseObject.h"
+
+namespace Scripting
+{
+
+void RaiseAS3NativeException(const char* type, const char* format, va_list list)
+{
+ va_list ap = list;
+ va_copy (ap, list);
+ char buffer[1024 * 5];
+ vsnprintf (buffer, 1024 * 5, format, ap);
+ string typeString;
+ typeString += type;
+ typeString += ":";
+ typeString += buffer;
+ //ErrorString(typeString);
+ Ext_Flash_ThrowError(typeString.c_str());
+ va_end (ap);
+}
+
+void RaiseArgumentException(const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseAS3NativeException("RaiseArgumentException", format, va);
+}
+
+void RaiseSecurityException(const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseAS3NativeException("RaiseSecurityException", format, va);
+}
+
+void RaiseNullException(const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseAS3NativeException("NullReferenceException", format, va);
+}
+
+void RaiseMonoException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseAS3NativeException("RaiseMonoException", format, va);
+}
+
+void RaiseNullExceptionObject(ScriptingObjectPtr object)
+{
+ ErrorString("RaiseNullExceptionObject not implemented");
+ Ext_Flash_ThrowError("RaiseNullExceptionObject");
+}
+
+void RaiseOutOfRangeException(const char* format, ...)
+{
+ ErrorString("RaiseOutOfRangeException not implemented");
+ Ext_Flash_ThrowError("RaiseOutOfRangeException");
+}
+
+
+void* GetCachedPtrFromScriptingWrapper(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ return NULL;
+
+ void* result;
+ __asm __volatile__("%0 = (marshallmap.getObjectWithId(%1) as UnityEngine._Object).m_CachedPtr;" : "=r"(result) : "r"(object));
+ return result;
+}
+
+void SetCachedPtrOnScriptingWrapper(ScriptingObjectPtr object, void* cachedPtr)
+{
+ __asm __volatile__("(marshallmap.getObjectWithId(%0) as UnityEngine._Object).m_CachedPtr = %1;" : : "r"(object), "r"(cachedPtr));
+}
+
+int GetInstanceIDFromScriptingWrapper(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ return 0;
+
+ int result;
+ __asm __volatile__("%0 = (marshallmap.getObjectWithId(%1) as UnityEngine._Object).m_InstanceID;" : "=r"(result) : "r"(object));
+ return result;
+}
+
+void SetInstanceIDOnScriptingWrapper(ScriptingObjectPtr object, int instanceID)
+{
+ __asm __volatile__("(marshallmap.getObjectWithId(%0) as UnityEngine._Object).m_InstanceID = %1;" : : "r"(object), "r"(instanceID));
+}
+
+void SetErrorOnScriptingWrapper(ScriptingObjectPtr object, ScriptingStringPtr error)
+{
+
+}
+
+ScriptingObjectPtr InstantiateScriptingWrapperForClassID(int classID)
+{
+ const string& name = Object::ClassIDToString(classID);
+ const char* cname = name.c_str();
+
+ ScriptingObjectPtr result = Ext_Scripting_InstantiateScriptingWrapperForClassWithName(cname);
+ if(result != NULL)
+ return result;
+
+ int superClassID = Object::GetSuperClassID(classID);
+ if(superClassID != ClassID(Object))
+ return InstantiateScriptingWrapperForClassID(superClassID);
+
+ return NULL;
+}
+
+ScriptingObjectPtr ScriptingObjectNULL(ScriptingClassPtr klass)
+{
+ return SCRIPTING_NULL;
+}
+
+void RaiseIfNull(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ RaiseNullException("(null)");
+}
+
+void RaiseIfNull(void* object)
+{
+ if(object == NULL)
+ RaiseNullException("(null)");
+}
+
+void SetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i, ScriptingObjectPtr value)
+{
+ void* raw = scripting_array_element_ptr(a, i, sizeof(ScriptingObjectPtr));
+ *(ScriptingObjectPtr*)raw = value;
+}
+
+void SetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i, ScriptingStringPtr value)
+{
+ void* raw = scripting_array_element_ptr(a, i, sizeof(ScriptingStringPtr));
+ *(ScriptingStringPtr*)raw = value;
+}
+
+ScriptingStringPtr* GetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i)
+{
+ return (ScriptingStringPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingStringPtr));
+}
+
+ScriptingObjectPtr* GetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i)
+{
+ return (ScriptingObjectPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingObjectPtr));
+}
+
+ScriptingStringPtr* GetScriptingArrayStringStartImpl(ScriptingArrayPtr a)
+{
+ return (ScriptingStringPtr*)scripting_array_element_ptr(a, 0, sizeof(ScriptingStringPtr));
+}
+
+ScriptingObjectPtr* GetScriptingArrayObjectStartImpl(ScriptingArrayPtr a)
+{
+ return (ScriptingObjectPtr*)scripting_array_element_ptr(a, 0, sizeof(ScriptingObjectPtr));
+}
+
+ScriptingStringPtr GetScriptingArrayStringElementNoRefImpl(ScriptingArrayPtr a, int i)
+{
+ return *((ScriptingStringPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingStringPtr)));
+}
+
+ScriptingObjectPtr GetScriptingArrayObjectElementNoRefImpl(ScriptingArrayPtr a, int i)
+{
+ return *((ScriptingObjectPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingObjectPtr)));
+}
+
+}//namespace Scripting \ No newline at end of file
diff --git a/Runtime/Scripting/Scripting_Mono.cpp b/Runtime/Scripting/Scripting_Mono.cpp
new file mode 100644
index 0000000..848a6a0
--- /dev/null
+++ b/Runtime/Scripting/Scripting_Mono.cpp
@@ -0,0 +1,247 @@
+#include "UnityPrefix.h"
+
+#include <stdarg.h>
+#include "Scripting.h"
+#include "Runtime/Mono/MonoManager.h"
+
+#ifdef _MSC_VER
+#define va_copy(a,z) ((void)((a)=(z)))
+#endif
+
+static UnityEngineObjectMemoryLayout* GetUnityEngineObjectMemoryLayout(ScriptingObjectPtr object)
+{
+ return reinterpret_cast<UnityEngineObjectMemoryLayout*>(((char*)object) + kMonoObjectOffset);
+}
+
+namespace Scripting
+{
+
+void* GetCachedPtrFromScriptingWrapper(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ return NULL;
+
+ return GetUnityEngineObjectMemoryLayout(object)->cachedPtr;
+}
+
+void SetCachedPtrOnScriptingWrapper(ScriptingObjectPtr object, void* cachedPtr)
+{
+ GetUnityEngineObjectMemoryLayout(object)->cachedPtr = cachedPtr;
+}
+
+int GetInstanceIDFromScriptingWrapper(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ return 0;
+
+ return GetUnityEngineObjectMemoryLayout(object)->instanceID;
+}
+
+void SetInstanceIDOnScriptingWrapper(ScriptingObjectPtr object, int instanceID)
+{
+ GetUnityEngineObjectMemoryLayout(object)->instanceID = instanceID;
+}
+
+void SetErrorOnScriptingWrapper(ScriptingObjectPtr object, ScriptingStringPtr error)
+{
+#if MONO_QUALITY_ERRORS
+ GetUnityEngineObjectMemoryLayout(object)->error = error;
+#endif
+}
+
+ScriptingObjectPtr InstantiateScriptingWrapperForClassID(int classID)
+{
+ return (ScriptingObjectPtr)MonoInstantiateScriptingWrapperForClassID(classID);
+}
+
+ScriptingObjectPtr ScriptingObjectNULL(ScriptingClassPtr klass)
+{
+ return MonoObjectNULL(klass);
+}
+
+ScriptingObjectPtr ScriptingObjectNULL(ScriptingClassPtr klass, ScriptingStringPtr error)
+{
+#if MONO_QUALITY_ERRORS
+ return MonoObjectNULL(klass,error);
+#else
+ return MonoObjectNULL(klass);
+#endif
+}
+
+
+DOES_NOT_RETURN void RaiseDotNetExceptionImpl (const char* ns, const char* type, const char* format, va_list list)
+{
+ va_list ap;
+ va_copy (ap, list);
+
+ char buffer[1024 * 5];
+ vsnprintf (buffer, 1024 * 5, format, ap);
+ va_end (ap);
+
+ MonoException* exception = mono_exception_from_name_msg (mono_get_corlib (), ns, type, buffer);
+ mono_raise_exception (exception);
+
+}
+
+DOES_NOT_RETURN void RaiseSystemExceptionImpl (const char* type, const char* format, va_list list)
+{
+ va_list ap;
+ va_copy (ap, list);
+ RaiseDotNetExceptionImpl("System",type,format,ap);
+}
+
+void RaiseManagedException (const char *ns, const char *type, const char *format, ...)
+{
+ va_list va;
+ va_start (va, format);
+ RaiseDotNetExceptionImpl (ns, type, format, va);
+}
+
+void RaiseMonoException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+
+ char buffer[1024 * 5];
+ vsnprintf (buffer, 1024 * 5, format, va);
+
+ MonoException* exception = mono_exception_from_name_msg (GetMonoManager ().GetEngineImage (), kEngineNameSpace, "UnityException", buffer);
+ mono_raise_exception (exception);
+}
+
+void RaiseOutOfRangeException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseSystemExceptionImpl("IndexOutOfRangeException", format, va);
+}
+
+void RaiseNullException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseSystemExceptionImpl("NullReferenceException", format, va);
+}
+
+void RaiseArgumentException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseSystemExceptionImpl("ArgumentException", format, va);
+}
+
+void RaiseInvalidOperationException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseSystemExceptionImpl("InvalidOperationException", format, va);
+}
+
+void RaiseSecurityException (const char* format, ...)
+{
+ va_list va;
+ va_start( va, format );
+ RaiseDotNetExceptionImpl("System.Security","SecurityException", format, va);
+}
+
+void RaiseNullExceptionObject (MonoObject* object)
+{
+ #if MONO_QUALITY_ERRORS
+ if (object)
+ {
+ MonoClass* klass = mono_object_get_class(object);
+ if (mono_class_is_subclass_of (mono_object_get_class(object), GetMonoManager().ClassIDToScriptingClass(ClassID(Object)), false))
+ {
+ UnityEngineObjectMemoryLayout& data = ExtractMonoObjectData<UnityEngineObjectMemoryLayout>(object);
+ string error = MonoStringToCpp(data.error);
+
+ // The object was destroyed underneath us - but if we hit a MissingReferenceException then we show that instead!
+ if (data.instanceID != 0 && error.find ("MissingReferenceException:") != 0)
+ {
+ error = Format("The object of type '%s' has been destroyed but you are still trying to access it.\n"
+ "Your script should either check if it is null or you should not destroy the object.", mono_class_get_name(klass));
+
+ MonoException* exception = mono_exception_from_name_msg (GetMonoManager().GetEngineImage(), "UnityEngine", "MissingReferenceException", error.c_str());
+ mono_raise_exception (exception);
+ }
+
+ // We got an error message, parse it and throw it
+ if (data.error)
+ {
+ error = MonoStringToCpp(data.error);
+ string::size_type exceptionTypePos = error.find(':');
+ if (exceptionTypePos != string::npos)
+ {
+ string type = string(error.begin(), error.begin() + exceptionTypePos);
+ error.erase(error.begin(), error.begin()+exceptionTypePos + 1);
+
+ MonoException* exception = mono_exception_from_name_msg (GetMonoManager().GetEngineImage(), "UnityEngine", type.c_str(), error.c_str ());
+ mono_raise_exception (exception);
+ }
+ }
+ }
+ }
+
+ MonoException* exception = mono_exception_from_name_msg (mono_get_corlib (), "System", "NullReferenceException", "");
+ mono_raise_exception (exception);
+ #else
+ MonoException* exception = mono_exception_from_name_msg (mono_get_corlib (), "System", "NullReferenceException", "");
+ mono_raise_exception (exception);
+ #endif
+}
+
+void RaiseIfNull(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ RaiseNullException("(null)");
+}
+
+void RaiseIfNull(void* object)
+{
+ if(object == NULL)
+ RaiseNullException("(null)");
+}
+
+void SetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i, ScriptingObjectPtr value)
+{
+ void* raw = scripting_array_element_ptr(a, i, sizeof(ScriptingObjectPtr));
+ *(ScriptingObjectPtr*)raw = value;
+}
+
+void SetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i, ScriptingStringPtr value)
+{
+ void* raw = scripting_array_element_ptr(a, i, sizeof(ScriptingStringPtr));
+ *(ScriptingStringPtr*)raw = value;
+}
+
+ScriptingStringPtr* GetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i)
+{
+ return (ScriptingStringPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingStringPtr));
+}
+
+ScriptingObjectPtr* GetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i)
+{
+ return (ScriptingObjectPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingObjectPtr));
+}
+
+ScriptingStringPtr* GetScriptingArrayStringStartImpl(ScriptingArrayPtr a)
+{
+ return (ScriptingStringPtr*)scripting_array_element_ptr(a, 0, sizeof(ScriptingStringPtr));
+}
+
+ScriptingObjectPtr* GetScriptingArrayObjectStartImpl(ScriptingArrayPtr a)
+{
+ return (ScriptingObjectPtr*)scripting_array_element_ptr(a, 0, sizeof(ScriptingObjectPtr));
+}
+
+ScriptingStringPtr GetScriptingArrayStringElementNoRefImpl(ScriptingArrayPtr a, int i)
+{
+ return *((ScriptingStringPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingStringPtr)));
+}
+
+ScriptingObjectPtr GetScriptingArrayObjectElementNoRefImpl(ScriptingArrayPtr a, int i)
+{
+ return *((ScriptingObjectPtr*)scripting_array_element_ptr(a, i, sizeof(ScriptingObjectPtr)));
+}
+
+}//namespace Scripting
diff --git a/Runtime/Scripting/Scripting_WinRT.cpp b/Runtime/Scripting/Scripting_WinRT.cpp
new file mode 100644
index 0000000..e995ca7
--- /dev/null
+++ b/Runtime/Scripting/Scripting_WinRT.cpp
@@ -0,0 +1,175 @@
+#include "UnityPrefix.h"
+
+#include "Scripting.h"
+#include "ScriptingManager.h"
+#include "Backend/ScriptingTypeRegistry.h"
+#include "Backend/ScriptingBackendApi.h"
+#include "PlatformDependent/MetroPlayer/MetroUtils.h"
+
+#include <wrl/wrappers/corewrappers.h>
+
+static BridgeInterface::IArrayTools^& GetWinRTArrayTools()
+{
+ static BridgeInterface::IArrayTools^ s_Cached = s_WinRTBridge->ArrayTools;
+ return s_Cached;
+}
+
+static BridgeInterface::IUnityEngineObjectTools^& GetWinRTUnityEngineObjectTools()
+{
+ static BridgeInterface::IUnityEngineObjectTools^ s_Cached = s_WinRTBridge->UnityEngineObjectTools;
+ return s_Cached;
+}
+
+namespace Scripting
+{
+
+void* GetCachedPtrFromScriptingWrapper(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ return NULL;
+
+ return (void*)GetWinRTUnityEngineObjectTools()->ScriptingObjectGetReferenceDataCachedPtrGC(object.GetHandle());
+}
+
+void SetCachedPtrOnScriptingWrapper(ScriptingObjectPtr object, void* cachedPtr)
+{
+ GetWinRTUnityEngineObjectTools()->ScriptingObjectSetReferenceDataCachedPtrGC(object.GetHandle(), (int)cachedPtr);
+}
+
+int GetInstanceIDFromScriptingWrapper(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ return 0;
+
+ return GetWinRTUnityEngineObjectTools()->ScriptingObjectGetReferenceDataInstanceIDGC(object.GetHandle());
+}
+
+void SetInstanceIDOnScriptingWrapper(ScriptingObjectPtr object, int instanceID)
+{
+ GetWinRTUnityEngineObjectTools()->ScriptingObjectSetReferenceDataInstanceIDGC(object.GetHandle(), instanceID);
+}
+
+void SetErrorOnScriptingWrapper(ScriptingObjectPtr object, ScriptingStringPtr error)
+{
+
+}
+
+#if !UNITY_EXTERNAL_TOOL
+ScriptingObjectPtr InstantiateScriptingWrapperForClassID(int classID)
+{
+ const string& name = Object::ClassIDToString(classID);
+
+ ScriptingClassPtr klass = GetScriptingTypeRegistry().GetType("UnityEngine", name.c_str());
+ if (klass != SCRIPTING_NULL)
+ return scripting_object_new(klass);
+
+ int superClassID = Object::GetSuperClassID(classID);
+ if(superClassID != ClassID(Object))
+ return InstantiateScriptingWrapperForClassID(superClassID);
+
+ return SCRIPTING_NULL;
+}
+#endif
+
+ScriptingObjectPtr ScriptingObjectNULL(ScriptingClassPtr klass)
+{
+ return SCRIPTING_NULL;
+}
+
+void RaiseSecurityException(const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ throw ref new Platform::FailureException(ConvertUtf8ToString(VFormat(format, va)));
+}
+
+void RaiseNullException(const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ throw ref new Platform::FailureException(ConvertUtf8ToString(VFormat(format, va)));
+}
+
+void RaiseNullExceptionObject(ScriptingObjectPtr object)
+{
+ throw ref new Platform::NullReferenceException();
+}
+
+void RaiseMonoException (const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ throw ref new Platform::FailureException(ConvertUtf8ToString(VFormat(format, va)));
+}
+
+void RaiseOutOfRangeException(const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ throw ref new Platform::OutOfBoundsException(ConvertUtf8ToString(VFormat(format, va)));
+}
+
+void RaiseArgumentException (const char* format, ...)
+{
+ va_list va;
+ va_start(va, format);
+ throw ref new Platform::InvalidArgumentException(ConvertUtf8ToString(VFormat(format, va)));
+}
+
+void RaiseIfNull(ScriptingObjectPtr object)
+{
+ if(object == SCRIPTING_NULL)
+ throw ref new Platform::NullReferenceException();
+}
+
+void RaiseIfNull(void* object)
+{
+ if(object == NULL)
+ RaiseNullException("(null)");
+}
+
+void SetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i, ScriptingObjectPtr value)
+{
+ GetWinRTArrayTools()->SetArrayValue(a.GetHandle(), i, value.GetHandle());
+}
+
+void SetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i, ScriptingStringPtr value)
+{
+ GetWinRTArrayTools()->SetArrayStringValue(a.GetHandle(), i, value);
+}
+
+ScriptingStringPtr* GetScriptingArrayStringElementImpl(ScriptingArrayPtr a, int i)
+{
+ FatalErrorMsg("Not allowed");
+ return NULL;
+}
+
+ScriptingObjectPtr* GetScriptingArrayObjectElementImpl(ScriptingArrayPtr a, int i)
+{
+ FatalErrorMsg("Not allowed");
+ return NULL;
+}
+
+ScriptingStringPtr* GetScriptingArrayStringStartImpl(ScriptingArrayPtr a)
+{
+ FatalErrorMsg("Not allowed");
+ return NULL;
+}
+
+ScriptingObjectPtr* GetScriptingArrayObjectStartImpl(ScriptingArrayPtr a)
+{
+ FatalErrorMsg("Not allowed");
+ return NULL;
+}
+
+ScriptingStringPtr GetScriptingArrayStringElementNoRefImpl(ScriptingArrayPtr a, int i)
+{
+ return GetWinRTArrayTools()->GetArrayStringValue(a.GetHandle(), i);
+}
+
+ScriptingObjectPtr GetScriptingArrayObjectElementNoRefImpl(ScriptingArrayPtr a, int i)
+{
+ return WinRTScriptingObjectWrapper(GetWinRTArrayTools()->GetArrayValue(a.GetHandle(), i));
+}
+
+} // namespace Scripting \ No newline at end of file
diff --git a/Runtime/Scripting/TextAsset.cpp b/Runtime/Scripting/TextAsset.cpp
new file mode 100644
index 0000000..f21b0e6
--- /dev/null
+++ b/Runtime/Scripting/TextAsset.cpp
@@ -0,0 +1,70 @@
+#include "UnityPrefix.h"
+#include "TextAsset.h"
+#include "Runtime/Serialize/TransferFunctions/SerializeTransfer.h"
+#if ENABLE_MONO
+#include "Runtime/Mono/MonoIncludes.h"
+#endif
+
+
+TextAsset::TextAsset(MemLabelId label, ObjectCreationMode mode)
+ : Super(label, mode)
+{
+}
+
+TextAsset::~TextAsset ()
+{
+}
+
+template<class TransferFunction>
+void TextAsset::Transfer (TransferFunction& transfer)
+{
+ Super::Transfer ( transfer);
+ transfer.Transfer (m_Script, "m_Script", kHideInEditorMask);
+ transfer.Transfer (m_PathName, "m_PathName", kHideInEditorMask);
+}
+
+void TextAsset::AwakeFromLoad (AwakeFromLoadMode awakeMode)
+{
+ Super::AwakeFromLoad (awakeMode);
+}
+
+void TextAsset::SetScriptDontDirty (const ScriptString& script) {
+ m_Script = script;
+}
+
+bool TextAsset::SetScript (const ScriptString& script) {
+ return SetScript(script,false);
+}
+
+bool TextAsset::SetScript (const ScriptString& script, bool actuallyContainsBinaryData)
+{
+ SET_ALLOC_OWNER(this);
+ m_Script = script;
+
+ #if ENABLE_MONO
+ // Fallback. If mono doesn't accept the string, strip everything non-ASCII
+ if(mono_string_new_wrapper(script.c_str()) == NULL && !actuallyContainsBinaryData)
+ {
+ m_Script.clear();
+
+ for(int i=0; i<script.size(); i++)
+ {
+ if((unsigned char)script[i] < 0x7f)
+ m_Script += script[i];
+ }
+ }
+ #endif
+
+ SetDirty ();
+ return true;
+}
+
+const UnityStr& TextAsset::GetScriptClassName() const {
+ static UnityStr sEmpty;
+ return sEmpty;
+}
+
+
+IMPLEMENT_CLASS (TextAsset)
+IMPLEMENT_OBJECT_SERIALIZE (TextAsset)
+INSTANTIATE_TEMPLATE_TRANSFER (TextAsset)
diff --git a/Runtime/Scripting/TextAsset.h b/Runtime/Scripting/TextAsset.h
new file mode 100644
index 0000000..5c42fb2
--- /dev/null
+++ b/Runtime/Scripting/TextAsset.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include "Runtime/BaseClasses/NamedObject.h"
+#include "Configuration/UnityConfigure.h"
+
+#include "Runtime/Misc/Allocator.h"
+
+
+class TextAsset : public NamedObject {
+public:
+
+ typedef UnityStr ScriptString;
+
+ REGISTER_DERIVED_CLASS (TextAsset, NamedObject)
+ DECLARE_OBJECT_SERIALIZE (TextAsset)
+
+ TextAsset(MemLabelId label, ObjectCreationMode mode);
+
+ virtual void AwakeFromLoad (AwakeFromLoadMode awakeMode);
+
+ // Set the script string.
+ // Subclasses override this in order to implement compiling, etc...
+ // @return whether the compilation succeeded
+ virtual bool SetScript (const ScriptString& script, bool actuallyContainsBinaryData);
+ virtual bool SetScript (const ScriptString& script);
+
+ // Get the script string.
+ const ScriptString &GetScript () const { return m_Script; }
+
+ void SetPathName (const std::string& path) { m_PathName = path; SetDirty (); }
+ const UnityStr& GetPathName () { return m_PathName; }
+
+ virtual const UnityStr& GetScriptClassName() const;
+ void SetScriptDontDirty (const ScriptString& script);
+
+protected:
+
+ UnityStr m_PathName;
+ ScriptString m_Script;
+};
diff --git a/Runtime/Scripting/WinRTHelper.h b/Runtime/Scripting/WinRTHelper.h
new file mode 100644
index 0000000..2fef260
--- /dev/null
+++ b/Runtime/Scripting/WinRTHelper.h
@@ -0,0 +1,29 @@
+#ifndef WINRTHELPER_H
+#define WINRTHELPER_H
+
+#if UNITY_WINRT
+
+# if UNITY_METRO_VS2012
+# if defined(__arm__)
+# include "build/temp/MetroSupport/metroARM/AutoGeneratedFuncDefs.h"
+# else
+# include "build/temp/MetroSupport/metro32/AutoGeneratedFuncDefs.h"
+# endif
+# elif UNITY_METRO_VS2013
+# if defined(__arm__)
+# include "build/temp/MetroSupport/metroBlueARM/AutoGeneratedFuncDefs.h"
+# else
+# include "build/temp/MetroSupport/metroBlue32/AutoGeneratedFuncDefs.h"
+# endif
+# elif UNITY_WP8
+# include "build/temp/WP8Support/AutoGeneratedFuncDefs.h"
+# endif
+#endif
+
+
+inline long long* GetWinRTFuncDefsPointers()
+{
+ return (long long*)UnityEngineDelegates::FunctionDefsDictionary::GetPointers();
+}
+
+#endif
diff --git a/Runtime/Scripting/WinRTMarshalers.cpp b/Runtime/Scripting/WinRTMarshalers.cpp
new file mode 100644
index 0000000..80d4d48
--- /dev/null
+++ b/Runtime/Scripting/WinRTMarshalers.cpp
@@ -0,0 +1,306 @@
+#include "UnityPrefix.h"
+
+#if UNITY_WINRT && ENABLE_SCRIPTING
+#include "Runtime/Scripting/Backend/ScriptingTypes.h"
+#include "Runtime/Scripting/ScriptingUtility.h"
+
+
+#include "Runtime/Misc/AssetBundleUtility.h"
+#include "Runtime/Camera/LODGroup.h"
+#include "Runtime/NavMesh/NavMeshTypes.h"
+#include "Runtime/Terrain/SplatDatabase.h"
+#include "Runtime/Terrain/DetailDatabase.h"
+#include "Runtime/Terrain/TreeDatabase.h"
+#include "Runtime/IMGUI/GUIContent.h"
+#include "Runtime/Mono/Coroutine.h"
+#include "Runtime/Export/WWW.h"
+#include "Runtime/Graphics/LightmapSettings.h"
+#include "Runtime/Animation/AnimationEvent.h"
+
+#include "Runtime/Dynamics/CharacterController.h"
+#include "Runtime/Misc/AsyncOperation.h"
+#include "Runtime/Dynamics/Collider.h"
+#include "Runtime/Physics2D/Collider2D.h"
+#include "Runtime/Physics2D/CollisionListener2D.h"
+#include "Runtime/Video/VideoTexture.h"
+#include "Runtime/Threads/ThreadSpecificValue.h"
+#include "Runtime/Filters/Misc/Font.h"
+
+UNITY_TLS_VALUE(void*) s_CurrentTarget;
+
+void _MarshalSetMonoLOD(float screenRelativeTransitionHeight, /*WinRTScriptingObjectWrapper*/long long renderers)
+{
+ MonoLOD* monoLOD = (MonoLOD*)s_CurrentTarget;
+ monoLOD->screenRelativeTransitionHeight = screenRelativeTransitionHeight;
+ monoLOD->renderers = renderers;
+}
+void _MarshalSetNavMeshPath(int ptr, /*WinRTScriptingObjectWrapper*/long long corners)
+{
+ MonoNavMeshPath* monoNavMeshPath = (MonoNavMeshPath*)s_CurrentTarget;
+ monoNavMeshPath->native = (NavMeshPath*)ptr;
+ monoNavMeshPath->corners = corners;
+}
+void _MarshalSetMonoGUIContent(Platform::String^ text, Platform::String^ tooltip, /*WinRTScriptingObjectWrapper*/long long image)
+{
+ MonoGUIContent* monoGUIContent = (MonoGUIContent*)s_CurrentTarget;
+ monoGUIContent->m_Text = text;
+ monoGUIContent->m_Tooltip = tooltip;
+ monoGUIContent->m_Image = image;
+}
+void _MarshalSetLightmapDataMono(/*WinRTScriptingObjectWrapper*/long long lightmap, /*WinRTScriptingObjectWrapper*/long long indirectLightmap)
+{
+ LightmapDataMono* monoLightmap = (LightmapDataMono*)s_CurrentTarget;
+ monoLightmap->m_Lightmap = lightmap;
+ monoLightmap->m_IndirectLightmap = indirectLightmap;
+}
+void _MarshalSetMonoTreePrototype(/*WinRTScriptingObjectWrapper*/long long prefab, float bendFactor)
+{
+ MonoTreePrototype* monoTreePrototype = (MonoTreePrototype*)s_CurrentTarget;
+ monoTreePrototype->prefab = prefab;
+ monoTreePrototype->bendFactor = bendFactor;
+}
+
+
+void _MarshalSetMonoDetailPrototype1(/*WinRTScriptingObjectWrapper*/long long prototype, /*WinRTScriptingObjectWrapper*/long long prototypeTexture,
+ float healthyColorR, float healthyColorG, float healthyColorB, float healthyColorA,
+ float dryColorR, float dryColorG, float dryColorB, float dryColorA)
+{
+ MonoDetailPrototype* monoDetailPrototype = (MonoDetailPrototype*)s_CurrentTarget;
+ monoDetailPrototype->prototype = prototype;
+ monoDetailPrototype->prototypeTexture = prototypeTexture;
+
+ monoDetailPrototype->healthyColor = ColorRGBAf(healthyColorR, healthyColorG, healthyColorB, healthyColorA);
+ monoDetailPrototype->dryColor = ColorRGBAf(dryColorR, dryColorG, dryColorB, dryColorA);
+}
+void _MarshalSetMonoDetailPrototype2(float minWidth, float maxWidth,
+ float minHeight, float maxHeight,
+ float noiseSpread,
+ float bendFactor,
+ int renderMode,
+ int usePrototypeMesh)
+{
+ MonoDetailPrototype* monoDetailPrototype = (MonoDetailPrototype*)s_CurrentTarget;
+
+ monoDetailPrototype->minWidth = minWidth;
+ monoDetailPrototype->maxWidth = maxWidth;
+ monoDetailPrototype->minHeight = minHeight;
+ monoDetailPrototype->maxHeight = maxHeight;
+ monoDetailPrototype->noiseSpread = noiseSpread;
+ monoDetailPrototype->bendFactor = bendFactor;
+ monoDetailPrototype->renderMode = renderMode;
+ monoDetailPrototype->usePrototypeMesh = usePrototypeMesh;
+}
+void _MarshalSetMonoSplatPrototype(/*WinRTScriptingObjectWrapper*/long long texture, /*WinRTScriptingObjectWrapper*/long long normalMap,
+ float tileSizeX, float tileSizeY,
+ float tileOffsetX, float tileOffsetY)
+{
+ MonoSplatPrototype* monoSplatPrototype = (MonoSplatPrototype*)s_CurrentTarget;
+ monoSplatPrototype->texture = texture;
+ monoSplatPrototype->normalMap = normalMap;
+ monoSplatPrototype->tileSize = Vector2f(tileSizeX, tileSizeY);
+ monoSplatPrototype->tileOffset = Vector2f(tileOffsetX, tileOffsetX);
+}
+void _MarshalSetScriptingCharacterInfo(int index, BridgeInterface::RectWrapper uv, BridgeInterface::RectWrapper vert, float width, int size, int style, bool flipped)
+{
+ ScriptingCharacterInfo* o = (ScriptingCharacterInfo*)s_CurrentTarget;
+ o->index = index;
+ o->uv = Rectf(uv.m_XMin, uv.m_YMin, uv.m_Width, uv.m_Height);
+ o->vert = Rectf(vert.m_XMin, vert.m_YMin, vert.m_Width, vert.m_Height);
+ o->width = width;
+ o->size = size;
+ o->style = style;
+ o->flipped = flipped;
+}
+
+void SetupMarshalCallbacks()
+{
+ GetWinRTMarshalling()->SetupMarshalCallbacks(
+ ref new BridgeInterface::MarshalSetMonoLOD(_MarshalSetMonoLOD),
+ ref new BridgeInterface::MarshalSetNavMeshPath(_MarshalSetNavMeshPath),
+ ref new BridgeInterface::MarshalSetMonoGUIContent(_MarshalSetMonoGUIContent),
+ ref new BridgeInterface::MarshalSetLightmapDataMono(_MarshalSetLightmapDataMono),
+ ref new BridgeInterface::MarshalSetMonoTreePrototype(_MarshalSetMonoTreePrototype),
+ ref new BridgeInterface::MarshalSetMonoDetailPrototype1(_MarshalSetMonoDetailPrototype1),
+ ref new BridgeInterface::MarshalSetMonoDetailPrototype2(_MarshalSetMonoDetailPrototype2),
+ ref new BridgeInterface::MarshalSetMonoSplatPrototype(_MarshalSetMonoSplatPrototype),
+ ref new BridgeInterface::MarshalSetScriptingCharacterInfo(_MarshalSetScriptingCharacterInfo));
+}
+//
+// Marshalling: Managed - to - Native
+//
+
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, AssetBundleCreateRequest** dest)
+{
+ *dest = (AssetBundleCreateRequest*)GetWinRTMarshalling()->MarshalGetAssetBundleCreateRequestPtr(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoLOD* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedMonoLOD(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoNavMeshPath* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedMonoNavMeshPath(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoGUIContent* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedMonoGUIContent(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, float* dest)
+{
+ *dest = GetWinRTMarshalling()->MarshallGetManagedWaitForSecondsWait(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, Coroutine** dest)
+{
+ *dest = (Coroutine*)GetWinRTMarshalling()->MarshallGetManagedCoroutinePtr(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, WWW** dest)
+{
+ *dest = (WWW*)GetWinRTMarshalling()->MarshallGetManagedWWWPtr(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, LightmapDataMono* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedLightmapDataMono(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoTreePrototype* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedMonoTreePrototype(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoDetailPrototype* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedMonoDetailPrototype(so.GetHandle());
+}
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoSplatPrototype* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedMonoSplatPrototype(so.GetHandle());
+}
+
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, ScriptingCharacterInfo* dest)
+{
+ s_CurrentTarget = dest;
+ GetWinRTMarshalling()->MarshallManagedScriptingCharacterInfo(so.GetHandle());
+}
+
+//
+// Marshalling: Native - to - Managed
+//
+void MarshallNativeStructIntoManaged(const AnimationEvent* src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeAnimationEventPtr((int)src, dest.GetHandle());
+}
+void MarshallNativeStructIntoManaged(const AssetBundleRequestMono& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeAssetBundleRequestTo((int)src.m_Result, src.m_AssetBundle, src.m_Path, src.m_Type, dest.GetHandle());
+}
+void MarshallNativeStructIntoManaged(const MonoNavMeshPath& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeNavMashPathTo((int)src.native, src.corners, dest.GetHandle());
+}
+void MarshallNativeStructIntoManaged(const void* src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeVoidPtrTo((int)src, dest.GetHandle());
+}
+
+void MarshallNativeStructIntoManaged(const ControllerColliderHit& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeControllerColliderHitTo(src.controller, src.collider,
+ src.point.x, src.point.y, src.point.z,
+ src.normal.x, src.normal.y, src.normal.z,
+ src.motionDirection.x, src.motionDirection.y, src.motionDirection.z,
+ src.motionLength,
+ src.push,
+ dest);
+}
+void MarshallNativeStructIntoManaged(const AsyncOperation* src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeAsyncOperationPtrTo((int)src, dest.GetHandle());
+}
+void MarshallNativeStructIntoManaged(const MonoContactPoint& src, ScriptingObjectPtr& dest)
+{
+ dest = GetWinRTMarshalling()->MarshallNativeMonoContactPointTo(src.point.x, src.point.y, src.point.z,
+ src.normal.x, src.normal.y, src.normal.z,
+ src.thisCollider,
+ src.otherCollider);
+}
+void MarshallNativeStructIntoManaged(const MonoTreePrototype& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeMonoTreePrototypeTo(src.prefab, src.bendFactor, dest.GetHandle());
+}
+
+#if ENABLE_WEBCAM
+void MarshallNativeStructIntoManaged(const MonoWebCamDevice& src, ScriptingObjectPtr& dest)
+{
+ dest = GetWinRTMarshalling()->MarshallNativeMonoWebCamDeviceTo(src.name, src.flags);
+}
+#endif
+
+void MarshallNativeStructIntoManaged(const MonoCollision& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeMonoCollisionTo(src.relativeVelocity.x, src.relativeVelocity.y, src.relativeVelocity.z,
+ src.rigidbody, src.collider, src.contacts.GetHandle(), dest.GetHandle());
+}
+void MarshallNativeStructIntoManaged(const LightmapDataMono& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeLightmapDataMonoTo(src.m_Lightmap, src.m_IndirectLightmap, dest.GetHandle());
+}
+
+void MarshallNativeStructIntoManaged(const MonoDetailPrototype& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeMonoDetailPrototype1To(
+ src.prototype, src.prototypeTexture,
+ src.healthyColor.r, src.healthyColor.g, src.healthyColor.b, src.healthyColor.a,
+ src.dryColor.r, src.dryColor.g, src.dryColor.b, src.dryColor.a,
+ dest);
+ GetWinRTMarshalling()->MarshallNativeMonoDetailPrototype2To(
+ src.minWidth, src.maxWidth,
+ src.minHeight, src.maxHeight,
+ src.noiseSpread, src.bendFactor,
+ src.renderMode, src.usePrototypeMesh,
+ dest);
+}
+void MarshallNativeStructIntoManaged(const MonoSplatPrototype& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeMonoSplatPrototypeTo(src.texture, src.normalMap,
+ src.tileSize.x, src.tileSize.y,
+ src.tileOffset.x, src.tileOffset.y,
+ dest);
+}
+#if ENABLE_2D_PHYSICS
+void MarshallNativeStructIntoManaged(const ScriptingCollision2D& src, ScriptingObjectPtr& dest)
+{
+ GetWinRTMarshalling()->MarshallNativeCollision2DTo(src.rigidbody.GetHandle(), src.collider.GetHandle(), src.contacts.GetHandle(), dest.GetHandle());
+}
+
+void MarshallNativeStructIntoManaged(const ScriptingContactPoint2D& src, ScriptingObjectPtr& dest)
+{
+ dest = GetWinRTMarshalling()->MarshallNativeContactPoint2DTo(
+ src.point.x, src.point.y,
+ src.normal.x, src.normal.y,
+ src.collider,
+ src.otherCollider);
+}
+#endif
+void MarshallNativeStructIntoManaged(const ScriptingCharacterInfo& src, ScriptingObjectPtr& dest)
+{
+ BridgeInterface::RectWrapper uv;
+ BridgeInterface::RectWrapper vert;
+ uv.m_XMin = src.uv.x;
+ uv.m_YMin = src.uv.y;
+ uv.m_Width = src.uv.width;
+ uv.m_Height = src.uv.height;
+
+ vert.m_XMin = src.vert.x;
+ vert.m_YMin = src.vert.y;
+ vert.m_Width = src.vert.width;
+ vert.m_Height = src.vert.height;
+ dest = GetWinRTMarshalling()->MarshallNativeScriptingCharacterInfoTo(src.index,
+ uv, vert,
+ src.width, src.size, src.style, src.flipped);
+}
+#endif
diff --git a/Runtime/Scripting/WinRTMarshalers.h b/Runtime/Scripting/WinRTMarshalers.h
new file mode 100644
index 0000000..c125a22
--- /dev/null
+++ b/Runtime/Scripting/WinRTMarshalers.h
@@ -0,0 +1,66 @@
+#ifndef WINRTMARSHALERS_H
+#define WINRTMARSHALERS_H
+
+#if UNITY_WINRT && ENABLE_SCRIPTING
+
+class AssetBundleCreateRequest;
+struct AssetBundleRequestMono;
+struct MonoLOD;
+struct MonoNavMeshPath;
+struct MonoGUIContent;
+struct Coroutine;
+class WWW;
+struct LightmapDataMono;
+struct MonoTreePrototype;
+struct AnimationEvent;
+struct ControllerColliderHit;
+class AsyncOperation;
+struct MonoContactPoint;
+struct MonoWebCamDevice;
+struct MonoCollision;
+struct MonoDetailPrototype;
+struct MonoSplatPrototype;
+struct ScriptingCollision2D;
+struct ScriptingContactPoint2D;
+struct ScriptingCharacterInfo;
+
+void SetupMarshalCallbacks();
+
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, AssetBundleCreateRequest** dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoLOD* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoNavMeshPath* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoGUIContent* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, float* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, Coroutine** dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, WWW** dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, LightmapDataMono* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoTreePrototype* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoDetailPrototype* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, MonoSplatPrototype* dest);
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, ScriptingCharacterInfo* dest);
+
+template<class T> inline
+void MarshallManagedStructIntoNative(ScriptingObjectPtr so, T* dest)
+{
+ MarshallManagedStructIntoNative(so, dest);
+}
+
+void MarshallNativeStructIntoManaged(const AnimationEvent* src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const AssetBundleRequestMono& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoNavMeshPath& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const void* src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const ControllerColliderHit& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const AsyncOperation* src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoContactPoint& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoTreePrototype& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoWebCamDevice& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoCollision& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const LightmapDataMono& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoDetailPrototype& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const MonoSplatPrototype& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const ScriptingCollision2D& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const ScriptingContactPoint2D& src, ScriptingObjectPtr& dest);
+void MarshallNativeStructIntoManaged(const ScriptingCharacterInfo& src, ScriptingObjectPtr& dest);
+#endif
+
+#endif