diff options
Diffstat (limited to 'Runtime/Export')
324 files changed, 40549 insertions, 0 deletions
diff --git a/Runtime/Export/AndroidInput.txt b/Runtime/Export/AndroidInput.txt new file mode 100644 index 0000000..7667f15 --- /dev/null +++ b/Runtime/Export/AndroidInput.txt @@ -0,0 +1,85 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Input/GetInput.h" +#include "Runtime/Mono/MonoBehaviour.h" + +#if UNITY_ANDROID + #include <PlatformDependent/AndroidPlayer/AndroidInput.h> + #include <PlatformDependent/AndroidPlayer/TouchInput.h> + #include <android/input.h> +#endif + +CSRAW + +namespace UnityEngine +{ + +// AndroidInput provides support for off-screen touch input, such as a touchpad. +CONDITIONAL UNITY_ANDROID || UNITY_EDITOR +CLASS AndroidInput + + // Hide constructor + CSRAW private AndroidInput() {} + + // Returns object representing status of a specific touch on a secondary touchpad (Does not allocate temporary variables). + CUSTOM static Touch GetSecondaryTouch (int index) + { + Touch touch; +#if UNITY_ANDROID + if (index >= 0 && index < GetTouchCount ((int)AINPUT_SOURCE_TOUCHPAD)) + { + if (!GetTouch ((int)AINPUT_SOURCE_TOUCHPAD, index, touch)) + Scripting::RaiseMonoException ("Internal error."); + } + else + Scripting::RaiseMonoException ("Index out of bounds."); +#endif + return touch; + } + + // Number of secondary touches. Guaranteed not to change throughout the frame. (RO). + CUSTOM_PROP static int touchCountSecondary + { +#if UNITY_ANDROID + return GetTouchCount((int)AINPUT_SOURCE_TOUCHPAD); +#else + return 0; +#endif + } + + // Property indicating whether the system provides secondary touch input. + CUSTOM_PROP static bool secondaryTouchEnabled + { +#if UNITY_ANDROID + return IsInputDeviceEnabled((int)AINPUT_SOURCE_TOUCHPAD); +#else + return false; +#endif + } + + // Property indicating the width of the secondary touchpad. + CUSTOM_PROP static int secondaryTouchWidth + { +#if UNITY_ANDROID + return GetTouchpadWidth(); +#else + return 0; +#endif + } + + // Property indicating the height of the secondary touchpad. + CUSTOM_PROP static int secondaryTouchHeight + { +#if UNITY_ANDROID + return GetTouchpadHeight(); +#else + return 0; +#endif + } + +END + +CSRAW +} diff --git a/Runtime/Export/AndroidJNI.txt b/Runtime/Export/AndroidJNI.txt new file mode 100644 index 0000000..fc7bd82 --- /dev/null +++ b/Runtime/Export/AndroidJNI.txt @@ -0,0 +1,918 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Mono/MonoScopedThreadAttach.h" + +#if UNITY_ANDROID + +#if UNITY_DEVELOPER_BUILD + static volatile bool DEBUGJNI = false; +#else + #define DEBUGJNI 0 +#endif + +#define DEBUGJNI_VERBOSE 0 + +#include "PlatformDependent/AndroidPlayer/EntryPoint.h" + + static MonoDomain* s_MonoDomain = 0; + jobject UnityJavaProxy_invoke(JNIEnv*, jobject thiz, jint delegate, jstring method, jobjectArray args) + { + ScopedThreadAttach mono(s_MonoDomain); + MonoObject* proxy = mono_gchandle_get_target(delegate); + void* params[] = {proxy, &method, &args}; + MonoObject* mresult = CallStaticMonoMethod("_AndroidJNIHelper", "InvokeJavaProxyMethod", params); + if (!mresult) + return 0; + return ExtractMonoObjectData<jobject>(mresult); + } + void UnityJavaProxy_finalize(JNIEnv*, jobject thiz, jint jdelegate) + { + ScopedThreadAttach mono(s_MonoDomain); + mono_gchandle_free(jdelegate); + } + +#if DEBUGJNI + #define SCOPED_JNI(x) DalvikAttachThreadScoped jni_env(x) +#else + #define SCOPED_JNI(x) DalvikAttachThreadScoped jni_env("AndroidJNI") +#endif + +#define JNI_GET_ID( GetIDFunc ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + string methodName = name; \ + string signature = sig; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %s, %s)", __FUNCTION__, clazz, methodName.c_str(), signature.c_str()); \ + if (clazz == 0) \ + return 0; \ + return jni_env->GetIDFunc((jclass)clazz, methodName.c_str(), signature.c_str()); \ + } while(0) + +#define ConvertToJNIArgs() \ + int numargs = mono_array_length(args); \ + jvalue* jni_args = (jvalue*)alloca(sizeof(jvalue) * numargs); \ + for (int i = 0; i < numargs; ++i) \ + { \ + jni_args[i] = GetMonoArrayElement<jvalue>(args, i); \ + if (DEBUGJNI) \ + printf_console(">\t\t\t, %08x", jni_args[i].i); \ + } \ + if (DEBUGJNI && numargs) \ + printf_console(">\t\t\t)"); + +#define JNI_CALL_METHOD( MethodFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %08x%s", __FUNCTION__, ClassOrObj, \ + (jmethodID)methodID, mono_array_length(args) ? " " : ")"); \ + if (ClassOrObj == 0 || (jmethodID)methodID == 0) \ + return 0; \ + ConvertToJNIArgs(); \ + return jni_env->MethodFunc(ClassOrObj, (jmethodID)methodID, jni_args); \ + } while(0) + +#define JNI_CALL_VOID_METHOD( MethodFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %08x%s", __FUNCTION__, ClassOrObj, \ + (jmethodID)methodID, mono_array_length(args) ? " " : ")"); \ + if (ClassOrObj == 0 || (jmethodID)methodID == 0) \ + return; \ + ConvertToJNIArgs(); \ + jni_env->MethodFunc(ClassOrObj, (jmethodID)methodID, jni_args); \ + } while(0) + +#define JNI_GET_FIELD( FieldFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x)", __FUNCTION__, ClassOrObj); \ + if (ClassOrObj == 0 || (jmethodID)fieldID == 0) \ + return 0; \ + return jni_env->FieldFunc(ClassOrObj, (jfieldID)fieldID); \ + } while(0) + +#define JNI_SET_FIELD( FieldFunc, ClassOrObj, Value ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x)", __FUNCTION__, ClassOrObj); \ + if (ClassOrObj == 0 || (jmethodID)fieldID == 0) \ + return; \ + jni_env->FieldFunc(ClassOrObj, (jfieldID)fieldID, Value); \ + } while(0) + +#define JNI_PASS_VOID_VOID( Func ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + jni_env->Func(); \ + } while(0) + +#define JNI_PASS_RETV_VOID( Func ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + return jni_env->Func(); \ + } while(0) + +#define JNI_PASS_VOID_ARGS( Func, ...) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + jni_env->Func(__VA_ARGS__); \ + } while(0) + +#define JNI_PASS_RETV_ARGS( Func, ...) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + if (DEBUGJNI) \ + printf_console("> %s()", __FUNCTION__); \ + return jni_env->Func(__VA_ARGS__); \ + } while(0) + +#define JNI_GET_JSTR_FIELD( FieldFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x)", __FUNCTION__, ClassOrObj); \ + if (ClassOrObj == 0 || (jmethodID)fieldID == 0) \ + return SCRIPTING_NULL; \ + jstring str = (jstring)jni_env->FieldFunc(ClassOrObj, (jfieldID)fieldID); \ + if (str == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + const char* cstring = jni_env->GetStringUTFChars(str, 0); \ + if (cstring == 0 || jni_env->ExceptionCheck()) \ + { \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return SCRIPTING_NULL; \ + } \ + MonoString* mstring = scripting_string_new(cstring); \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return mstring; \ + } while(0) + +#define JNI_CALL_JSTR_METHOD( MethodFunc, ClassOrObj ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + if (DEBUGJNI) \ + printf_console("> %s(%08x, %08x%s", __FUNCTION__, ClassOrObj, \ + (jmethodID)methodID, mono_array_length(args) ? " " : ")"); \ + if (ClassOrObj == 0 || (jmethodID)methodID == 0) \ + return SCRIPTING_NULL; \ + ConvertToJNIArgs(); \ + jstring str = (jstring)jni_env->MethodFunc(ClassOrObj, (jmethodID)methodID, jni_args); \ + if (str == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + const char* cstring = jni_env->GetStringUTFChars(str, 0); \ + if (cstring == 0 || jni_env->ExceptionCheck()) \ + { \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return SCRIPTING_NULL; \ + } \ + MonoString* mstring = scripting_string_new(cstring); \ + jni_env->ReleaseStringUTFChars(str, cstring); \ + jni_env->DeleteLocalRef(str); \ + return mstring; \ + } while(0) + +#define JNI_NEW_ARRAY( NewArrayType, Type, ArrayType ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + int size = mono_array_length(array); \ + ArrayType jni_array = jni_env->New ## NewArrayType ## Array(size); \ + if (jni_array == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + for (int i = 0; i < size; ++i) \ + { \ + Type val = GetMonoArrayElement<Type>(array, i); \ + jni_env->Set ## NewArrayType ## ArrayRegion(jni_array, i, 1, &val); \ + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + } \ + return jni_array; \ + } while(0) + +#define JNI_GET_ARRAY( GetArrayType, Type, ArrayType, ArrayClass ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return SCRIPTING_NULL; \ + jsize length = jni_env->GetArrayLength((jarray)array); \ + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + MonoArray* csarray = mono_array_new(mono_domain_get(), ArrayClass, length); \ + Type* mem = jni_env->Get ## GetArrayType ## ArrayElements((ArrayType)array, 0); \ + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; \ + for (int i = 0; i < length; ++i) \ + Scripting::SetScriptingArrayElement<Type>(csarray, i, mem[i]); \ + jni_env->Release ## GetArrayType ## ArrayElements((ArrayType)array, mem, JNI_ABORT); \ + return csarray; \ + } while(0) + +#define JNI_GET_ARRAY_ELEMENT( GetArrayType, Type, ArrayType ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return 0; \ + Type val; \ + jni_env->Get ## GetArrayType ## ArrayRegion((ArrayType)array, index, 1, &val); \ + return val; \ + } while(0) + +#define JNI_SET_ARRAY_ELEMENT( SetArrayType, Type, ArrayType ) \ + do { \ + SCOPED_JNI(__FUNCTION__); \ + if (!jni_env) return; \ + jni_env->Get ## SetArrayType ## ArrayRegion((ArrayType)array, index, 1, &val); \ + } while(0) + +struct jStringWrapper +{ + std::string cString; + jstring javaString; + jStringWrapper(ICallString& cs) + : javaString(0) + { + cString = cs; + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + } + + ~jStringWrapper() + { + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + if (!javaString) + return; + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return; + jni_env->DeleteLocalRef(javaString); + } + + operator jstring() + { + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + javaString = jni_env->NewStringUTF(cString.c_str()); + return javaString; + } + operator const char*() + { + if (DEBUGJNI_VERBOSE) + printf_console("> [%s](\"%s\")", __FUNCTION__, cString.c_str()); + return cString.c_str(); + } +}; + +#else // UNITY_ANDROID + +typedef void* jobject; +typedef void* jclass; + +#define JNI_GET_ID( GetIDFunc ) do { return 0; } while(0) +#define JNI_CALL_METHOD( MethodFunc, ClassOrObj ) do { (void)ClassOrObj; return 0; } while(0) +#define JNI_CALL_VOID_METHOD( MethodFunc, ClassOrObj ) do { (void)ClassOrObj; } while(0) +#define JNI_GET_FIELD( FieldFunc, ClassOrObj ) do { (void)ClassOrObj; return 0; } while(0) +#define JNI_GET_JSTR_FIELD( FieldFunc, ClassOrObj ) do { (void)ClassOrObj; return SCRIPTING_NULL; } while(0) +#define JNI_SET_FIELD( FieldFunc, ClassOrObj, Value ) do { (void)ClassOrObj; (void)Value; } while(0) +#define JNI_PASS_VOID_VOID( Func ) do { ; } while(0) +#define JNI_PASS_RETV_VOID( Func) do { return 0; } while(0) +#define JNI_PASS_VOID_ARGS( Func, ...) do { ; } while(0) +#define JNI_PASS_RETV_ARGS( Func, ...) do { return 0; } while(0) +#define JNI_CALL_JSTR_METHOD( MethodFunc, ClassOrObj ) do { (void)ClassOrObj; return SCRIPTING_NULL; } while(0) +#define JNI_NEW_ARRAY( NewArrayFunc, Type, ArrayType ) do { return SCRIPTING_NULL; } while(0) +#define JNI_GET_ARRAY( GetArrayType, Type, ArrayType, ArrayClass ) do { return SCRIPTING_NULL; } while(0) +#define JNI_GET_ARRAY_ELEMENT( GetArrayType, Type, ArrayType ) do { return 0; } while(0) +#define JNI_SET_ARRAY_ELEMENT( SetArrayType, Type, ArrayType ) do { ; } while(0) + +#endif + +CSRAW +#if UNITY_EDITOR || UNITY_ANDROID +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UnityEngine +{ + [StructLayout(LayoutKind.Explicit)] + public struct jvalue + { + [FieldOffset(0)] public bool z; + [FieldOffset(0)] public byte b; + [FieldOffset(0)] public char c; + [FieldOffset(0)] public short s; + [FieldOffset(0)] public int i; + [FieldOffset(0)] public long j; + [FieldOffset(0)] public float f; + [FieldOffset(0)] public double d; + [FieldOffset(0)] public System.IntPtr l; + } + +// Helper interface for JNI interaction; signature creation and method lookups +CONDITIONAL !UNITY_WINRT +CLASS AndroidJNIHelper + + CSRAW private AndroidJNIHelper() {} + + // Set /debug/ to true to log calls through the AndroidJNIHelper + CUSTOM_PROP static bool debug + { + #if UNITY_ANDROID && UNITY_DEVELOPER_BUILD + return DEBUGJNI; + #else + return false; + #endif + } + { + #if UNITY_ANDROID && UNITY_DEVELOPER_BUILD + DEBUGJNI = value; + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return; + jclass cls_up = jni_env->FindClass("com/unity3d/player/ReflectionHelper"); + if (!cls_up || jni_env->ExceptionCheck()) + return; + jfieldID fid_get = jni_env->GetStaticFieldID(cls_up, "LOG", "Z"); + if (!fid_get || jni_env->ExceptionCheck()) + { + jni_env->DeleteLocalRef(cls_up); + return; + } + jni_env->SetStaticBooleanField(cls_up, fid_get, value); + jni_env->DeleteLocalRef(cls_up); + #endif + } + + // Scans a particular Java class for a constructor method matching a signature. + CSRAW public static IntPtr GetConstructorID(IntPtr javaClass, string signature = "") + { + return _AndroidJNIHelper.GetConstructorID(javaClass, signature); + } + + // Scans a particular Java class for a method matching a name and a signature. + CSRAW public static IntPtr GetMethodID(IntPtr javaClass, string methodName, string signature = "", bool isStatic = false) + { + return _AndroidJNIHelper.GetMethodID(javaClass, methodName, signature, isStatic); + } + + CSRAW public static IntPtr GetFieldID(IntPtr javaClass, string fieldName, string signature = "", bool isStatic = false) + { + return _AndroidJNIHelper.GetFieldID(javaClass, fieldName, signature, isStatic); + } + + // Creates a UnityJavaRunnable object (implements java.lang.Runnable). + CSRAW public static IntPtr CreateJavaRunnable(AndroidJavaRunnable jrunnable) + { + return _AndroidJNIHelper.CreateJavaRunnable(jrunnable); + } + + // Creates a UnityJavaProxy object (implements jinterface). + THREAD_SAFE CUSTOM static IntPtr CreateJavaProxy(AndroidJavaProxy proxy) + { + #if UNITY_ANDROID + s_MonoDomain = mono_domain_get(); + + int gcHandle = mono_gchandle_new(proxy, 0); + void* params[] = { &gcHandle, proxy }; + MonoException* exception; + MonoObject* result = CallStaticMonoMethod("_AndroidJNIHelper", "CreateJavaProxy", params, &exception); + if (exception) + { + mono_gchandle_free(gcHandle); + mono_raise_exception(exception); + return 0; + } + return ExtractMonoObjectData<jobject>(result); + #else + return 0; + #endif + } + + // Creates a Java array from a managed array + CSRAW public static IntPtr ConvertToJNIArray(System.Array array) + { + return _AndroidJNIHelper.ConvertToJNIArray(array); + } + + // Creates the parameter array to be used as argument list when invoking Java code through CallMethod() in AndroidJNI. + CSRAW public static jvalue[] CreateJNIArgArray(object[] args) + { + return _AndroidJNIHelper.CreateJNIArgArray(args); + } + + // Deletes any local jni references previously allocated by CreateJNIArgArray() + // + // @param jniArgs the array returned by CreateJNIArgArray() + // @param args the array of arguments used as a parameter to CreateJNIArgArray() + // + CSRAW public static void DeleteJNIArgArray(object[] args, jvalue[] jniArgs) + { + _AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + + // Get a JNI method ID for a constructor based on calling arguments. + // Scans a particular Java class for a constructor method matching a signature based on passed arguments. + // The signature comparison is done to allow for sub-/base-classes of the class types. + // + // @param javaClass Raw JNI Java class object (obtained by calling AndroidJNI.FindClass). + // @param args Array with parameters to be passed to the constructor when invoked. + // + CSRAW public static System.IntPtr GetConstructorID(System.IntPtr jclass, object[] args) + { + return _AndroidJNIHelper.GetConstructorID(jclass, args); + } + // Get a JNI method ID based on calling arguments. + CSRAW public static System.IntPtr GetMethodID(System.IntPtr jclass, string methodName, object[] args, bool isStatic) + { + return _AndroidJNIHelper.GetMethodID(jclass, methodName, args, isStatic); + } + + // Creates the JNI signature string for particular object type + CSRAW public static string GetSignature(object obj) + { + return _AndroidJNIHelper.GetSignature(obj); + } + + // Creates the JNI signature string for an object parameter list. + CSRAW public static string GetSignature(object[] args) + { + return _AndroidJNIHelper.GetSignature(args); + } + + //=================================================================== + + // Creates a managed array from a Java array + CSRAW public static ArrayType ConvertFromJNIArray<ArrayType>(IntPtr array) + { + return _AndroidJNIHelper.ConvertFromJNIArray<ArrayType>(array); + } + + // Get a JNI method ID based on calling arguments. + CSRAW public static System.IntPtr GetMethodID<ReturnType>(System.IntPtr jclass, string methodName, object[] args, bool isStatic) + { + return _AndroidJNIHelper.GetMethodID<ReturnType>(jclass, methodName, args, isStatic); + } + + // Get a JNI field ID based on type detection. Generic parameter represents the field type. + CSRAW public static System.IntPtr GetFieldID<FieldType>(System.IntPtr jclass, string fieldName, bool isStatic) + { + return _AndroidJNIHelper.GetFieldID<FieldType>(jclass, fieldName, isStatic); + } + + // Creates the JNI signature string for an object parameter list. + CSRAW public static string GetSignature<ReturnType>(object[] args) + { + return _AndroidJNIHelper.GetSignature<ReturnType>(args); + } +END + +// 'Raw' JNI interface to Android Dalvik (Java) VM from Mono (CS/JS) +CONDITIONAL !UNITY_WINRT +CLASS AndroidJNI + + CSRAW private AndroidJNI() {} + + // Attaches the current thread to a Java (Dalvik) VM. + THREAD_SAFE CUSTOM static int AttachCurrentThread() + { + #if UNITY_ANDROID + JavaVM* vm = GetJavaVm(); + Assert(vm); + JNIEnv* env; + return vm->AttachCurrentThread(&env, 0); + #else + return 0; + #endif + } + // Detaches the current thread from a Java (Dalvik) VM. + THREAD_SAFE CUSTOM static int DetachCurrentThread() + { + #if UNITY_ANDROID + JavaVM* vm = GetJavaVm(); + Assert(vm); + return vm->DetachCurrentThread(); + #else + return 0; + #endif + } + + // Returns the version of the native method interface. + THREAD_SAFE CUSTOM static int GetVersion() { JNI_PASS_RETV_VOID( GetVersion ); } + + // This function loads a locally-defined class. + THREAD_SAFE CUSTOM static IntPtr FindClass(string name) { JNI_PASS_RETV_ARGS( FindClass, jStringWrapper(name) ); } + + // Converts a <tt>java.lang.reflect.Method</tt> or <tt>java.lang.reflect.Constructor</tt> object to a method ID. + THREAD_SAFE CUSTOM static IntPtr FromReflectedMethod(IntPtr refMethod) { JNI_PASS_RETV_ARGS( FromReflectedMethod, (jobject)refMethod ); } + // Converts a <tt>java.lang.reflect.Field</tt> to a field ID. + THREAD_SAFE CUSTOM static IntPtr FromReflectedField(IntPtr refField) { JNI_PASS_RETV_ARGS( FromReflectedField, (jobject)refField ); } + // Converts a method ID derived from clazz to a <tt>java.lang.reflect.Method</tt> or <tt>java.lang.reflect.Constructor</tt> object. + THREAD_SAFE CUSTOM static IntPtr ToReflectedMethod(IntPtr clazz, IntPtr methodID, bool isStatic) { JNI_PASS_RETV_ARGS( ToReflectedMethod, (jclass)clazz, (jmethodID)methodID, isStatic ); } + // Converts a field ID derived from cls to a <tt>java.lang.reflect.Field</tt> object. + THREAD_SAFE CUSTOM static IntPtr ToReflectedField(IntPtr clazz, IntPtr fieldID, bool isStatic) { JNI_PASS_RETV_ARGS( ToReflectedField, (jclass)clazz, (jfieldID)fieldID, isStatic ); } + + // If <tt>clazz</tt> represents any class other than the class <tt>Object</tt>, then this function returns the object that represents the superclass of the class specified by <tt>clazz</tt>. + THREAD_SAFE CUSTOM static IntPtr GetSuperclass(IntPtr clazz) { JNI_PASS_RETV_ARGS( GetSuperclass, (jclass)clazz ); } + // Determines whether an object of <tt>clazz1</tt> can be safely cast to <tt>clazz2</tt>. + THREAD_SAFE CUSTOM static bool IsAssignableFrom(IntPtr clazz1, IntPtr clazz2) { JNI_PASS_RETV_ARGS( IsAssignableFrom, (jclass)clazz1, (jclass)clazz2 ); } + + // Causes a <tt>java.lang.Throwable</tt> object to be thrown. + THREAD_SAFE CUSTOM static int Throw(IntPtr obj) { JNI_PASS_RETV_ARGS( Throw, (jthrowable)obj ); } + // Constructs an exception object from the specified class with the <tt>message</tt> specified by message and causes that exception to be thrown. + THREAD_SAFE CUSTOM static int ThrowNew(IntPtr clazz, string message) { JNI_PASS_RETV_ARGS( ThrowNew, (jclass)clazz, jStringWrapper(message) ); } + // Determines if an exception is being thrown + THREAD_SAFE CUSTOM static IntPtr ExceptionOccurred() { JNI_PASS_RETV_VOID( ExceptionOccurred ); } + // Prints an exception and a backtrace of the stack to the <tt>logcat</tt> + THREAD_SAFE CUSTOM static void ExceptionDescribe() { JNI_PASS_VOID_VOID( ExceptionDescribe ); } + // Clears any exception that is currently being thrown. + THREAD_SAFE CUSTOM static void ExceptionClear() { JNI_PASS_VOID_VOID( ExceptionClear ); } + // Raises a fatal error and does not expect the VM to recover. This function does not return. + THREAD_SAFE CUSTOM static void FatalError(string message) { JNI_PASS_VOID_ARGS( FatalError, jStringWrapper(message) ); } + + // Creates a new local reference frame, in which at least a given number of local references can be created. + THREAD_SAFE CUSTOM static int PushLocalFrame(int capacity) { JNI_PASS_RETV_ARGS( PushLocalFrame, capacity ); } + // Pops off the current local reference frame, frees all the local references, and returns a local reference in the previous local reference frame for the given <tt>result</tt> object. + THREAD_SAFE CUSTOM static IntPtr PopLocalFrame(IntPtr result) { JNI_PASS_RETV_ARGS( PopLocalFrame, (jobject)result ); } + + // Creates a new global reference to the object referred to by the <tt>obj</tt> argument. + THREAD_SAFE CUSTOM static IntPtr NewGlobalRef(IntPtr obj) { JNI_PASS_RETV_ARGS( NewGlobalRef, (jobject)obj ); } + // Deletes the global reference pointed to by <tt>obj</tt>. + THREAD_SAFE CUSTOM static void DeleteGlobalRef(IntPtr obj) { JNI_PASS_VOID_ARGS( DeleteGlobalRef, (jobject)obj ); } + // Creates a new local reference that refers to the same object as <tt>obj</tt>. + THREAD_SAFE CUSTOM static IntPtr NewLocalRef(IntPtr obj) { JNI_PASS_RETV_ARGS( NewLocalRef, (jobject)obj ); } + // Deletes the local reference pointed to by <tt>obj</tt>. + THREAD_SAFE CUSTOM static void DeleteLocalRef(IntPtr obj) { JNI_PASS_VOID_ARGS( DeleteLocalRef, (jobject)obj ); } + // Tests whether two references refer to the same Java object. + THREAD_SAFE CUSTOM static bool IsSameObject(IntPtr obj1, IntPtr obj2) { JNI_PASS_RETV_ARGS( IsSameObject, (jobject)obj1, (jobject)obj2 ); } + + // Ensures that at least a given number of local references can be created in the current thread. + THREAD_SAFE CUSTOM static int EnsureLocalCapacity(int capacity) { JNI_PASS_RETV_ARGS( EnsureLocalCapacity, capacity ); } + + + //------------------------------------------- + + // Allocates a new Java object without invoking any of the constructors for the object. + THREAD_SAFE CUSTOM static IntPtr AllocObject(IntPtr clazz) { JNI_PASS_RETV_ARGS( AllocObject, (jclass)clazz ); } + // Constructs a new Java object. The method ID indicates which constructor method to invoke. This ID must be obtained by calling GetMethodID() with <init> as the method name and void (V) as the return type. + THREAD_SAFE CUSTOM static IntPtr NewObject(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( NewObjectA, (jclass)clazz ); } + + // Returns the class of an object. + THREAD_SAFE CUSTOM static IntPtr GetObjectClass(IntPtr obj) { JNI_PASS_RETV_ARGS( GetObjectClass, (jobject)obj ); } + // Tests whether an object is an instance of a class. + THREAD_SAFE CUSTOM static bool IsInstanceOf(IntPtr obj, IntPtr clazz){ JNI_PASS_RETV_ARGS( IsInstanceOf, (jobject)obj, (jclass)clazz ); } + + // Returns the method ID for an instance (nonstatic) method of a class or interface. + THREAD_SAFE CUSTOM static IntPtr GetMethodID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetMethodID); } + // Returns the field ID for an instance (nonstatic) field of a class. + THREAD_SAFE CUSTOM static IntPtr GetFieldID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetFieldID); } + // Returns the method ID for a static method of a class. + THREAD_SAFE CUSTOM static IntPtr GetStaticMethodID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetStaticMethodID); } + // Returns the field ID for a static field of a class. + THREAD_SAFE CUSTOM static IntPtr GetStaticFieldID(IntPtr clazz, string name, string sig) { JNI_GET_ID(GetStaticFieldID); } + + // Constructs a new <tt>java.lang.String</tt> object from an array of characters in modified UTF-8 encoding. + THREAD_SAFE CUSTOM static IntPtr NewStringUTF(string bytes) { JNI_PASS_RETV_ARGS( NewStringUTF, jStringWrapper(bytes) ); } + // Returns the length in bytes of the modified UTF-8 representation of a string. + THREAD_SAFE CUSTOM static int GetStringUTFLength(IntPtr str) { JNI_PASS_RETV_ARGS( GetStringUTFLength, (jstring) str); } + // Returns a managed string object representing the string in modified UTF-8 encoding. + THREAD_SAFE CUSTOM static string GetStringUTFChars(IntPtr str) + { + #if UNITY_ANDROID + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + if (DEBUGJNI) + printf_console("> %s()", __FUNCTION__); + const char* cstring = jni_env->GetStringUTFChars((jstring)str, 0); + if (cstring == 0 || jni_env->ExceptionCheck()) + { + jni_env->ReleaseStringUTFChars((jstring)str, cstring); + return 0; + } + MonoString* mstring = scripting_string_new(cstring); + jni_env->ReleaseStringUTFChars((jstring)str, cstring); + return mstring; + #else + return SCRIPTING_NULL; + #endif + } + + //--------------------------------------------- + + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static string CallStringMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_JSTR_METHOD(CallObjectMethodA, (jobject)obj); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static IntPtr CallObjectMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallObjectMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int32 CallIntMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallIntMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static bool CallBooleanMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallBooleanMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int16 CallShortMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallShortMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Byte CallByteMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallByteMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Char CallCharMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallCharMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static float CallFloatMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallFloatMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static double CallDoubleMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallDoubleMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int64 CallLongMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallLongMethodA, (jobject)obj ); } + // Calls an instance (nonstatic) Java method defined by <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static void CallVoidMethod(IntPtr obj, IntPtr methodID, jvalue[] args) { JNI_CALL_VOID_METHOD( CallVoidMethodA, (jobject)obj ); } + + //--------------------------------------------- + + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static string GetStringField(IntPtr obj, IntPtr fieldID) { JNI_GET_JSTR_FIELD( GetObjectField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static IntPtr GetObjectField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetObjectField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static bool GetBooleanField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetBooleanField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Byte GetByteField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetByteField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Char GetCharField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetCharField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Int16 GetShortField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetShortField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Int32 GetIntField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetIntField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static Int64 GetLongField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetLongField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static float GetFloatField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetFloatField, (jobject)obj ); } + // This function returns the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static double GetDoubleField(IntPtr obj, IntPtr fieldID) { JNI_GET_FIELD( GetDoubleField, (jobject)obj ); } + + //--------------------------------------------- + + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetStringField(IntPtr obj, IntPtr fieldID, string val) { JNI_PASS_VOID_ARGS( SetObjectField, (jobject)obj, (jfieldID)fieldID, jStringWrapper(val) ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetObjectField(IntPtr obj, IntPtr fieldID, IntPtr val) { JNI_SET_FIELD( SetObjectField, (jobject)obj, (jobject)val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetBooleanField(IntPtr obj, IntPtr fieldID, bool val) { JNI_SET_FIELD( SetBooleanField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetByteField(IntPtr obj, IntPtr fieldID, Byte val) { JNI_SET_FIELD( SetByteField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetCharField(IntPtr obj, IntPtr fieldID, Char val) { JNI_SET_FIELD( SetCharField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetShortField(IntPtr obj, IntPtr fieldID, Int16 val) { JNI_SET_FIELD( SetShortField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetIntField(IntPtr obj, IntPtr fieldID, Int32 val) { JNI_SET_FIELD( SetIntField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetLongField(IntPtr obj, IntPtr fieldID, Int64 val) { JNI_SET_FIELD( SetLongField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetFloatField(IntPtr obj, IntPtr fieldID, float val) { JNI_SET_FIELD( SetFloatField, (jobject)obj, val ); } + // This function sets the value of an instance (nonstatic) field of an object. + THREAD_SAFE CUSTOM static void SetDoubleField(IntPtr obj, IntPtr fieldID, double val) { JNI_SET_FIELD( SetDoubleField, (jobject)obj, val ); } + + + //--------------------------------------------- + + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static string CallStaticStringMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_JSTR_METHOD(CallStaticObjectMethodA, (jclass)clazz); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static IntPtr CallStaticObjectMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticObjectMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int32 CallStaticIntMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticIntMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static bool CallStaticBooleanMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticBooleanMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int16 CallStaticShortMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticShortMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Byte CallStaticByteMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticByteMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Char CallStaticCharMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticCharMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static float CallStaticFloatMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticFloatMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static double CallStaticDoubleMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticDoubleMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static Int64 CallStaticLongMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_METHOD( CallStaticLongMethodA, (jclass)clazz ); } + // Invokes a static method on a Java object, according to the specified <tt>methodID</tt>, optionally passing an array of arguments (<tt>args</tt>) to the method. + THREAD_SAFE CUSTOM static void CallStaticVoidMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) { JNI_CALL_VOID_METHOD( CallStaticVoidMethodA, (jclass)clazz ); } + + //--------------------------------------------- + + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static string GetStaticStringField(IntPtr clazz, IntPtr fieldID) { JNI_GET_JSTR_FIELD( GetStaticObjectField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static IntPtr GetStaticObjectField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticObjectField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static bool GetStaticBooleanField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticBooleanField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Byte GetStaticByteField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticByteField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Char GetStaticCharField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticCharField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Int16 GetStaticShortField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticShortField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Int32 GetStaticIntField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticIntField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static Int64 GetStaticLongField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticLongField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static float GetStaticFloatField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticFloatField, (jclass)clazz ); } + // This function returns the value of a static field of an object. + THREAD_SAFE CUSTOM static double GetStaticDoubleField(IntPtr clazz, IntPtr fieldID) { JNI_GET_FIELD( GetStaticDoubleField, (jclass)clazz ); } + + //--------------------------------------------- + + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticStringField(IntPtr clazz, IntPtr fieldID, string val) { JNI_PASS_VOID_ARGS( SetStaticObjectField, (jclass)clazz, (jfieldID)fieldID, jStringWrapper(val) ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticObjectField(IntPtr clazz, IntPtr fieldID, IntPtr val) { JNI_SET_FIELD( SetStaticObjectField, (jclass)clazz, (jclass)val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticBooleanField(IntPtr clazz, IntPtr fieldID, bool val) { JNI_SET_FIELD( SetStaticBooleanField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticByteField(IntPtr clazz, IntPtr fieldID, Byte val) { JNI_SET_FIELD( SetStaticByteField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticCharField(IntPtr clazz, IntPtr fieldID, Char val) { JNI_SET_FIELD( SetStaticCharField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticShortField(IntPtr clazz, IntPtr fieldID, Int16 val) { JNI_SET_FIELD( SetStaticShortField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticIntField(IntPtr clazz, IntPtr fieldID, Int32 val) { JNI_SET_FIELD( SetStaticIntField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticLongField(IntPtr clazz, IntPtr fieldID, Int64 val) { JNI_SET_FIELD( SetStaticLongField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticFloatField(IntPtr clazz, IntPtr fieldID, float val) { JNI_SET_FIELD( SetStaticFloatField, (jclass)clazz, val ); } + // This function ets the value of a static field of an object. + THREAD_SAFE CUSTOM static void SetStaticDoubleField(IntPtr clazz, IntPtr fieldID, double val) { JNI_SET_FIELD( SetStaticDoubleField, (jclass)clazz, val ); } + + +//--------------------------------------- + + // Convert a managed array of System.Boolean to a Java array of <tt>boolean</tt>. + THREAD_SAFE CUSTOM static IntPtr ToBooleanArray(Boolean[] array) { JNI_NEW_ARRAY( Boolean, jboolean, jbooleanArray );} + // Convert a managed array of System.Byte to a Java array of <tt>byte</tt>. + THREAD_SAFE CUSTOM static IntPtr ToByteArray(Byte[] array) { JNI_NEW_ARRAY( Byte, jbyte, jbyteArray ); } + // Convert a managed array of System.Char to a Java array of <tt>char</tt>. + THREAD_SAFE CUSTOM static IntPtr ToCharArray(Char[] array) { JNI_NEW_ARRAY( Char, jchar, jcharArray ); } + // Convert a managed array of System.Int16 to a Java array of <tt>short</tt>. + THREAD_SAFE CUSTOM static IntPtr ToShortArray(Int16[] array) { JNI_NEW_ARRAY( Short, jshort, jshortArray ); } + // Convert a managed array of System.Int32 to a Java array of <tt>int</tt>. + THREAD_SAFE CUSTOM static IntPtr ToIntArray(Int32[] array) { JNI_NEW_ARRAY( Int, jint, jintArray ); } + // Convert a managed array of System.Int64 to a Java array of <tt>long</tt>. + THREAD_SAFE CUSTOM static IntPtr ToLongArray(Int64[] array) { JNI_NEW_ARRAY( Long, jlong, jlongArray ); } + // Convert a managed array of System.Single to a Java array of <tt>float</tt>. + THREAD_SAFE CUSTOM static IntPtr ToFloatArray(float[] array) { JNI_NEW_ARRAY( Float, jfloat, jfloatArray ); } + // Convert a managed array of System.Double to a Java array of <tt>double</tt>. + THREAD_SAFE CUSTOM static IntPtr ToDoubleArray(double[] array) { JNI_NEW_ARRAY( Double, jdouble, jdoubleArray ); } + // Convert a managed array of System.IntPtr, representing Java objects, to a Java array of <tt>java.lang.Object</tt>. + THREAD_SAFE CUSTOM static IntPtr ToObjectArray(IntPtr[] array) + { + #if UNITY_ANDROID + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + int size = mono_array_length(array); + jclass obj_class = jni_env->FindClass("java/lang/Object"); + if (obj_class == 0 || jni_env->ExceptionCheck()) return SCRIPTING_NULL; + jobjectArray jni_array = jni_env->NewObjectArray(size, obj_class, 0); + if (jni_array == 0 || jni_env->ExceptionCheck()) + { + jni_env->DeleteLocalRef(obj_class); + return SCRIPTING_NULL; + } + for (int i = 0; i < size; ++i) + { + void* val = GetMonoArrayElement<void*>(array, i); + jni_env->SetObjectArrayElement(jni_array, i, (jobject)val); + jni_env->DeleteLocalRef((jobject) val); + if (jni_env->ExceptionCheck()) + { + jni_env->DeleteLocalRef(jni_array); + jni_env->DeleteLocalRef(obj_class); + return SCRIPTING_NULL; + } + } + jni_env->DeleteLocalRef(obj_class); + return jni_array; + #else + return 0; + #endif + } + + // Convert a Java array of <tt>boolean</tt> to a managed array of System.Boolean. + THREAD_SAFE CUSTOM static Boolean[] FromBooleanArray(IntPtr array) { JNI_GET_ARRAY( Boolean, jboolean, jbooleanArray, mono_get_boolean_class() ); } + // Convert a Java array of <tt>byte</tt> to a managed array of System.Byte. + THREAD_SAFE CUSTOM static Byte[] FromByteArray(IntPtr array) { JNI_GET_ARRAY( Byte, jbyte, jbyteArray, mono_get_byte_class() ); } + // Convert a Java array of <tt>char</tt> to a managed array of System.Char. + THREAD_SAFE CUSTOM static Char[] FromCharArray(IntPtr array) { JNI_GET_ARRAY( Char, jchar, jcharArray, mono_get_char_class() ); } + // Convert a Java array of <tt>short</tt> to a managed array of System.Int16. + THREAD_SAFE CUSTOM static Int16[] FromShortArray(IntPtr array) { JNI_GET_ARRAY( Short, jshort, jshortArray, mono_get_int16_class() ); } + // Convert a Java array of <tt>int</tt> to a managed array of System.Int32. + THREAD_SAFE CUSTOM static Int32[] FromIntArray(IntPtr array) { JNI_GET_ARRAY( Int, jint, jintArray, mono_get_int32_class() ); } + // Convert a Java array of <tt>long</tt> to a managed array of System.Int64. + THREAD_SAFE CUSTOM static Int64[] FromLongArray(IntPtr array) { JNI_GET_ARRAY( Long, jlong, jlongArray, mono_get_int64_class() ); } + // Convert a Java array of <tt>float</tt> to a managed array of System.Single. + THREAD_SAFE CUSTOM static float[] FromFloatArray(IntPtr array) { JNI_GET_ARRAY( Float, jfloat, jfloatArray, mono_get_single_class() ); } + // Convert a Java array of <tt>double</tt> to a managed array of System.Double. + THREAD_SAFE CUSTOM static double[] FromDoubleArray(IntPtr array) { JNI_GET_ARRAY( Double, jdouble, jdoubleArray, mono_get_double_class() ); } + // Convert a Java array of <tt>java.lang.Object</tt> to a managed array of System.IntPtr, representing Java objects. + THREAD_SAFE CUSTOM static IntPtr[] FromObjectArray(IntPtr array) + { + #if UNITY_ANDROID + SCOPED_JNI(__FUNCTION__); + if (!jni_env) return 0; + jsize length = jni_env->GetArrayLength((jarray)array); + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; + MonoClass* clazz = mono_class_from_name (mono_get_corlib (), "System", "IntPtr"); + MonoArray* csarray = mono_array_new(mono_domain_get(), clazz, length); + for (int i = 0; i < length; ++i) + { + jobject obj = jni_env->GetObjectArrayElement((jobjectArray)array, i); + if (jni_env->ExceptionCheck()) return SCRIPTING_NULL; + Scripting::SetScriptingArrayElement<jobject>(csarray, i, obj); + } + return csarray; + #else + return SCRIPTING_NULL; + #endif + } + + // Returns the number of elements in the array. + THREAD_SAFE CUSTOM static int GetArrayLength(IntPtr array) { JNI_PASS_RETV_ARGS( GetArrayLength, (jarray) array); } + + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewBooleanArray(int size) { JNI_PASS_RETV_ARGS( NewBooleanArray, (jsize)size);} + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewByteArray(int size) { JNI_PASS_RETV_ARGS( NewByteArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewCharArray(int size) { JNI_PASS_RETV_ARGS( NewCharArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewShortArray(int size) { JNI_PASS_RETV_ARGS( NewShortArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewIntArray(int size) { JNI_PASS_RETV_ARGS( NewIntArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewLongArray(int size) { JNI_PASS_RETV_ARGS( NewLongArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewFloatArray(int size) { JNI_PASS_RETV_ARGS( NewFloatArray, (jsize)size); } + // Construct a new primitive array object. + THREAD_SAFE CUSTOM static IntPtr NewDoubleArray(int size) { JNI_PASS_RETV_ARGS( NewDoubleArray, (jsize)size); } + // Constructs a new array holding objects in class <tt>clazz</tt>. All elements are initially set to <tt>obj</tt>. + THREAD_SAFE CUSTOM static IntPtr NewObjectArray(int size, IntPtr clazz, IntPtr obj) { JNI_PASS_RETV_ARGS( NewObjectArray, (jsize)size, (jclass)clazz, (jobject) obj); } + + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static bool GetBooleanArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Boolean, jboolean, jbooleanArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Byte GetByteArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Byte, jbyte, jbyteArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Char GetCharArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Char, jchar, jcharArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Int16 GetShortArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Short, jshort, jshortArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Int32 GetIntArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Int, jint, jintArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static Int64 GetLongArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Long, jlong, jlongArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static float GetFloatArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Float, jfloat, jfloatArray ); } + // Returns the value of one element of a primitive array. + THREAD_SAFE CUSTOM static double GetDoubleArrayElement(IntPtr array, int index) { JNI_GET_ARRAY_ELEMENT( Double, jdouble, jdoubleArray ); } + // Returns an element of an <tt>Object</tt> array. + THREAD_SAFE CUSTOM static IntPtr GetObjectArrayElement(IntPtr array, int index) { JNI_PASS_RETV_ARGS( GetObjectArrayElement, (jobjectArray)array, (jsize)index); } + + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetBooleanArrayElement(IntPtr array, int index, byte val) { JNI_SET_ARRAY_ELEMENT( Boolean, jboolean, jbooleanArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetByteArrayElement(IntPtr array, int index, sbyte val) { JNI_SET_ARRAY_ELEMENT( Byte, jbyte, jbyteArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetCharArrayElement(IntPtr array, int index, Char val) { JNI_SET_ARRAY_ELEMENT( Char, jchar, jcharArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetShortArrayElement(IntPtr array, int index, Int16 val) { JNI_SET_ARRAY_ELEMENT( Short, jshort, jshortArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetIntArrayElement(IntPtr array, int index, Int32 val) { JNI_SET_ARRAY_ELEMENT( Int, jint, jintArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetLongArrayElement(IntPtr array, int index, Int64 val) { JNI_SET_ARRAY_ELEMENT( Long, jlong, jlongArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetFloatArrayElement(IntPtr array, int index, float val) { JNI_SET_ARRAY_ELEMENT( Float, jfloat, jfloatArray ); } + // Sets the value of one element in a primitive array. + THREAD_SAFE CUSTOM static void SetDoubleArrayElement(IntPtr array, int index, double val) { JNI_SET_ARRAY_ELEMENT( Double, jdouble, jdoubleArray ); } + // Sets an element of an <tt>Object</tt> array. + THREAD_SAFE CUSTOM static void SetObjectArrayElement(IntPtr array, int index, IntPtr obj) { JNI_PASS_VOID_ARGS( SetObjectArrayElement, (jobjectArray)array, (jsize)index, (jobject)obj); } +END + + +CSRAW +} +#endif diff --git a/Runtime/Export/AndroidJNISafe.cs b/Runtime/Export/AndroidJNISafe.cs new file mode 100644 index 0000000..8883059 --- /dev/null +++ b/Runtime/Export/AndroidJNISafe.cs @@ -0,0 +1,514 @@ +#if UNITY_EDITOR || UNITY_ANDROID + +using System; + +namespace UnityEngine +{ +internal class AndroidJNISafe +{ + public static void CheckException() + { + IntPtr jthrowable = AndroidJNI.ExceptionOccurred(); + if (jthrowable != IntPtr.Zero) + { + AndroidJNI.ExceptionClear(); + IntPtr jthrowableClass = AndroidJNI.FindClass("java/lang/Throwable"); + try + { + IntPtr toStringMethodId = AndroidJNI.GetMethodID(jthrowableClass, "toString", "()Ljava/lang/String;"); + throw new AndroidJavaException(AndroidJNI.CallStringMethod(jthrowable, toStringMethodId, new jvalue[]{})); + } + finally + { + AndroidJNISafe.DeleteLocalRef(jthrowable); + AndroidJNISafe.DeleteLocalRef(jthrowableClass); + } + } + } + + public static void DeleteGlobalRef(IntPtr globalref) + { + if (globalref != IntPtr.Zero) AndroidJNI.DeleteGlobalRef(globalref); + } + + public static void DeleteLocalRef(IntPtr localref) + { + if (localref != IntPtr.Zero) AndroidJNI.DeleteLocalRef(localref); + } + + public static IntPtr NewStringUTF(string bytes) + { + try { return AndroidJNI.NewStringUTF(bytes); } finally { CheckException(); } + } + + public static string GetStringUTFChars(IntPtr str) + { + try { return AndroidJNI.GetStringUTFChars(str); } finally { CheckException(); } + } + + public static IntPtr GetObjectClass(IntPtr ptr) + { + try { return AndroidJNI.GetObjectClass(ptr); } finally { CheckException(); } + } + + public static IntPtr GetStaticMethodID(IntPtr clazz, string name, string sig) + { + try { return AndroidJNI.GetStaticMethodID(clazz, name, sig); } finally { CheckException(); } + } + + public static IntPtr GetMethodID(IntPtr obj, string name, string sig) + { + try { return AndroidJNI.GetMethodID(obj, name, sig); } finally { CheckException(); } + } + + public static IntPtr GetFieldID(IntPtr clazz, string name, string sig) + { + try { return AndroidJNI.GetFieldID(clazz, name, sig); } finally { CheckException(); } + } + + public static IntPtr GetStaticFieldID(IntPtr clazz, string name, string sig) + { + try { return AndroidJNI.GetStaticFieldID(clazz, name, sig); } finally { CheckException(); } + } + + public static IntPtr FromReflectedMethod(IntPtr refMethod) + { + try { return AndroidJNI.FromReflectedMethod(refMethod); } finally { CheckException(); } + } + + public static IntPtr FromReflectedField(IntPtr refField) + { + try { return AndroidJNI.FromReflectedField(refField); } finally { CheckException(); } + } + + public static IntPtr FindClass(string name) + { + try { return AndroidJNI.FindClass(name); } finally { CheckException(); } + } + + public static IntPtr NewObject(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.NewObject(clazz, methodID, args); } finally { CheckException(); } + } + + + public static void SetStaticObjectField(IntPtr clazz, IntPtr fieldID, IntPtr val) + { + try { AndroidJNI.SetStaticObjectField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticStringField(IntPtr clazz, IntPtr fieldID, string val) + { + try { AndroidJNI.SetStaticStringField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticCharField(IntPtr clazz, IntPtr fieldID, Char val) + { + try { AndroidJNI.SetStaticCharField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticDoubleField(IntPtr clazz, IntPtr fieldID, double val) + { + try { AndroidJNI.SetStaticDoubleField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticFloatField(IntPtr clazz, IntPtr fieldID, float val) + { + try { AndroidJNI.SetStaticFloatField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticLongField(IntPtr clazz, IntPtr fieldID, Int64 val) + { + try { AndroidJNI.SetStaticLongField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticShortField(IntPtr clazz, IntPtr fieldID, Int16 val) + { + try { AndroidJNI.SetStaticShortField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticByteField(IntPtr clazz, IntPtr fieldID, Byte val) + { + try { AndroidJNI.SetStaticByteField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticBooleanField(IntPtr clazz, IntPtr fieldID, bool val) + { + try { AndroidJNI.SetStaticBooleanField(clazz, fieldID, val); } finally { CheckException(); } + } + + public static void SetStaticIntField(IntPtr clazz, IntPtr fieldID, Int32 val) + { + try { AndroidJNI.SetStaticIntField(clazz, fieldID, val); } finally { CheckException(); } + } + + + public static IntPtr GetStaticObjectField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticObjectField(clazz, fieldID); } finally { CheckException(); } + } + + public static string GetStaticStringField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticStringField(clazz, fieldID); } finally { CheckException(); } + } + + public static Char GetStaticCharField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticCharField(clazz, fieldID); } finally { CheckException(); } + } + + public static double GetStaticDoubleField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticDoubleField(clazz, fieldID); } finally { CheckException(); } + } + + public static float GetStaticFloatField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticFloatField(clazz, fieldID); } finally { CheckException(); } + } + + public static Int64 GetStaticLongField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticLongField(clazz, fieldID); } finally { CheckException(); } + } + + public static Int16 GetStaticShortField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticShortField(clazz, fieldID); } finally { CheckException(); } + } + + public static Byte GetStaticByteField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticByteField(clazz, fieldID); } finally { CheckException(); } + } + + public static bool GetStaticBooleanField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticBooleanField(clazz, fieldID); } finally { CheckException(); } + } + + public static Int32 GetStaticIntField(IntPtr clazz, IntPtr fieldID) + { + try { return AndroidJNI.GetStaticIntField(clazz, fieldID); } finally { CheckException(); } + } + + + public static void CallStaticVoidMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { AndroidJNI.CallStaticVoidMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static IntPtr CallStaticObjectMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticObjectMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static string CallStaticStringMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticStringMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static Char CallStaticCharMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticCharMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static double CallStaticDoubleMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticDoubleMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static float CallStaticFloatMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticFloatMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static Int64 CallStaticLongMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticLongMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static Int16 CallStaticShortMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticShortMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static Byte CallStaticByteMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticByteMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static bool CallStaticBooleanMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticBooleanMethod(clazz, methodID, args); } finally { CheckException(); } + } + + public static Int32 CallStaticIntMethod(IntPtr clazz, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStaticIntMethod(clazz, methodID, args); } finally { CheckException(); } + } + + + public static void SetObjectField(IntPtr obj, IntPtr fieldID, IntPtr val) + { + try { AndroidJNI.SetObjectField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetStringField(IntPtr obj, IntPtr fieldID, string val) + { + try { AndroidJNI.SetStringField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetCharField(IntPtr obj, IntPtr fieldID, Char val) + { + try { AndroidJNI.SetCharField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetDoubleField(IntPtr obj, IntPtr fieldID, double val) + { + try { AndroidJNI.SetDoubleField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetFloatField(IntPtr obj, IntPtr fieldID, float val) + { + try { AndroidJNI.SetFloatField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetLongField(IntPtr obj, IntPtr fieldID, Int64 val) + { + try { AndroidJNI.SetLongField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetShortField(IntPtr obj, IntPtr fieldID, Int16 val) + { + try { AndroidJNI.SetShortField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetByteField(IntPtr obj, IntPtr fieldID, Byte val) + { + try { AndroidJNI.SetByteField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetBooleanField(IntPtr obj, IntPtr fieldID, bool val) + { + try { AndroidJNI.SetBooleanField(obj, fieldID, val); } finally { CheckException(); } + } + + public static void SetIntField(IntPtr obj, IntPtr fieldID, Int32 val) + { + try { AndroidJNI.SetIntField(obj, fieldID, val); } finally { CheckException(); } + } + + + public static IntPtr GetObjectField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetObjectField(obj, fieldID); } finally { CheckException(); } + } + + public static string GetStringField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetStringField(obj, fieldID); } finally { CheckException(); } + } + + public static Char GetCharField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetCharField(obj, fieldID); } finally { CheckException(); } + } + + public static double GetDoubleField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetDoubleField(obj, fieldID); } finally { CheckException(); } + } + + public static float GetFloatField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetFloatField(obj, fieldID); } finally { CheckException(); } + } + + public static Int64 GetLongField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetLongField(obj, fieldID); } finally { CheckException(); } + } + + public static Int16 GetShortField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetShortField(obj, fieldID); } finally { CheckException(); } + } + + public static Byte GetByteField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetByteField(obj, fieldID); } finally { CheckException(); } + } + + public static bool GetBooleanField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetBooleanField(obj, fieldID); } finally { CheckException(); } + } + + public static Int32 GetIntField(IntPtr obj, IntPtr fieldID) + { + try { return AndroidJNI.GetIntField(obj, fieldID); } finally { CheckException(); } + } + + + public static void CallVoidMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { AndroidJNI.CallVoidMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static IntPtr CallObjectMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallObjectMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static string CallStringMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallStringMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static Char CallCharMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallCharMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static double CallDoubleMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallDoubleMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static float CallFloatMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallFloatMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static Int64 CallLongMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallLongMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static Int16 CallShortMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallShortMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static Byte CallByteMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallByteMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static bool CallBooleanMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallBooleanMethod(obj, methodID, args); } finally { CheckException(); } + } + + public static Int32 CallIntMethod(IntPtr obj, IntPtr methodID, jvalue[] args) + { + try { return AndroidJNI.CallIntMethod(obj, methodID, args); } finally { CheckException(); } + } + + + public static IntPtr[] FromObjectArray(IntPtr array) + { + try { return AndroidJNI.FromObjectArray(array); } finally { CheckException(); } + } + + public static Char[] FromCharArray(IntPtr array) + { + try { return AndroidJNI.FromCharArray(array); } finally { CheckException(); } + } + + public static double[] FromDoubleArray(IntPtr array) + { + try { return AndroidJNI.FromDoubleArray(array); } finally { CheckException(); } + } + + public static float[] FromFloatArray(IntPtr array) + { + try { return AndroidJNI.FromFloatArray(array); } finally { CheckException(); } + } + + public static Int64[] FromLongArray(IntPtr array) + { + try { return AndroidJNI.FromLongArray(array); } finally { CheckException(); } + } + + public static Int16[] FromShortArray(IntPtr array) + { + try { return AndroidJNI.FromShortArray(array); } finally { CheckException(); } + } + + public static Byte[] FromByteArray(IntPtr array) + { + try { return AndroidJNI.FromByteArray(array); } finally { CheckException(); } + } + + public static bool[] FromBooleanArray(IntPtr array) + { + try { return AndroidJNI.FromBooleanArray(array); } finally { CheckException(); } + } + + public static Int32[] FromIntArray(IntPtr array) + { + try { return AndroidJNI.FromIntArray(array); } finally { CheckException(); } + } + + + public static IntPtr ToObjectArray(IntPtr[] array) + { + try { return AndroidJNI.ToObjectArray(array); } finally { CheckException(); } + } + + public static IntPtr ToCharArray(Char[] array) + { + try { return AndroidJNI.ToCharArray(array); } finally { CheckException(); } + } + + public static IntPtr ToDoubleArray(double[] array) + { + try { return AndroidJNI.ToDoubleArray(array); } finally { CheckException(); } + } + + public static IntPtr ToFloatArray(float[] array) + { + try { return AndroidJNI.ToFloatArray(array); } finally { CheckException(); } + } + + public static IntPtr ToLongArray(Int64[] array) + { + try { return AndroidJNI.ToLongArray(array); } finally { CheckException(); } + } + + public static IntPtr ToShortArray(Int16[] array) + { + try { return AndroidJNI.ToShortArray(array); } finally { CheckException(); } + } + + public static IntPtr ToByteArray(Byte[] array) + { + try { return AndroidJNI.ToByteArray(array); } finally { CheckException(); } + } + + public static IntPtr ToBooleanArray(bool[] array) + { + try { return AndroidJNI.ToBooleanArray(array); } finally { CheckException(); } + } + + public static IntPtr ToIntArray(Int32[] array) + { + try { return AndroidJNI.ToIntArray(array); } finally { CheckException(); } + } + + public static IntPtr GetObjectArrayElement(IntPtr array, int index) + { + try { return AndroidJNI.GetObjectArrayElement(array, index); } finally { CheckException(); } + } + + public static int GetArrayLength(IntPtr array) + { + try { return AndroidJNI.GetArrayLength(array); } finally { CheckException(); } + } +} +} + +#endif diff --git a/Runtime/Export/AndroidJava.txt b/Runtime/Export/AndroidJava.txt new file mode 100644 index 0000000..ab2c9f5 --- /dev/null +++ b/Runtime/Export/AndroidJava.txt @@ -0,0 +1,114 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" + +CSRAW +#if UNITY_EDITOR || UNITY_ANDROID +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UnityEngine +{ + +// AndroidJavaObject is the Unity representation of a generic instance of java.lang.Object. +NONSEALED_CLASS AndroidJavaObject : IDisposable + + // Construct an AndroidJavaObject based on the name of the class. + CSRAW public AndroidJavaObject(string className, params object[] args) : this() + { + _AndroidJavaObject(className, args); + } + + // IDisposable callback + CSRAW public void Dispose() + { + _Dispose(); + } + + //=================================================================== + + // Calls a Java method on an object (non-static). + CSRAW public void Call(string methodName, params object[] args) + { + _Call(methodName, args); + } + + //=================================================================== + + // Call a static Java method on a class. + CSRAW public void CallStatic(string methodName, params object[] args) + { + _CallStatic(methodName, args); + } + + //=================================================================== + + // Get the value of a field in an object (non-static). + CSRAW public FieldType Get<FieldType>(string fieldName) + { + return _Get<FieldType>(fieldName); + } + + + // Set the value of a field in an object (non-static). + CSRAW public void Set<FieldType>(string fieldName, FieldType val) + { + _Set<FieldType>(fieldName, val); + } + + + //=================================================================== + + // Get the value of a static field in an object type. + CSRAW public FieldType GetStatic<FieldType>(string fieldName) + { + return _GetStatic<FieldType>(fieldName); + } + + + // Set the value of a static field in an object type. + CSRAW public void SetStatic<FieldType>(string fieldName, FieldType val) + { + _SetStatic<FieldType>(fieldName, val); + } + + + //=================================================================== + + // Retrieve the <i>raw</i> jobject pointer to the Java object. + CSRAW public IntPtr GetRawObject() { return _GetRawObject(); } + // Retrieve the <i>raw</i> jclass pointer to the Java class; + CSRAW public IntPtr GetRawClass() { return _GetRawClass(); } + + //=================================================================== + + // Call a Java method on an object. + CSRAW public ReturnType Call<ReturnType>(string methodName, params object[] args) + { + return _Call<ReturnType>(methodName, args); + } + + // Call a static Java method on a class. + CSRAW public ReturnType CallStatic<ReturnType>(string methodName, params object[] args) + { + return _CallStatic<ReturnType>(methodName, args); + } +END + +// AndroidJavaClass is the Unity representation of a generic instance of java.lang.Class +NONSEALED_CLASS AndroidJavaClass : AndroidJavaObject + + // Construct an AndroidJavaClass from the class name + CSRAW public AndroidJavaClass(string className) : base() + { + _AndroidJavaClass(className); + } +END + +CSRAW +} +#endif diff --git a/Runtime/Export/AndroidJavaImpl.cs b/Runtime/Export/AndroidJavaImpl.cs new file mode 100644 index 0000000..84429cd --- /dev/null +++ b/Runtime/Export/AndroidJavaImpl.cs @@ -0,0 +1,1147 @@ +#if UNITY_EDITOR || UNITY_ANDROID + +using UnityEngine; +using System; +using System.Reflection; +using System.Runtime.InteropServices; +using System.Collections.Generic; + + +namespace UnityEngine +{ + public delegate void AndroidJavaRunnable(); + + public sealed class AndroidJavaException : Exception + { + internal AndroidJavaException(string message) : base(message) { } + } + + + internal class AndroidJavaRunnableProxy : AndroidJavaProxy + { + private AndroidJavaRunnable mRunnable; + public AndroidJavaRunnableProxy(AndroidJavaRunnable runnable) : base("java/lang/Runnable") { mRunnable = runnable; } + public void run() { mRunnable(); } + } + + public class AndroidJavaProxy + { + + public readonly AndroidJavaClass javaInterface; + public AndroidJavaProxy(string javaInterface) : this(new AndroidJavaClass(javaInterface)) {} + public AndroidJavaProxy(AndroidJavaClass javaInterface) + { + this.javaInterface = javaInterface; + } + + public virtual AndroidJavaObject Invoke(string methodName, object[] args) + { + Exception error = null; + BindingFlags binderFlags = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; + Type[] argTypes = new Type[args.Length]; + for (int i = 0; i < args.Length; ++i) + argTypes[i] = args[i] == null ? typeof(AndroidJavaObject) : args[i].GetType(); + try + { + MethodInfo method = GetType().GetMethod(methodName, binderFlags, null, argTypes, null); + if (method != null) + return _AndroidJNIHelper.Box(method.Invoke(this, args)); + } + catch (TargetInvocationException invocationError) + { + error = invocationError.InnerException; + } + catch (Exception invocationError) + { + error = invocationError; + } + + // Log error + string[] argTypeNames = new string[args.Length]; + for (int i = 0; i < argTypes.Length; ++i) + argTypeNames[i] = argTypes[i].ToString(); + + if (error != null) + throw new TargetInvocationException(GetType() + "." + methodName + "(" + string.Join(",", argTypeNames) + ")", error); + + throw new Exception("No such proxy method: " + GetType() + "." + methodName + "(" + string.Join(",", argTypeNames) + ")"); + } + + public virtual AndroidJavaObject Invoke(string methodName, AndroidJavaObject[] javaArgs) + { + object[] args = new object[javaArgs.Length]; + for (int i = 0; i < javaArgs.Length; ++i) + args[i] = _AndroidJNIHelper.Unbox(javaArgs[i]); + return Invoke(methodName, args); + } + } + + public partial class AndroidJavaObject + { + //=================================================================== + + private static bool enableDebugPrints = false; + + protected void DebugPrint(string msg) + { + if (!enableDebugPrints) + return; + Debug.Log(msg); + } + protected void DebugPrint(string call, string methodName, string signature, object[] args) + { + if (!enableDebugPrints) + return; + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + foreach (object obj in args) + { + sb.Append(", "); + sb.Append(obj == null ? "<null>" : obj.GetType().ToString()); + } + Debug.Log(call + "(\"" + methodName + "\"" + sb.ToString() + ") = " + signature); + } + + //=================================================================== + + private void _AndroidJavaObject(string className, params object[] args) + { + DebugPrint("Creating AndroidJavaObject from " + className); + if (args==null) args = new object[] { null }; + using (var clazz = FindClass(className)) + { + m_jclass = AndroidJNI.NewGlobalRef(clazz.GetRawObject()); + jvalue[] jniArgs = AndroidJNIHelper.CreateJNIArgArray(args); + try + { + IntPtr constructorID = AndroidJNIHelper.GetConstructorID(m_jclass, args); + IntPtr jobject = AndroidJNISafe.NewObject(m_jclass, constructorID, jniArgs); + m_jobject = AndroidJNI.NewGlobalRef(jobject); + AndroidJNISafe.DeleteLocalRef(jobject); + } + finally + { + AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + } + } + internal AndroidJavaObject(IntPtr jobject) : this() // should be protected and friends with AndroidJNIHelper.. + { + if (jobject == IntPtr.Zero) + { + throw new Exception("JNI: Init'd AndroidJavaObject with null ptr!"); + } + + IntPtr jclass = AndroidJNISafe.GetObjectClass(jobject); + m_jobject = AndroidJNI.NewGlobalRef(jobject); + m_jclass = AndroidJNI.NewGlobalRef(jclass); + AndroidJNISafe.DeleteLocalRef(jclass); + } + + internal AndroidJavaObject() + { + } + + ~AndroidJavaObject() + { + Dispose(true); + } + + private bool m_disposed = false; + protected virtual void Dispose(bool disposing) + { + if(m_disposed) + return; + + m_disposed = true; + + AndroidJNISafe.DeleteGlobalRef(m_jobject); + AndroidJNISafe.DeleteGlobalRef(m_jclass); + } + protected void _Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + //=================================================================== + + protected void _Call(string methodName, params object[] args) + { + if (args==null) args = new object[] { null }; + IntPtr methodID = AndroidJNIHelper.GetMethodID(m_jclass, methodName, args, false); + jvalue[] jniArgs = AndroidJNIHelper.CreateJNIArgArray(args); + try + { + AndroidJNISafe.CallVoidMethod(m_jobject, methodID, jniArgs); + } + finally + { + AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + } + protected ReturnType _Call<ReturnType>(string methodName, params object[] args) + { + if (args==null) args = new object[] { null }; + IntPtr methodID = AndroidJNIHelper.GetMethodID<ReturnType>(m_jclass, methodName, args, false); + jvalue[] jniArgs = AndroidJNIHelper.CreateJNIArgArray(args); + try + { + if (typeof(ReturnType).IsPrimitive) + { + if (typeof(ReturnType) == typeof(Int32)) + return (ReturnType)(object)AndroidJNISafe.CallIntMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Boolean)) + return (ReturnType)(object)AndroidJNISafe.CallBooleanMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Byte)) + return (ReturnType)(object)AndroidJNISafe.CallByteMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Int16)) + return (ReturnType)(object)AndroidJNISafe.CallShortMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Int64)) + return (ReturnType)(object)AndroidJNISafe.CallLongMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Single)) + return (ReturnType)(object)AndroidJNISafe.CallFloatMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Double)) + return (ReturnType)(object)AndroidJNISafe.CallDoubleMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Char)) + return (ReturnType)(object)AndroidJNISafe.CallCharMethod(m_jobject, methodID, jniArgs); + } + else if (typeof(ReturnType) == typeof(String)) + return (ReturnType)(object)AndroidJNISafe.CallStringMethod(m_jobject, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(AndroidJavaClass)) + { + IntPtr jclass = AndroidJNISafe.CallObjectMethod(m_jobject, methodID, jniArgs); + return (ReturnType)(object)AndroidJavaClassDeleteLocalRef(jclass); + } + else if (typeof(ReturnType) == typeof(AndroidJavaObject)) + { + IntPtr jobject = AndroidJNISafe.CallObjectMethod(m_jobject, methodID, jniArgs); + return (ReturnType)(object)AndroidJavaObjectDeleteLocalRef(jobject); + } + else if (typeof(System.Array).IsAssignableFrom(typeof(ReturnType))) + { + IntPtr jobject = AndroidJNISafe.CallObjectMethod(m_jobject, methodID, jniArgs); + return (ReturnType)(object)AndroidJNIHelper.ConvertFromJNIArray<ReturnType>(jobject); + } + else + { + throw new Exception("JNI: Unknown return type '" + typeof(ReturnType) + "'"); + } + return default(ReturnType); + } + finally + { + AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + } + + //=================================================================== + + protected FieldType _Get<FieldType>(string fieldName) + { + IntPtr fieldID = AndroidJNIHelper.GetFieldID<FieldType>(m_jclass, fieldName, false); + if (typeof(FieldType).IsPrimitive) + { + if (typeof(FieldType) == typeof(Int32)) + return (FieldType)(object)AndroidJNISafe.GetIntField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Boolean)) + return (FieldType)(object)AndroidJNISafe.GetBooleanField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Byte)) + return (FieldType)(object)AndroidJNISafe.GetByteField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Int16)) + return (FieldType)(object)AndroidJNISafe.GetShortField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Int64)) + return (FieldType)(object)AndroidJNISafe.GetLongField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Single)) + return (FieldType)(object)AndroidJNISafe.GetFloatField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Double)) + return (FieldType)(object)AndroidJNISafe.GetDoubleField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(Char)) + return (FieldType)(object)AndroidJNISafe.GetCharField(m_jobject, fieldID); + } + else if (typeof(FieldType) == typeof(String)) + return (FieldType)(object)AndroidJNISafe.GetStringField(m_jobject, fieldID); + else if (typeof(FieldType) == typeof(AndroidJavaClass)) + { + IntPtr jclass = AndroidJNISafe.GetObjectField(m_jobject, fieldID); + return (FieldType)(object)AndroidJavaClassDeleteLocalRef(jclass); + } + else if (typeof(FieldType) == typeof(AndroidJavaObject)) + { + IntPtr jobject = AndroidJNISafe.GetObjectField(m_jobject, fieldID); + return (FieldType)(object)AndroidJavaObjectDeleteLocalRef(jobject); + } + else if (typeof(System.Array).IsAssignableFrom(typeof(FieldType))) + { + IntPtr jobject = AndroidJNISafe.GetObjectField(m_jobject, fieldID); + return (FieldType)(object)AndroidJNIHelper.ConvertFromJNIArray<FieldType>(jobject); + } + else + { + throw new Exception("JNI: Unknown field type '" + typeof(FieldType) + "'"); + } + return default(FieldType); + } + protected void _Set<FieldType>(string fieldName, FieldType val) + { + IntPtr fieldID = AndroidJNIHelper.GetFieldID<FieldType>(m_jclass, fieldName, false); + if (typeof(FieldType).IsPrimitive) + { + if (typeof(FieldType) == typeof(Int32)) + AndroidJNISafe.SetIntField(m_jobject, fieldID, (Int32)(object)val); + else if (typeof(FieldType) == typeof(Boolean)) + AndroidJNISafe.SetBooleanField(m_jobject, fieldID, (Boolean)(object)val); + else if (typeof(FieldType) == typeof(Byte)) + AndroidJNISafe.SetByteField(m_jobject, fieldID, (Byte)(object)val); + else if (typeof(FieldType) == typeof(Int16)) + AndroidJNISafe.SetShortField(m_jobject, fieldID, (Int16)(object)val); + else if (typeof(FieldType) == typeof(Int64)) + AndroidJNISafe.SetLongField(m_jobject, fieldID, (Int64)(object)val); + else if (typeof(FieldType) == typeof(Single)) + AndroidJNISafe.SetFloatField(m_jobject, fieldID, (Single)(object)val); + else if (typeof(FieldType) == typeof(Double)) + AndroidJNISafe.SetDoubleField(m_jobject, fieldID, (Double)(object)val); + else if (typeof(FieldType) == typeof(Char)) + AndroidJNISafe.SetCharField(m_jobject, fieldID, (Char)(object)val); + } + else if (typeof(FieldType) == typeof(String)) + AndroidJNISafe.SetStringField(m_jobject, fieldID, (String)(object)val); + else if (typeof(FieldType) == typeof(AndroidJavaClass)) + { + AndroidJNISafe.SetObjectField(m_jobject, fieldID, ((AndroidJavaClass)(object)val).m_jclass); + } + else if (typeof(FieldType) == typeof(AndroidJavaObject)) + { + AndroidJNISafe.SetObjectField(m_jobject, fieldID, ((AndroidJavaObject)(object)val).m_jobject); + } + else if (typeof(System.Array).IsAssignableFrom(typeof(FieldType))) + { + IntPtr jobject = AndroidJNIHelper.ConvertToJNIArray((Array)(object)val); + AndroidJNISafe.SetObjectField(m_jclass, fieldID, jobject); + } + else + { + throw new Exception("JNI: Unknown field type '" + typeof(FieldType) + "'"); + } + } + + //=================================================================== + + protected void _CallStatic(string methodName, params object[] args) + { + if (args==null) args = new object[] { null }; + IntPtr methodID = AndroidJNIHelper.GetMethodID(m_jclass, methodName, args, true); + jvalue[] jniArgs = AndroidJNIHelper.CreateJNIArgArray(args); + try + { + AndroidJNISafe.CallStaticVoidMethod(m_jclass, methodID, jniArgs); + } + finally + { + AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + } + protected ReturnType _CallStatic<ReturnType>(string methodName, params object[] args) + { + if (args==null) args = new object[] { null }; + IntPtr methodID = AndroidJNIHelper.GetMethodID<ReturnType>(m_jclass, methodName, args, true); + jvalue[] jniArgs = AndroidJNIHelper.CreateJNIArgArray(args); + try + { + if (typeof(ReturnType).IsPrimitive) + { + if (typeof(ReturnType) == typeof(Int32)) + return (ReturnType)(object)AndroidJNISafe.CallStaticIntMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Boolean)) + return (ReturnType)(object)AndroidJNISafe.CallStaticBooleanMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Byte)) + return (ReturnType)(object)AndroidJNISafe.CallStaticByteMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Int16)) + return (ReturnType)(object)AndroidJNISafe.CallStaticShortMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Int64)) + return (ReturnType)(object)AndroidJNISafe.CallStaticLongMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Single)) + return (ReturnType)(object)AndroidJNISafe.CallStaticFloatMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Double)) + return (ReturnType)(object)AndroidJNISafe.CallStaticDoubleMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(Char)) + return (ReturnType)(object)AndroidJNISafe.CallStaticCharMethod(m_jclass, methodID, jniArgs); + } + else if (typeof(ReturnType) == typeof(String)) + return (ReturnType)(object)AndroidJNISafe.CallStaticStringMethod(m_jclass, methodID, jniArgs); + else if (typeof(ReturnType) == typeof(AndroidJavaClass)) + { + IntPtr jclass = AndroidJNISafe.CallStaticObjectMethod(m_jclass, methodID, jniArgs); + return (ReturnType)(object)AndroidJavaClassDeleteLocalRef(jclass); + } + else if (typeof(ReturnType) == typeof(AndroidJavaObject)) + { + IntPtr jobject = AndroidJNISafe.CallStaticObjectMethod(m_jclass, methodID, jniArgs); + return (ReturnType)(object)AndroidJavaObjectDeleteLocalRef(jobject); + } + else if (typeof(System.Array).IsAssignableFrom(typeof(ReturnType))) + { + IntPtr jobject = AndroidJNISafe.CallStaticObjectMethod(m_jclass, methodID, jniArgs); + return (ReturnType)(object)AndroidJNIHelper.ConvertFromJNIArray<ReturnType>(jobject); + } + else + { + throw new Exception("JNI: Unknown return type '" + typeof(ReturnType) + "'"); + } + + return default(ReturnType); + } + finally + { + AndroidJNIHelper.DeleteJNIArgArray(args, jniArgs); + } + } + + //=================================================================== + + protected FieldType _GetStatic<FieldType>(string fieldName) + { + IntPtr fieldID = AndroidJNIHelper.GetFieldID<FieldType>(m_jclass, fieldName, true); + if (typeof(FieldType).IsPrimitive) + { + if (typeof(FieldType) == typeof(Int32)) + return (FieldType)(object)AndroidJNISafe.GetStaticIntField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Boolean)) + return (FieldType)(object)AndroidJNISafe.GetStaticBooleanField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Byte)) + return (FieldType)(object)AndroidJNISafe.GetStaticByteField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Int16)) + return (FieldType)(object)AndroidJNISafe.GetStaticShortField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Int64)) + return (FieldType)(object)AndroidJNISafe.GetStaticLongField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Single)) + return (FieldType)(object)AndroidJNISafe.GetStaticFloatField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Double)) + return (FieldType)(object)AndroidJNISafe.GetStaticDoubleField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(Char)) + return (FieldType)(object)AndroidJNISafe.GetStaticCharField(m_jclass, fieldID); + } + else if (typeof(FieldType) == typeof(String)) + return (FieldType)(object)AndroidJNISafe.GetStaticStringField(m_jclass, fieldID); + else if (typeof(FieldType) == typeof(AndroidJavaClass)) + { + IntPtr jclass = AndroidJNISafe.GetStaticObjectField(m_jclass, fieldID); + return (FieldType)(object)AndroidJavaClassDeleteLocalRef(jclass); + } + else if (typeof(FieldType) == typeof(AndroidJavaObject)) + { + IntPtr jobject = AndroidJNISafe.GetStaticObjectField(m_jclass, fieldID); + return (FieldType)(object)AndroidJavaObjectDeleteLocalRef(jobject); + } + else if (typeof(System.Array).IsAssignableFrom(typeof(FieldType))) + { + IntPtr jobject = AndroidJNISafe.GetStaticObjectField(m_jclass, fieldID); + return (FieldType)(object)AndroidJNIHelper.ConvertFromJNIArray<FieldType>(jobject); + } + else + { + throw new Exception("JNI: Unknown field type '" + typeof(FieldType) + "'"); + } + return default(FieldType); + } + protected void _SetStatic<FieldType>(string fieldName, FieldType val) + { + IntPtr fieldID = AndroidJNIHelper.GetFieldID<FieldType>(m_jclass, fieldName, true); + if (typeof(FieldType).IsPrimitive) + { + if (typeof(FieldType) == typeof(Int32)) + AndroidJNISafe.SetStaticIntField(m_jclass, fieldID, (Int32)(object)val); + else if (typeof(FieldType) == typeof(Boolean)) + AndroidJNISafe.SetStaticBooleanField(m_jclass, fieldID, (Boolean)(object)val); + else if (typeof(FieldType) == typeof(Byte)) + AndroidJNISafe.SetStaticByteField(m_jclass, fieldID, (Byte)(object)val); + else if (typeof(FieldType) == typeof(Int16)) + AndroidJNISafe.SetStaticShortField(m_jclass, fieldID, (Int16)(object)val); + else if (typeof(FieldType) == typeof(Int64)) + AndroidJNISafe.SetStaticLongField(m_jclass, fieldID, (Int64)(object)val); + else if (typeof(FieldType) == typeof(Single)) + AndroidJNISafe.SetStaticFloatField(m_jclass, fieldID, (Single)(object)val); + else if (typeof(FieldType) == typeof(Double)) + AndroidJNISafe.SetStaticDoubleField(m_jclass, fieldID, (Double)(object)val); + else if (typeof(FieldType) == typeof(Char)) + AndroidJNISafe.SetStaticCharField(m_jclass, fieldID, (Char)(object)val); + } + else if (typeof(FieldType) == typeof(String)) + AndroidJNISafe.SetStaticStringField(m_jclass, fieldID, (String)(object)val); + else if (typeof(FieldType) == typeof(AndroidJavaClass)) + { + AndroidJNISafe.SetStaticObjectField(m_jclass, fieldID, ((AndroidJavaClass)(object)val).m_jclass); + } + else if (typeof(FieldType) == typeof(AndroidJavaObject)) + { + AndroidJNISafe.SetStaticObjectField(m_jclass, fieldID, ((AndroidJavaObject)(object)val).m_jobject); + } + else if (typeof(System.Array).IsAssignableFrom(typeof(FieldType))) + { + IntPtr jobject = AndroidJNIHelper.ConvertToJNIArray((Array)(object)val); + AndroidJNISafe.SetStaticObjectField(m_jclass, fieldID, jobject); + } + else + { + throw new Exception("JNI: Unknown field type '" + typeof(FieldType) + "'"); + } + } + + internal static AndroidJavaObject AndroidJavaObjectDeleteLocalRef(IntPtr jobject) + { + try { return new AndroidJavaObject(jobject); } finally { AndroidJNISafe.DeleteLocalRef(jobject); } + } + + internal static AndroidJavaClass AndroidJavaClassDeleteLocalRef(IntPtr jclass) + { + try { return new AndroidJavaClass(jclass); } finally { AndroidJNISafe.DeleteLocalRef(jclass); } + } + + //=================================================================== + protected IntPtr _GetRawObject() { return m_jobject; } + protected IntPtr _GetRawClass() { return m_jclass; } + + protected IntPtr m_jobject; + protected IntPtr m_jclass; // use this for static lookups; reset in subclases + + protected static AndroidJavaObject FindClass(string name) + { + return JavaLangClass.CallStatic<AndroidJavaObject>("forName", name.Replace('/', '.')); + } + + private static AndroidJavaClass s_JavaLangClass; + protected static AndroidJavaClass JavaLangClass + { + get + { + if (s_JavaLangClass == null) + s_JavaLangClass = new AndroidJavaClass(AndroidJNISafe.FindClass("java/lang/Class")); + return s_JavaLangClass; + } + } + } + + public partial class AndroidJavaClass + { + private void _AndroidJavaClass(string className) + { + DebugPrint("Creating AndroidJavaClass from " + className); + using (var clazz = FindClass(className)) + { + m_jclass = AndroidJNI.NewGlobalRef(clazz.GetRawObject()); + m_jobject = IntPtr.Zero; + } + } + + internal AndroidJavaClass(IntPtr jclass) // should be protected and friends with AndroidJNIHelper.. + { + if (jclass == IntPtr.Zero) + { + throw new Exception("JNI: Init'd AndroidJavaClass with null ptr!"); + } + + m_jclass = AndroidJNI.NewGlobalRef(jclass); + m_jobject = IntPtr.Zero; + } + } + + internal class AndroidReflection + { + private static IntPtr GetStaticMethodID(string clazz, string methodName, string signature) + { + IntPtr jclass = AndroidJNISafe.FindClass(clazz); + try + { + return AndroidJNISafe.GetStaticMethodID(jclass, methodName, signature); + } + finally + { + AndroidJNISafe.DeleteLocalRef(jclass); + } + } + + private const string RELECTION_HELPER_CLASS_NAME = "com/unity3d/player/ReflectionHelper"; + private static IntPtr s_ReflectionHelperClass = AndroidJNI.NewGlobalRef(AndroidJNISafe.FindClass(RELECTION_HELPER_CLASS_NAME)); + private static IntPtr s_ReflectionHelperGetConstructorID = GetStaticMethodID(RELECTION_HELPER_CLASS_NAME, "getConstructorID", "(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/reflect/Constructor;"); + private static IntPtr s_ReflectionHelperGetMethodID = GetStaticMethodID(RELECTION_HELPER_CLASS_NAME, "getMethodID", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/reflect/Method;"); + private static IntPtr s_ReflectionHelperGetFieldID = GetStaticMethodID(RELECTION_HELPER_CLASS_NAME, "getFieldID", "(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Z)Ljava/lang/reflect/Field;"); + private static IntPtr s_ReflectionHelperNewProxyInstance = GetStaticMethodID(RELECTION_HELPER_CLASS_NAME, "newProxyInstance", "(ILjava/lang/Class;)Ljava/lang/Object;"); + + public static IntPtr GetConstructorMember(IntPtr jclass, string signature) + { + jvalue[] jniArgs = new jvalue[2]; + try + { + jniArgs[0].l = jclass; + jniArgs[1].l = AndroidJNISafe.NewStringUTF(signature); + return AndroidJNISafe.CallStaticObjectMethod(s_ReflectionHelperClass, s_ReflectionHelperGetConstructorID, jniArgs); + } + finally + { + AndroidJNISafe.DeleteLocalRef(jniArgs[1].l); + } + } + + public static IntPtr GetMethodMember(IntPtr jclass, string methodName, string signature, bool isStatic) + { + jvalue[] jniArgs = new jvalue[4]; + try + { + jniArgs[0].l = jclass; + jniArgs[1].l = AndroidJNISafe.NewStringUTF(methodName); + jniArgs[2].l = AndroidJNISafe.NewStringUTF(signature); + jniArgs[3].z = isStatic; + return AndroidJNISafe.CallStaticObjectMethod(s_ReflectionHelperClass, s_ReflectionHelperGetMethodID, jniArgs); + } + finally + { + AndroidJNISafe.DeleteLocalRef(jniArgs[1].l); + AndroidJNISafe.DeleteLocalRef(jniArgs[2].l); + } + } + + public static IntPtr GetFieldMember(IntPtr jclass, string fieldName, string signature, bool isStatic) + { + jvalue[] jniArgs = new jvalue[4]; + try + { + jniArgs[0].l = jclass; + jniArgs[1].l = AndroidJNISafe.NewStringUTF(fieldName); + jniArgs[2].l = AndroidJNISafe.NewStringUTF(signature); + jniArgs[3].z = isStatic; + return AndroidJNISafe.CallStaticObjectMethod(s_ReflectionHelperClass, s_ReflectionHelperGetFieldID, jniArgs); + } + finally + { + AndroidJNISafe.DeleteLocalRef(jniArgs[1].l); + AndroidJNISafe.DeleteLocalRef(jniArgs[2].l); + } + } + + public static IntPtr NewProxyInstance(int delegateHandle, IntPtr interfaze) + { + jvalue[] jniArgs = new jvalue[2]; + jniArgs[0].i = delegateHandle; + jniArgs[1].l = interfaze; + return AndroidJNISafe.CallStaticObjectMethod(s_ReflectionHelperClass, s_ReflectionHelperNewProxyInstance, jniArgs); + } + } + + sealed class _AndroidJNIHelper + { + public static IntPtr CreateJavaProxy(int delegateHandle, AndroidJavaProxy proxy) + { + return AndroidReflection.NewProxyInstance(delegateHandle, proxy.javaInterface.GetRawClass()); + } + + public static IntPtr CreateJavaRunnable(AndroidJavaRunnable jrunnable) + { + return AndroidJNIHelper.CreateJavaProxy(new AndroidJavaRunnableProxy(jrunnable)); + } + + public static IntPtr InvokeJavaProxyMethod(AndroidJavaProxy proxy, IntPtr jmethodName, IntPtr jargs) + { + int arrayLen = AndroidJNISafe.GetArrayLength(jargs); + AndroidJavaObject[] args = new AndroidJavaObject[arrayLen]; + for (int i = 0; i < arrayLen; ++i) + { + IntPtr objectRef = AndroidJNISafe.GetObjectArrayElement(jargs, i); + args[i] = objectRef != IntPtr.Zero ? new AndroidJavaObject(objectRef) : null; + } + using (AndroidJavaObject result = proxy.Invoke(AndroidJNI.GetStringUTFChars(jmethodName), args)) + { + if (result == null) + return IntPtr.Zero; + + return AndroidJNI.NewLocalRef(result.GetRawObject()); + } + } + + public static jvalue[] CreateJNIArgArray(object[] args) + { + jvalue[] ret = new jvalue[args.GetLength(0)]; + int i = 0; + foreach( object obj in args) + { + if (obj == null) + ret[i].l = System.IntPtr.Zero; + else if (obj.GetType().IsPrimitive) + { + if (obj is System.Int32) + ret[i].i = (System.Int32)obj; + else if (obj is System.Boolean) + ret[i].z = (System.Boolean)obj; + else if (obj is System.Byte) + ret[i].b = (System.Byte)obj; + else if (obj is System.Int16) + ret[i].s = (System.Int16)obj; + else if (obj is System.Int64) + ret[i].j = (System.Int64)obj; + else if (obj is System.Single) + ret[i].f = (System.Single)obj; + else if (obj is System.Double) + ret[i].d = (System.Double)obj; + else if (obj is System.Char) + ret[i].c = (System.Char)obj; + } + else if (obj is System.String) + { + ret[i].l = AndroidJNISafe.NewStringUTF((System.String)obj); + } + else if (obj is AndroidJavaClass) + { + ret[i].l = ((AndroidJavaClass)obj).GetRawClass(); + } + else if (obj is AndroidJavaObject) + { + ret[i].l = ((AndroidJavaObject)obj).GetRawObject(); + } + else if (obj is System.Array) + { + ret[i].l = ConvertToJNIArray((System.Array)obj); + } + else if (obj is AndroidJavaProxy) + { + ret[i].l = AndroidJNIHelper.CreateJavaProxy((AndroidJavaProxy)obj); + } + else if (obj is AndroidJavaRunnable) + { + ret[i].l = AndroidJNIHelper.CreateJavaRunnable((AndroidJavaRunnable)obj); + } + else + { + throw new Exception("JNI; Unknown argument type '" + obj.GetType() + "'"); + } + ++i; + } + return ret; + } + + public static object UnboxArray(AndroidJavaObject obj) + { + if (obj == null) + return null; + + AndroidJavaClass arrayUtil = new AndroidJavaClass("java/lang/reflect/Array"); + AndroidJavaObject objClass = obj.Call<AndroidJavaObject>("getClass"); + AndroidJavaObject compClass = objClass.Call<AndroidJavaObject>("getComponentType"); + string className = compClass.Call<string>("getName"); + + int arrayLength = arrayUtil.Call<int>("getLength", obj); + Array array; + if (compClass.Call<bool>("IsPrimitive")) // need to setup primitive array + { + if ("I" == className) + array = new int[arrayLength]; + else if ("Z" == className) + array = new bool[arrayLength]; + else if ("B" == className) + array = new byte[arrayLength]; + else if ("S" == className) + array = new short[arrayLength]; + else if ("L" == className) + array = new long[arrayLength]; + else if ("F" == className) + array = new float[arrayLength]; + else if ("D" == className) + array = new double[arrayLength]; + else if ("C" == className) + array = new char[arrayLength]; + else + throw new Exception("JNI; Unknown argument type '" + className + "'"); + } + else if ("java.lang.String" == className) + array = new string[arrayLength]; + else if ("java.lang.Class" == className) + array = new AndroidJavaClass[arrayLength]; + else + array = new AndroidJavaObject[arrayLength]; + + for (int i = 0; i < arrayLength; ++i) + array.SetValue(Unbox(arrayUtil.CallStatic<AndroidJavaObject>("get", obj, i)), i); + + return array; + } + + public static object Unbox(AndroidJavaObject obj) + { + if (obj == null) + return null; + + AndroidJavaObject clazz = obj.Call<AndroidJavaObject>("getClass"); + string className = clazz.Call<string>("getName"); + if ("java.lang.Integer" == className) + return obj.Call<System.Int32>("intValue"); + else if ("java.lang.Boolean" == className) + return obj.Call<System.Boolean>("booleanValue"); + else if ("java.lang.Byte" == className) + return obj.Call<System.Byte>("byteValue"); + else if ("java.lang.Short" == className) + return obj.Call<System.Int16>("shortValue"); + else if ("java.lang.Long" == className) + return obj.Call<System.Int32>("longValue"); + else if ("java.lang.Float" == className) + return obj.Call<System.Single>("floatValue"); + else if ("java.lang.Double" == className) + return obj.Call<System.Double>("doubleValue"); + else if ("java.lang.Character" == className) + return obj.Call<System.Char>("charValue"); + else if ("java.lang.String" == className) + return obj.Call<System.String>("toString"); // um, can obvoiusly be performed in a better fasion + else if ("java.lang.Class" == className) + return new AndroidJavaClass(obj.GetRawObject()); + else if (clazz.Call<bool>("isArray")) + return UnboxArray(obj); + else + return obj; + } + + public static AndroidJavaObject Box(object obj) + { + if (obj == null) + return null; + else if (obj.GetType().IsPrimitive) + { + if (obj is System.Int32) + return new AndroidJavaObject("java.lang.Integer", (System.Int32)obj); + else if (obj is System.Boolean) + return new AndroidJavaObject("java.lang.Boolean", (System.Boolean)obj); + else if (obj is System.Byte) + return new AndroidJavaObject("java.lang.Byte", (System.Byte)obj); + else if (obj is System.Int16) + return new AndroidJavaObject("java.lang.Short", (System.Int16)obj); + else if (obj is System.Int64) + return new AndroidJavaObject("java.lang.Long", (System.Int64)obj); + else if (obj is System.Single) + return new AndroidJavaObject("java.lang.Float", (System.Single)obj); + else if (obj is System.Double) + return new AndroidJavaObject("java.lang.Double", (System.Double)obj); + else if (obj is System.Char) + return new AndroidJavaObject("java.lang.Character", (System.Char)obj); + else + throw new Exception("JNI; Unknown argument type '" + obj.GetType() + "'"); + } + else if (obj is System.String) + { + return new AndroidJavaObject("java.lang.String", (System.String)obj); + } + else if (obj is AndroidJavaClass) + { + return new AndroidJavaObject(((AndroidJavaClass)obj).GetRawClass()); + } + else if (obj is AndroidJavaObject) + { + return (AndroidJavaObject)obj; + } + else if (obj is System.Array) + { + return AndroidJavaObject.AndroidJavaObjectDeleteLocalRef(ConvertToJNIArray((System.Array)obj)); + } + else if (obj is AndroidJavaProxy) + { + return AndroidJavaObject.AndroidJavaObjectDeleteLocalRef(AndroidJNIHelper.CreateJavaProxy((AndroidJavaProxy)obj)); + } + else if (obj is AndroidJavaRunnable) + { + return AndroidJavaObject.AndroidJavaObjectDeleteLocalRef(AndroidJNIHelper.CreateJavaRunnable((AndroidJavaRunnable)obj)); + } + else + { + throw new Exception("JNI; Unknown argument type '" + obj.GetType() + "'"); + } + } + + public static void DeleteJNIArgArray(object[] args, jvalue[] jniArgs) + { + int i = 0; + foreach (object obj in args) + { + if (obj is System.String || obj is AndroidJavaRunnable || obj is AndroidJavaProxy || obj is System.Array) + AndroidJNISafe.DeleteLocalRef(jniArgs[i].l); + + ++i; + } + } + + public static IntPtr ConvertToJNIArray(System.Array array) + { + Type type = array.GetType().GetElementType(); + if (type.IsPrimitive) + { + if (type == typeof(Int32)) + return AndroidJNISafe.ToIntArray((Int32[])array); + else if (type == typeof(Boolean)) + return AndroidJNISafe.ToBooleanArray((Boolean[])array); + else if (type == typeof(Byte)) + return AndroidJNISafe.ToByteArray((Byte[])array); + else if (type == typeof(Int16)) + return AndroidJNISafe.ToShortArray((Int16[])array); + else if (type == typeof(Int64)) + return AndroidJNISafe.ToLongArray((Int64[])array); + else if (type == typeof(Single)) + return AndroidJNISafe.ToFloatArray((Single[])array); + else if (type == typeof(Double)) + return AndroidJNISafe.ToDoubleArray((Double[])array); + else if (type == typeof(Char)) + return AndroidJNISafe.ToCharArray((Char[])array); + } + else if (type == typeof(String)) + { + String[] strArray = (string[])array; + int arrayLen = array.GetLength(0); + IntPtr[] jniStrs = new IntPtr[arrayLen]; + for (int i = 0; i < arrayLen; ++i) + { + jniStrs[i] = AndroidJNISafe.NewStringUTF(strArray[i]); + } + return AndroidJNISafe.ToObjectArray(jniStrs); + } + else if (type == typeof(AndroidJavaObject)) + { + AndroidJavaObject[] objArray = (AndroidJavaObject[])array; + int arrayLen = array.GetLength(0); + IntPtr[] jniObjs = new IntPtr[arrayLen]; + for (int i = 0; i < arrayLen; ++i) + { + jniObjs[i] = objArray[i] == null ? IntPtr.Zero : objArray[i].GetRawObject(); + } + return AndroidJNISafe.ToObjectArray(jniObjs); + } + else + { + throw new Exception("JNI; Unknown array type '" + type + "'"); + } + return IntPtr.Zero; + } + public static ArrayType ConvertFromJNIArray<ArrayType>(IntPtr array) + { + Type type = typeof(ArrayType).GetElementType(); + if (type.IsPrimitive) + { + if (type == typeof(Int32)) + return (ArrayType)(object)AndroidJNISafe.FromIntArray(array); + else if (type == typeof(Boolean)) + return (ArrayType)(object)AndroidJNISafe.FromBooleanArray(array); + else if (type == typeof(Byte)) + return (ArrayType)(object)AndroidJNISafe.FromByteArray(array); + else if (type == typeof(Int16)) + return (ArrayType)(object)AndroidJNISafe.FromShortArray(array); + else if (type == typeof(Int64)) + return (ArrayType)(object)AndroidJNISafe.FromLongArray(array); + else if (type == typeof(Single)) + return (ArrayType)(object)AndroidJNISafe.FromFloatArray(array); + else if (type == typeof(Double)) + return (ArrayType)(object)AndroidJNISafe.FromDoubleArray(array); + else if (type == typeof(Char)) + return (ArrayType)(object)AndroidJNISafe.FromCharArray(array); + } + else if (type == typeof(String)) + { + IntPtr[] jniStrs = AndroidJNISafe.FromObjectArray(array); + int arrayLen = jniStrs.GetLength(0); + string[] strArray = new string[arrayLen]; + for (int i = 0; i < arrayLen; ++i) + { + strArray[i] = AndroidJNISafe.GetStringUTFChars(jniStrs[i]); + } + return (ArrayType)(object)strArray; + } + else if (type == typeof(AndroidJavaObject)) + { + IntPtr[] jniObjs = AndroidJNISafe.FromObjectArray(array); + int arrayLen = jniObjs.GetLength(0); + AndroidJavaObject[] objArray = new AndroidJavaObject[arrayLen]; + for (int i = 0; i < arrayLen; ++i) + { + objArray[i] = new AndroidJavaObject(jniObjs[i]); + } + return (ArrayType)(object)objArray; + } + else + { + throw new Exception("JNI: Unknown generic array type '" + type + "'"); + } + return default(ArrayType); + } + + public static System.IntPtr GetConstructorID(System.IntPtr jclass, object[] args) + { + return AndroidJNIHelper.GetConstructorID(jclass, GetSignature(args)); + } + public static System.IntPtr GetMethodID(System.IntPtr jclass, string methodName, object[] args, bool isStatic) + { + return AndroidJNIHelper.GetMethodID(jclass, methodName, GetSignature(args), isStatic); + } + public static System.IntPtr GetMethodID<ReturnType>(System.IntPtr jclass, string methodName, object[] args, bool isStatic) + { + return AndroidJNIHelper.GetMethodID(jclass, methodName, GetSignature<ReturnType>(args), isStatic); + } + public static System.IntPtr GetFieldID<ReturnType>(System.IntPtr jclass, string fieldName, bool isStatic) + { + return AndroidJNIHelper.GetFieldID(jclass, fieldName, GetSignature(typeof(ReturnType)), isStatic); + } + + public static IntPtr GetConstructorID(IntPtr jclass, string signature) + { + IntPtr constructor = IntPtr.Zero; + try + { + constructor = AndroidReflection.GetConstructorMember(jclass, signature); + return AndroidJNISafe.FromReflectedMethod(constructor); + } + catch (Exception e) + { + IntPtr memberID = AndroidJNISafe.GetMethodID(jclass, "<init>", signature); + if (memberID != IntPtr.Zero) + return memberID; + throw e; + } + finally + { + AndroidJNISafe.DeleteLocalRef(constructor); + } + } + + public static IntPtr GetMethodID(IntPtr jclass, string methodName, string signature, bool isStatic) + { + IntPtr method = IntPtr.Zero; + try + { + method = AndroidReflection.GetMethodMember(jclass, methodName, signature, isStatic); + return AndroidJNISafe.FromReflectedMethod(method); + } + catch (Exception e) + { + IntPtr memberID = isStatic + ? AndroidJNISafe.GetStaticMethodID(jclass, methodName, signature) + : AndroidJNISafe.GetMethodID(jclass, methodName, signature); + if (memberID != IntPtr.Zero) + return memberID; + throw e; + } + finally + { + AndroidJNISafe.DeleteLocalRef(method); + } + } + + public static IntPtr GetFieldID(IntPtr jclass, string fieldName, string signature, bool isStatic) + { + IntPtr field = IntPtr.Zero; + try + { + field = AndroidReflection.GetFieldMember(jclass, fieldName, signature, isStatic); + return AndroidJNISafe.FromReflectedField(field); + } + catch (Exception e) + { + IntPtr memberID = isStatic + ? AndroidJNISafe.GetStaticFieldID(jclass, fieldName, signature) + : AndroidJNISafe.GetFieldID(jclass, fieldName, signature); + if (memberID != IntPtr.Zero) + return memberID; + throw e; + } + finally + { + AndroidJNISafe.DeleteLocalRef(field); + } + } + + public static string GetSignature(object obj) + { + if (obj == null) + return "Ljava/lang/Object;"; + System.Type type = (obj is System.Type) ? (System.Type)obj : obj.GetType(); + if (type.IsPrimitive) + { + if (type.Equals(typeof(System.Int32))) + return "I"; + else if (type.Equals(typeof(System.Boolean))) + return "Z"; + else if (type.Equals(typeof(System.Byte))) + return "B"; + else if (type.Equals(typeof(System.Int16))) + return "S"; + else if (type.Equals(typeof(System.Int64))) + return "J"; + else if (type.Equals(typeof(System.Single))) + return "F"; + else if (type.Equals(typeof(System.Double))) + return "D"; + else if (type.Equals(typeof(System.Char))) + return "C"; + } + else if (type.Equals(typeof(System.String))) + { + return "Ljava/lang/String;"; + } + else if (obj is AndroidJavaProxy) + { + AndroidJavaObject javaClass = new AndroidJavaObject(((AndroidJavaProxy) obj).javaInterface.GetRawClass()); + return "L" + javaClass.Call<System.String>("getName") + ";"; + } + else if (type.Equals(typeof(AndroidJavaRunnable))) + { + return "Ljava/lang/Runnable;"; + } + else if (type.Equals(typeof(AndroidJavaClass))) + { + return "Ljava/lang/Class;"; + } + else if (type.Equals(typeof(AndroidJavaObject))) + { + if (obj == type) + { + return "Ljava/lang/Object;"; + } + AndroidJavaObject javaObject = (AndroidJavaObject)obj; + using (AndroidJavaObject javaClass = javaObject.Call<AndroidJavaObject>("getClass")) + { + return "L" + javaClass.Call<System.String>("getName") + ";"; + } + } + else if (typeof(System.Array).IsAssignableFrom(type)) + { + if (type.GetArrayRank() != 1) + { + throw new Exception("JNI: System.Array in n dimensions is not allowed"); + } + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append('['); + sb.Append(GetSignature(type.GetElementType())); + return sb.ToString(); + } + else + { + throw new Exception("JNI: Unknown signature for type '" + type + "' (obj = " + obj + ") " + (type == obj? "equal":"instance")); + } + return ""; + } + public static string GetSignature(object[] args) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append('('); + foreach (object obj in args) + { + sb.Append(GetSignature(obj)); + } + sb.Append(")V"); + return sb.ToString(); + } + + public static string GetSignature<ReturnType>(object[] args) + { + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append('('); + foreach (object obj in args) + { + sb.Append(GetSignature(obj)); + } + sb.Append(')'); + sb.Append(GetSignature(typeof(ReturnType))); + return sb.ToString(); + } + } +} + +#endif // UNITY_EDITOR || UNITY_ANDROID diff --git a/Runtime/Export/AssemblyInfo.cs b/Runtime/Export/AssemblyInfo.cs new file mode 100644 index 0000000..4a16238 --- /dev/null +++ b/Runtime/Export/AssemblyInfo.cs @@ -0,0 +1,15 @@ +using System.Runtime.CompilerServices; + +//TODO: Think about if this is secure or not, and if we should be using UnityEditor's public key instead. +//I think we're cool, because we ifdef it out in the version of UnityEngine.dll that we ship with the webplayer. +#if UNITY_EDITOR +[assembly: InternalsVisibleTo("UnityEditor")] +[assembly: InternalsVisibleTo("Unity.PureCSharpTests")] +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] // for Moq +[assembly: InternalsVisibleTo("UnityEditor.Graphs")] +[assembly: InternalsVisibleTo("UnityEditor.Xbox360.Extensions")] +#endif + +#if UNITY_WINRT +[assembly: InternalsVisibleTo("WinRTBridge")] +#endif
\ No newline at end of file diff --git a/Runtime/Export/AssetBundleBindings.txt b/Runtime/Export/AssetBundleBindings.txt new file mode 100644 index 0000000..08f097e --- /dev/null +++ b/Runtime/Export/AssetBundleBindings.txt @@ -0,0 +1,175 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Misc/AssetBundle.h" +#include "Runtime/Misc/AssetBundleUtility.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/Backend/ScriptingBackendApi.h" +#include "Runtime/Misc/SaveAndLoadHelper.h" +#include "Runtime/Misc/AsyncOperation.h" +#include "Runtime/Scripting/Scripting.h" + + +using namespace std; + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; +using UnityEngineInternal; + +namespace UnityEngine +{ + + +// Asynchronous create request for an [[AssetBundle]]. +CONDITIONAL ENABLE_WWW +CLASS AssetBundleCreateRequest : AsyncOperation + + C++RAW + #define GET_REQUEST(variableName) \ + AssetBundleCreateRequest* variableName; \ + MarshallManagedStructIntoNative (self, &variableName); + + // Asset object being loaded (RO). + CUSTOM_PROP AssetBundle assetBundle + { + GET_REQUEST (ptr); + return Scripting::ScriptingWrapperFor(ptr->GetAssetBundle()); + } + + CUSTOM internal void DisableCompatibilityChecks() + { + GET_REQUEST (ptr); + ptr->SetEnableCompatibilityChecks (false); + } + + C++RAW + #undef GET_REQUEST + +END + +// Asynchronous load request from an [[AssetBundle]]. +CSRAW [StructLayout (LayoutKind.Sequential)] +CLASS AssetBundleRequest : AsyncOperation + C++RAW + #define GET ExtractMonoObjectData<PreloadManagerOperation*> (self) + + CSRAW internal AssetBundle m_AssetBundle; + CSRAW internal string m_Path; + CSRAW internal Type m_Type; + + // Asset object being loaded (RO). + CSRAW public Object asset { get { return m_AssetBundle.Load(m_Path, m_Type); } } + + C++RAW + #undef GET + +END + +// AssetBundles let you stream additional assets via the WWW class and instantiate them at runtime. AssetBundles are created via BuildPipeline.BuildAssetBundle. + +CLASS AssetBundle : Object + + // Asynchronously create an AssetBundle from a memory region. + CONDITIONAL ENABLE_WWW + CUSTOM static AssetBundleCreateRequest CreateFromMemory(byte[] binary) + { + if (!binary) + return SCRIPTING_NULL; + + int dataSize = GetScriptingArraySize(binary); + UInt8* dataPtr = Scripting::GetScriptingArrayStart<UInt8>(binary); + + AsyncOperation* req = new AssetBundleCreateRequest(dataPtr, dataSize); + + + return CreateScriptingObjectFromNativeStruct(MONO_COMMON.assetBundleCreateRequest,req); + } + + // Loads an asset bundle from a disk. + CUSTOM static AssetBundle CreateFromFile(string path) + { + return Scripting::ScriptingWrapperFor(ExtractAssetBundle(path)); + } + + // Main asset that was supplied when building the asset bundle (RO). + CUSTOM_PROP Object mainAsset { return Scripting::ScriptingWrapperFor(LoadMainObjectFromAssetBundle(*self)); } + + // Check if an AssetBundle contains a specific object. + CUSTOM bool Contains (string name) + { + string lowerName = ToLower(name.AsUTF8()); + AssetBundle::range found = self->GetPathRange(lowerName); + return found.first != found.second; + } + + // Loads object with /name/ from the bundle. + CSRAW public Object Load (string name) + { + return Load(name, typeof(Object)); + } + + // Loads object with /name/ of a given /type/ from the bundle. + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedBySecondArgument)] + CONSTRUCTOR_SAFE + CUSTOM Object Load (string name, Type type) + { + Scripting::RaiseIfNull (type); + Object* o = LoadNamedObjectFromAssetBundle(*self, name, type); + if (o==0) return SCRIPTING_NULL; + return Scripting::ScriptingWrapperFor(o); + } + + // Asynchronously loads object with /name/ of a given /type/ from the bundle. + CUSTOM AssetBundleRequest LoadAsync (string name, Type type) + { + AsyncOperation* result = PreloadLevelOperation::LoadAssetBundle(*self, name); + #if ENABLE_MONO || UNITY_WINRT + ScriptingObjectPtr mono = scripting_object_new(MONO_COMMON.assetBundleRequest); + AssetBundleRequestMono data; + data.m_Result = result; + data.m_Path = name.GetNativeString(); + data.m_Type = type; + data.m_AssetBundle = Scripting::ScriptingWrapperFor((AssetBundle*)self); + MarshallNativeStructIntoManaged(data, mono); + + return mono; + #else + return SCRIPTING_NULL; + #endif + + } + + // Loads all objects contained in the asset bundle that inherit from /type/. + CUSTOM Object[] LoadAll (Type type) + { + Scripting::RaiseIfNull (type); + + vector<Object* > objects; + LoadAllFromAssetBundle(*self, type, objects); + return CreateScriptingArrayFromUnityObjects(objects, ClassID(Object)); + } + + // Loads all objects contained in the asset bundle. + CSRAW public Object[] LoadAll () + { + return LoadAll(typeof(Object)); + } + + // Unloads all assets in the bundle. + CUSTOM void Unload (bool unloadAllLoadedObjects) + { + AssetBundle& file = *self; + UnloadAssetBundle(file, unloadAllLoadedObjects); + } +END + +CSRAW } diff --git a/Runtime/Export/AttributeHelperEngine.cs b/Runtime/Export/AttributeHelperEngine.cs new file mode 100644 index 0000000..d8188e0 --- /dev/null +++ b/Runtime/Export/AttributeHelperEngine.cs @@ -0,0 +1,84 @@ +using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + + +namespace AOT +{ + // Mono AOT compiler detects this attribute by name and generates required wrappers for + // native->managed callbacks. Works only for static methods. + [System.AttributeUsage(System.AttributeTargets.Method)] + public class MonoPInvokeCallbackAttribute : Attribute + { + public MonoPInvokeCallbackAttribute (Type type) {} + } +} + +namespace UnityEngine +{ + +internal class WrapperlessIcall : System.Attribute { + public WrapperlessIcall () { + } +} + +class AttributeHelperEngine +{ + static Type[] GetRequiredComponents (Type klass) + { + // Generate an array for all required components + // .NET doesnt give us multiple copies of the same attribute on derived classes + // Thus we do it manually + List<Type> required = null; + while (klass != null && klass != typeof (MonoBehaviour)) + { + object[] attrs = klass.GetCustomAttributes(typeof(RequireComponent), false); + + + for (int i=0;i<attrs.Length;i++) + { + RequireComponent attri = (RequireComponent)attrs[i]; + if (required == null && attrs.Length == 1 && klass.BaseType == typeof (MonoBehaviour)) + { + Type[] types = { attri.m_Type0, attri.m_Type1, attri.m_Type2 }; + return types; + } + else + { + if (required == null) + required = new List<Type>(); + + if (attri.m_Type0 != null) + required.Add(attri.m_Type0); + if (attri.m_Type1 != null) + required.Add(attri.m_Type1); + if (attri.m_Type2 != null) + required.Add(attri.m_Type2); + } + } + + klass = klass.BaseType; + } + if (required == null) + return null; + else + return required.ToArray(); + } + + static bool CheckIsEditorScript (Type klass) + { + while (klass != null && klass != typeof (MonoBehaviour)) + { + object[] attrs = klass.GetCustomAttributes(typeof(ExecuteInEditMode), false); + if (attrs.Length != 0) + return true; + klass = klass.BaseType; + } + return false; + } +} +}
\ No newline at end of file diff --git a/Runtime/Export/BaseClass.txt b/Runtime/Export/BaseClass.txt new file mode 100644 index 0000000..f083ca0 --- /dev/null +++ b/Runtime/Export/BaseClass.txt @@ -0,0 +1,1174 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Utilities/PathNameUtility.h" +#include "Runtime/Input/InputManager.h" +#include "Runtime/Input/TimeManager.h" +#include "Runtime/Misc/ResourceManager.h" +#include "Runtime/Profiler/ProfilerImpl.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/BaseClasses/Tags.h" +#include "Runtime/Misc/DebugUtility.h" +#include "Runtime/Misc/PlayerSettings.h" +#include "Runtime/GameCode/CloneObject.h" +#include "Runtime/Math/Random/Random.h" +#include "Runtime/Misc/PreloadManager.h" +#include "Runtime/Allocator/MemoryManager.h" +#include "Runtime/Audio/AudioClip.h" +#if ENABLE_AUDIO +#include "Runtime/Audio/AudioSource.h" +#include "Runtime/Audio/AudioListener.h" +#include "Runtime/Audio/AudioManager.h" +#include "Runtime/Audio/AudioReverbZone.h" +#include "Runtime/Audio/AudioReverbFilter.h" +#include "Runtime/Audio/AudioHighPassFilter.h" +#include "Runtime/Audio/AudioLowPassFilter.h" +#include "Runtime/Audio/AudioChorusFilter.h" +#include "Runtime/Audio/AudioDistortionFilter.h" +#include "Runtime/Audio/AudioEchoFilter.h" +#endif +#include "Runtime/Animation/Animation.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Utilities/PlayerPrefs.h" +#include "Runtime/Camera/Camera.h" +#include "Runtime/Dynamics/RigidBody.h" +#include "Runtime/Utilities/Word.h" +#include "Runtime/Camera/Light.h" +#include "Runtime/Filters/Misc/TextMesh.h" +#include "Runtime/Dynamics/ConstantForce.h" +#include "Runtime/Filters/Renderer.h" +#include "Runtime/Misc/SaveAndLoadHelper.h" +#include "Runtime/Network/NetworkView.h" +#include "Runtime/Network/NetworkManager.h" +#include "Runtime/Camera/RenderLayers/GUIText.h" +#include "Runtime/Camera/RenderLayers/GUITexture.h" +#include "Runtime/Dynamics/Collider.h" +#include "Runtime/Dynamics/HingeJoint.h" +#include "Runtime/Filters/Particles/ParticleEmitter.h" +#include "Runtime/Misc/Player.h" +#include "Runtime/BaseClasses/IsPlaying.h" +#include "Runtime/Misc/CaptureScreenshot.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Misc/Plugins.h" +#include "Runtime/Misc/ResourceManagerUtility.h" +#include "Runtime/Utilities/PathNameUtility.h" +#include "Runtime/Utilities/File.h" +#include <ctime> +#include "Runtime/Input/GetInput.h" +#include "Runtime/NavMesh/NavMeshAgent.h" +#include "Runtime/NavMesh/NavMesh.h" +#include "Runtime/NavMesh/OffMeshLink.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Animation/AnimationManager.h" +#include "Runtime/Animation/AnimationClip.h" +#include "Runtime/BaseClasses/RefCounted.h" +#include "Runtime/Misc/GOCreation.h" +#include "Runtime/Utilities/URLUtility.h" +#include "Runtime/Graphics/ScreenManager.h" +#include "Runtime/Serialize/PersistentManager.h" +#include "Runtime/Shaders/GraphicsCaps.h" +#include "Runtime/Misc/SystemInfo.h" +#include "Runtime/Utilities/FileUtilities.h" +#include "Runtime/Misc/GraphicsDevicesDB.h" +#include "Configuration/UnityConfigureVersion.h" +#include "Runtime/Profiler/CollectProfilerStats.h" +#include "Runtime/File/ApplicationSpecificPersistentDataPath.h" +#include "Runtime/Mono/Coroutine.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/GetComponent.h" +#include "Runtime/Scripting/Backend/ScriptingBackendApi.h" +#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +#if SUPPORT_REPRODUCE_LOG +#include "Runtime/Misc/ReproductionLog.h" +#endif + +#if WEBPLUG + #include "PlatformDependent/CommonWebPlugin/UnityWebStream.h" + #include "PlatformDependent/CommonWebPlugin/WebScripting.h" +#endif + +#if UNITY_EDITOR + #include "Editor/Src/EditorSettings.h" + #include "Editor/Src/EditorUserBuildSettings.h" + #include "Editor/Mono/MonoEditorUtility.h" +#endif + +#if UNITY_WII + #include "PlatformDependent/Wii/WiiUtility.h" +#endif + +using namespace Unity; + +/* + Mono defines a bool as either 1 or 2 bytes. + On windows a bool on the C++ side needs to be 2 bytes. + We use the typemap to map bool's to short's. + When using the C++ keyword and you want to export a bool value + to mono you have to use a short on the C++ side. +*/ + + +void PauseEditor (); +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; +using UnityEngineInternal; + +namespace UnityEngine +{ + +[StructLayout (LayoutKind.Sequential)] +internal struct ReferenceData +{ + public int instanceID; + public IntPtr cachedPtr; +} + +// Bit mask that controls object destruction and visibility in inspectors +CSRAW [Flags] +ENUM HideFlags + // A normal, visible object. This is the default. + None = 0, + + // The object will not appear in the hierarchy and will not show up in the project view if it is stored in an asset. + HideInHierarchy = 1, + + // It is not possible to view it in the inspector + HideInInspector = 2, + + // The object will not be saved to the scene. __It will not be destroyed when a new scene is loaded__. + DontSave = 4, + + // The object is not be editable in the inspector + NotEditable = 8, + + // A combination of not shown in the hierarchy and not saved to to scenes. + HideAndDontSave = 13 +END + +// Options for how to send a message. +ENUM SendMessageOptions + // A receiver is required for SendMessage. + RequireReceiver = 0, + + // No receiver is required for SendMessage. + DontRequireReceiver = 1 +END + +// The various primitives that can be created using the GameObject.CreatePrimitive function. +CSRAW +ENUM PrimitiveType + // A sphere primitive + Sphere = 0, + + // A capsule primitive + Capsule = 1, + + // A cylinder primitive + Cylinder = 2, + + // A cube primitive + Cube = 3, + + // A plane primitive + Plane = 4, + + // A quad primitive + Quad = 5 +END + +// The coordinate space in which to operate. +ENUM Space + // Applies transformation relative to the world coordinate system + World = 0, + // Applies transformation relative to the local coordinate system + Self = 1 +END + + + +// LayerMask allow you to display the LayerMask popup menu in the inspector +STRUCT LayerMask + CSRAW + private int m_Mask; + + //*undocumented* TODO: make this actually work + CSRAW public static implicit operator int (LayerMask mask) { return mask.m_Mask; } + + // implicitly converts an integer to a LayerMask + public static implicit operator LayerMask (int intVal) { LayerMask mask; mask.m_Mask = intVal; return mask; } + + // Converts a layer mask value to an integer value. + CSRAW public int value { get { return m_Mask; } set { m_Mask = value; } } + + // Given a layer number, returns the name of the layer as defined in either a Builtin or a User Layer in the [[wiki:class-TagManager|Tag Manager]] + CUSTOM static string LayerToName (int layer) { return scripting_string_new(LayerToString(layer)); } + + // Given a layer name, returns the layer index as defined by either a Builtin or a User Layer in the [[wiki:class-TagManager|Tag Manager]] + CUSTOM static int NameToLayer (string layerName) { return StringToLayer(layerName); } +END + + +// The platform application is running. Returned by Application.platform. +ENUM RuntimePlatform + // In the Unity editor on Mac OS X. + OSXEditor = 0, + + // In the player on Mac OS X. + OSXPlayer = 1, + + // In the player on Windows. + WindowsPlayer = 2, + + // In the web player on Mac OS X. + OSXWebPlayer = 3, + + // In the Dashboard widget on Mac OS X. + OSXDashboardPlayer = 4, + + // In the web player on Windows. + WindowsWebPlayer = 5, + + // In the player on Nintendo Wii. + WiiPlayer = 6, + + // In the Unity editor on Windows. + WindowsEditor = 7, + + // In the player on the iPhone. + IPhonePlayer = 8, + + // In the player on the XBOX360 + XBOX360 = 10, + + // In the player on the Play Station 3 + PS3 = 9, + + // In the player on Android devices. + Android = 11, + + //Google Native Client + NaCl = 12, + + //*undocumented* + LinuxPlayer = 13, + + //Flash Player + FlashPlayer = 15, + + //*undocumented* + MetroPlayerX86 = 18, + + //*undocumented* + MetroPlayerX64 = 19, + + //*undocumented* + MetroPlayerARM = 20, + + //*undocumented* + WP8Player = 21, + + //*undocumented* + BB10Player = 22, + + //*undocumented* + TizenPlayer = 23, + +END + +// The language the user's operating system is running in. Returned by Application.systemLanguage. +ENUM SystemLanguage + //Afrikaans + Afrikaans = 0, + //Arabic + Arabic = 1, + //Basque + Basque = 2, + //Belarusian + Belarusian = 3, + //Bulgarian + Bulgarian = 4, + //Catalan + Catalan = 5, + //Chinese + Chinese = 6, + //Czech + Czech = 7, + //Danish + Danish = 8, + //Dutch + Dutch = 9, + //English + English = 10, + //Estonian + Estonian = 11, + //Faroese + Faroese = 12, + //Finnish + Finnish = 13, + //French + French = 14, + //German + German = 15, + //Greek + Greek = 16, + //Hebrew + Hebrew = 17, + //*undocumented* + Hugarian = 18, + //Icelandic + Icelandic = 19, + //Indonesian + Indonesian = 20, + //Italian + Italian = 21, + //Japanese + Japanese = 22, + //Korean + Korean = 23, + //Latvian + Latvian = 24, + //Lithuanian + Lithuanian = 25, + //Norwegian + Norwegian = 26, + //Polish + Polish = 27, + //Portuguese + Portuguese = 28, + //Romanian + Romanian = 29, + //Russian + Russian = 30, + //Serbo-Croatian + SerboCroatian = 31, + //Slovak + Slovak = 32, + //Slovenian + Slovenian = 33, + //Spanish + Spanish = 34, + //Swedish + Swedish = 35, + //Thai + Thai = 36, + //Turkish + Turkish = 37, + //Ukrainian + Ukrainian = 38, + //Vietnamese + Vietnamese = 39, + //Unknown + Unknown = 40, + //Hungarian + Hungarian = 18 +END + +// The type of the log message in the delegate registered with Application.RegisterLogCallback. +ENUM LogType + // LogType used for Errors. + Error = 0, + // LogType used for Asserts. (These indicate an error inside Unity itself.) + Assert = 1, + // LogType used for Warnings. + Warning = 2, + // LogType used for regular log messages. + Log = 3, + // LogType used for Exceptions. + Exception = 4 +END + +// Enumeration for [[SystemInfo.deviceType]], denotes a coarse grouping of kinds of devices. +ENUM DeviceType + // Device type is unknown. You should never see this in practice. + Unknown = 0, + + // A handheld device like mobile phone or a tablet. + Handheld = 1, + + // A stationary gaming console. + Console = 2, + + // Desktop or laptop computer. + Desktop = 3, +END + +// Access system information. +CLASS SystemInfo + + // Operating system name with version (RO). + CUSTOM_PROP static string operatingSystem { return scripting_string_new( systeminfo::GetOperatingSystem() ); } + + // Processor name (RO). + CUSTOM_PROP static string processorType { return scripting_string_new( systeminfo::GetProcessorType() ); } + + // Number of processors present (RO). + CUSTOM_PROP static int processorCount { return systeminfo::GetProcessorCount(); } + + // Amount of system memory present (RO). + CUSTOM_PROP static int systemMemorySize { return systeminfo::GetPhysicalMemoryMB(); } + + + // Amount of video memory present (RO). + CUSTOM_PROP static int graphicsMemorySize { return (int)gGraphicsCaps.videoMemoryMB; } + + + // The name of the graphics device (RO). + CUSTOM_PROP static string graphicsDeviceName { return scripting_string_new(gGraphicsCaps.rendererString.c_str()); } + + + // The vendor of the graphics device (RO). + CUSTOM_PROP static string graphicsDeviceVendor { return scripting_string_new(gGraphicsCaps.vendorString.c_str()); } + + + // The identifier code of the graphics device (RO). + CUSTOM_PROP static int graphicsDeviceID { return gGraphicsCaps.rendererID; } + + + // The identifier code of the graphics device vendor (RO). + CUSTOM_PROP static int graphicsDeviceVendorID { return gGraphicsCaps.vendorID; } + + + // The graphics API version supported by the graphics device (RO). + CUSTOM_PROP static string graphicsDeviceVersion { return scripting_string_new(gGraphicsCaps.fixedVersionString.c_str()); } + + + + // Graphics device shader capability level (RO). + CUSTOM_PROP static int graphicsShaderLevel { return gGraphicsCaps.shaderCaps; } + + + // Approximate pixel fill-rate of the graphics device (RO). + CUSTOM_PROP static int graphicsPixelFillrate { + return GetGraphicsPixelFillrate (gGraphicsCaps.vendorID, gGraphicsCaps.rendererID); + } + + + // Are built-in shadows supported? (RO) + CUSTOM_PROP static bool supportsShadows { + return RenderTexture::IsEnabled() && GetBuildSettings().hasShadows && gGraphicsCaps.supportsRenderTextureFormat[kRTFormatDepth]; + } + // Are render textures supported? (RO) + CUSTOM_PROP static bool supportsRenderTextures { + return RenderTexture::IsEnabled(); + } + CUSTOM_PROP static bool supportsRenderToCubemap { + return RenderTexture::IsEnabled() && (gGraphicsCaps.hasRenderToCubemap); + } + // Are image effects supported? (RO) + CUSTOM_PROP static bool supportsImageEffects { + return RenderTexture::IsEnabled() && (gGraphicsCaps.npotRT >= kNPOTRestricted); + } + + // Are 3D (volume) textures supported? (RO) + CUSTOM_PROP static bool supports3DTextures { + return gGraphicsCaps.has3DTexture; + } + + // Are compute shaders supported? (RO) + CUSTOM_PROP static bool supportsComputeShaders { + return gGraphicsCaps.hasComputeShader; + } + + // Is GPU draw call instancing supported? (RO) + CUSTOM_PROP static bool supportsInstancing { + return gGraphicsCaps.hasInstancing; + } + + // How many simultaneous render targets (MRTs) are supported? (RO) + CUSTOM_PROP static int supportedRenderTargetCount { + return RenderTexture::IsEnabled() ? gGraphicsCaps.maxMRTs : 0; + } + + // Is the stencil buffer supported? (RO) + CUSTOM_PROP static int supportsStencil { + return gGraphicsCaps.hasStencil && GetBuildSettings ().hasAdvancedVersion; + } + + //*undocumented* + CUSTOM_PROP static bool supportsVertexPrograms { return true; } + + // Is render texture format supported? + CUSTOM static bool SupportsRenderTextureFormat (RenderTextureFormat format) { + return RenderTexture::IsEnabled() && gGraphicsCaps.supportsRenderTextureFormat[format]; + } + + /// What [[NPOT|NPOTSupport]] support does GPU provide? (RO) + /// + /// SA: [[NPOTSupport]] enum. + CUSTOM_PROP static NPOTSupport npotSupport { return gGraphicsCaps.npot; } + + //A unique device identifier. It is guaranteed to be unique for every device (RO). + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + CUSTOM_PROP static string deviceUniqueIdentifier { + return scripting_string_new (systeminfo::GetDeviceUniqueIdentifier ()); + } + + // The user defined name of the device (RO). + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + CUSTOM_PROP static string deviceName { + return scripting_string_new (systeminfo::GetDeviceName ()); + } + + // The model of the device (RO). + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + CUSTOM_PROP static string deviceModel { + return scripting_string_new (systeminfo::GetDeviceModel ()); + } + + // Returns a boolean value that indicates whether an accelerometer is + CUSTOM_PROP static bool supportsAccelerometer { + return systeminfo::SupportsAccelerometer (); + } + + // Returns a boolean value that indicates whether a gyroscope is available + CUSTOM_PROP static bool supportsGyroscope { + return IsGyroAvailable (); + } + + // Returns a boolean value that indicates whether the device is capable to + CUSTOM_PROP static bool supportsLocationService { + return systeminfo::SupportsLocationService (); + } + + // Returns a boolean value that indicates whether the device is capable to + CUSTOM_PROP static bool supportsVibration { + return systeminfo::SupportsVibration (); + } + + // Returns the kind of device the application is running on. See [[DeviceType]] enumeration for possible values. + CUSTOM_PROP static DeviceType deviceType + { + return systeminfo::DeviceType (); + } + + CUSTOM_PROP static int maxTextureSize + { + return gGraphicsCaps.maxTextureSize; + } + +END + +// Suspends the coroutine execution for the given amount of seconds. +CSRAW [StructLayout(LayoutKind.Sequential)] +CLASS WaitForSeconds : YieldInstruction + //*undocumented* + CSRAW internal float m_Seconds; + + // Creates a yield instruction to wait for a given number of seconds + CSRAW public WaitForSeconds (float seconds) { m_Seconds = seconds; } +END + +// Waits until next fixed frame rate update function. SA: MonoBehaviour::pref::FixedUpdate. +CLASS WaitForFixedUpdate : YieldInstruction +END + +// Waits until the end of the frame after all cameras and GUI is rendered, just before displaying the frame on screen. +CLASS WaitForEndOfFrame : YieldInstruction +END + + +// MonoBehaviour.StartCoroutine returns a Coroutine. Instances of this class are only used to reference these coroutines and do not hold any exposed properties or functions. +CSRAW [StructLayout (LayoutKind.Sequential)] + +CLASS Coroutine : YieldInstruction + CSRAW internal IntPtr m_Ptr; + private Coroutine () { } + + THREAD_SAFE + CUSTOM private void ReleaseCoroutine () + { + Assert (self.GetPtr() != NULL); + Coroutine::CleanupCoroutineGC (self); + } + + CSRAW + ~Coroutine () + { + ReleaseCoroutine (); + } +END + +CSRAW + +// The RequireComponent attribute lets automatically add required component as a dependency. + + +CSRAW [AttributeUsage(AttributeTargets.Class, AllowMultiple=true)] +CLASS RequireComponent : Attribute + //*undocumented* + CSRAW public Type m_Type0; + //*undocumented* + CSRAW public Type m_Type1; + //*undocumented* + CSRAW public Type m_Type2; + + // Require a single component + CSRAW public RequireComponent (Type requiredComponent) { m_Type0 = requiredComponent; } + // Require a two components + CSRAW public RequireComponent (Type requiredComponent, Type requiredComponent2) { m_Type0 = requiredComponent; m_Type1 = requiredComponent2; } + // Require three components + CSRAW public RequireComponent (Type requiredComponent, Type requiredComponent2, Type requiredComponent3) { m_Type0 = requiredComponent; m_Type1 = requiredComponent2; m_Type2 = requiredComponent3; } +END + + +// The AddComponentMenu attribute allows you to place a script anywhere in the "Component" menu, instead of just the "Component->Scripts" menu. + +CLASS AddComponentMenu : Attribute + CSRAW private string m_AddComponentMenu; + + // The script will be placed in the component menu according to /menuName/. /menuName/ is the path to the component + CSRAW public AddComponentMenu (string menuName) { m_AddComponentMenu = menuName; } + + //* undocumented + CSRAW public string componentMenu { get {return m_AddComponentMenu; } } +END + + +// The ContextMenu attribute allows you to add commands to the context menu +CLASS ContextMenu : Attribute + + // Adds the function to the context menu of the component. + CSRAW public ContextMenu (string name) { m_ItemName = name; } + + + CSRAW private string m_ItemName; + + //* undocumented + CSRAW public string menuItem { get { return m_ItemName; } } +END + + +// Makes a script execute in edit mode. +CLASS ExecuteInEditMode : Attribute +END + + +// Makes a variable not show up in the inspector but be serialized. +CLASS HideInInspector : Attribute +END + +// A class you can derive from if you want to create objects that don't need to be attached to game objects. +CSRAW +[StructLayout (LayoutKind.Sequential)] +NONSEALED_CLASS ScriptableObject : Object + + //*undocumented* Users are not supposed to instantiate unextended ScriptableObjects, are they? + CSRAW public ScriptableObject () + { + Internal_CreateScriptableObject(this); + } + + THREAD_SAFE + CUSTOM private static void Internal_CreateScriptableObject([Writable]ScriptableObject self) + { + Scripting::CreateEngineScriptableObject(self.GetScriptingObject()); + } + + CONDITIONAL ENABLE_MONO + OBSOLETE warning Use EditorUtility.SetDirty instead + AUTO void SetDirty (); + + // Creates an instance of a scriptable object with /className/. + CUSTOM static ScriptableObject CreateInstance (string className) { return Scripting::CreateScriptableObject (className.AsUTF8()); } + + // Creates an instance of a scriptable object with /type/. + CSRAW public static ScriptableObject CreateInstance (Type type) { return CreateInstanceFromType(type); } + + CUSTOM private static ScriptableObject CreateInstanceFromType (Type type) { return Scripting::CreateScriptableObjectWithType (type); } + + CSRAW + #if ENABLE_GENERICS + // Creates an instance of a scriptable object with /T/. + public static T CreateInstance<T> () where T : ScriptableObject + { + return (T)CreateInstance(typeof(T)); + } + #endif + + // This function is called when the object is loaded + CSNONE void OnEnable (); + + + // This function is called when the scriptable object goes out of scope + CSNONE void OnDisable(); + + // This function is called when the scriptable object will be destroyed. + CSNONE void OnDestroy(); + + +END + +// The Resources class allows you to find and access Objects including assets. +CLASS Resources + + CONDITIONAL (ENABLE_GENERICS && !UNITY_FLASH) + CSRAW internal static T[] ConvertObjects<T>(Object[] rawObjects) where T : Object + { + if (rawObjects == null) return null; + T[] typedObjects = new T[rawObjects.Length]; + for (int i = 0; i < typedObjects.Length; i++) + typedObjects[i] = (T)rawObjects[i]; + return typedObjects; + } + + // Returns a list of all objects of Type /type/. + CSRAW + [TypeInferenceRule(TypeInferenceRules.ArrayOfTypeReferencedByFirstArgument)] + CUSTOM static Object[] FindObjectsOfTypeAll (Type type) { DISALLOW_IN_CONSTRUCTOR return Scripting::FindObjectsOfType (type, Scripting::kFindAnything); } + + CONDITIONAL (ENABLE_GENERICS && !UNITY_FLASH) + CSRAW public static T[] FindObjectsOfTypeAll<T> () where T : Object + { + return ConvertObjects<T>(FindObjectsOfTypeAll (typeof (T))); + } + + // Loads an asset stored at /path/ in a Resources folder. + + CSRAW public static Object Load (string path) + { + return Load(path, typeof(Object)); + } + + CONDITIONAL ENABLE_GENERICS + CSRAW public static T Load<T> (string path) where T : Object + { + return (T) Load (path, typeof (T)); + } + + // Loads an asset stored at /path/ in a Resources folder. + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedBySecondArgument)] + CUSTOM static Object Load (string path, Type systemTypeInstance) + { + Scripting::RaiseIfNull (systemTypeInstance); + + ScriptingClassPtr klass = GetScriptingTypeRegistry().GetType(systemTypeInstance); + string lowerPath = ToLower(path.AsUTF8()); + ResourceManager::range found = GetResourceManager().GetPathRange(lowerPath); + + Object* obj = NULL; + ScriptingObjectPtr o = SCRIPTING_NULL; + for (ResourceManager::iterator i=found.first;i != found.second;i++) + { + obj = i->second; + GetResourceManager ().PreloadDependencies (obj->GetInstanceID ()); + + o = Scripting::ScriptingWrapperFor(obj); + if (o == SCRIPTING_NULL) + continue; + + ScriptingClassPtr k = scripting_object_get_class(o, GetScriptingTypeRegistry()); + if (o && scripting_class_is_subclass_of(k,klass)) + { + break; + } + + GameObject* go = dynamic_pptr_cast<GameObject*> (obj); + if (go != NULL) + { + o = ScriptingGetComponentOfType(*go, systemTypeInstance, false); + if (o != SCRIPTING_NULL) + { + break; + } + } + } + + // Android keeps its Resources folder split up (to minimize seeks inside the .apk) + // To not "leak" SerializedFile objects we need to unload the added stream here.. + if (obj && UNITY_ANDROID) + { + PersistentManager& pm = GetPersistentManager(); + pm.UnloadNonDirtyStreams(); + } + + return o; + } + + // Loads all assets in a folder or file at /path/ in a Resources folder. + CUSTOM static Object[] LoadAll (string path, Type systemTypeInstance) + { + Scripting::RaiseIfNull (systemTypeInstance); + + ScriptingClassPtr klass = GetScriptingTypeRegistry().GetType(systemTypeInstance); + ResourceManager::range found = GetResourceManager().GetAll(); + string cpath = ToLower(path.AsUTF8()); + + vector<PPtr<Object> > objects; + + for (ResourceManager::iterator i=found.first;i != found.second;i++) + { + // Path doesn't match (But allow empty path for all objects) + if (!StartsWithPath(i->first, cpath)) + continue; + + Object* obj = i->second; + GetResourceManager ().PreloadDependencies (obj->GetInstanceID ()); + + ScriptingObjectPtr o = Scripting::ScriptingWrapperFor(obj); + if (o == SCRIPTING_NULL) + continue; + + ScriptingClassPtr k = scripting_object_get_class(o, GetScriptingTypeRegistry()); + if (o && scripting_class_is_subclass_of(k, klass)) + { + objects.push_back(i->second); + } + else + { + GameObject* go = dynamic_pptr_cast<GameObject*> (obj); + if (go != NULL) + { + o = ScriptingGetComponentOfType(*go, systemTypeInstance, false); + if (o != SCRIPTING_NULL) + { + objects.push_back(ScriptingObjectToObject<Object>(o)); + } + } + } + } + + return CreateScriptingArrayFromUnityObjects (objects, ClassID(Object)); + } + + // Loads all assets in a folder or file at /path/ in a Resources folder. + + CSRAW public static Object[] LoadAll (string path) + { + return LoadAll(path, typeof(Object)); + } + + CONDITIONAL (ENABLE_GENERICS && !UNITY_FLASH) + CSRAW public static T[] LoadAll<T> (string path) where T : Object + { + return ConvertObjects<T>(LoadAll (path, typeof (T))); + } + + // *undocumented + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CUSTOM static Object GetBuiltinResource (Type type, string path) + { + Scripting::RaiseIfNull(type); + return GetScriptingBuiltinResource(type, path.AsUTF8()); + } + + CONDITIONAL ENABLE_GENERICS + CSRAW public static T GetBuiltinResource<T> (string path) where T : Object + { + return (T) GetBuiltinResource (typeof (T), path); + } + + // Returns a resource at an asset path (Editor Only). + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedBySecondArgument)] + CUSTOM static Object LoadAssetAtPath (string assetPath, Type type) + { + #if UNITY_EDITOR + return LoadAssetAtPath(assetPath, type); + #else + return SCRIPTING_NULL; + #endif + } + + CONDITIONAL ENABLE_GENERICS + CSRAW public static T LoadAssetAtPath<T> (string assetPath) where T : Object + { + return (T) LoadAssetAtPath (assetPath, typeof (T)); + } + + // Unloads /assetToUnload/ from memory. + CUSTOM static void UnloadAsset (Object assetToUnload) { Scripting::UnloadAssetFromScripting (assetToUnload); } + + // Unloads assets that are not used. + CUSTOM static AsyncOperation UnloadUnusedAssets () + { + AsyncOperation* result = UnloadUnusedAssetsOperation::UnloadUnusedAssets (); + ScriptingObjectPtr o = scripting_object_new(MONO_COMMON.asyncOperation); + ScriptingObjectWithIntPtrField<AsyncOperation>(o).SetPtr(result); + return o; + } + +END + + +OBSOLETE warning Use SerializeField on the private variables that you want to be serialized instead +CLASS SerializePrivateVariables : Attribute +END + +// Priority of a thread. +ENUM ThreadPriority + // Lowest thread priority + Low = 0, + // Below normal thread priority + BelowNormal = 1, + // Normal thread priority + Normal = 2, + // Highest thread priority + High = 4 +END + + +// Force Unity to serialize a private field. + + + +CLASS SerializeField : Attribute +END + +// Controls the [[wiki:Profiler]] from script. +CLASS Profiler + + // *undocumented* + CUSTOM_PROP static bool supported + { + #if ENABLE_PROFILER + return GetBuildSettings().hasPROVersion; + #else + return false; + #endif + } + + + // Sets profiler output file in built players. + CUSTOM_PROP static string logFile + { + #if ENABLE_PROFILER + return scripting_string_new(UnityProfiler::Get().GetLogPath()); + #else + return SCRIPTING_NULL; + #endif + } + { + #if ENABLE_PROFILER + if (!GetBuildSettings().hasPROVersion) + { + ErrorString("Profiler is only supported in Unity Pro."); + return; + } + UnityProfiler::Get().SetLogPath(value); + #else + ErrorString("Profiler is not supported in this build"); + #endif + } + + // Sets profiler output file in built players. + CUSTOM_PROP static bool enableBinaryLog + { + #if ENABLE_PROFILER + return UnityProfiler::Get().BinaryLogEnabled(); + #else + return false; + #endif + } + { + #if ENABLE_PROFILER + if (!GetBuildSettings().hasPROVersion) + { + ErrorString("Profiler is only supported in Unity Pro."); + return; + } + UnityProfiler::Get().EnableBinaryLog(value); + #else + ErrorString("Profiler is not supported in this build"); + #endif + } + + // Enables the Profiler. + CUSTOM_PROP static bool enabled + { + #if ENABLE_PROFILER + return UnityProfiler::Get().GetEnabled(); + #else + return false; + #endif + } + { + #if ENABLE_PROFILER + if (!GetBuildSettings().hasPROVersion) + { + ErrorString("Profiler is only supported in Unity Pro."); + return; + } + return UnityProfiler::Get().SetEnabled(value); + #else + ErrorString("Profiler is not supported in this build"); + #endif + } + + + // Displays the recorded profiledata in the profiler. + CSRAW [System.Diagnostics.ConditionalAttribute("ENABLE_PROFILER")] + CUSTOM static void AddFramesFromFile (string file) + { + #if ENABLE_PROFILER + if(file.Length() == 0) + { + ErrorString ("AddFramesFromFile: Invalid empty path"); + return; + } + UnityProfiler::Get().AddFramesFromFile(file); + #endif + } + + + /// *listonly* + CSRAW [System.Diagnostics.ConditionalAttribute("ENABLE_PROFILER")] + CSRAW static public void BeginSample(string name) + { + BeginSampleOnly(name); + } + + // Begin profiling a piece of code with a custom label. + CSRAW [System.Diagnostics.ConditionalAttribute("ENABLE_PROFILER")] + CUSTOM static void BeginSample(string name, Object targetObject) + { + #if ENABLE_PROFILER + UnityProfilerPerThread* prof = UnityProfilerPerThread::ms_InstanceTLS; + if (prof && prof->GetIsActive()) + prof->BeginSampleDynamic(name, targetObject); + #endif + } + + CUSTOM private static void BeginSampleOnly(string name) + { + #if ENABLE_PROFILER + UnityProfilerPerThread* prof = UnityProfilerPerThread::ms_InstanceTLS; + if (prof && prof->GetIsActive()) + prof->BeginSampleDynamic(name, NULL); + #endif + } + + // End profiling a piece of code with a custom label. + CSRAW [System.Diagnostics.ConditionalAttribute("ENABLE_PROFILER")] + CUSTOM static void EndSample () + { + #if ENABLE_PROFILER + UnityProfilerPerThread* prof = UnityProfilerPerThread::ms_InstanceTLS; + if (prof) + prof->EndSampleDynamic(); + #endif + } + + // Heap size used by the program + CUSTOM_PROP static uint usedHeapSize + { + #if ENABLE_PROFILER + return GetUsedHeapSize(); + #else + return 0; + #endif + } + + // Returns the runtime memory usage of the resource. + + CUSTOM static int GetRuntimeMemorySize(Object o) + { + #if ENABLE_PROFILER + return o->GetRuntimeMemorySize(); + #else + return 0; + #endif + } + + // Returns the size of the mono heap + CUSTOM static uint GetMonoHeapSize () + { + #if ENABLE_PROFILER && ENABLE_MONO + return mono_gc_get_heap_size (); + #else + return 0; + #endif + } + + // Returns the used size from mono + CUSTOM static uint GetMonoUsedSize () + { + #if ENABLE_PROFILER && ENABLE_MONO + return mono_gc_get_used_size (); + #else + return 0; + #endif + } + ///*undocumented* + CUSTOM static uint GetTotalAllocatedMemory() + { + #if ENABLE_MEMORY_MANAGER + return GetMemoryManager().GetTotalAllocatedMemory(); + #else + return 0; + #endif + } + ///*undocumented* + CUSTOM static uint GetTotalUnusedReservedMemory() + { + #if ENABLE_MEMORY_MANAGER + return GetMemoryManager().GetTotalUnusedReservedMemory(); + #else + return 0; + #endif + } + ///*undocumented* + CUSTOM static uint GetTotalReservedMemory() + { + #if ENABLE_MEMORY_MANAGER + return GetMemoryManager().GetTotalReservedMemory(); + #else + return 0; + #endif + } + + //CUSTOM static void SharkBeginRemoteProfiling () + //{ + // #if ENABLE_SHARK_PROFILE + // SharkBeginRemoteProfiling(); + // #endif + //} + // + //CUSTOM static void SharkEndRemoteProfiling () + //{ + // #if ENABLE_SHARK_PROFILE + // SharkEndRemoteProfiling(); + // #endif + //} +END + +CSRAW } + +CSRAW +namespace UnityEngineInternal +{ + +using UnityEngine; + +//*undocumented* +// class for reproduction framework +CONDITIONAL ENABLE_MONO +CLASS Reproduction + + CUSTOM static void CaptureScreenshot () + { +#if SUPPORT_REPRODUCE_LOG + CaptureScreenshotReproduction(true); +#else + Scripting::RaiseMonoException("This method only works with internal development builds."); +#endif + } + +END + +CSRAW } diff --git a/Runtime/Export/CanConvertToFlash.cs b/Runtime/Export/CanConvertToFlash.cs new file mode 100644 index 0000000..7e1da8c --- /dev/null +++ b/Runtime/Export/CanConvertToFlash.cs @@ -0,0 +1,17 @@ +using System.Diagnostics; + +namespace UnityEngine +{ +[Conditional("UNITY_FLASH")] +internal class CanConvertToFlashAttribute : System.Attribute +{ + public CanConvertToFlashAttribute() {} + public CanConvertToFlashAttribute(params string[] members) {} +} +// ToDo: Move this to generic place +[Conditional("UNITY_FLASH"), Conditional("UNITY_WINRT")] +internal class MarshallOnlyFirstField : System.Attribute +{ +} + +} diff --git a/Runtime/Export/ClassLibraryInitializer.cs b/Runtime/Export/ClassLibraryInitializer.cs new file mode 100644 index 0000000..d561399 --- /dev/null +++ b/Runtime/Export/ClassLibraryInitializer.cs @@ -0,0 +1,17 @@ +namespace UnityEngine +{ + internal static class ClassLibraryInitializer + { + static void Init() + { +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + UnityLogWriter.Init(); +#endif + +#if UNITY_STANDALONE || (WEBPLUG && !UNITY_NACL) + if (Application.platform.ToString().Contains("WebPlayer")) + System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.DefaultSurrogateSelector = new UnityEngine.Serialization.UnitySurrogateSelector(); +#endif + } + } +}
\ No newline at end of file diff --git a/Runtime/Export/Coroutines.cs b/Runtime/Export/Coroutines.cs new file mode 100644 index 0000000..3333b40 --- /dev/null +++ b/Runtime/Export/Coroutines.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections; +using System.Reflection; + +namespace UnityEngine +{ +#if ENABLE_MONO || UNITY_WP8 +internal class SetupCoroutine +{ + static public object InvokeMember (object behaviour, string name, object variable) + { + object[] args = null; + if (variable != null) + { + args = new System.Object[1]; + args[0] = variable; + } + + return behaviour.GetType ().InvokeMember (name, BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public, null, behaviour, args, null, null, null); + } + + static public object InvokeStatic (Type klass, string name, object variable) + { + object[] args = null; + if (variable != null) + { + args = new System.Object[1]; + args[0] = variable; + } + + return klass.InvokeMember (name, BindingFlags.InvokeMethod | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public, null, null, args, null, null, null); + } + +} +#endif +} diff --git a/Runtime/Export/CppAttributes.cs b/Runtime/Export/CppAttributes.cs new file mode 100644 index 0000000..57c1e13 --- /dev/null +++ b/Runtime/Export/CppAttributes.cs @@ -0,0 +1,52 @@ +using System; + +namespace UnityEngine +{ + //TodoBC: make all these internal next time we do a breaking release + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)] + internal class CppIncludeAttribute : Attribute + { + public CppIncludeAttribute(string header) {} + } + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = true)] + internal class CppDefineAttribute : Attribute + { + public CppDefineAttribute(string symbol, string value) {} + } + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple = false)] + internal class CppBodyAttribute : Attribute + { + public CppBodyAttribute(string body) {} + } + + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + internal class CppInvokeAttribute : Attribute + { + } + + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] + internal class CppPropertyBodyAttribute : Attribute + { + public CppPropertyBodyAttribute(string getterBody, string setterBody) {} + public CppPropertyBodyAttribute(string getterBody) {} + } + + [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)] + internal class CppPropertyAttribute : Attribute + { + public CppPropertyAttribute(string getter, string setter) { } + public CppPropertyAttribute(string getter) { } + } + + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property, AllowMultiple = false)] + public class ThreadSafeAttribute : Attribute {} + + [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property, AllowMultiple = false)] + public class ConstructorSafeAttribute : Attribute {} + + [AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)] + internal class WritableAttribute: Attribute { } +} + diff --git a/Runtime/Export/CrashReporter.txt b/Runtime/Export/CrashReporter.txt new file mode 100644 index 0000000..2f689c9 --- /dev/null +++ b/Runtime/Export/CrashReporter.txt @@ -0,0 +1,150 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +CSRAW +using System; +using System.Collections.Generic; + +namespace UnityEngine +{ + +CLASS CrashReport + CSRAW static List<CrashReport> internalReports; + CSRAW static object reportsLock = new object(); + + CSRAW static int Compare(CrashReport c1, CrashReport c2) + { + long t1 = c1.time.Ticks; + long t2 = c2.time.Ticks; + if (t1 > t2) + return 1; + if (t1 < t2) + return -1; + return 0; + } + + CSRAW static void PopulateReports() + { + lock (reportsLock) + { + if (internalReports != null) + return; + + string[] ids = GetReports(); + internalReports = new List<CrashReport>(ids.Length); + foreach (var id in ids) + { + double secondsSinceUnixEpoch; + string text; + GetReportData(id, out secondsSinceUnixEpoch, out text); + DateTime time = new DateTime(1970, 1, 1).AddSeconds(secondsSinceUnixEpoch); + internalReports.Add(new CrashReport(id, time, text)); + } + internalReports.Sort(Compare); + } + } + + CSRAW public static CrashReport[] reports + { + get + { + PopulateReports(); + lock (reportsLock) + { + return internalReports.ToArray(); + } + } + } + + CSRAW public static CrashReport lastReport + { + get + { + PopulateReports(); + lock (reportsLock) + { + if (internalReports.Count > 0) + { + return internalReports[internalReports.Count - 1]; + } + } + + return null; + } + } + + CSRAW public static void RemoveAll() + { + foreach (var report in reports) + report.Remove(); + } + + CSRAW readonly string id; + CSRAW public readonly DateTime time; + CSRAW public readonly string text; + + CSRAW CrashReport(string id, DateTime time, string text) + { + this.id = id; + this.time = time; + this.text = text; + } + + CSRAW public void Remove() + { + if (RemoveReport(id)) + { + lock (reportsLock) + { + internalReports.Remove(this); + } + } + } + + THREAD_SAFE CUSTOM private static string[] GetReports() + { + if (!GetBuildSettings().hasAdvancedVersion) + { + ErrorString("Crash reports are only supported in Unity Pro."); + std::vector<std::string> reports; + return Scripting::StringVectorToMono(reports); + } + +#if UNITY_IPHONE + extern ScriptingArrayPtr GetCrashReports(); + return GetCrashReports(); +#else + std::vector<std::string> reports; + return Scripting::StringVectorToMono(reports); +#endif + } + + THREAD_SAFE CUSTOM private static void GetReportData(string id, out double secondsSinceUnixEpoch, out string text) + { +#if UNITY_IPHONE + extern void GetCrashReportData(ICallString id, double* secondsSinceUnixEpoch, ICallString* text); + GetCrashReportData(id, secondsSinceUnixEpoch, text); +#else + *secondsSinceUnixEpoch = 0.0; +#if !UNITY_WINRT && !UNITY_FLASH + text->str = scripting_string_new(""); +#endif +#endif + } + + THREAD_SAFE CUSTOM private static bool RemoveReport(string id) + { +#if UNITY_IPHONE + extern bool RemoveCrashReport(ICallString id); + return RemoveCrashReport(id); +#else + return false; +#endif + } +END + +CSRAW +} diff --git a/Runtime/Export/CursorBindings.txt b/Runtime/Export/CursorBindings.txt new file mode 100644 index 0000000..104bad4 --- /dev/null +++ b/Runtime/Export/CursorBindings.txt @@ -0,0 +1,44 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/BaseClasses/Cursor.h" + +using namespace std; + +CSRAW +using System; +using UnityEngine; +using Object=UnityEngine.Object; + +namespace UnityEngine +{ +// How should the custom cursor be rendered +ENUM CursorMode + // Use hardware cursors on supported platforms. + Auto = 0, + + // Force the use of software cursors. + ForceSoftware = 1, +END + +// Cursor API for setting the cursor that is used for rendering. +CLASS Cursor + + // Change the mouse cursor to the set texture OnMouseEnter. + + CSRAW static void SetCursor (Texture2D texture, CursorMode cursorMode) + { + SetCursor (texture, Vector2.zero, cursorMode); + } + + // + CUSTOM static void SetCursor (Texture2D texture, Vector2 hotspot, CursorMode cursorMode) + { + Cursors::SetCursor (texture, hotspot, cursorMode); + } +END + +CSRAW +} diff --git a/Runtime/Export/EventBindings.txt b/Runtime/Export/EventBindings.txt new file mode 100644 index 0000000..fe49b68 --- /dev/null +++ b/Runtime/Export/EventBindings.txt @@ -0,0 +1,1066 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/IMGUI/IMGUIUtils.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +/* + Mono defines a bool as either 1 or 2 bytes. + On windows a bool on the C++ side needs to be 2 bytes. + We use the typemap to map bool's to short's. + When using the C++ keyword and you want to export a bool value + to mono you have to use a short on the C++ side. +*/ + + +void PauseEditor (); +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +C++RAW + static void CleanupInputEvent(void* inputEvent){ delete (InputEvent*)inputEvent; }; + +// A UnityGUI event. +CSRAW [StructLayout (LayoutKind.Sequential)] +CLASS Event + +CSRAW + // *undocumented + public Event () { + Init (); + } + THREAD_SAFE + CUSTOM private void Init () { + InputEvent* newEvent = new InputEvent (); + self.SetPtr(newEvent,CleanupInputEvent); + newEvent->Init(); + } + + // Copy an event + CSRAW public Event (Event other) { + if (other == null) + throw new ArgumentException ("Event to copy from is null."); + InitCopy (other); + } + + // *undocumented + CSRAW private Event (IntPtr ptr) { + InitPtr (ptr); + } + + // *undocumented + CSRAW ~Event () { + Cleanup (); + } + THREAD_SAFE + CUSTOM private void Cleanup () { + CleanupInputEvent(self.GetPtr()); + } + + THREAD_SAFE + CUSTOM private void InitCopy (Event other) + { + self.SetPtr(new InputEvent (*other), CleanupInputEvent); + } + + THREAD_SAFE + CUSTOM private void InitPtr (IntPtr ptr) + { + self.SetPtr((InputEvent*)ptr, CleanupInputEvent); + } + + +CSRAW + [System.NonSerialized] [NotRenamed] + internal IntPtr m_Ptr; + + CUSTOM_PROP EventType rawType + { return self->type; } + + // The type of event. + CUSTOM_PROP EventType type + { return IMGUI::GetEventType (GetGUIState(), *self); } + { self->type = value; } + + CUSTOM EventType GetTypeForControl (int controlID) + { return IMGUI::GetEventTypeForControl (GetGUIState(), *self, controlID); } + + + /// Information about the current mouse or touch event, available during On*Event series of callbacks. + CONDITIONAL ENABLE_NEW_EVENT_SYSTEM + CUSTOM_PROP Touch touch { return self->touch; } + + // The mouse position. + CSRAW public Vector2 mousePosition { get { + Vector2 tmp; Internal_GetMousePosition(out tmp); return tmp; } + set { Internal_SetMousePosition (value); } + } + CUSTOM private void Internal_SetMousePosition (Vector2 value) + { +#if ENABLE_NEW_EVENT_SYSTEM + self->touch.pos = value; +#else + self->mousePosition = value; +#endif + } + CUSTOM private void Internal_GetMousePosition (out Vector2 value) + { +#if ENABLE_NEW_EVENT_SYSTEM + *value = self->touch.pos; +#else + *value = self->mousePosition; +#endif + } + + + // The relative movement of the mouse compared to last event. + CSRAW public Vector2 delta { get { + Vector2 tmp; Internal_GetMouseDelta(out tmp); return tmp; } + set { Internal_SetMouseDelta (value); } + } + CUSTOM private void Internal_SetMouseDelta (Vector2 value) + { +#if ENABLE_NEW_EVENT_SYSTEM + self->touch.deltaPos = value; +#else + self->delta = value; +#endif + } + CUSTOM private void Internal_GetMouseDelta (out Vector2 value) + { +#if ENABLE_NEW_EVENT_SYSTEM + *value = self->touch.deltaPos; +#else + *value = self->delta; +#endif + } + + OBSOLETE error Use HandleUtility.GUIPointToWorldRay(Event.current.mousePosition); + CSRAW public Ray mouseRay { get { return new Ray (Vector3.up, Vector3.up); } set { }} + + // Which mouse button was pressed. + CUSTOM_PROP int button + { return self->button; } + { self->button = value; } + + // Which modifier keys are held down. + CUSTOM_PROP EventModifiers modifiers + { return self->modifiers; } + { self->modifiers = value; } + + // *undocumented* + CUSTOM_PROP float pressure + { return self->pressure; } + { self->pressure = value; } + + // How many consecutive mouse clicks have we received. + // Detects consecutive clicks and prints them. + // + CUSTOM_PROP int clickCount + { return self->clickCount; } + { self->clickCount = value; } + + // The character typed. + // Detects characters pressed and prints them. + // + CUSTOM_PROP char character + { return self->character; } + { self->character = value; } + + // The name of an ExecuteCommand or ValidateCommand Event + CUSTOM_PROP string commandName + { + char* commandString = self->commandString; + return scripting_string_new(commandString == NULL ? "" : commandString); + } + { +#if ENABLE_MONO + char* oldPtr = reinterpret_cast<char*>(self->commandString); + delete[] oldPtr; + char *str = mono_string_to_utf8 (value.str); + self->commandString = new char[strlen (str) + 1]; + strcpy (self->commandString, str); +#endif + } + + // The raw key code for keyboard events. + CUSTOM_PROP KeyCode keyCode + { return self->keycode; } + { self->keycode = value; } + + // Is Shift held down? (RO) + CSRAW public bool shift { get { + return (modifiers & EventModifiers.Shift) != 0; } + set { if (!value) modifiers &= ~EventModifiers.Shift; else modifiers |= EventModifiers.Shift; } + } + + // Is Control key held down? (RO) + CSRAW public bool control { get { + return (modifiers & EventModifiers.Control) != 0; } + set { if (!value) modifiers &= ~EventModifiers.Control; else modifiers |= EventModifiers.Control; } + } + + // Is Alt/Option key held down? (RO) + CSRAW public bool alt { get { + return (modifiers & EventModifiers.Alt) != 0; } + set { if (!value) modifiers &= ~EventModifiers.Alt; else modifiers |= EventModifiers.Alt; } } + + + // Is Command/Windows key held down? (RO) + CSRAW public bool command { get { + return (modifiers & EventModifiers.Command) != 0; } + set { if (!value) modifiers &= ~EventModifiers.Command; else modifiers |= EventModifiers.Command; } + } + + // Is Caps Lock on? (RO) + CSRAW public bool capsLock { get { + return (modifiers & EventModifiers.CapsLock) != 0; } + set { if (!value) modifiers &= ~EventModifiers.CapsLock; else modifiers |= EventModifiers.CapsLock; } + } + + // Is the current keypress on the numeric keyboard? (RO) + CSRAW public bool numeric { get { + return (modifiers & EventModifiers.Numeric) != 0; } + set { if (!value) modifiers &= ~EventModifiers.Shift; else modifiers |= EventModifiers.Shift; } + } + + // Is the current keypress a function key? (RO) + CSRAW public bool functionKey { get { return (modifiers & EventModifiers.FunctionKey) != 0; } } + + // The current event that's being processed right now. + // TODO: set this to null outside the event loop. + // + CSRAW public static Event current { get { + // return null if Event.current is queried outside OnGUI + // Only in editor because of backwards compat. + #if UNITY_EDITOR + if (GUIUtility.Internal_GetGUIDepth () > 0) + return s_Current; + else + return null; + #else + return s_Current; + #endif + } + set + { + if (value != null) + s_Current = value; + else + s_Current = s_MasterEvent; + Internal_SetNativeEvent (s_Current.m_Ptr); + } + } + CSRAW static Event s_Current; + CSRAW static Event s_MasterEvent; + + CUSTOM static private void Internal_SetNativeEvent (IntPtr ptr) + { + GetGUIState().Internal_SetManagedEvent (ptr); + } + + CSRAW static private void Internal_MakeMasterEventCurrent () + { + if (s_MasterEvent == null) + s_MasterEvent = new Event (); + s_Current = s_MasterEvent; + Internal_SetNativeEvent (s_MasterEvent.m_Ptr); + } + + // Use this event. + CUSTOM void Use () { self->Use(); } + + // Is this event a keyboard event? (RO) + CSRAW public bool isKey { get { + EventType t = type; return t == EventType.KeyDown || t == EventType.KeyUp; } + } + + // Is this event a mouse event? (RO) + CSRAW public bool isMouse { get { + EventType t = type; return t == EventType.MouseMove || t == EventType.MouseDown || t == EventType.MouseUp || t == EventType.MouseDrag; } + } + + // Create a keyboard event. + CSRAW public static Event KeyboardEvent (string key) { + Event evt = new Event (); + evt.type = EventType.KeyDown; + // Can't use string.IsNullOrEmpty because it's not supported in NET 1.1 + if (key == null || key == String.Empty) + return evt; + int startIdx = 0; + bool found = false; + do { + found = true; + if (startIdx >= key.Length) + { found = false; break; } + switch (key[startIdx]) { + case '&': // Alt + evt.modifiers |= EventModifiers.Alt; startIdx++; + break; + case '^': // Ctrl + evt.modifiers |= EventModifiers.Control; startIdx++; + break; + case '%': + evt.modifiers |= EventModifiers.Command; startIdx++; + break; + case '#': + evt.modifiers |= EventModifiers.Shift; startIdx++; + break; + default: + found = false; + break; + } + } while (found); + string subStr = key.Substring (startIdx, key.Length - startIdx).ToLower(); + switch (subStr) { + case "[0]": evt.character = '0'; evt.keyCode = KeyCode.Keypad0; break; + case "[1]": evt.character = '1'; evt.keyCode = KeyCode.Keypad1; break; + case "[2]": evt.character = '2'; evt.keyCode = KeyCode.Keypad2; break; + case "[3]": evt.character = '3'; evt.keyCode = KeyCode.Keypad3; break; + case "[4]": evt.character = '4'; evt.keyCode = KeyCode.Keypad4; break; + case "[5]": evt.character = '5'; evt.keyCode = KeyCode.Keypad5; break; + case "[6]": evt.character = '6'; evt.keyCode = KeyCode.Keypad6; break; + case "[7]": evt.character = '7'; evt.keyCode = KeyCode.Keypad7; break; + case "[8]": evt.character = '8'; evt.keyCode = KeyCode.Keypad8; break; + case "[9]": evt.character = '9'; evt.keyCode = KeyCode.Keypad9; break; + case "[.]": evt.character = '.'; evt.keyCode = KeyCode.KeypadPeriod; break; + case "[/]": evt.character = '/'; evt.keyCode = KeyCode.KeypadDivide; break; + case "[-]": evt.character = '-'; evt.keyCode = KeyCode.KeypadMinus; break; + case "[+]": evt.character = '+'; evt.keyCode = KeyCode.KeypadPlus; break; + case "[=]": evt.character = '='; evt.keyCode = KeyCode.KeypadEquals; break; + case "[equals]": evt.character = '='; evt.keyCode = KeyCode.KeypadEquals; break; + case "[enter]": evt.character = '\n'; evt.keyCode = KeyCode.KeypadEnter; break; + case "up": /*evt.character = (char)63232; */evt.keyCode = KeyCode.UpArrow; evt.modifiers |= EventModifiers.FunctionKey; break; + case "down": /*evt.character = (char)63233; */evt.keyCode = KeyCode.DownArrow; evt.modifiers |= EventModifiers.FunctionKey; break; + case "left": /*evt.character = (char)63234; */evt.keyCode = KeyCode.LeftArrow; evt.modifiers |= EventModifiers.FunctionKey; break; + case "right": /*evt.character = (char)63235; */evt.keyCode = KeyCode.RightArrow; evt.modifiers |= EventModifiers.FunctionKey; break; + case "insert": evt.keyCode = KeyCode.Insert; evt.modifiers |= EventModifiers.FunctionKey; break; + case "home": /*evt.character = (char)63273; */evt.keyCode = KeyCode.Home; evt.modifiers |= EventModifiers.FunctionKey; break; + case "end": /*evt.character = (char)63275; */evt.keyCode = KeyCode.End; evt.modifiers |= EventModifiers.FunctionKey; break; + case "pgup": /*evt.character = (char)63276; */evt.keyCode = KeyCode.PageDown; evt.modifiers |= EventModifiers.FunctionKey; break; + case "page up": /*evt.character = (char)63276; */evt.keyCode = KeyCode.PageUp; evt.modifiers |= EventModifiers.FunctionKey; break; + case "pgdown": /*evt.character = (char)63277; */evt.keyCode = KeyCode.PageUp; evt.modifiers |= EventModifiers.FunctionKey; break; + case "page down": /*evt.character = (char)63277; */evt.keyCode = KeyCode.PageDown; evt.modifiers |= EventModifiers.FunctionKey; break; + case "backspace": /*evt.character = (char)127; */evt.keyCode = KeyCode.Backspace; evt.modifiers |= EventModifiers.FunctionKey; break; + case "delete": /*evt.character = (char)63272; */evt.keyCode = KeyCode.Delete; evt.modifiers |= EventModifiers.FunctionKey; break; + case "tab": /*evt.character = (char)9; */evt.keyCode = KeyCode.Tab; break; + case "f1": /*evt.character = (char)63236; */evt.keyCode = KeyCode.F1; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f2": /*evt.character = (char)63237; */evt.keyCode = KeyCode.F2; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f3": /*evt.character = (char)63238; */evt.keyCode = KeyCode.F3; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f4": /*evt.character = (char)63239; */evt.keyCode = KeyCode.F4; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f5": /*evt.character = (char)63240; */evt.keyCode = KeyCode.F5; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f6": /*evt.character = (char)63241; */evt.keyCode = KeyCode.F6; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f7": /*evt.character = (char)63242; */evt.keyCode = KeyCode.F7; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f8": /*evt.character = (char)63243; */evt.keyCode = KeyCode.F8; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f9": /*evt.character = (char)63244; */evt.keyCode = KeyCode.F9; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f10": /*evt.character = (char)63245; */evt.keyCode = KeyCode.F10; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f11": /*evt.character = (char)63246; */evt.keyCode = KeyCode.F11; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f12": /*evt.character = (char)63247; */evt.keyCode = KeyCode.F12; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f13": /*evt.character = (char)63248; */evt.keyCode = KeyCode.F13; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f14": /*evt.character = (char)63249; */evt.keyCode = KeyCode.F14; evt.modifiers |= EventModifiers.FunctionKey; break; + case "f15": /*evt.character = (char)63250; */evt.keyCode = KeyCode.F15; evt.modifiers |= EventModifiers.FunctionKey; break; + case "[esc]": evt.keyCode = KeyCode.Escape; break; + case "return": evt.character = '\n'; evt.keyCode = KeyCode.Return; evt.modifiers &= ~EventModifiers.FunctionKey; break; + case "space": evt.keyCode = KeyCode.Space; evt.character = ' '; evt.modifiers &= ~EventModifiers.FunctionKey; break; + default: + if (subStr.Length != 1) + { + // soren: try this first + try { + evt.keyCode = (KeyCode)Enum.Parse(typeof(KeyCode), subStr, true); + } + catch (ArgumentException) + { + Debug.LogError (UnityString.Format ("Unable to find key name that matches '{0}'", subStr)); + } + } + else + { + evt.character = subStr.ToLower()[0]; + evt.keyCode = (KeyCode)evt.character; + if ((int)evt.modifiers != 0) + evt.character = (char)0; + } + break; + } + return evt; + } + + // Calculate the hash code + CSRAW public override int GetHashCode( ) { + int hc = 1; + if (isKey) + hc = (ushort)keyCode; + if (isMouse) + hc = mousePosition.GetHashCode (); + hc = hc*37 | (int)modifiers; +// Debug.Log (hc + " GetHashCode of " + ToString()); + return hc; + } + + + CSRAW public override bool Equals (object obj) { + if (obj == null) + return false; + if (Object.ReferenceEquals (this, obj)) + return true; + if (obj.GetType () != GetType()) + return false; + + + Event rhs = (Event)obj; + if (type != rhs.type || modifiers != rhs.modifiers) + return false; + if (isKey) + return keyCode == rhs.keyCode && modifiers == rhs.modifiers; + if (isMouse) + return mousePosition == rhs.mousePosition; + return false; + } + + + + CSRAW public override string ToString( ) + { + if (isKey) { + if ((int)character == 0) + return UnityString.Format ("Event:{0} Character:\\0 Modifiers:{1} KeyCode:{2}", type, modifiers, keyCode); + else { + return UnityString.Format ("Event:" +type + " Character:" + (int)(character) + " Modifiers:" + modifiers + " KeyCode:" + keyCode); + } + } + if (isMouse) + return UnityString.Format ("Event: {0} Position: {1} Modifiers: {2}", type, mousePosition, modifiers); + + if (type == EventType.ExecuteCommand || type == EventType.ValidateCommand) + return UnityString.Format ("Event: {0} \"{1}\"", type, commandName); + + return "" + type; + } +C++RAW + + +END + + +// Key codes returned by Event.keyCode. These map directly to a physical key on the keyboard. +ENUM KeyCode + // Not assigned (never returned as the result of a keystroke) + None = 0, + // The backspace key + Backspace = 8, + // The forward delete key + Delete = 127, + // The tab key + Tab = 9, + // The Clear key + Clear = 12, + // Return key + Return = 13, + // Pause on PC machines + Pause = 19, + // Escape key + Escape = 27, + // Space key + Space = 32, + + // Numeric keypad 0 + Keypad0 = 256, + // Numeric keypad 1 + Keypad1 = 257, + // Numeric keypad 2 + Keypad2 = 258, + // Numeric keypad 3 + Keypad3 = 259, + // Numeric keypad 4 + Keypad4 = 260, + // Numeric keypad 5 + Keypad5 = 261, + // Numeric keypad 6 + Keypad6 = 262, + // Numeric keypad 7 + Keypad7 = 263, + // Numeric keypad 8 + Keypad8 = 264, + // Numeric keypad 9 + Keypad9 = 265, + // Numeric keypad '.' + KeypadPeriod = 266, + // Numeric keypad '/' + KeypadDivide = 267, + // Numeric keypad '*' + KeypadMultiply = 268, + // Numeric keypad '-' + KeypadMinus = 269, + // Numeric keypad '+' + KeypadPlus = 270, + // Numeric keypad enter + KeypadEnter = 271, + // Numeric keypad '=' + KeypadEquals = 272, + + // Up arrow key + UpArrow = 273, + // Down arrow key + DownArrow = 274, + // Right arrow key + RightArrow = 275, + // Left arrow key + LeftArrow = 276, + // Insert key key + Insert = 277, + // Home key + Home = 278, + // End key + End = 279, + // Page up + PageUp = 280, + // Page down + PageDown = 281, + + // F1 function key + F1 = 282, + // F2 function key + F2 = 283, + // F3 function key + F3 = 284, + // F4 function key + F4 = 285, + // F5 function key + F5 = 286, + // F6 function key + F6 = 287, + // F7 function key + F7 = 288, + // F8 function key + F8 = 289, + // F9 function key + F9 = 290, + // F10 function key + F10 = 291, + // F11 function key + F11 = 292, + // F12 function key + F12 = 293, + // F13 function key + F13 = 294, + // F14 function key + F14 = 295, + // F15 function key + F15 = 296, + + // The '0' key on the top of the alphanumeric keyboard. + Alpha0 = 48, + // The '1' key on the top of the alphanumeric keyboard. + Alpha1 = 49, + // The '2' key on the top of the alphanumeric keyboard. + Alpha2 = 50, + // The '3' key on the top of the alphanumeric keyboard. + Alpha3 = 51, + // The '4' key on the top of the alphanumeric keyboard. + Alpha4 = 52, + // The '5' key on the top of the alphanumeric keyboard. + Alpha5 = 53, + // The '6' key on the top of the alphanumeric keyboard. + Alpha6 = 54, + // The '7' key on the top of the alphanumeric keyboard. + Alpha7 = 55, + // The '8' key on the top of the alphanumeric keyboard. + Alpha8 = 56, + // The '9' key on the top of the alphanumeric keyboard. + Alpha9 = 57, + + // Exclamation mark key '!' + Exclaim = 33, + // Double quote key '"' + DoubleQuote = 34, + // Hash key '#' + Hash = 35, + // Dollar sign key '$' + Dollar = 36, + // Ampersand key '&' + Ampersand = 38, + // Quote key ' + Quote = 39, + // Left Parenthesis key '(' + LeftParen = 40, + // Right Parenthesis key ')' + RightParen = 41, + // Asterisk key '*' + Asterisk = 42, + // Plus key '+' + Plus = 43, + // Comma ',' key + Comma = 44, + + // Minus '-' key + Minus = 45, + // Period '.' key + Period = 46, + // Slash '/' key + Slash = 47, + + // Colon ':' key + Colon = 58, + // Semicolon ';' key + Semicolon = 59, + // Less than '<' key + Less = 60, + // Equals '=' key + Equals = 61, + // Greater than '>' key + Greater = 62, + // Question mark '?' key + Question = 63, + // At key '@' + At = 64, + + // Left square bracket key '[' + LeftBracket = 91, + // Backslash key '\' + Backslash = 92, + // Right square bracket key ']' + RightBracket = 93, + // Caret key '^' + Caret = 94, + // Underscore '_' key + Underscore = 95, + // Back quote key '`' + BackQuote = 96, + + // 'a' key + A = 97, + // 'b' key + B = 98, + // 'c' key + C = 99, + // 'd' key + D = 100, + // 'e' key + E = 101, + // 'f' key + F = 102, + // 'g' key + G = 103, + // 'h' key + H = 104, + // 'i' key + I = 105, + // 'j' key + J = 106, + // 'k' key + K = 107, + // 'l' key + L = 108, + // 'm' key + M = 109, + // 'n' key + N = 110, + // 'o' key + O = 111, + // 'p' key + P = 112, + // 'q' key + Q = 113, + // 'r' key + R = 114, + // 's' key + S = 115, + // 't' key + T = 116, + // 'u' key + U = 117, + // 'v' key + V = 118, + // 'w' key + W = 119, + // 'x' key + X = 120, + // 'y' key + Y = 121, + // 'z' key + Z = 122, + + // Numlock key + Numlock = 300, + // Capslock key + CapsLock = 301, + // Scroll lock key + ScrollLock = 302, + // Right shift key + RightShift = 303, + // Left shift key + LeftShift = 304, + // Right Control key + RightControl = 305, + // Left Control key + LeftControl = 306, + // Right Alt key + RightAlt = 307, + // Left Alt key + LeftAlt = 308, + + // Left Command key + LeftCommand = 310, + // Left Command key + LeftApple = 310, + // Left Windows key + LeftWindows = 311, + // Right Command key + RightCommand = 309, + // Right Command key + RightApple = 309, + // Right Windows key + RightWindows = 312, + // Alt Gr key + AltGr = 313, + + // Help key + Help = 315, + // Print key + Print = 316, + // Sys Req key + SysReq = 317, + // Break key + Break = 318, + // Menu key + Menu = 319, + + // First (primary) mouse button + Mouse0 = 323, + // Second (secondary) mouse button + Mouse1 = 324, + // Third mouse button + Mouse2 = 325, + // Fourth mouse button + Mouse3 = 326, + // Fifth mouse button + Mouse4 = 327, + // Sixth mouse button + Mouse5 = 328, + // Seventh mouse button + Mouse6 = 329, + + // Button 0 on any joystick + JoystickButton0 = 330, + // Button 1 on any joystick + JoystickButton1 = 331, + // Button 2 on any joystick + JoystickButton2 = 332, + // Button 3 on any joystick + JoystickButton3 = 333, + // Button 4 on any joystick + JoystickButton4 = 334, + // Button 5 on any joystick + JoystickButton5 = 335, + // Button 6 on any joystick + JoystickButton6 = 336, + // Button 7 on any joystick + JoystickButton7 = 337, + // Button 8 on any joystick + JoystickButton8 = 338, + // Button 9 on any joystick + JoystickButton9 = 339, + // Button 10 on any joystick + JoystickButton10 = 340, + // Button 11 on any joystick + JoystickButton11 = 341, + // Button 12 on any joystick + JoystickButton12 = 342, + // Button 13 on any joystick + JoystickButton13 = 343, + // Button 14 on any joystick + JoystickButton14 = 344, + // Button 15 on any joystick + JoystickButton15 = 345, + // Button 16 on any joystick + JoystickButton16 = 346, + // Button 17 on any joystick + JoystickButton17 = 347, + // Button 18 on any joystick + JoystickButton18 = 348, + // Button 19 on any joystick + JoystickButton19 = 349, + + // Button 0 on first joystick + Joystick1Button0 = 350, + // Button 1 on first joystick + Joystick1Button1 = 351, + // Button 2 on first joystick + Joystick1Button2 = 352, + // Button 3 on first joystick + Joystick1Button3 = 353, + // Button 4 on first joystick + Joystick1Button4 = 354, + // Button 5 on first joystick + Joystick1Button5 = 355, + // Button 6 on first joystick + Joystick1Button6 = 356, + // Button 7 on first joystick + Joystick1Button7 = 357, + // Button 8 on first joystick + Joystick1Button8 = 358, + // Button 9 on first joystick + Joystick1Button9 = 359, + // Button 10 on first joystick + Joystick1Button10 = 360, + // Button 11 on first joystick + Joystick1Button11 = 361, + // Button 12 on first joystick + Joystick1Button12 = 362, + // Button 13 on first joystick + Joystick1Button13 = 363, + // Button 14 on first joystick + Joystick1Button14 = 364, + // Button 15 on first joystick + Joystick1Button15 = 365, + // Button 16 on first joystick + Joystick1Button16 = 366, + // Button 17 on first joystick + Joystick1Button17 = 367, + // Button 18 on first joystick + Joystick1Button18 = 368, + // Button 19 on first joystick + Joystick1Button19 = 369, + + // Button 0 on second joystick + Joystick2Button0 = 370, + // Button 1 on second joystick + Joystick2Button1 = 371, + // Button 2 on second joystick + Joystick2Button2 = 372, + // Button 3 on second joystick + Joystick2Button3 = 373, + // Button 4 on second joystick + Joystick2Button4 = 374, + // Button 5 on second joystick + Joystick2Button5 = 375, + // Button 6 on second joystick + Joystick2Button6 = 376, + // Button 7 on second joystick + Joystick2Button7 = 377, + // Button 8 on second joystick + Joystick2Button8 = 378, + // Button 9 on second joystick + Joystick2Button9 = 379, + // Button 10 on second joystick + Joystick2Button10 = 380, + // Button 11 on second joystick + Joystick2Button11 = 381, + // Button 12 on second joystick + Joystick2Button12 = 382, + // Button 13 on second joystick + Joystick2Button13 = 383, + // Button 14 on second joystick + Joystick2Button14 = 384, + // Button 15 on second joystick + Joystick2Button15 = 385, + // Button 16 on second joystick + Joystick2Button16 = 386, + // Button 17 on second joystick + Joystick2Button17 = 387, + // Button 18 on second joystick + Joystick2Button18 = 388, + // Button 19 on second joystick + Joystick2Button19 = 389, + + // Button 0 on third joystick + Joystick3Button0 = 390, + // Button 1 on third joystick + Joystick3Button1 = 391, + // Button 2 on third joystick + Joystick3Button2 = 392, + // Button 3 on third joystick + Joystick3Button3 = 393, + // Button 4 on third joystick + Joystick3Button4 = 394, + // Button 5 on third joystick + Joystick3Button5 = 395, + // Button 6 on third joystick + Joystick3Button6 = 396, + // Button 7 on third joystick + Joystick3Button7 = 397, + // Button 8 on third joystick + Joystick3Button8 = 398, + // Button 9 on third joystick + Joystick3Button9 = 399, + // Button 10 on third joystick + Joystick3Button10 = 400, + // Button 11 on third joystick + Joystick3Button11 = 401, + // Button 12 on third joystick + Joystick3Button12 = 402, + // Button 13 on third joystick + Joystick3Button13 = 403, + // Button 14 on third joystick + Joystick3Button14 = 404, + // Button 15 on third joystick + Joystick3Button15 = 405, + // Button 16 on third joystick + Joystick3Button16 = 406, + // Button 17 on third joystick + Joystick3Button17 = 407, + // Button 18 on third joystick + Joystick3Button18 = 408, + // Button 19 on third joystick + Joystick3Button19 = 409, + + // Button 0 on forth joystick + Joystick4Button0 = 410, + // Button 1 on forth joystick + Joystick4Button1 = 411, + // Button 2 on forth joystick + Joystick4Button2 = 412, + // Button 3 on forth joystick + Joystick4Button3 = 413, + // Button 4 on forth joystick + Joystick4Button4 = 414, + // Button 5 on forth joystick + Joystick4Button5 = 415, + // Button 6 on forth joystick + Joystick4Button6 = 416, + // Button 7 on forth joystick + Joystick4Button7 = 417, + // Button 8 on forth joystick + Joystick4Button8 = 418, + // Button 9 on forth joystick + Joystick4Button9 = 419, + // Button 10 on forth joystick + Joystick4Button10 = 420, + // Button 11 on forth joystick + Joystick4Button11 = 421, + // Button 12 on forth joystick + Joystick4Button12 = 422, + // Button 13 on forth joystick + Joystick4Button13 = 423, + // Button 14 on forth joystick + Joystick4Button14 = 424, + // Button 15 on forth joystick + Joystick4Button15 = 425, + // Button 16 on forth joystick + Joystick4Button16 = 426, + // Button 17 on forth joystick + Joystick4Button17 = 427, + // Button 18 on forth joystick + Joystick4Button18 = 428, + // Button 19 on forth joystick + Joystick4Button19 = 429, + + // We could expose all 10 joysticks here, but I think that a user would rarely want to explicitly + // specify a fifth or higher joystick (and they still can using the string version of Input.KeyDown). + // Four joysticks, however, are a common setup (especially on consoles), and we've had a bug report + // for only exposing three, so I added a forth. +END + + + +// Types of UnityGUI input and processing events. +ENUM EventType + // Mouse button was pressed. + MouseDown = 0, + // Mouse button was released. + MouseUp = 1, + // Mouse was moved (editor views only). + MouseMove = 2, + // Mouse was dragged. + MouseDrag = 3, + // A keyboard key was pressed. + KeyDown = 4, + // A keyboard key was released. + KeyUp = 5, + // The scroll wheel was moved. + ScrollWheel = 6, + // A repaint event. One is sent every frame. + Repaint = 7, + // A layout event. + Layout = 8, + + // Editor only: drag & drop operation updated. + DragUpdated = 9, + // Editor only: drag & drop operation performed. + DragPerform = 10, + // Editor only: drag & drop operation exited. + DragExited = 15, + + // [[Event]] should be ignored. + Ignore = 11, + + // Already processed event. + Used = 12, + + // Validates a special command (e.g. copy & paste) + ValidateCommand = 13, + + // Execute a special command (eg. copy & paste) + ExecuteCommand = 14, + + // User has right-clicked (or control-clicked on the mac). + ContextClick = 16, + + OBSOLETE planned Please use EventType.MouseDown (with a capital M) + mouseDown = 0, + OBSOLETE planned Please use EventType.MouseUp (with a capital M) + mouseUp = 1, + OBSOLETE planned Please use EventType.MouseMove (with a capital M) + mouseMove = 2, + OBSOLETE planned Please use EventType.MouseDrag (with a capital M) + mouseDrag = 3, + OBSOLETE planned Please use EventType.KeyDown (with a capital K) + keyDown = 4, + OBSOLETE planned Please use EventType.KeyUp (with a capital K) + keyUp = 5, + OBSOLETE planned Please use EventType.ScrollWheel (with a capital S) + scrollWheel = 6, + OBSOLETE planned Please use EventType.Repaint (with a capital R) + repaint = 7, + OBSOLETE planned Please use EventType.Layout (with a capital L) + layout = 8, + + OBSOLETE planned Please use EventType.DragUpdated (with a capital D) + dragUpdated = 9, + OBSOLETE planned Please use EventType.DragPerform (with a capital D) + dragPerform = 10, + + OBSOLETE planned Please use EventType.Ignore (with a capital I) + ignore = 11, + + OBSOLETE planned Please use EventType.Used (with a capital U) + used = 12 +END + +// Types of modifier key that can be active during a keystroke event. +CSRAW [Flags] +ENUM EventModifiers + // Shift key + Shift = 1, + + // Control key + Control = 2, + + // Alt key + Alt = 4, + + // Command key (Mac) + Command = 8, + + // Num lock key + Numeric = 16, + + // Caps lock key + CapsLock = 32, + + // Function key + FunctionKey = 64 +END + + +CSRAW } diff --git a/Runtime/Export/FlashHelper.cs b/Runtime/Export/FlashHelper.cs new file mode 100644 index 0000000..5edd077 --- /dev/null +++ b/Runtime/Export/FlashHelper.cs @@ -0,0 +1,32 @@ +using System; +using System.Reflection; + +namespace UnityEngine +{ +#if UNITY_FLASH + [NotRenamed] + internal static class ScriptingMethodHelper + { + [NotRenamed] + internal static MethodInfo GetMethodInfo(Type type, string methodName) + { + return type.GetMethod(methodName); + } + + [NotRenamed] + internal static int NumberOfArgumentsOf(MethodInfo methodInfo) + { + return methodInfo.GetParameters().Length; + } + + [NotRenamed] + internal static Type NthArgumentType(MethodInfo methodInfo, int index) + { + var args = methodInfo.GetParameters(); + if (args.Length <= index) + return null; + return args[index].ParameterType; + } + } +#endif +} diff --git a/Runtime/Export/GUI.txt b/Runtime/Export/GUI.txt new file mode 100644 index 0000000..bda95db --- /dev/null +++ b/Runtime/Export/GUI.txt @@ -0,0 +1,1723 @@ +C++RAW + +#include "UnityPrefix.h" + +#include "External/shaderlab/Library/FastPropertyName.h" +#include "External/shaderlab/Library/properties.h" + +#include "Runtime/IMGUI/GUIState.h" +#include "Runtime/IMGUI/IDList.h" +#include "Runtime/IMGUI/GUIContent.h" +#include "Runtime/IMGUI/GUILabel.h" +#include "Runtime/IMGUI/GUIToggle.h" +#include "Runtime/IMGUI/GUIButton.h" +#include "Runtime/IMGUI/GUIWindows.h" +#include "Runtime/IMGUI/IMGUIUtils.h" +#include "Runtime/IMGUI/GUIManager.h" +#include "Runtime/IMGUI/GUIStyle.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" +#include "Runtime/Shaders/Material.h" + +#if UNITY_EDITOR +# include "Editor/Platform/Interface/EditorWindows.h" +#endif + +using namespace Unity; +using namespace std; + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEngine +{ + +// Scaling mode to draw textures with +ENUM ScaleMode + // Stretches the texture to fill the complete rectangle passed in to GUI.DrawTexture + StretchToFill = 0, + // Scales the texture, maintaining aspect ratio, so it completely covers the /position/ rectangle passed to GUI.DrawTexture. If the texture is being draw to a rectangle with a different aspect ratio than the original, the image is cropped. + ScaleAndCrop = 1, + // Scales the texture, maintaining aspect ratio, so it completely fits withing the /position/ rectangle passed to GUI.DrawTexture. + ScaleToFit = 2 +END + +// The GUI class is the interface for Unity's GUI with manual positioning. +NONSEALED_CLASS GUI + CSRAW + static float scrollStepSize = 10f; + internal static DateTime nextScrollStepTime { get; set; } + static int scrollControlID; + internal static int scrollTroughSide { get; set; } + + #if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + static int hotTextField = -1; + #endif + + // *undocumented* + CSRAW static GUI() + { + nextScrollStepTime = DateTime.Now; // whatever but null + } + + CSRAW static UnityEngine.GUISkin s_Skin; + + // The global skin to use. + CSRAW public static GUISkin skin { + set { + GUIUtility.CheckOnGUI(); + if (!value) + value = GUIUtility.GetDefaultSkin (); + s_Skin = value; + value.MakeCurrent (); + } + get { GUIUtility.CheckOnGUI(); return s_Skin; } + } + +// COLORS + // Global tinting color for the GUI. + CUSTOM_PROP static Color color + { return IMGUI::GetColor (GetGUIState()); } + { IMGUI::SetColor (GetGUIState(), value); } + + // Global tinting color for all background elements rendered by the GUI. + CUSTOM_PROP static Color backgroundColor + { return IMGUI::GetBackgroundColor (GetGUIState()); } + { IMGUI::SetBackgroundColor (GetGUIState(), value); } + + // Tinting color for all text rendered by the GUI. + CUSTOM_PROP static Color contentColor + { return IMGUI::GetContentColor (GetGUIState()); } + { IMGUI::SetContentColor (GetGUIState(), value); } + + // Returns true if any controls changed the value of the input data. + CUSTOM_PROP static bool changed + { return IMGUI::GetChanged (GetGUIState()); } + { IMGUI::SetChanged (GetGUIState(), value); } + +// ENABLED + // Is the GUI enabled? + CUSTOM_PROP static bool enabled + { return IMGUI::GetEnabled (GetGUIState()); } + { IMGUI::SetEnabled (GetGUIState(), value); } + +// MATRIX + // The GUI transform matrix. + CSRAW public static Matrix4x4 matrix { + get { return GUIClip.GetMatrix (); } + set { GUIClip.SetMatrix (value); } + } + + + // The tooltip of the control the mouse is currently over, or which has keyboard focus. (RO). + CSRAW public static string tooltip { + get { + string str = Internal_GetTooltip (); + if (str != null) + return str; + return ""; + } + set { Internal_SetTooltip (value); } + } + CUSTOM private static string Internal_GetTooltip () + { + GUIState &cState = GetGUIState(); + UTF16String *mouseTooltip = cState.m_OnGUIState.m_MouseTooltip; + UTF16String *keyTooltip = cState.m_OnGUIState.m_KeyTooltip; + UTF16String *tooltip = NULL; + if (mouseTooltip) + { + tooltip = mouseTooltip; + } + else if (keyTooltip) + { + tooltip = keyTooltip; + } + if (tooltip) + return tooltip->GetScriptingString (); + return SCRIPTING_NULL; + } + + CUSTOM private static void Internal_SetTooltip (string value) + { +#if ENABLE_MONO + UTF16String str (value.AsUTF8().c_str()); + GUIState &cState = GetGUIState(); + cState.m_OnGUIState.SetMouseTooltip (str); + cState.m_OnGUIState.SetKeyTooltip (str); +#endif + } + + // *undocumented* + CSRAW static protected string mouseTooltip { get { return Internal_GetMouseTooltip (); } } + CUSTOM private static string Internal_GetMouseTooltip () + { + GUIState &cState = GetGUIState(); + UTF16String *mouseTooltip = cState.m_OnGUIState.m_MouseTooltip; + return mouseTooltip ? mouseTooltip->GetScriptingString () : SCRIPTING_NULL; + } + + // *undocumented* + CSRAW protected static Rect tooltipRect { get { return s_ToolTipRect; } set { s_ToolTipRect = value; } } + CSRAW static internal Rect s_ToolTipRect; + + + + // The sorting depth of the currently executing GUI behaviour. + CUSTOM_PROP static int depth + { return IMGUI::GetDepth (GetGUIState()); } + { IMGUI::SetDepth (GetGUIState(), value); } + + + /// *listonly* + CSRAW public static void Label (Rect position, string text) { Label (position, GUIContent.Temp (text), s_Skin.label); } + /// *listonly* + CSRAW public static void Label (Rect position, Texture image) { Label (position, GUIContent.Temp (image), s_Skin.label); } + /// *listonly* + CSRAW public static void Label (Rect position, GUIContent content) { Label (position, content, s_Skin.label); } + /// *listonly* + CSRAW public static void Label (Rect position, string text, GUIStyle style) { Label (position, GUIContent.Temp (text), style); } + /// *listonly* + CSRAW public static void Label (Rect position, Texture image, GUIStyle style) { Label (position, GUIContent.Temp (image), style); } + + // Make a text or texture label on screen. + public static void Label (Rect position, GUIContent content, GUIStyle style) { + DoLabel (position, content, style.m_Ptr); + } + + CUSTOM private static void DoLabel (Rect position, GUIContent content, IntPtr style) + { + IMGUI::GUILabel ( + GetGUIState(), + position, + MonoGUIContentToTempNative (content), + *reinterpret_cast<GUIStyle*>(style) + ); + } + + + CUSTOM private static void InitializeGUIClipTexture () { InitializeGUIClipTexture(); } + + // Draw a texture within a rectangle. + CSRAW public static void DrawTexture (Rect position, Texture image, ScaleMode scaleMode = ScaleMode.StretchToFill, bool alphaBlend = true, float imageAspect = 0) { + if (Event.current.type == EventType.Repaint) { + if (image == null) { + Debug.LogWarning("null texture passed to GUI.DrawTexture"); + return; + } + + if (imageAspect == 0) + imageAspect = (float)image.width / image.height; + + Material mat = alphaBlend ? blendMaterial : blitMaterial; + float destAspect = position.width / position.height; + + InternalDrawTextureArguments arguments = new InternalDrawTextureArguments (); + #if UNITY_WINRT + arguments.textureInstanceId = image.GetInstanceID(); + #else + arguments.texture = image; + #endif + arguments.leftBorder = 0; + arguments.rightBorder = 0; + arguments.topBorder = 0; + arguments.bottomBorder = 0; + arguments.color = GUI.color; + #if UNITY_WINRT + arguments.matInstanceId = mat.GetInstanceID(); + #else + arguments.mat = mat; + #endif + + switch (scaleMode) { + case ScaleMode.StretchToFill: + arguments.screenRect = position; + arguments.sourceRect = new Rect (0,0,1,1); + Graphics.DrawTexture (ref arguments); + break; + case ScaleMode.ScaleAndCrop: + if (destAspect > imageAspect) { + float stretch = imageAspect / destAspect; + arguments.screenRect = position; + arguments.sourceRect = new Rect (0, (1 - stretch) * .5f, 1, stretch); + Graphics.DrawTexture (ref arguments); + } else { + float stretch = destAspect / imageAspect; + arguments.screenRect = position; + arguments.sourceRect = new Rect (.5f - stretch * .5f, 0, stretch, 1); + Graphics.DrawTexture (ref arguments); + } break; + case ScaleMode.ScaleToFit: + if (destAspect > imageAspect) { + float stretch = imageAspect / destAspect; + arguments.screenRect = new Rect (position.xMin + position.width * (1.0f - stretch) * .5f, position.yMin, stretch * position.width, position.height); + arguments.sourceRect = new Rect (0, 0, 1, 1); + Graphics.DrawTexture (ref arguments); + } else { + float stretch = destAspect / imageAspect; + arguments.screenRect = new Rect (position.xMin, position.yMin + position.height * (1.0f - stretch) * .5f, position.width, stretch * position.height); + arguments.sourceRect = new Rect (0, 0, 1, 1); + Graphics.DrawTexture (ref arguments); + } break; + } + } + } + + // Calculate screenrect and sourcerect for different scalemodes + CSRAW internal static bool CalculateScaledTextureRects(Rect position, ScaleMode scaleMode, float imageAspect, ref Rect outScreenRect, ref Rect outSourceRect) + { + float destAspect = position.width / position.height; + bool ret = false; + + switch (scaleMode) + { + case ScaleMode.StretchToFill: + outScreenRect = position; + outSourceRect = new Rect (0,0,1,1); + ret = true; + break; + case ScaleMode.ScaleAndCrop: + if (destAspect > imageAspect) { + float stretch = imageAspect / destAspect; + outScreenRect = position; + outSourceRect = new Rect (0, (1 - stretch) * .5f, 1, stretch); + ret = true; + } else { + float stretch = destAspect / imageAspect; + outScreenRect = position; + outSourceRect = new Rect (.5f - stretch * .5f, 0, stretch, 1); + ret = true; + } break; + case ScaleMode.ScaleToFit: + if (destAspect > imageAspect) { + float stretch = imageAspect / destAspect; + outScreenRect = new Rect (position.xMin + position.width * (1.0f - stretch) * .5f, position.yMin, stretch * position.width, position.height); + outSourceRect = new Rect (0, 0, 1, 1); + ret = true; + } else { + float stretch = destAspect / imageAspect; + outScreenRect = new Rect (position.xMin, position.yMin + position.height * (1.0f - stretch) * .5f, position.width, stretch * position.height); + outSourceRect = new Rect (0, 0, 1, 1); + ret = true; + } break; + } + + return ret; + } + + // Draw a texture within a rectangle with the given texture coordinates. Use this function for clipping or tiling the image within the given rectangle. + CSRAW public static void DrawTextureWithTexCoords (Rect position, Texture image, Rect texCoords, bool alphaBlend = true) + { + if (Event.current.type == EventType.Repaint) { + + Material mat = alphaBlend ? blendMaterial : blitMaterial; + + InternalDrawTextureArguments arguments = new InternalDrawTextureArguments (); + #if UNITY_WINRT + arguments.textureInstanceId = image.GetInstanceID(); + #else + arguments.texture = image; + #endif + arguments.leftBorder = 0; + arguments.rightBorder = 0; + arguments.topBorder = 0; + arguments.bottomBorder = 0; + arguments.color = GUI.color; + #if UNITY_WINRT + arguments.matInstanceId = mat.GetInstanceID(); + #else + arguments.mat = mat; + #endif + arguments.screenRect = position; + arguments.sourceRect = texCoords; + Graphics.DrawTexture (ref arguments); + } + } + + CUSTOM_PROP static private Material blendMaterial + { + return Scripting::ScriptingWrapperFor(GetGUIBlendMaterial()); + } + + CUSTOM_PROP static private Material blitMaterial + { + return Scripting::ScriptingWrapperFor(GetGUIBlitMaterial()); + } + + /// *listonly* + CSRAW public static void Box (Rect position, string text) { Box (position, GUIContent.Temp (text), s_Skin.box); } + /// *listonly* + CSRAW public static void Box (Rect position, Texture image) { Box (position, GUIContent.Temp (image), s_Skin.box); } + /// *listonly* + CSRAW public static void Box (Rect position, GUIContent content) { Box (position, content, s_Skin.box); } + /// *listonly* + CSRAW public static void Box (Rect position, string text, GUIStyle style) { Box (position, GUIContent.Temp (text), style); } + /// *listonly* + CSRAW public static void Box (Rect position, Texture image, GUIStyle style) { Box (position, GUIContent.Temp (image), style); } + + // Make a graphical box. + public static void Box (Rect position, GUIContent content, GUIStyle style) { + GUIUtility.CheckOnGUI (); + int id = GUIUtility.GetControlID (boxHash, FocusType.Passive); + if (Event.current.type == EventType.Repaint) { + style.Draw (position, content, id); + } + } + static int boxHash = "Box".GetHashCode (); + + /// *listonly* + CSRAW public static bool Button (Rect position, string text) { return DoButton (position, GUIContent.Temp (text), s_Skin.button.m_Ptr); } + /// *listonly* + CSRAW public static bool Button (Rect position, Texture image) { return DoButton (position, GUIContent.Temp (image), s_Skin.button.m_Ptr); } + /// *listonly* + CSRAW public static bool Button (Rect position, GUIContent content) { return DoButton (position, content, s_Skin.button.m_Ptr); } + /// *listonly* + CSRAW public static bool Button (Rect position, string text, GUIStyle style) { return DoButton (position, GUIContent.Temp (text), style.m_Ptr); } + /// *listonly* + CSRAW public static bool Button (Rect position, Texture image, GUIStyle style) { return DoButton (position, GUIContent.Temp (image), style.m_Ptr); } + + // Make a single press button. The user clicks them and something happens immediately. + CSRAW public static bool Button (Rect position, GUIContent content, GUIStyle style) + { return DoButton (position, content, style.m_Ptr); } + + CUSTOM private static bool DoButton (Rect position, GUIContent content, IntPtr style) + { + return IMGUI::GUIButton ( + GetGUIState(), + position, + MonoGUIContentToTempNative (content), + *reinterpret_cast<GUIStyle*>(style) + ); + } + + /// *listonly* + CSRAW public static bool RepeatButton (Rect position, string text) { return DoRepeatButton (position, GUIContent.Temp (text), s_Skin.button, FocusType.Native); } + /// *listonly* + CSRAW public static bool RepeatButton (Rect position, Texture image) { return DoRepeatButton (position, GUIContent.Temp (image), s_Skin.button, FocusType.Native); } + /// *listonly* + CSRAW public static bool RepeatButton (Rect position, GUIContent content) { return DoRepeatButton (position, content, s_Skin.button, FocusType.Native); } + /// *listonly* + CSRAW public static bool RepeatButton (Rect position, string text, GUIStyle style) { return DoRepeatButton (position, GUIContent.Temp (text), style, FocusType.Native); } + /// *listonly* + CSRAW public static bool RepeatButton (Rect position, Texture image, GUIStyle style) { return DoRepeatButton (position, GUIContent.Temp (image), style, FocusType.Native); } + + // Make a button that is active as long as the user holds it down. + CSRAW public static bool RepeatButton (Rect position, GUIContent content, GUIStyle style) { return DoRepeatButton (position, content, style, FocusType.Native); } + + CSRAW static bool DoRepeatButton (Rect position, GUIContent content, GUIStyle style, FocusType focusType) { + GUIUtility.CheckOnGUI (); + int id = GUIUtility.GetControlID (repeatButtonHash, focusType, position); + switch (Event.current.GetTypeForControl (id)) { + case EventType.MouseDown: + // If the mouse is inside the button, we say that we're the hot control + if (position.Contains (Event.current.mousePosition)) { + GUIUtility.hotControl = id; + Event.current.Use (); + } + return false; + case EventType.MouseUp: + if (GUIUtility.hotControl == id) { + GUIUtility.hotControl = 0; + + // If we got the mousedown, the mouseup is ours as well + // (no matter if the click was in the button or not) + Event.current.Use (); + + // But we only return true if the button was actually clicked + return position.Contains (Event.current.mousePosition); + } + return false; + case EventType.Repaint: + style.Draw (position, content, id); + // Handles.Repaint (); + return id == GUIUtility.hotControl && position.Contains (Event.current.mousePosition); + } + return false; + } + static int repeatButtonHash = "repeatButton".GetHashCode (); + +// ====================================================== TEXTFIELDS =============================== + /// *listonly* + CSRAW public static string TextField (Rect position, string text) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, false, -1, GUI.skin.textField); + return t.text; + } + /// *listonly* + CSRAW public static string TextField (Rect position, string text, int maxLength) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, false, maxLength, GUI.skin.textField); + return t.text; + } + /// *listonly* + CSRAW public static string TextField (Rect position, string text, GUIStyle style) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, false, -1, style); + return t.text; + } + // Make a single-line text field where the user can edit a string. + CSRAW public static string TextField (Rect position, string text, int maxLength, GUIStyle style) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, true, maxLength, style); + return t.text; + } + + + // PASSWORDFIELD HERE =============================================================== + /// *listonly* + CSRAW public static string PasswordField (Rect position, string password, char maskChar) { + return PasswordField (position, password, maskChar, -1, GUI.skin.textField); + } + + /// *listonly* + CSRAW public static string PasswordField (Rect position, string password, char maskChar, int maxLength) { + return PasswordField (position, password, maskChar, maxLength, GUI.skin.textField); + } + /// *listonly* + CSRAW public static string PasswordField (Rect position, string password, char maskChar, GUIStyle style) { + return PasswordField (position, password, maskChar, -1, style); + } + + // Make a text field where the user can enter a password. + CSRAW public static string PasswordField (Rect position, string password, char maskChar, int maxLength, GUIStyle style) { + string strPassword = PasswordFieldGetStrToShow(password, maskChar); + + GUIContent t = GUIContent.Temp (strPassword); + bool oldGUIChanged = GUI.changed; + GUI.changed = false; +#if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard), t, false, maxLength, style, password, maskChar); +#else + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, false, maxLength, style); +#endif + + strPassword = GUI.changed ? t.text : password; + + GUI.changed |= oldGUIChanged; + + return strPassword; + } + + // *undocumented* + CSRAW internal static string PasswordFieldGetStrToShow(string password, char maskChar) + { +#if !UNITY_WEBGL + return (Event.current.type == EventType.repaint || Event.current.type == EventType.mouseDown) ? + "".PadRight(password.Length, maskChar) : password; +#else + return password; +#endif + } + + // TEXTAREA HERE ==================================================================== + /// *listonly* + CSRAW public static string TextArea (Rect position, string text) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, true, -1, GUI.skin.textArea); + return t.text; + } + /// *listonly* + CSRAW public static string TextArea (Rect position, string text, int maxLength) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, true, maxLength, GUI.skin.textArea); + return t.text; + } + /// *listonly* + CSRAW public static string TextArea (Rect position, string text, GUIStyle style) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, true, -1, style); + return t.text; + } + // Make a Multi-line text area where the user can edit a string. + CSRAW public static string TextArea (Rect position, string text, int maxLength, GUIStyle style) { + GUIContent t = GUIContent.Temp (text); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, false, maxLength, style); + return t.text; + } + // LATER... + static string TextArea (Rect position, GUIContent content, int maxLength, GUIStyle style) { + GUIContent t = GUIContent.Temp (content.text, content.image); + DoTextField (position, GUIUtility.GetControlID (FocusType.Keyboard, position), t, false, maxLength, style); + return t.text; + } + + CSRAW + internal static void DoTextField (Rect position, int id, GUIContent content, bool multiline, int maxLength, GUIStyle style +#if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + , string secureText = null, char maskChar = '\0' +#endif + ) { + + //Pre-cull input string to maxLength. + if (maxLength >= 0 && content.text.Length > maxLength) + content.text = content.text.Substring (0, maxLength); + + GUIUtility.CheckOnGUI (); + TextEditor editor = (TextEditor)GUIUtility.GetStateObject (typeof (TextEditor), id); + editor.content.text = content.text; + editor.SaveBackup (); + editor.position = position; + editor.style = style; + editor.multiline = multiline; + editor.controlID = id; + editor.ClampPos (); + Event evt = Event.current; + +#if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + switch (evt.type) { + case EventType.MouseDown: + if (position.Contains (evt.mousePosition)) { + GUIUtility.hotControl = id; + + // Disable keyboard for previously active text field, if any + if (hotTextField != -1 && hotTextField != id) { + TextEditor currentEditor = (TextEditor)GUIUtility.GetStateObject (typeof (TextEditor), hotTextField); + currentEditor.keyboardOnScreen = null; + } + + hotTextField = id; + + // in player setting keyboard control calls OnFocus every time, don't want that. In editor it does not do that for some reason + if (GUIUtility.keyboardControl != id) + GUIUtility.keyboardControl = id; + + editor.keyboardOnScreen = TouchScreenKeyboard.Open( + (secureText != null) ? secureText : content.text, + TouchScreenKeyboardType.Default, + true, // autocorrection + multiline, + (secureText != null)); + + evt.Use (); + } + break; + case EventType.Repaint: + if (editor.keyboardOnScreen != null) { + content.text = editor.keyboardOnScreen.text; + if (maxLength >= 0 && content.text.Length > maxLength) + content.text = content.text.Substring (0, maxLength); + + if (editor.keyboardOnScreen.done) { + editor.keyboardOnScreen = null; + changed = true; + } + } + + // if we use system keyboard we will have normal text returned (hiding symbols is done inside os) + // so before drawing make sure we hide them ourselves + string clearText = content.text; + + if(secureText != null) + content.text = PasswordFieldGetStrToShow(clearText, maskChar); + + style.Draw (position, content, id, false); + content.text = clearText; + + break; + } +#else // #if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + bool change = false; + switch (evt.type) { + case EventType.MouseDown: + if (position.Contains (evt.mousePosition)) { + GUIUtility.hotControl = id; + GUIUtility.keyboardControl = id; + editor.m_HasFocus = true; + editor.MoveCursorToPosition (Event.current.mousePosition); + if (Event.current.clickCount == 2 && GUI.skin.settings.doubleClickSelectsWord) { + editor.SelectCurrentWord (); + editor.DblClickSnap(TextEditor.DblClickSnapping.WORDS); + editor.MouseDragSelectsWholeWords (true); + } if (Event.current.clickCount == 3 && GUI.skin.settings.tripleClickSelectsLine) { + editor.SelectCurrentParagraph (); + editor.MouseDragSelectsWholeWords (true); + editor.DblClickSnap(TextEditor.DblClickSnapping.PARAGRAPHS); + } + evt.Use (); + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == id) + { + if (evt.shift) + editor.MoveCursorToPosition (Event.current.mousePosition); + else + editor.SelectToPosition (Event.current.mousePosition); + evt.Use (); + } + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == id) { + editor.MouseDragSelectsWholeWords (false); + GUIUtility.hotControl = 0; + evt.Use (); + } + break; + case EventType.KeyDown: + if (GUIUtility.keyboardControl != id) + return; + + if (editor.HandleKeyEvent (evt)) { + evt.Use (); + change = true; + content.text = editor.content.text; + break; + } + + // Ignore tab & shift-tab in textfields + if (evt.keyCode == KeyCode.Tab || evt.character == '\t') + return; + + char c = evt.character; + + if (c == '\n' && !multiline && !evt.alt) + return; + + + // Simplest test: only allow the character if the display font supports it. + Font font = style.font; + if (!font) + font = GUI.skin.font; + + if (font.HasCharacter (c) || c == '\n') { + editor.Insert (c); + change = true; + break; + } + + // On windows, keypresses also send events with keycode but no character. Eat them up here. + if (c == 0) { + + // if we have a composition string, make sure we clear the previous selection. + if (Input.compositionString.Length > 0) + { + editor.ReplaceSelection (""); + change = true; + } + + evt.Use (); + } +// else { +// REALLY USEFUL: +// Debug.Log ("unhandled " +evt); +// evt.Use (); +// } + break; + case EventType.Repaint: + // If we have keyboard focus, draw the cursor + // TODO: check if this OpenGL view has keyboard focus + if (GUIUtility.keyboardControl != id) { + style.Draw (position, content, id, false); + } else { + editor.DrawCursor (content.text); + } + break; + } + + if (GUIUtility.keyboardControl == id) + GUIUtility.textFieldInput = true; + + if (change) { + changed = true; + content.text = editor.content.text; + if (maxLength >= 0 && content.text.Length > maxLength) + content.text = content.text.Substring (0, maxLength); + evt.Use (); + } + #endif // #if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + } + + +// INPUT CONTROLS + + // Set the name of the next control. + CUSTOM static void SetNextControlName (string name) + { + GetGUIState().SetNameOfNextKeyboardControl (name); + } + + // Get the name of named control that has focus. + CUSTOM static string GetNameOfFocusedControl () + { + return scripting_string_new(GetGUIState().GetNameOfFocusedControl ().c_str()); + } + + + + // Move keyboard focus to a named control. + CUSTOM static void FocusControl (string name) + { + GetGUIState().FocusKeyboardControl (name); + } + + +// ====================================================== TOGGLES =============================== + /// *listonly* + CSRAW public static bool Toggle (Rect position, bool value, string text) { return Toggle (position, value, GUIContent.Temp (text), s_Skin.toggle); } + /// *listonly* + CSRAW public static bool Toggle (Rect position, bool value, Texture image) { return Toggle (position, value, GUIContent.Temp (image), s_Skin.toggle); } + /// *listonly* + CSRAW public static bool Toggle (Rect position, bool value, GUIContent content) { return Toggle (position, value, content, s_Skin.toggle); } + /// *listonly* + CSRAW public static bool Toggle (Rect position, bool value, string text, GUIStyle style) { return Toggle (position, value, GUIContent.Temp (text), style); } + /// *listonly* + CSRAW public static bool Toggle (Rect position, bool value, Texture image, GUIStyle style) { return Toggle (position, value, GUIContent.Temp (image), style); } + // Make an on/off toggle button. + CSRAW public static bool Toggle (Rect position, bool value, GUIContent content, GUIStyle style) + { return DoToggle (position, GUIUtility.GetControlID (toggleHash, FocusType.Native, position), value, content, style.m_Ptr); } + + CSRAW static int toggleHash = "Toggle".GetHashCode (); + CUSTOM internal static bool DoToggle (Rect position, int id, bool value, GUIContent content, IntPtr style) + { + return IMGUI::GUIToggle ( + GetGUIState(), + position, + value, + MonoGUIContentToTempNative (content), + *reinterpret_cast<GUIStyle*>(style), + id + ); + } + + /// *listonly* + CSRAW public static int Toolbar (Rect position, int selected, string[] texts) { return Toolbar (position, selected, GUIContent.Temp (texts), s_Skin.button); } + /// *listonly* + CSRAW public static int Toolbar (Rect position, int selected, Texture[] images) { return Toolbar (position, selected, GUIContent.Temp (images), s_Skin.button); } + /// *listonly* + public static int Toolbar (Rect position, int selected, GUIContent[] content) { return Toolbar (position, selected, content, s_Skin.button); } + /// *listonly* + CSRAW public static int Toolbar (Rect position, int selected, string[] texts, GUIStyle style) { return Toolbar (position, selected, GUIContent.Temp (texts), style); } + /// *listonly* + CSRAW public static int Toolbar (Rect position, int selected, Texture[] images, GUIStyle style) { return Toolbar (position, selected, GUIContent.Temp (images), style); } + // Make a toolbar + CSRAW public static int Toolbar (Rect position, int selected, GUIContent[] contents, GUIStyle style) { + // Get the styles here + GUIStyle firstStyle, midStyle, lastStyle; + FindStyles (ref style, out firstStyle, out midStyle, out lastStyle, "left", "mid", "right"); + + return DoButtonGrid (position, selected, contents, contents.Length, style, firstStyle, midStyle, lastStyle); + } + + + /// *listonly* + CSRAW public static int SelectionGrid (Rect position, int selected, string[] texts, int xCount) { return SelectionGrid (position, selected, GUIContent.Temp (texts), xCount, null); } + /// *listonly* + CSRAW public static int SelectionGrid (Rect position, int selected, Texture[] images, int xCount) { return SelectionGrid (position, selected, GUIContent.Temp (images), xCount, null); } + /// *listonly* + CSRAW public static int SelectionGrid (Rect position, int selected, GUIContent[] content, int xCount) { return SelectionGrid (position, selected, content, xCount, null); } + /// *listonly* + CSRAW public static int SelectionGrid (Rect position, int selected, string[] texts, int xCount, GUIStyle style) { return SelectionGrid (position, selected, GUIContent.Temp (texts), xCount, style); } + /// *listonly* + CSRAW public static int SelectionGrid (Rect position, int selected, Texture[] images, int xCount, GUIStyle style) { return SelectionGrid (position, selected, GUIContent.Temp (images), xCount, style); } + // Make a grid of buttons. + CSRAW public static int SelectionGrid (Rect position, int selected, GUIContent[] contents, int xCount, GUIStyle style) { + if (style == null) style = s_Skin.button; + return DoButtonGrid (position, selected, contents, xCount, style, style, style, style); + } + + // Internal toolbar & buttongrid code + // ============================================= + CSRAW + // Find many GUIStyles from style.name permutations (Helper function for toolbars). + internal static void FindStyles (ref GUIStyle style, out GUIStyle firstStyle, out GUIStyle midStyle, out GUIStyle lastStyle, string first, string mid, string last) { + if (style == null) + style = GUI.skin.button; + string baseName = style.name; + midStyle = GUI.skin.FindStyle (baseName + mid); + if (midStyle == null) + midStyle = style; + firstStyle = GUI.skin.FindStyle (baseName + first); + if (firstStyle == null) + firstStyle = midStyle; + lastStyle = GUI.skin.FindStyle (baseName + last); + if (lastStyle == null) + lastStyle = midStyle; + } + + static internal int CalcTotalHorizSpacing (int xCount, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle) { + if (xCount < 2) + return 0; + if (xCount == 2) + return Mathf.Max (firstStyle.margin.right, lastStyle.margin.left); + + int internalSpace = Mathf.Max (midStyle.margin.left, midStyle.margin.right); + return Mathf.Max (firstStyle.margin.right, midStyle.margin.left) + Mathf.Max (midStyle.margin.right, lastStyle.margin.left) + internalSpace * (xCount - 3); + } + + // Make a button grid + static int DoButtonGrid (Rect position, int selected, GUIContent[] contents, int xCount, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle) { + GUIUtility.CheckOnGUI (); + int count = contents.Length; + if (count == 0) + return selected; + if (xCount <= 0) + { + Debug.LogWarning("You are trying to create a SelectionGrid with zero or less elements to be displayed in the horizontal direction. Set xCount to a positive value."); + return selected; + } + int id = GUIUtility.GetControlID (buttonGridHash, FocusType.Native, position); + + // Figure out how large each element should be + int rows = count / xCount; + if (count % xCount != 0) + rows++; + float totalHorizSpacing = CalcTotalHorizSpacing (xCount, style, firstStyle, midStyle, lastStyle); + float totalVerticalSpacing = Mathf.Max (style.margin.top, style.margin.bottom) * (rows - 1); + float elemWidth = (position.width - totalHorizSpacing) / xCount; + float elemHeight = (position.height - totalVerticalSpacing) / (float)rows; + + if (style.fixedWidth != 0) + elemWidth = style.fixedWidth; + if (style.fixedHeight != 0) + elemHeight = style.fixedHeight; + + Rect[] buttonRects; + switch (Event.current.GetTypeForControl (id)) { + case EventType.MouseDown: + if (position.Contains (Event.current.mousePosition)) { + //Check if the mouse is over a button (nobody says the grid is filled out) + buttonRects = CalcMouseRects (position, count, xCount, elemWidth, elemHeight, style, firstStyle, midStyle, lastStyle, false); + if (GetButtonGridMouseSelection (buttonRects, Event.current.mousePosition, true) != -1) { + GUIUtility.hotControl = id; + Event.current.Use (); + } + } + break; + case EventType.MouseDrag: + if (GUIUtility.hotControl == id) + Event.current.Use (); + break; + case EventType.MouseUp: + if (GUIUtility.hotControl == id) { + GUIUtility.hotControl = 0; + Event.current.Use (); + + buttonRects = CalcMouseRects (position, count, xCount, elemWidth, elemHeight, style, firstStyle, midStyle, lastStyle, false); + int mouseSel = GetButtonGridMouseSelection (buttonRects, Event.current.mousePosition, true); + + GUI.changed = true; + return mouseSel; + } + break; + case EventType.Repaint: + GUIStyle selStyle = null; + + GUIClip.Push (position, Vector2.zero, Vector2.zero, false); + position = new Rect (0,0,position.width, position.height); + + buttonRects = CalcMouseRects (position, count, xCount, elemWidth, elemHeight, style, firstStyle, midStyle, lastStyle, false); + int mouseOverSel = GetButtonGridMouseSelection (buttonRects, Event.current.mousePosition, id == GUIUtility.hotControl); + + bool mouseInside = position.Contains (Event.current.mousePosition); + GUIUtility.mouseUsed |= mouseInside; + + for (int i =0; i < count;i++) { + // Figure out the style + GUIStyle s = null; + if (i != 0) + s = midStyle; + else + s = firstStyle; + if (i == count - 1) + s = lastStyle; + if (count == 1) + s = style; + + if (i != selected) // We draw the selected one last, so it overflows nicer + { + s.Draw (buttonRects[i], contents[i], i == mouseOverSel && (enabled || id == GUIUtility.hotControl) && (id == GUIUtility.hotControl || GUIUtility.hotControl == 0), id == GUIUtility.hotControl && GUI.enabled, false, false); + } else + { + selStyle = s; + } + } + + // Draw it at the end + if (selected < count && selected > -1) + { + selStyle.Draw (buttonRects[selected], contents[selected], selected == mouseOverSel && (enabled || id == GUIUtility.hotControl) && (id == GUIUtility.hotControl || GUIUtility.hotControl == 0), id == GUIUtility.hotControl, true, false); +// selStyle.Draw (buttonRects[selected], contents[selected], selected == mouseOverSel, id == GUIUtility.hotControl || (selected == mouseOverSel && GUIUtility.hotControl = 0), true, false); + } + + if (mouseOverSel >= 0) + { + tooltip = contents[mouseOverSel].tooltip; + } + + GUIClip.Pop (); + break; + } + return selected; + } + static int buttonGridHash = "ButtonGrid".GetHashCode (); + + // Helper function: Get all mouse rects + static Rect[] CalcMouseRects (Rect position, int count, int xCount, float elemWidth, float elemHeight, GUIStyle style, GUIStyle firstStyle, GUIStyle midStyle, GUIStyle lastStyle, bool addBorders) { + int y = 0; + int x = 0; + float xPos = position.xMin, yPos = position.yMin; + GUIStyle currentButtonStyle = style; + Rect[] retval = new Rect[count]; + if (count > 1) + currentButtonStyle = firstStyle; + for (int i = 0; i < count; i++) { + if (!addBorders) + retval[i] = new Rect (xPos, yPos, elemWidth, elemHeight); + else + retval[i] = currentButtonStyle.margin.Add (new Rect (xPos, yPos, elemWidth, elemHeight)); + + // Correct way to get the rounded width: + retval[i].width = Mathf.Round (retval[i].xMax) - Mathf.Round (retval[i].x); + // Round the position *after* the position has been rounded: + retval[i].x = Mathf.Round (retval[i].x); + + // Don't round xPos here. If rounded, the right edge of this rect may + // not line up correctly with the left edge of the next, + // plus it can cause cumulative rounding errors. + // (See case 366967) + + GUIStyle nextStyle = midStyle; + if (i == count - 2) + nextStyle = lastStyle; + xPos += elemWidth + Mathf.Max (currentButtonStyle.margin.right, nextStyle.margin.left); + + x++; + if (x >= xCount) { + y++; + x = 0; + yPos += elemHeight + Mathf.Max (style.margin.top, style.margin.bottom); + xPos = position.xMin; + } + } + return retval; + } + + + // Helper function: Get the index of the element under the mouse position + static int GetButtonGridMouseSelection (Rect[] buttonRects, Vector2 mousePos, bool findNearest) { + // This could be implemented faster, but for now this is not supposed to be used for a gazillion elements :) + + for (int i = 0; i < buttonRects.Length; i++) { + if (buttonRects[i].Contains (mousePos)) + return i; + } + if (!findNearest) + return -1; + // We haven't found any we're over, so we need to find the closest button. + float minDist = 10000000; + int minIndex = -1; + for (int i = 0; i < buttonRects.Length; i++) { + Rect r = buttonRects[i]; + Vector2 v = new Vector2 (Mathf.Clamp (mousePos.x, r.xMin, r.xMax), Mathf.Clamp (mousePos.y, r.yMin, r.yMax)); + float dSqr = (mousePos - v).sqrMagnitude; + if (dSqr < minDist) { + minIndex = i; + minDist = dSqr; + } + } + + return minIndex; + } + + /// *listonly* + CSRAW public static float HorizontalSlider(Rect position, float value, float leftValue, float rightValue) + { return Slider (position, value, 0, leftValue, rightValue, skin.horizontalSlider, skin.horizontalSliderThumb, true, GUIUtility.GetControlID (sliderHash, FocusType.Native, position)); } + // A horizontal slider the user can drag to change a value between a min and a max. + CSRAW public static float HorizontalSlider (Rect position, float value, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb) + { return Slider (position, value, 0, leftValue, rightValue, slider, thumb, true, GUIUtility.GetControlID (sliderHash, FocusType.Native, position)); } + + /// *listonly* + CSRAW public static float VerticalSlider (Rect position, float value, float topValue, float bottomValue) + { return Slider (position, value, 0, topValue, bottomValue, skin.verticalSlider, skin.verticalSliderThumb, false, GUIUtility.GetControlID (sliderHash, FocusType.Native, position)); } + // A vertical slider the user can drag to change a value between a min and a max. + CSRAW public static float VerticalSlider (Rect position, float value, float topValue, float bottomValue, GUIStyle slider, GUIStyle thumb) + { return Slider (position, value, 0, topValue, bottomValue, slider, thumb, false, GUIUtility.GetControlID (sliderHash, FocusType.Native, position)); } + + + // Main slider function. + // Handles scrollbars & sliders in both horizontal & vertical directions. + //*undocumented* + CSRAW public static float Slider (Rect position, float value, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id) { + GUIUtility.CheckOnGUI (); + return new SliderHandler(position, value, size, start, end, slider, thumb, horiz, id).Handle(); + } + static int sliderHash = "Slider".GetHashCode (); + + // should scrollbars do paging + CUSTOM_PROP static internal bool usePageScrollbars + { + #if UNITY_OSX + //respect system preference. + Boolean exists; + Boolean scroll = CFPreferencesGetAppBooleanValue(CFSTR("AppleScrollerPagingBehavior"),CFSTR("Apple Global Domain"),&exists); + return !scroll; + #else + return true; + #endif + } + + + /// *listonly* + CSRAW public static float HorizontalScrollbar (Rect position, float value, float size, float leftValue, float rightValue) + { return Scroller (position, value, size, leftValue, rightValue, skin.horizontalScrollbar, skin.horizontalScrollbarThumb, skin.horizontalScrollbarLeftButton, skin.horizontalScrollbarRightButton, true); } + // Make a horizontal scrollbar. Scrollbars are what you use to scroll through a document. Most likely, you want to use scrollViews instead. + CSRAW public static float HorizontalScrollbar (Rect position, float value, float size, float leftValue, float rightValue, GUIStyle style) + { return Scroller (position, value, size, leftValue, rightValue, style, skin.GetStyle (style.name + "thumb"), skin.GetStyle (style.name + "leftbutton"), skin.GetStyle (style.name + "rightbutton"), true); } + + // *undocumented* + CUSTOM static internal void InternalRepaintEditorWindow() + { + #if UNITY_EDITOR + GUIView *view = GUIView::GetCurrent (); + if (view) { + view->RequestRepaint (); + } else { + ErrorString ("InternalRepaint called outside an editor OnGUI"); + } + #endif + } + + // *undocumented* + CSRAW internal static bool ScrollerRepeatButton(int scrollerID, Rect rect, GUIStyle style) + { + bool changed = false; + + if (DoRepeatButton (rect, GUIContent.none, style, FocusType.Passive)) + { + bool firstClick = scrollControlID != scrollerID; + scrollControlID = scrollerID; + + if (firstClick) + { + changed = true; + nextScrollStepTime = DateTime.Now.AddMilliseconds(ScrollWaitDefinitions.firstWait); + } + else + { + if (DateTime.Now >= nextScrollStepTime) + { + changed = true; + nextScrollStepTime = DateTime.Now.AddMilliseconds(ScrollWaitDefinitions.regularWait); + } + } + + if (Event.current.type == EventType.Repaint) + InternalRepaintEditorWindow(); + } + + return changed; + } + + /// *listonly* + CSRAW public static float VerticalScrollbar (Rect position, float value, float size, float topValue, float bottomValue) + { return Scroller (position, value, size, topValue, bottomValue, skin.verticalScrollbar, skin.verticalScrollbarThumb, skin.verticalScrollbarUpButton, skin.verticalScrollbarDownButton, false); } + // Make a vertical scrollbar. Scrollbars are what you use to scroll through a document. Most likely, you want to use scrollViews instead. + CSRAW public static float VerticalScrollbar (Rect position, float value, float size, float topValue, float bottomValue, GUIStyle style) + { return Scroller (position, value, size, topValue, bottomValue, style, skin.GetStyle (style.name + "thumb"), skin.GetStyle (style.name + "upbutton"), skin.GetStyle (style.name + "downbutton"), false); } + + static float Scroller (Rect position, float value, float size, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, GUIStyle leftButton, GUIStyle rightButton, bool horiz) { + GUIUtility.CheckOnGUI (); + + int id = GUIUtility.GetControlID (sliderHash, FocusType.Passive, position); + + Rect sliderRect, minRect, maxRect; + + if (horiz) { + sliderRect = new Rect ( + position.x + leftButton.fixedWidth, position.y, + position.width - leftButton.fixedWidth - rightButton.fixedWidth, position.height + ); + minRect = new Rect (position.x, position.y, leftButton.fixedWidth, position.height); + maxRect = new Rect (position.xMax - rightButton.fixedWidth, position.y, rightButton.fixedWidth, position.height); + } else { + sliderRect = new Rect ( + position.x, position.y + leftButton.fixedHeight, + position.width, position.height - leftButton.fixedHeight - rightButton.fixedHeight + ); + minRect = new Rect (position.x, position.y, position.width, leftButton.fixedHeight); + maxRect = new Rect (position.x, position.yMax - rightButton.fixedHeight, position.width, rightButton.fixedHeight); + } + + value = Slider (sliderRect, value, size, leftValue, rightValue, slider, thumb, horiz, id); + + bool wasMouseUpEvent = false; + if (Event.current.type == EventType.MouseUp) + wasMouseUpEvent = true; + + if (ScrollerRepeatButton(id, minRect, leftButton)) + value -= scrollStepSize * (leftValue < rightValue ? 1f : -1f); + + if (ScrollerRepeatButton(id, maxRect, rightButton)) + value += scrollStepSize * (leftValue < rightValue ? 1f : -1f); + + if (wasMouseUpEvent && Event.current.type == EventType.Used) // repeat buttons ate mouse up event - release scrolling + scrollControlID = 0; + + if (leftValue < rightValue) + value = Mathf.Clamp (value, leftValue, rightValue - size); + else + value = Mathf.Clamp (value, rightValue, leftValue - size); + return value; + } + + + /// *listonly* + CSRAW public static void BeginGroup (Rect position) { BeginGroup (position, GUIContent.none, GUIStyle.none); } + /// *listonly* + CSRAW public static void BeginGroup (Rect position, string text) { BeginGroup (position, GUIContent.Temp (text), GUIStyle.none); } + /// *listonly* + CSRAW public static void BeginGroup (Rect position, Texture image) { BeginGroup (position, GUIContent.Temp (image), GUIStyle.none); } + /// *listonly* + CSRAW public static void BeginGroup (Rect position, GUIContent content) { BeginGroup (position, content, GUIStyle.none); } + /// *listonly* + CSRAW public static void BeginGroup (Rect position, GUIStyle style) { BeginGroup (position, GUIContent.none, style); } + /// *listonly* + CSRAW public static void BeginGroup (Rect position, string text, GUIStyle style) { BeginGroup (position, GUIContent.Temp (text), style); } + /// *listonly* + CSRAW public static void BeginGroup (Rect position, Texture image, GUIStyle style) { BeginGroup (position, GUIContent.Temp (image), style); } + + // Begin a group. Must be matched with a call to ::ref::EndGroup. + CSRAW public static void BeginGroup (Rect position, GUIContent content, GUIStyle style) { + GUIUtility.CheckOnGUI (); + + int id = GUIUtility.GetControlID (beginGroupHash, FocusType.Passive); + + if (content != GUIContent.none || style != GUIStyle.none) { + switch (Event.current.type) { + case EventType.Repaint: + style.Draw (position, content, id); + break; + default: + if (position.Contains (Event.current.mousePosition)) + GUIUtility.mouseUsed = true; + break; + } + } + + GUIClip.Push (position, Vector2.zero, Vector2.zero, false); + } + static int beginGroupHash = "BeginGroup".GetHashCode (); + + // End a group. + CSRAW public static void EndGroup () { + GUIClip.Pop (); + } + + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect) + { return BeginScrollView (position, scrollPosition, viewRect, false, false, skin.horizontalScrollbar, skin.verticalScrollbar, GUI.skin.scrollView); } + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal, bool alwaysShowVertical) + { return BeginScrollView (position, scrollPosition, viewRect, alwaysShowHorizontal, alwaysShowVertical, skin.horizontalScrollbar, skin.verticalScrollbar, GUI.skin.scrollView); } + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar) + { return BeginScrollView (position, scrollPosition, viewRect, false, false, horizontalScrollbar, verticalScrollbar, GUI.skin.scrollView); } + // Begin a scrolling view inside your GUI. + CSRAW public static Vector2 BeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal, bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar) + { return BeginScrollView (position, scrollPosition, viewRect, alwaysShowHorizontal, alwaysShowVertical, horizontalScrollbar, verticalScrollbar, null); } + + // *undocumented + CSRAW protected static Vector2 DoBeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal, bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background) { + return BeginScrollView (position, scrollPosition, viewRect, alwaysShowHorizontal, alwaysShowVertical, horizontalScrollbar, verticalScrollbar, background); + } + CSRAW internal static Vector2 BeginScrollView (Rect position, Vector2 scrollPosition, Rect viewRect, bool alwaysShowHorizontal, bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background) { + GUIUtility.CheckOnGUI (); + + #if UNITY_EDITOR + if (Event.current.type == EventType.DragUpdated && position.Contains(Event.current.mousePosition)) + { + if (Mathf.Abs(Event.current.mousePosition.y - position.y) < 8) + { + scrollPosition.y -= 16; + InternalRepaintEditorWindow (); + } + else if (Mathf.Abs(Event.current.mousePosition.y - position.yMax) < 8) + { + scrollPosition.y += 16; + InternalRepaintEditorWindow (); + } + } + #endif + + int id = GUIUtility.GetControlID (scrollviewHash, FocusType.Passive); + ScrollViewState state = (ScrollViewState)GUIUtility.GetStateObject (typeof (ScrollViewState), id); + + if (state.apply) { + scrollPosition = state.scrollPosition; + state.apply = false; + } + state.position = position; + state.scrollPosition = scrollPosition; + state.visibleRect = state.viewRect = viewRect; + state.visibleRect.width = position.width; + state.visibleRect.height = position.height; + s_ScrollViewStates.Push (state); + + Rect clipRect = new Rect (position); + switch (Event.current.type) { + case EventType.Layout: + GUIUtility.GetControlID (sliderHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID (sliderHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + break; + case EventType.Used: + break; + default: + bool needsVertical = alwaysShowVertical, needsHorizontal = alwaysShowHorizontal; + + // Check if we need a horizontal scrollbar + if (needsHorizontal || viewRect.width > clipRect.width) { + state.visibleRect.height = position.height - horizontalScrollbar.fixedHeight + horizontalScrollbar.margin.top; + clipRect.height -= horizontalScrollbar.fixedHeight + horizontalScrollbar.margin.top; + needsHorizontal = true; + } + if (needsVertical || viewRect.height > clipRect.height) { + state.visibleRect.width = position.width - verticalScrollbar.fixedWidth + verticalScrollbar.margin.left; + clipRect.width -= verticalScrollbar.fixedWidth + verticalScrollbar.margin.left; + needsVertical = true; + if (!needsHorizontal && viewRect.width > clipRect.width) { + state.visibleRect.height = position.height - horizontalScrollbar.fixedHeight + horizontalScrollbar.margin.top; + clipRect.height -= horizontalScrollbar.fixedHeight + horizontalScrollbar.margin.top; + needsHorizontal = true; + } + } + + if (Event.current.type == EventType.Repaint && background != GUIStyle.none) { + background.Draw (position, position.Contains (Event.current.mousePosition), false, needsHorizontal && needsVertical, false); + } + if (needsHorizontal && horizontalScrollbar != GUIStyle.none) { + scrollPosition.x = HorizontalScrollbar (new Rect (position.x, position.yMax - horizontalScrollbar.fixedHeight, clipRect.width, horizontalScrollbar.fixedHeight), + scrollPosition.x, clipRect.width, 0, viewRect.width, + horizontalScrollbar); + } else { + GUIUtility.GetControlID (sliderHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + if (horizontalScrollbar != GUIStyle.none) + scrollPosition.x = 0; + else + scrollPosition.x = Mathf.Clamp (scrollPosition.x, 0, Mathf.Max (viewRect.width - position.width, 0)); + } + + if (needsVertical && verticalScrollbar != GUIStyle.none) { + scrollPosition.y = VerticalScrollbar (new Rect (clipRect.xMax + verticalScrollbar.margin.left, clipRect.y, verticalScrollbar.fixedWidth, clipRect.height), + scrollPosition.y, clipRect.height, 0, viewRect.height, + verticalScrollbar); + } else { + GUIUtility.GetControlID (sliderHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + GUIUtility.GetControlID (repeatButtonHash, FocusType.Passive); + if (verticalScrollbar != GUIStyle.none) + scrollPosition.y = 0; + else + scrollPosition.y = Mathf.Clamp (scrollPosition.y, 0, Mathf.Max (viewRect.height - position.height, 0)); + } + break; + } + GUIClip.Push (clipRect, new Vector2 (Mathf.Round (-scrollPosition.x - viewRect.x), Mathf.Round (-scrollPosition.y - viewRect.y)),Vector2.zero, false); + return scrollPosition; + } + static int scrollviewHash = "scrollView".GetHashCode (); + static UnityEngineInternal.GenericStack s_ScrollViewStates = new UnityEngineInternal.GenericStack (); + CLASS internal ScrollViewState + CSRAW + //*undocumented* + public Rect position, visibleRect, viewRect; + //*undocumented* + public Vector2 scrollPosition; + //*undocumented* + public bool apply = false; + //*undocumented* + public bool hasScrollTo = false; + + //*undocumented* + /*public void ScrollTo (Rect position) { + Vector2 pos = GUIClip.Unclip (new Vector2 (position.xMin, position.yMin)); + if (!hasScrollTo) { + hasScrollTo = true; + scrollTo.xMin = pos.x; + scrollTo.yMin = pos.y; + pos = GUIClip.Unclip (new Vector2 (position.xMax, position.yMax)); + scrollTo.xMax = pos.x; + scrollTo.yMax = pos.y; + hasScrollTo = true; + } else { + scrollTo.x = Mathf.Min (pos.x, scrollTo.x); + scrollTo.y = Mathf.Min (pos.y, scrollTo.y); + pos = GUIClip.Unclip (new Vector2 (position.xMax, position.yMax)); + scrollTo.xMax = Mathf.Max (pos.x, scrollTo.xMax); + scrollTo.yMax = Mathf.Max (pos.y, scrollTo.yMax); + } + }*/ + + /*internal void ScrollTo (Rect position) { + Vector2 pos = new Vector2 (position.xMin, position.yMin); + if (!hasScrollTo) { + // Is hasScrollTo ever true outside of this method? + // The ScrollTo method doesn't seems to have any recursive logic so not sure what it's used for. + hasScrollTo = true; + + // scrollTo is being set to the same as position but in a really cumbersome way? + scrollTo.xMin = pos.x; + scrollTo.yMin = pos.y; + pos = new Vector2 (position.xMax, position.yMax); + scrollTo.xMax = pos.x; + scrollTo.yMax = pos.y; + hasScrollTo = true; + + Rect r = visibleRect; + r.x += scrollPosition.x; + r.y += scrollPosition.y; + + Vector2 bottomRight = new Vector2 (scrollTo.xMax, scrollTo.yMax); + Vector2 topLeft = new Vector2 (scrollTo.xMin, scrollTo.yMin); + + if (bottomRight.x > r.xMax) + scrollPosition.x += bottomRight.x - r.xMax; + if (topLeft.x < r.xMin) + scrollPosition.x -= r.xMin - topLeft.x; + + if (bottomRight.y > r.yMax) + scrollPosition.y += bottomRight.y - r.yMax; + if (topLeft.y < r.yMin) + scrollPosition.y -= r.yMin - topLeft.y; + + apply = true; + hasScrollTo = false; + } else { + scrollTo.x = Mathf.Min (pos.x, scrollTo.x); + scrollTo.y = Mathf.Min (pos.y, scrollTo.y); + pos = new Vector2 (position.xMax, position.yMax); + scrollTo.xMax = Mathf.Max (pos.x, scrollTo.xMax); + scrollTo.yMax = Mathf.Max (pos.y, scrollTo.yMax); + } + }*/ + + internal void ScrollTo (Rect position) + { + ScrollTowards (position, Mathf.Infinity); + } + + internal bool ScrollTowards (Rect position, float maxDelta) + { + Vector2 scrollVector = ScrollNeeded (position); + + // If we don't need scrolling, return false + if (scrollVector.sqrMagnitude < 0.0001f) + return false; + + // If we need scrolling but don't actually allow any, just return true to + // indicate scrolling is needed to be able to see position + if (maxDelta == 0) + return true; + + // Clamp scrolling to max allowed delta + if (scrollVector.magnitude > maxDelta) + scrollVector = scrollVector.normalized * maxDelta; + + // Apply scrolling + scrollPosition += scrollVector; + apply = true; + + return true; + } + + internal Vector2 ScrollNeeded (Rect position) + { + Rect r = visibleRect; + r.x += scrollPosition.x; + r.y += scrollPosition.y; + + // If the rect we want to see is larger than the visible rect, then trim it, + // otherwise we can get oscillation or other unwanted behavior + float excess = position.height - visibleRect.height; + if (excess > 0) + { + position.width -= excess; + position.x += excess * 0.5f; + } + excess = position.height - visibleRect.height; + if (excess > 0) + { + position.height -= excess; + position.y += excess * 0.5f; + } + + Vector2 scrollVector = Vector2.zero; + + // Calculate needed x scrolling + if (position.xMax > r.xMax) + scrollVector.x += position.xMax - r.xMax; + else if (position.xMin < r.xMin) + scrollVector.x -= r.xMin - position.xMin; + + // Calculate needed y scrolling + if (position.yMax > r.yMax) + scrollVector.y += position.yMax - r.yMax; + else if (position.yMin < r.yMin) + scrollVector.y -= r.yMin - position.yMin; + + // Clamp scrolling to bounds so we don't request to scroll past the edge + scrollVector.x = Mathf.Clamp (scrollVector.x, viewRect.xMin-scrollPosition.x, viewRect.xMax-visibleRect.width-scrollPosition.x); + scrollVector.y = Mathf.Clamp (scrollVector.y, viewRect.yMin-scrollPosition.y, viewRect.yMax-visibleRect.height-scrollPosition.y); + + return scrollVector; + } + END + + // Ends a scrollview started with a call to BeginScrollView. + public static void EndScrollView () { + EndScrollView (true); + } + + public static void EndScrollView (bool handleScrollWheel) { + ScrollViewState state = (ScrollViewState)s_ScrollViewStates.Peek (); + + GUIUtility.CheckOnGUI (); + GUIClip.Pop (); + + s_ScrollViewStates.Pop (); + + // This is the mac way of handling things: if the mouse is over a scrollview, the scrollview gets the event. + if (handleScrollWheel && Event.current.type == EventType.scrollWheel && state.position.Contains (Event.current.mousePosition)) { + state.scrollPosition.x = Mathf.Clamp (state.scrollPosition.x + (Event.current.delta.x * 20f), 0f, state.viewRect.width - state.visibleRect.width); + state.scrollPosition.y = Mathf.Clamp (state.scrollPosition.y + (Event.current.delta.y * 20f), 0f, state.viewRect.height - state.visibleRect.height); + state.apply = true; + Event.current.Use (); + } + } + + internal static ScrollViewState GetTopScrollView() + { + if (s_ScrollViewStates.Count != 0) + return (ScrollViewState)s_ScrollViewStates.Peek (); + return null; + } + + // Scrolls all enclosing scrollviews so they try to make /position/ visible. + public static void ScrollTo (Rect position) + { + ScrollViewState topmost = GetTopScrollView(); + if (topmost != null) + topmost.ScrollTo(position); + } + + // Scrolls all enclosing scrollviews towards making /position/ visible. + public static bool ScrollTowards (Rect position, float maxDelta) + { + ScrollViewState topmost = GetTopScrollView(); + if (topmost == null) + return false; + return topmost.ScrollTowards(position, maxDelta); + } + +CSRAW +// ====================================================== WINDOWS =============================== + + + /// *listonly* + public delegate void WindowFunction(int id); + /// *listonly* + CSRAW public static Rect Window (int id, Rect clientRect, WindowFunction func, string text) + { return DoWindow (id, clientRect, func, GUIContent.Temp (text), GUI.skin.window, GUI.skin, true); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect clientRect, WindowFunction func, Texture image) + { return DoWindow (id, clientRect, func, GUIContent.Temp (image), GUI.skin.window, GUI.skin, true); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect clientRect, WindowFunction func, GUIContent content) + { return DoWindow (id, clientRect, func, content, GUI.skin.window, GUI.skin, true); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect clientRect, WindowFunction func, string text, GUIStyle style) + { return DoWindow (id, clientRect, func, GUIContent.Temp (text), style, GUI.skin, true); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect clientRect, WindowFunction func, Texture image, GUIStyle style) + { return DoWindow (id, clientRect, func, GUIContent.Temp (image), style, GUI.skin, true); } + + // Make a popup window. + +BEGIN DOC + + Windows float above normal GUI controls, feature click-to-focus and can optionally be dragged around by the end user. + Unlike other controls, you need to pass them a separate function for the GUI controls to put inside the window. + + <b>Note:</b> If you are using [[GUILayout]] to place your components inside the window, you should use GUILayout.Window. + Here is a small example to get you started: + + You can use the same function to create multiple windows. Just make sure that ''each window has its own ID''. Example: + + To stop showing a window, simply stop calling GUI.Window from inside your main OnGUI function: + + To make a window that gets its size from automatic GUI layouting, use GUILayout.Window. + + __Call Ordering__ + + Windows need to be drawn back-to-front; windows on top of other windows need to be drawn later than the ones below them. This means that you can not count on your DoWindow functions to + be called in any particular order. In order for this to work seamlessly, the following values are stored when you create your window (using the __Window__ function), and retrieved when your DoWindow gets called: + GUI.skin, GUI.enabled, GUI.color, GUI.backgroundColor, GUI.contentColor, GUI.matrix + + + This means it's easy to do colored windows like this: + Hint: you can use the alpha component of GUI.color to fade windows in and out. + + + SA: ::ref::DragWindow, ::ref::BringWindowToFront, ::ref::BringWindowToBack + + @param id A unique ID to use for each window. This is the ID you'll use to interface to. + @param clientRect Rectangle on the screen to use for the group. + @param func The function that creates the GUI /inside/ the window. This function must take one parameter - the /id/ of the window it's currently making GUI for. + @param text Text to display as a title for the window. + @param image [[Texture]] to display an image in the titlebar. + @param content Text, image and tooltip for this window. + @param style An optional style to use for the window. If left out, the /window/ style from the current [[GUISkin]] is used. + @returns the rectangle the window is at. +END DOC + + CSRAW public static Rect Window (int id, Rect clientRect, WindowFunction func, GUIContent title, GUIStyle style) { return DoWindow (id, clientRect, func, title, style, GUI.skin, true); } + + // TODO: DOCME + CSRAW public static Rect ModalWindow (int id, Rect clientRect, WindowFunction func, string text) + { return DoModalWindow(id, clientRect, func, GUIContent.Temp(text), GUI.skin.window, GUI.skin); } + + CSRAW public static Rect ModalWindow (int id, Rect clientRect, WindowFunction func, Texture image) + { return DoModalWindow(id, clientRect, func, GUIContent.Temp(image), GUI.skin.window, GUI.skin); } + + CSRAW public static Rect ModalWindow (int id, Rect clientRect, WindowFunction func, GUIContent content) + { return DoModalWindow(id, clientRect, func, content, GUI.skin.window, GUI.skin); } + + CSRAW public static Rect ModalWindow (int id, Rect clientRect, WindowFunction func, string text, GUIStyle style) + { return DoModalWindow(id, clientRect, func, GUIContent.Temp(text), style, GUI.skin); } + + CSRAW public static Rect ModalWindow (int id, Rect clientRect, WindowFunction func, Texture image, GUIStyle style) + { return DoModalWindow(id, clientRect, func, GUIContent.Temp(image), style, GUI.skin); } + + CSRAW public static Rect ModalWindow (int id, Rect clientRect, WindowFunction func, GUIContent content, GUIStyle style) + { return DoModalWindow(id, clientRect, func, content, style, GUI.skin); } + + CUSTOM private static Rect DoModalWindow (int id, Rect clientRect, WindowFunction func, GUIContent content, GUIStyle style, GUISkin skin) + { + return IMGUI::DoWindow (GetGUIState (), id, clientRect, func, MonoGUIContentToTempNative (content), style.GetScriptingObject(), skin, true, true); + } + + CSRAW internal static void CallWindowDelegate (WindowFunction func, int id, GUISkin _skin, int forceRect, float width, float height, GUIStyle style) + { + GUILayoutUtility.SelectIDList (id, true); + GUISkin temp = skin; + if (Event.current.type == EventType.Layout) + { + if (forceRect != 0) { + GUILayoutOption[] options = { GUILayout.Width (width), GUILayout.Height(height) }; + + // Tell the GUILayout system we're starting a window, our style and our size. Then layouting is just the same as anything else + GUILayoutUtility.BeginWindow (id, style, options); + } else { + // If we don't want to force the rect (which is when we come from GUILayout.window), don't pass in the fixedsize options + GUILayoutUtility.BeginWindow (id, style, null); + } + } + skin = _skin; + func (id); + + if (Event.current.type == EventType.Layout) + { + // Now layout the window. + GUILayoutUtility.Layout (); + } + skin = temp; + } + + CUSTOM private static Rect DoWindow (int id, Rect clientRect, WindowFunction func, GUIContent title, GUIStyle style, GUISkin skin, bool forceRectOnLayout) { + return IMGUI::DoWindow (GetGUIState (), id, clientRect, func, MonoGUIContentToTempNative (title), style.GetScriptingObject(), skin, forceRectOnLayout); + } + + // Make a window draggable. + CUSTOM static void DragWindow (Rect position) + { IMGUI::DragWindow (GetGUIState(), position); } + + + // If you want to have the entire window background to act as a drag area, use the version of DragWindow that takes no parameters and put it at the end of the window function. + CSRAW public static void DragWindow () { DragWindow (new Rect (0,0, 10000,10000)); } + + // Bring a specific window to front of the floating windows. + CUSTOM static void BringWindowToFront (int windowID) + { + IMGUI::BringWindowToFront (GetGUIState(), windowID); + } + + // Bring a specific window to back of the floating windows. + CUSTOM static void BringWindowToBack (int windowID) + { + IMGUI::BringWindowToBack (GetGUIState(), windowID); + } + + // Make a window become the active window. + CUSTOM static void FocusWindow (int windowID) + { + IMGUI::FocusWindow (GetGUIState(), windowID); + } + + // Remove focus from all windows. + CUSTOM static void UnfocusWindow () { + IMGUI::FocusWindow (GetGUIState(), -1); + } + + CSRAW + // Call at the beginning of a frame. + // e event to process + // windowInfo - the list of windows we're currently using. + // *undocumented* + internal static void BeginWindows (int skinMode, int editorWindowInstanceID) { + // Let's just remember where we came from + GUILayoutGroup oldTopLevel = GUILayoutUtility.current.topLevel; + UnityEngineInternal.GenericStack oldLayoutGroups = GUILayoutUtility.current.layoutGroups; + GUILayoutGroup oldWindows = GUILayoutUtility.current.windows; + Matrix4x4 mat = GUI.matrix; + + // Call into C++ land + Internal_BeginWindows (); + + GUI.matrix = mat; + GUILayoutUtility.current.topLevel = oldTopLevel; + GUILayoutUtility.current.layoutGroups = oldLayoutGroups; + GUILayoutUtility.current.windows = oldWindows; + } + + CUSTOM private static void Internal_BeginWindows () + { + IMGUI::BeginWindows (GetGUIState(), false); + } + + // Call at the end of frame (at layer 0) to do all windows + CSRAW internal static void EndWindows () { + // Let's just remember where we came from + GUILayoutGroup oldTopLevel = GUILayoutUtility.current.topLevel; + UnityEngineInternal.GenericStack oldLayoutGroups = GUILayoutUtility.current.layoutGroups; + GUILayoutGroup oldWindows = GUILayoutUtility.current.windows; + + // Call Into C++ land + Internal_EndWindows (); + + GUILayoutUtility.current.topLevel = oldTopLevel; + GUILayoutUtility.current.layoutGroups = oldLayoutGroups; + GUILayoutUtility.current.windows = oldWindows; + } + + CUSTOM private static void Internal_EndWindows () + { + IMGUI::EndWindows (GetGUIState()); + } +END + + +CSRAW + +} // namespace diff --git a/Runtime/Export/GUIContentBindings.txt b/Runtime/Export/GUIContentBindings.txt new file mode 100644 index 0000000..c53201b --- /dev/null +++ b/Runtime/Export/GUIContentBindings.txt @@ -0,0 +1,132 @@ +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + + + +// The contents of a GUI element. +CSRAW [StructLayout (LayoutKind.Sequential)] +CSRAW [System.Serializable] +CLASS GUIContent + + // MUST MATCH MEMORY LAYOUT IN GUICONTENT.CPP + CSRAW + [SerializeField] + string m_Text = ""; + [SerializeField] + Texture m_Image; + [SerializeField] + string m_Tooltip = ""; + + + + // The text contained. + CSRAW public string text { get { return m_Text; } set { m_Text = value; } } + + // The icon image contained. + CSRAW public Texture image { get { return m_Image; } set { m_Image = value; } } + + // The tooltip of this element. + CSRAW public string tooltip { get { return m_Tooltip; } set { m_Tooltip = value; } } + + + // Constructor for GUIContent in all shapes and sizes + CSRAW public GUIContent () {} + // Build a GUIContent object containing only text. + CSRAW public GUIContent (string text) { + m_Text = text; + } + + // Build a GUIContent object containing only an image. + CSRAW public GUIContent (Texture image) { + m_Image = image; + } + + // Build a GUIContent object containing both /text/ and an image. + CSRAW public GUIContent (string text, Texture image) { + m_Text = text; + m_Image = image; + } + + // Build a GUIContent containing some /text/. When the user hovers the mouse over it, the global GUI::ref::tooltip is set to the /tooltip/. + CSRAW public GUIContent (string text, string tooltip) { + m_Text = text; + m_Tooltip = tooltip; + } + + // Build a GUIContent containing an image. When the user hovers the mouse over it, the global GUI::ref::tooltip is set to the /tooltip/. + CSRAW public GUIContent (Texture image, string tooltip) { + m_Image = image; + m_Tooltip = tooltip; + } + + // Build a GUIContent that contains both /text/, an /image/ and has a /tooltip/ defined. When the user hovers the mouse over it, the global GUI::ref::tooltip is set to the /tooltip/. + CSRAW public GUIContent (string text, Texture image, string tooltip) { + m_Text = text; + m_Image = image; + m_Tooltip = tooltip; + } + + // Build a GUIContent as a copy of another GUIContent. + CSRAW public GUIContent (GUIContent src) { + m_Text = src.m_Text; + m_Image = src.m_Image; + m_Tooltip = src.m_Tooltip; + } + + // Shorthand for empty content. + CSRAW public static GUIContent none = new GUIContent (""); + + // *undocumented* + CSRAW + internal int hash {get { + int h = 0; + if (m_Text != null && m_Text != "") + h = m_Text.GetHashCode () * 37; + return h; + }} + static GUIContent s_Text = new GUIContent(), s_Image = new GUIContent(), s_TextImage = new GUIContent(); + internal static GUIContent Temp (string t) { + s_Text.m_Text = t; + return s_Text; + } + internal static GUIContent Temp (Texture i) { + s_Image.m_Image = i; + return s_Image; + } + internal static GUIContent Temp (string t, Texture i) { + s_TextImage.m_Text = t; + s_TextImage.m_Image = i; + return s_TextImage; + } + internal static void ClearStaticCache() + { + s_Text.m_Text = null; + s_Image.m_Image = null; + s_TextImage.m_Text = null; + s_TextImage.m_Image = null; + } + + internal static GUIContent[] Temp (string[] texts) { + GUIContent[] retval = new GUIContent[texts.Length]; + for (int i = 0; i < texts.Length; i++) { + retval[i] = new GUIContent (texts[i]); + } + return retval; + } + internal static GUIContent[] Temp (Texture[] images) { + GUIContent[] retval = new GUIContent[images.Length]; + for (int i = 0; i < images.Length; i++) { + retval[i] = new GUIContent (images[i]); + } + return retval; + } +END + +CSRAW +} diff --git a/Runtime/Export/GUILayout.txt b/Runtime/Export/GUILayout.txt new file mode 100644 index 0000000..c795017 --- /dev/null +++ b/Runtime/Export/GUILayout.txt @@ -0,0 +1,517 @@ +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + + +// The GUILayout class is the interface for Unity gui with automatic layout. +CLASS GUILayout +CSRAW + /// *listonly* + CSRAW static public void Label (Texture image, params GUILayoutOption[] options) { DoLabel (GUIContent.Temp (image), GUI.skin.label, options); } + /// *listonly* + CSRAW static public void Label (string text, params GUILayoutOption[] options) { DoLabel (GUIContent.Temp (text), GUI.skin.label, options); } + /// *listonly* + CSRAW static public void Label (GUIContent content, params GUILayoutOption[] options) { DoLabel (content, GUI.skin.label, options); } + /// *listonly* + CSRAW static public void Label (Texture image, GUIStyle style, params GUILayoutOption[] options) { DoLabel (GUIContent.Temp (image), style, options); } + /// *listonly* + CSRAW static public void Label (string text, GUIStyle style, params GUILayoutOption[] options) { DoLabel (GUIContent.Temp (text), style, options); } + // Make an auto-layout label. + CSRAW static public void Label (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { DoLabel (content, style, options); } + CSRAW static void DoLabel (GUIContent content, GUIStyle style, GUILayoutOption[] options) + { GUI.Label (GUILayoutUtility.GetRect (content, style, options), content, style); } + + + /// *listonly* + CSRAW static public void Box (Texture image, params GUILayoutOption[] options) { DoBox (GUIContent.Temp (image), GUI.skin.box, options); } + /// *listonly* + CSRAW static public void Box (string text, params GUILayoutOption[] options) { DoBox (GUIContent.Temp (text), GUI.skin.box, options); } + /// *listonly* + CSRAW static public void Box (GUIContent content, params GUILayoutOption[] options) { DoBox (content, GUI.skin.box, options); } + /// *listonly* + CSRAW static public void Box (Texture image, GUIStyle style, params GUILayoutOption[] options) { DoBox (GUIContent.Temp (image), style, options); } + /// *listonly* + CSRAW static public void Box (string text, GUIStyle style, params GUILayoutOption[] options) { DoBox (GUIContent.Temp (text), style, options); } + // Make an auto-layout box. + CSRAW static public void Box (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { DoBox (content, style, options); } + CSRAW static void DoBox (GUIContent content, GUIStyle style, GUILayoutOption[] options) + { GUI.Box (GUILayoutUtility.GetRect (content, style, options), content, style); } + + /// *listonly* + CSRAW static public bool Button (Texture image, params GUILayoutOption[] options) { return DoButton (GUIContent.Temp (image), GUI.skin.button, options); } + /// *listonly* + CSRAW static public bool Button (string text, params GUILayoutOption[] options) { return DoButton (GUIContent.Temp (text), GUI.skin.button, options); } + /// *listonly* + CSRAW static public bool Button (GUIContent content, params GUILayoutOption[] options) { return DoButton (content, GUI.skin.button, options); } + /// *listonly* + CSRAW static public bool Button (Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoButton (GUIContent.Temp (image), style, options); } + /// *listonly* + CSRAW static public bool Button (string text, GUIStyle style, params GUILayoutOption[] options) { return DoButton (GUIContent.Temp (text), style, options); } + // Make a single press button. The user clicks them and something happens immediately. + CSRAW static public bool Button (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoButton (content, style, options); } + CSRAW static bool DoButton (GUIContent content, GUIStyle style, GUILayoutOption[] options) + { return GUI.Button (GUILayoutUtility.GetRect (content, style, options), content, style); } + + + + /// *listonly* + CSRAW static public bool RepeatButton (Texture image, params GUILayoutOption[] options) { return DoRepeatButton (GUIContent.Temp (image), GUI.skin.button, options); } + /// *listonly* + CSRAW static public bool RepeatButton (string text, params GUILayoutOption[] options) { return DoRepeatButton (GUIContent.Temp (text), GUI.skin.button, options); } + /// *listonly* + CSRAW static public bool RepeatButton (GUIContent content, params GUILayoutOption[] options) { return DoRepeatButton (content, GUI.skin.button, options); } + /// *listonly* + CSRAW static public bool RepeatButton (Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton (GUIContent.Temp (image), style, options); } + /// *listonly* + CSRAW static public bool RepeatButton (string text, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton (GUIContent.Temp (text), style, options); } + // Make a repeating button. The button returns true as long as the user holds down the mouse + CSRAW static public bool RepeatButton (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoRepeatButton (content, style, options); } + CSRAW static bool DoRepeatButton (GUIContent content, GUIStyle style, GUILayoutOption[] options) + { return GUI.RepeatButton (GUILayoutUtility.GetRect (content, style, options), content, style); } + + /// *listonly* + CSRAW public static string TextField (string text, params GUILayoutOption[] options) { return DoTextField (text, -1, false, GUI.skin.textField, options); } + /// *listonly* + CSRAW public static string TextField (string text, int maxLength, params GUILayoutOption[] options) { return DoTextField (text, maxLength, false, GUI.skin.textField, options); } + /// *listonly* + CSRAW public static string TextField (string text, GUIStyle style, params GUILayoutOption[] options) { return DoTextField (text, -1, false, style, options); } + // Make a single-line text field where the user can edit a string. + CSRAW public static string TextField (string text, int maxLength, GUIStyle style, params GUILayoutOption[] options) { return DoTextField (text, maxLength, true, style, options); } + + /// *listonly* + CSRAW public static string PasswordField (string password, char maskChar, params GUILayoutOption[] options) { + return PasswordField(password, maskChar, -1, GUI.skin.textField, options); + } + /// *listonly* + CSRAW public static string PasswordField (string password, char maskChar, int maxLength, params GUILayoutOption[] options) { + return PasswordField(password, maskChar, maxLength, GUI.skin.textField, options); + } + /// *listonly* + CSRAW public static string PasswordField (string password, char maskChar, GUIStyle style, params GUILayoutOption[] options) { + return PasswordField(password, maskChar, -1, style, options); + } + // Make a text field where the user can enter a password. + CSRAW public static string PasswordField (string password, char maskChar, int maxLength, GUIStyle style, params GUILayoutOption[] options) { + GUIContent t = GUIContent.Temp (GUI.PasswordFieldGetStrToShow(password, maskChar)); + return GUI.PasswordField(GUILayoutUtility.GetRect (t, GUI.skin.textField, options), password, maskChar, maxLength, style); + } + + /// *listonly* + CSRAW public static string TextArea (string text, params GUILayoutOption[] options) { return DoTextField (text, -1, true, GUI.skin.textArea, options); } + /// *listonly* + CSRAW public static string TextArea (string text, int maxLength, params GUILayoutOption[] options) { return DoTextField (text, maxLength, true, GUI.skin.textArea, options); } + /// *listonly* + CSRAW public static string TextArea (string text, GUIStyle style, params GUILayoutOption[] options) { return DoTextField (text, -1, true, style, options); } + // Make a multi-line text field where the user can edit a string. + CSRAW public static string TextArea (string text, int maxLength, GUIStyle style, params GUILayoutOption[] options) { return DoTextField (text, maxLength, true, style, options); } + + CSRAW static string DoTextField (string text, int maxLength, bool multiline, GUIStyle style, GUILayoutOption[] options) { + int id = GUIUtility.GetControlID (FocusType.Keyboard); + GUIContent content = GUIContent.Temp (text); + Rect r; + if (GUIUtility.keyboardControl != id) + content = GUIContent.Temp (text); + else + content = GUIContent.Temp (text + Input.compositionString); + + r = GUILayoutUtility.GetRect (content, style, options); + if (GUIUtility.keyboardControl == id) + content = GUIContent.Temp (text); + GUI.DoTextField (r, id, content, multiline, maxLength, style); + return content.text; + } + + /// *listonly* + CSRAW static public bool Toggle (bool value, Texture image, params GUILayoutOption[] options) { return DoToggle (value, GUIContent.Temp (image), GUI.skin.toggle, options); } + /// *listonly* + CSRAW static public bool Toggle (bool value, string text, params GUILayoutOption[] options) { return DoToggle (value, GUIContent.Temp (text), GUI.skin.toggle, options); } + /// *listonly* + CSRAW static public bool Toggle (bool value, GUIContent content, params GUILayoutOption[] options) { return DoToggle (value, content, GUI.skin.toggle, options); } + /// *listonly* + CSRAW static public bool Toggle (bool value, Texture image, GUIStyle style, params GUILayoutOption[] options) { return DoToggle (value, GUIContent.Temp (image), style, options); } + /// *listonly* + CSRAW static public bool Toggle (bool value, string text, GUIStyle style, params GUILayoutOption[] options) { return DoToggle (value, GUIContent.Temp (text), style, options); } + // Make an on/off toggle button. + CSRAW static public bool Toggle (bool value, GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoToggle (value, content, style, options); } + + //*undocumented* + CSRAW static bool DoToggle (bool value, GUIContent content, GUIStyle style, GUILayoutOption[] options) + { return GUI.Toggle (GUILayoutUtility.GetRect (content, style, options), value, content, style); } + + + + /// *listonly* + CSRAW public static int Toolbar (int selected, string[] texts, params GUILayoutOption[] options) { return Toolbar (selected, GUIContent.Temp (texts), GUI.skin.button, options); } + /// *listonly* + CSRAW public static int Toolbar (int selected, Texture[] images, params GUILayoutOption[] options) { return Toolbar (selected, GUIContent.Temp (images), GUI.skin.button, options); } + /// *listonly* + CSRAW public static int Toolbar (int selected, GUIContent[] content, params GUILayoutOption[] options) { return Toolbar (selected, content, GUI.skin.button, options); } + /// *listonly* + CSRAW public static int Toolbar (int selected, string[] texts, GUIStyle style, params GUILayoutOption[] options) { return Toolbar (selected, GUIContent.Temp (texts), style, options); } + /// *listonly* + CSRAW public static int Toolbar (int selected, Texture[] images, GUIStyle style, params GUILayoutOption[] options) { return Toolbar (selected, GUIContent.Temp (images), style, options); } + // Make a toolbar + CSRAW public static int Toolbar (int selected, GUIContent[] contents, GUIStyle style, params GUILayoutOption[] options) { + GUIStyle firstStyle, midStyle, lastStyle; + GUI.FindStyles (ref style, out firstStyle, out midStyle, out lastStyle, "left", "mid", "right"); + + Vector2 size = new Vector2(); + int count = contents.Length; + GUIStyle currentStyle = count > 1 ? firstStyle : style; + GUIStyle nextStyle = count > 1 ? midStyle : style; + GUIStyle endStyle = count > 1 ? lastStyle : style; + int margins = currentStyle.margin.left; + + for (int i = 0; i < contents.Length; i++) + { + if (i == count - 2) + { + currentStyle = nextStyle; + nextStyle = endStyle; + } + if (i == count - 1) + currentStyle = endStyle; + + Vector2 thisSize = currentStyle.CalcSize (contents[i]); + + if (thisSize.x > size.x) + size.x = thisSize.x; + if (thisSize.y > size.y) + size.y = thisSize.y; + + if (i == count - 1) + margins += currentStyle.margin.right; + else + margins += Mathf.Max (currentStyle.margin.right, nextStyle.margin.left); + } + + size.x = size.x * contents.Length + margins; + + return GUI.Toolbar (GUILayoutUtility.GetRect (size.x, size.y, style, options), selected, contents, style); + } + + /// *listonly* + CSRAW public static int SelectionGrid (int selected, string[] texts, int xCount, params GUILayoutOption[] options) { return SelectionGrid (selected, GUIContent.Temp (texts), xCount, GUI.skin.button, options); } + /// *listonly* + CSRAW public static int SelectionGrid (int selected, Texture[] images, int xCount, params GUILayoutOption[] options) { return SelectionGrid (selected, GUIContent.Temp (images), xCount, GUI.skin.button, options); } + /// *listonly* + CSRAW public static int SelectionGrid (int selected, GUIContent[] content, int xCount, params GUILayoutOption[] options) { return SelectionGrid (selected, content, xCount, GUI.skin.button, options); } + /// *listonly* + CSRAW public static int SelectionGrid (int selected, string[] texts, int xCount, GUIStyle style, params GUILayoutOption[] options) { return SelectionGrid (selected, GUIContent.Temp (texts), xCount, style, options); } + /// *listonly* + CSRAW public static int SelectionGrid (int selected, Texture[] images, int xCount, GUIStyle style, params GUILayoutOption[] options) { return SelectionGrid (selected, GUIContent.Temp (images), xCount, style, options); } + // Make a Selection Grid + CSRAW public static int SelectionGrid (int selected, GUIContent[] contents, int xCount, GUIStyle style, params GUILayoutOption[] options) { + return GUI.SelectionGrid (GUIGridSizer.GetRect (contents, xCount, style, options), selected, contents, xCount, style); + } + + /// *listonly* + static public float HorizontalSlider (float value, float leftValue, float rightValue, params GUILayoutOption[] options) + { return DoHorizontalSlider(value, leftValue, rightValue, GUI.skin.horizontalSlider, GUI.skin.horizontalSliderThumb, options); } + // A horizontal slider the user can drag to change a value between a min and a max. + static public float HorizontalSlider (float value, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, params GUILayoutOption[] options) + { return DoHorizontalSlider(value, leftValue, rightValue, slider, thumb, options); } + static float DoHorizontalSlider (float value, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, GUILayoutOption[] options) + { return GUI.HorizontalSlider(GUILayoutUtility.GetRect (GUIContent.Temp ("mmmm"), slider, options), value, leftValue, rightValue, slider, thumb); } + + /// *listonly* + static public float VerticalSlider (float value, float leftValue, float rightValue, params GUILayoutOption[] options) + { return DoVerticalSlider(value, leftValue, rightValue, GUI.skin.verticalSlider, GUI.skin.verticalSliderThumb, options); } + // A vertical slider the user can drag to change a value between a min and a max. + static public float VerticalSlider (float value, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, params GUILayoutOption[] options) + { return DoVerticalSlider(value, leftValue, rightValue, slider, thumb, options); } + static float DoVerticalSlider (float value, float leftValue, float rightValue, GUIStyle slider, GUIStyle thumb, params GUILayoutOption[] options) + { return GUI.VerticalSlider(GUILayoutUtility.GetRect (GUIContent.Temp ("\n\n\n\n\n"), slider, options), value, leftValue, rightValue, slider, thumb); } + + + /// *listonly* + CSRAW public static float HorizontalScrollbar (float value, float size, float leftValue, float rightValue, params GUILayoutOption[] options) + { return HorizontalScrollbar (value, size, leftValue, rightValue, GUI.skin.horizontalScrollbar, options); } + // Make a horiztonal scrollbar. + CSRAW public static float HorizontalScrollbar (float value, float size, float leftValue, float rightValue, GUIStyle style, params GUILayoutOption[] options) + { return GUI.HorizontalScrollbar (GUILayoutUtility.GetRect (GUIContent.Temp ("mmmm"), style, options), value, size, leftValue, rightValue, style); } + + + + /// *listonly* + CSRAW public static float VerticalScrollbar (float value, float size, float topValue, float bottomValue, params GUILayoutOption[] options) + { return VerticalScrollbar (value, size, topValue, bottomValue, GUI.skin.verticalScrollbar, options); } + // Make a vertical scrollbar. + CSRAW public static float VerticalScrollbar (float value, float size, float topValue, float bottomValue, GUIStyle style, params GUILayoutOption[] options) + { return GUI.VerticalScrollbar (GUILayoutUtility.GetRect (GUIContent.Temp ("\n\n\n\n"), style, options), value, size, topValue, bottomValue, style); } + + // Insert a space in the current layout group. + CSRAW static public void Space (float pixels) { + GUIUtility.CheckOnGUI(); + if (GUILayoutUtility.current.topLevel.isVertical) + GUILayoutUtility.GetRect (0, pixels, GUILayoutUtility.spaceStyle, GUILayout.Height (pixels)); + else + GUILayoutUtility.GetRect (pixels, 0, GUILayoutUtility.spaceStyle, GUILayout.Width (pixels)); + } + + // Insert a flexible space element. + CSRAW static public void FlexibleSpace () { + GUIUtility.CheckOnGUI(); + GUILayoutOption op; + if (GUILayoutUtility.current.topLevel.isVertical) + op = ExpandHeight (true); + else + op = ExpandWidth (true); + + op.value = 10000; + GUILayoutUtility.GetRect (0,0, GUILayoutUtility.spaceStyle, op); + } + + + + + /// *listonly* + CSRAW public static void BeginHorizontal (params GUILayoutOption[] options) + { BeginHorizontal (GUIContent.none, GUIStyle.none, options); } + /// *listonly* + CSRAW public static void BeginHorizontal (GUIStyle style, params GUILayoutOption[] options) + { BeginHorizontal (GUIContent.none, style, options); } + /// *listonly* + CSRAW public static void BeginHorizontal (string text, GUIStyle style, params GUILayoutOption[] options) + { BeginHorizontal (GUIContent.Temp(text), style, options); } + /// *listonly* + CSRAW public static void BeginHorizontal (Texture image, GUIStyle style, params GUILayoutOption[] options) + { BeginHorizontal (GUIContent.Temp(image), style, options); } + // Begin a Horizontal control group. + CSRAW public static void BeginHorizontal (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { + GUILayoutGroup g = GUILayoutUtility.BeginLayoutGroup (style, options, typeof (GUILayoutGroup)); + g.isVertical = false; + if (style != GUIStyle.none || content != GUIContent.none) + GUI.Box (g.rect, content, style); + } + + // Close a group started with BeginHorizontal + CSRAW public static void EndHorizontal () { + GUILayoutUtility.EndGroup ("GUILayout.EndHorizontal"); + GUILayoutUtility.EndLayoutGroup (); + } + + /// *listonly* + CSRAW public static void BeginVertical (params GUILayoutOption[] options) + { BeginVertical (GUIContent.none, GUIStyle.none, options); } + /// *listonly* + CSRAW public static void BeginVertical (GUIStyle style, params GUILayoutOption[] options) + { BeginVertical (GUIContent.none, style, options); } + /// *listonly* + CSRAW public static void BeginVertical (string text, GUIStyle style, params GUILayoutOption[] options) + { BeginVertical (GUIContent.Temp(text), style, options); } + /// *listonly* + CSRAW public static void BeginVertical (Texture image, GUIStyle style, params GUILayoutOption[] options) + { BeginVertical (GUIContent.Temp(image), style, options); } + // Begin a vertical control group. + CSRAW public static void BeginVertical (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { + GUILayoutGroup g = GUILayoutUtility.BeginLayoutGroup (style, options, typeof (GUILayoutGroup)); + g.isVertical = true; + if (style != GUIStyle.none) + GUI.Box (g.rect, content, style); + } + + // Close a group started with BeginVertical + CSRAW public static void EndVertical () { + GUILayoutUtility.EndGroup ("GUILayout.EndVertical"); + GUILayoutUtility.EndLayoutGroup (); + } + + + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect) { BeginArea (screenRect, GUIContent.none, GUIStyle.none); } + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect, string text) { BeginArea (screenRect, GUIContent.Temp (text), GUIStyle.none); } + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect, Texture image) { BeginArea (screenRect, GUIContent.Temp (image), GUIStyle.none); } + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect, GUIContent content) { BeginArea (screenRect, GUIContent.none, GUIStyle.none); } + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect, GUIStyle style) { BeginArea (screenRect, GUIContent.none, style); } + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect, string text, GUIStyle style) { BeginArea (screenRect, GUIContent.Temp (text), style); } + /// *listonly* + CSRAW static public void BeginArea (Rect screenRect, Texture image, GUIStyle style) { BeginArea (screenRect, GUIContent.Temp (image), style); } + + // Begin a GUILayout block of GUI controls in a fixed screen area. + CSRAW static public void BeginArea (Rect screenRect, GUIContent content, GUIStyle style) + { + GUIUtility.CheckOnGUI (); + GUILayoutGroup g = GUILayoutUtility.BeginLayoutArea (style, typeof (GUILayoutGroup)); + if (Event.current.type == EventType.Layout) + { + g.resetCoords = true; + g.minWidth = g.maxWidth = screenRect.width; + g.minHeight = g.maxHeight = screenRect.height; + g.rect = Rect.MinMaxRect(screenRect.xMin, screenRect.yMin, g.rect.xMax, g.rect.yMax); + } + + GUI.BeginGroup (g.rect, content, style); + } + + // Close a GUILayout block started with BeginArea + CSRAW static public void EndArea () { + GUIUtility.CheckOnGUI (); + if (Event.current.type == EventType.Used) + return; + GUILayoutUtility.current.layoutGroups.Pop (); + GUILayoutUtility.current.topLevel = (GUILayoutGroup)GUILayoutUtility.current.layoutGroups.Peek (); + GUI.EndGroup (); + } + + +// ====================================================== SCROLLVIEWS =============================== + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, params GUILayoutOption[] options) { return BeginScrollView (scrollPosition, false, false, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUI.skin.scrollView, options); } + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical, params GUILayoutOption[] options) { return BeginScrollView (scrollPosition, alwaysShowHorizontal, alwaysShowVertical, GUI.skin.horizontalScrollbar, GUI.skin.verticalScrollbar, GUI.skin.scrollView, options); } + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, params GUILayoutOption[] options) { return BeginScrollView (scrollPosition, false, false, horizontalScrollbar, verticalScrollbar, GUI.skin.scrollView, options); } + + // We need to keep both of the following versions of BeginScrollView() since it was added with a different signature in 3.5 + // Adding an optional argument with params unfortunately *does* change the function signature + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, GUIStyle style) + { + GUILayoutOption[] option = null; + return BeginScrollView (scrollPosition, style, option); + } + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, GUIStyle style, params GUILayoutOption[] options) + { + string name = style.name; + + GUIStyle vertical = GUI.skin.FindStyle (name + "VerticalScrollbar"); + if (vertical == null) + vertical = GUI.skin.verticalScrollbar; + GUIStyle horizontal = GUI.skin.FindStyle (name + "HorizontalScrollbar"); + if (horizontal == null) + horizontal = GUI.skin.horizontalScrollbar; + return BeginScrollView (scrollPosition, false, false, horizontal, vertical, style, options); + } + + /// *listonly* + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, params GUILayoutOption[] options) + { return BeginScrollView (scrollPosition, alwaysShowHorizontal, alwaysShowVertical, horizontalScrollbar, verticalScrollbar, GUI.skin.scrollView, options); } + + // Begin an automatically laid out scrollview. + CSRAW public static Vector2 BeginScrollView (Vector2 scrollPosition, bool alwaysShowHorizontal, bool alwaysShowVertical, GUIStyle horizontalScrollbar, GUIStyle verticalScrollbar, GUIStyle background, params GUILayoutOption[] options) { + GUIUtility.CheckOnGUI(); + + GUIScrollGroup g = (GUIScrollGroup)GUILayoutUtility.BeginLayoutGroup (background, null, typeof (GUIScrollGroup)); + switch (Event.current.type) { + case EventType.Layout: + g.resetCoords = true; + g.isVertical = true; + g.stretchWidth = 1; + g.stretchHeight = 1; + g.verticalScrollbar = verticalScrollbar; + g.horizontalScrollbar = horizontalScrollbar; + g.needsVerticalScrollbar = alwaysShowVertical; + g.needsHorizontalScrollbar = alwaysShowHorizontal; + g.ApplyOptions (options); + break; + default: + break; + } + return GUI.BeginScrollView (g.rect, scrollPosition, new Rect (0,0,g.clientWidth,g.clientHeight), alwaysShowHorizontal, alwaysShowVertical, horizontalScrollbar, verticalScrollbar, background); + } + // End a scroll view begun with a call to BeginScrollView. + public static void EndScrollView () { + EndScrollView (true); + } + + + internal static void EndScrollView (bool handleScrollWheel) { + GUILayoutUtility.EndGroup ("GUILayout.EndScrollView"); + GUILayoutUtility.EndLayoutGroup (); + GUI.EndScrollView (handleScrollWheel); + } + + /// *listonly* + CSRAW public static Rect Window (int id, Rect screenRect, GUI.WindowFunction func, string text, params GUILayoutOption[ ] options) { return DoWindow (id, screenRect, func, GUIContent.Temp (text), GUI.skin.window, options); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect screenRect, GUI.WindowFunction func, Texture image, params GUILayoutOption[ ] options) { return DoWindow (id, screenRect, func, GUIContent.Temp (image), GUI.skin.window, options); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect screenRect, GUI.WindowFunction func, GUIContent content, params GUILayoutOption[ ] options) { return DoWindow (id, screenRect, func, content, GUI.skin.window, options); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect screenRect, GUI.WindowFunction func, string text, GUIStyle style, params GUILayoutOption[ ] options) { return DoWindow (id, screenRect, func, GUIContent.Temp (text), style, options); } + /// *listonly* + CSRAW public static Rect Window (int id, Rect screenRect, GUI.WindowFunction func, Texture image, GUIStyle style, params GUILayoutOption[ ] options) { return DoWindow (id, screenRect, func, GUIContent.Temp (image), style, options); } + + // Make a popup window that layouts its contents automatically. + CSRAW public static Rect Window (int id, Rect screenRect, GUI.WindowFunction func, GUIContent content, GUIStyle style, params GUILayoutOption[ ] options) { return DoWindow (id, screenRect, func, content, style, options); } + // Make an auto-sized draggable window... + CSRAW static Rect DoWindow (int id, Rect screenRect, GUI.WindowFunction func, GUIContent content, GUIStyle style, GUILayoutOption[ ] options) { + GUIUtility.CheckOnGUI (); + LayoutedWindow lw = new LayoutedWindow (func, screenRect, content, options, style); + return GUI.Window (id, screenRect, lw.DoWindow, content, style); + } + + CLASS private LayoutedWindow + CSRAW + GUI.WindowFunction func; + Rect screenRect; + GUILayoutOption[ ] options; + GUIStyle style; + //*undocumented* + internal LayoutedWindow (GUI.WindowFunction f, Rect _screenRect, GUIContent _content, GUILayoutOption[ ] _options, GUIStyle _style) { + func = f; + screenRect = _screenRect; + options = _options; + style = _style; + } + + //*undocumented* + public void DoWindow (int windowID) { + GUILayoutGroup g = GUILayoutUtility.current.topLevel; + + switch (Event.current.type) { + case EventType.Layout: + // TODO: Add layoutoptions + // TODO: Take titlebar size into consideration + g.resetCoords = true; + g.rect = screenRect; + if (options != null) + g.ApplyOptions (options); + g.isWindow = true; + g.windowID = windowID; + g.style = style; + break; + default: + g.ResetCursor (); + break; + } + func (windowID); + } + END + + // Option passed to a control to give it an absolute width. + CSRAW static public GUILayoutOption Width (float width) { return new GUILayoutOption (GUILayoutOption.Type.fixedWidth, width); } + // Option passed to a control to specify a minimum width.\\ + CSRAW static public GUILayoutOption MinWidth (float minWidth) { return new GUILayoutOption (GUILayoutOption.Type.minWidth, minWidth); } + // Option passed to a control to specify a maximum width. + CSRAW static public GUILayoutOption MaxWidth (float maxWidth) { return new GUILayoutOption (GUILayoutOption.Type.maxWidth, maxWidth); } + // Option passed to a control to give it an absolute height. + CSRAW static public GUILayoutOption Height (float height) { return new GUILayoutOption (GUILayoutOption.Type.fixedHeight, height); } + + // Option passed to a control to specify a minimum height. + CSRAW static public GUILayoutOption MinHeight (float minHeight) { return new GUILayoutOption (GUILayoutOption.Type.minHeight, minHeight); } + + // Option passed to a control to specify a maximum height. + CSRAW static public GUILayoutOption MaxHeight (float maxHeight) { return new GUILayoutOption (GUILayoutOption.Type.maxHeight, maxHeight); } + + // Option passed to a control to allow or disallow horizontal expansion. + CSRAW static public GUILayoutOption ExpandWidth (bool expand) { return new GUILayoutOption (GUILayoutOption.Type.stretchWidth, expand ? 1 : 0); } + // Option passed to a control to allow or disallow vertical expansion. + CSRAW static public GUILayoutOption ExpandHeight (bool expand) { return new GUILayoutOption (GUILayoutOption.Type.stretchHeight, expand ? 1 : 0); } +END + +CSRAW + +} diff --git a/Runtime/Export/GUILayoutUtility.txt b/Runtime/Export/GUILayoutUtility.txt new file mode 100644 index 0000000..df94ffa --- /dev/null +++ b/Runtime/Export/GUILayoutUtility.txt @@ -0,0 +1,1420 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Math/Rect.h" +#include "Runtime/IMGUI/GUIWindows.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEngine +{ + +// Utility functions for implementing and extending the GUILayout class. +NONSEALED_CLASS GUILayoutUtility +CSRAW + + CLASS internal LayoutCache + CSRAW + //*undocumented* + internal GUILayoutGroup topLevel = new GUILayoutGroup (); + //*undocumented* + internal UnityEngineInternal.GenericStack layoutGroups = new UnityEngineInternal.GenericStack (); + //*undocumented* + internal GUILayoutGroup windows = new GUILayoutGroup (); + + //*undocumented* + internal LayoutCache () { + layoutGroups.Push (topLevel); + } + + internal LayoutCache (LayoutCache other) + { + topLevel = other.topLevel; + layoutGroups = other.layoutGroups; + windows = other.windows; + } + END + + // TODO: Clean these up after a while + static Dictionary<int, LayoutCache> storedLayouts = new Dictionary<int, LayoutCache> (); + static Dictionary<int, LayoutCache> storedWindows = new Dictionary<int, LayoutCache> (); + + static internal LayoutCache current = new LayoutCache (); + + static Rect kDummyRect = new Rect (0, 0, 1, 1); + + CSRAW static internal LayoutCache SelectIDList (int instanceID, bool isWindow) { + Dictionary<int, LayoutCache> store = isWindow ? storedWindows : storedLayouts; + LayoutCache cache; + if (store.TryGetValue(instanceID, out cache) == false) { +// Debug.Log ("Creating ID " +instanceID + " " + Event.current.type); + cache = new LayoutCache(); + store[instanceID] = cache; + } else { +// Debug.Log ("reusing ID " +instanceID + " " + Event.current.type); + } + current.topLevel = cache.topLevel; + current.layoutGroups = cache.layoutGroups; + current.windows = cache.windows; + return cache; + } + + // Set up the internal GUILayouting + // Called by the main GUI class automatically (from GUI.Begin) + CSRAW static internal void Begin (int instanceID) { + LayoutCache cache = SelectIDList (instanceID, false); + // Make a vertical group to encompass the whole thing + if (Event.current.type == EventType.Layout) { + current.topLevel = cache.topLevel = new GUILayoutGroup (); + current.layoutGroups.Clear (); + current.layoutGroups.Push (current.topLevel); + current.windows = cache.windows = new GUILayoutGroup (); + } else { + current.topLevel = cache.topLevel; + current.layoutGroups = cache.layoutGroups; + current.windows = cache.windows; + } + } + + CSRAW static internal void BeginWindow (int windowID, GUIStyle style, GUILayoutOption[] options) { + LayoutCache cache = SelectIDList (windowID, true); + // Make a vertical group to encompass the whole thing + if (Event.current.type == EventType.Layout) { + current.topLevel = cache.topLevel = new GUILayoutGroup (); + current.topLevel.style = style; + current.topLevel.windowID = windowID; + if (options != null) + current.topLevel.ApplyOptions (options); + current.layoutGroups.Clear (); + current.layoutGroups.Push (current.topLevel); + current.windows = cache.windows = new GUILayoutGroup (); + } else { + current.topLevel = cache.topLevel; + current.layoutGroups = cache. layoutGroups; + current.windows = cache.windows; + } + } + + // TODO: actually make these check... + // *undocumented* + CSRAW static public void BeginGroup (string GroupName) {} + // *undocumented* + CSRAW static public void EndGroup (string groupName) {} + + + static internal void Layout () { + if (current.topLevel.windowID == -1) { + // Normal GUILayout.whatever -outside beginArea calls. + // Here we go over all entries and calculate their sizes + current.topLevel.CalcWidth (); + current.topLevel.SetHorizontal (0, Mathf.Min (Screen.width, current.topLevel.maxWidth)); + current.topLevel.CalcHeight (); + current.topLevel.SetVertical (0, Mathf.Min (Screen.height, current.topLevel.maxHeight)); + +// UNCOMMENT ME TO DEBUG THE ROOT LAYOUT RESULTS +// Debug.Log ("ROOT: " + current.topLevel); + // Layout all beginarea parts... + LayoutFreeGroup (current.windows); + } else { + LayoutSingleGroup (current.topLevel); + LayoutFreeGroup (current.windows); +// Debug.Log ("Windows: " + current.windows); + } + } + + // Global fayout function. Called from EditorWindows (differs from game view in that they use the full window size and try to stretch GUI + // *undocumented* + static internal void LayoutFromEditorWindow () { + current.topLevel.CalcWidth (); + current.topLevel.SetHorizontal (0, Screen.width); + current.topLevel.CalcHeight (); + current.topLevel.SetVertical (0, Screen.height); + +// UNCOMMENT ME TO DEBUG THE EditorWindow ROOT LAYOUT RESULTS +// Debug.Log (current.topLevel); + // Layout all beginarea parts... + LayoutFreeGroup (current.windows); + } + + + // Global layout function. Calculates all sizes of all windows etc & assigns. + // After this call everything has a properly calculated size + // Called by Unity automatically. + // Is public so we can access it from editor inspectors, but not supported by public stuff + // *undocumented* + static internal float LayoutFromInspector (float width) { + if (current.topLevel != null && current.topLevel.windowID == -1) { + // Here we go over all entries and calculate their sizes + current.topLevel.CalcWidth (); + current.topLevel.SetHorizontal (0, width); + current.topLevel.CalcHeight (); + current.topLevel.SetVertical (0, Mathf.Min (Screen.height, current.topLevel.maxHeight)); +// UNCOMMENT ME TO DEBUG THE INSPECTOR +// Debug.Log (current.topLevel); + float height = ((GUILayoutGroup)current.topLevel).minHeight; + // Layout all beginarea parts... + // TODO: NOT SURE HOW THIS WORKS IN AN INSPECTOR + LayoutFreeGroup (current.windows); + return height; + } + else { + if (current.topLevel != null) + LayoutSingleGroup (current.topLevel); + return 0; + } + } + + static internal void LayoutFreeGroup (GUILayoutGroup toplevel) { + foreach (GUILayoutGroup i in toplevel.entries) { + LayoutSingleGroup (i); + } + toplevel.ResetCursor (); + } + + static void LayoutSingleGroup (GUILayoutGroup i) { + if (!i.isWindow) { + // CalcWidth knocks out minWidth with the calculated sizes from its children. Normally, this is fine, but since we're in a fixed-size area, + // we want to maintain that (godammit) + float origMinWidth = i.minWidth; + float origMaxWidth = i.maxWidth; + + // Figure out the group's min & maxWidth. + i.CalcWidth (); + + // Make it as wide as possible, but the Rect supplied takes precedence... + i.SetHorizontal (i.rect.x, Mathf.Clamp (i.maxWidth, origMinWidth, origMaxWidth)); + + // Do the same preservation for CalcHeight... + float origMinHeight = i.minHeight; + float origMaxHeight = i.maxHeight; + + i.CalcHeight (); + // Make it as high as possible, but the Rect supplied takes precedence... + i.SetVertical (i.rect.y, Mathf.Clamp (i.maxHeight, origMinHeight, origMaxHeight)); + +// UNCOMMENT ME TO SEE BEGINAREA/ENDAREA BLOCKS +// Debug.Log (i); + } else { + // Figure out the group's min & maxWidth. + i.CalcWidth (); + + Rect winRect = Internal_GetWindowRect (i.windowID); + + // Make it as wide as possible, but the Rect supplied takes precedence... + i.SetHorizontal (winRect.x, Mathf.Clamp (winRect.width, i.minWidth, i.maxWidth)); + + i.CalcHeight (); + + // Make it as high as possible, but the Rect supplied takes precedence... + i.SetVertical (winRect.y, Mathf.Clamp (winRect.height, i.minHeight, i.maxHeight)); + + // If GUILayout did any resizing, make sure the window reflects this. + + Internal_MoveWindow (i.windowID, i.rect); + } + } + + CUSTOM static private Rect Internal_GetWindowRect (int windowID) + { + return IMGUI::GetWindowRect (GetGUIState (), windowID); + } + + CUSTOM static private void Internal_MoveWindow (int windowID, Rect r) + { + IMGUI::MoveWindowFromLayout (GetGUIState (), windowID, r); + } + + CUSTOM static internal Rect GetWindowsBounds () + { + return IMGUI::GetWindowsBounds (GetGUIState ()); + } + + CSRAW + [System.Security.SecuritySafeCritical] + static GUILayoutGroup CreateGUILayoutGroupInstanceOfType(System.Type LayoutType) + { + if (!typeof(GUILayoutGroup).IsAssignableFrom(LayoutType)) + throw new ArgumentException("LayoutType needs to be of type GUILayoutGroup"); + return (GUILayoutGroup)System.Activator.CreateInstance (LayoutType); + } + + // Generic helper - use this when creating a layoutgroup. It will make sure everything is wired up correctly. + internal static GUILayoutGroup BeginLayoutGroup (GUIStyle style, GUILayoutOption[] options, System.Type LayoutType) { + GUILayoutGroup g; + switch (Event.current.type) { + case EventType.Used: + case EventType.Layout: + g = CreateGUILayoutGroupInstanceOfType (LayoutType); + g.style = style; + if (options != null) + g.ApplyOptions (options); + current.topLevel.Add (g); + break; + default: + g = current.topLevel.GetNext() as GUILayoutGroup; + if (g == null) + throw new ArgumentException("GUILayout: Mismatched LayoutGroup." + Event.current.type); + g.ResetCursor (); + break; + } + current.layoutGroups.Push (g); + current.topLevel = g; + return g; + } + + // The matching end for BeginLayoutGroup + internal static void EndLayoutGroup () { + switch (Event.current.type) { + default: + current.layoutGroups.Pop (); + current.topLevel = (GUILayoutGroup)current.layoutGroups.Peek (); + return; + } + } + + // Generic helper - use this when creating a layoutgroup. It will make sure everything is wired up correctly. + internal static GUILayoutGroup BeginLayoutArea (GUIStyle style, System.Type LayoutType) { + GUILayoutGroup g; + switch (Event.current.type) { + case EventType.Used: + case EventType.Layout: + g = CreateGUILayoutGroupInstanceOfType (LayoutType); + g.style = style; + current.windows.Add (g); + break; + default: + g = current.windows.GetNext() as GUILayoutGroup; + if (g == null) + throw new ArgumentException("GUILayout: Mismatched LayoutGroup." + Event.current.type); + g.ResetCursor (); + break; + } + current.layoutGroups.Push (g); + current.topLevel = g; + return g; + } + + // Trampoline for Editor stuff + //*undocumented* + internal static GUILayoutGroup DoBeginLayoutArea (GUIStyle style, System.Type LayoutType) { + return BeginLayoutArea (style, LayoutType); + } + internal static GUILayoutGroup topLevel { + get { return current.topLevel; } + } + + + /// *listonly* + CSRAW public static Rect GetRect (GUIContent content, GUIStyle style) { return DoGetRect (content, style, null); } + // Reserve layout space for a rectangle for displaying some contents with a specific style. + CSRAW public static Rect GetRect (GUIContent content, GUIStyle style, params GUILayoutOption[] options) { return DoGetRect (content, style, options); } + CSRAW static Rect DoGetRect (GUIContent content, GUIStyle style, GUILayoutOption[] options) { + GUIUtility.CheckOnGUI(); + + switch (Event.current.type) { + case EventType.Layout: { + if (style.isHeightDependantOnWidth) { + current.topLevel.Add (new GUIWordWrapSizer (style, content, options)); + } else { + Vector2 size = style.CalcSize (content); + current.topLevel.Add (new GUILayoutEntry (size.x, size.x, size.y, size.y, style, options)); + } + return kDummyRect; + } + case EventType.Used: + return kDummyRect; + default: + return current.topLevel.GetNext ().rect; + } + } + + /// *listonly* + CSRAW public static Rect GetRect (float width, float height) { return DoGetRect (width, width, height, height, GUIStyle.none, null);} + /// *listonly* + CSRAW public static Rect GetRect (float width, float height, GUIStyle style) {return DoGetRect (width, width, height, height, style, null);} + /// *listonly* + CSRAW public static Rect GetRect (float width, float height, params GUILayoutOption[] options) {return DoGetRect (width, width, height, height, GUIStyle.none, options);} + // Reserve layout space for a rectangle with a fixed content area. + CSRAW public static Rect GetRect (float width, float height, GUIStyle style, params GUILayoutOption[] options) + {return DoGetRect (width, width, height, height, style, options);} + + + + /// *listonly* + CSRAW public static Rect GetRect (float minWidth, float maxWidth, float minHeight, float maxHeight) + { return DoGetRect (minWidth, maxWidth, minHeight, maxHeight, GUIStyle.none, null); } + /// *listonly* + CSRAW public static Rect GetRect (float minWidth, float maxWidth, float minHeight, float maxHeight, GUIStyle style) + { return DoGetRect (minWidth, maxWidth, minHeight, maxHeight, style, null); } + /// *listonly* + CSRAW public static Rect GetRect (float minWidth, float maxWidth, float minHeight, float maxHeight, params GUILayoutOption[] options) + { return DoGetRect (minWidth, maxWidth, minHeight, maxHeight, GUIStyle.none, options); } + // Reserve layout space for a flexible rect. + CSRAW public static Rect GetRect (float minWidth, float maxWidth, float minHeight, float maxHeight, GUIStyle style, params GUILayoutOption[] options) + { return DoGetRect (minWidth, maxWidth, minHeight, maxHeight, style, options); } + CSRAW static Rect DoGetRect (float minWidth, float maxWidth, float minHeight, float maxHeight, GUIStyle style, GUILayoutOption[] options) { + switch (Event.current.type) { + case EventType.Layout: + current.topLevel.Add (new GUILayoutEntry (minWidth, maxWidth, minHeight, maxHeight, style, options)); + return kDummyRect; + case EventType.Used: + return kDummyRect; + default: + return current.topLevel.GetNext ().rect; + } + } + + // Get the rectangle last used by GUILayout for a control. + CSRAW public static Rect GetLastRect () { + switch (Event.current.type) { + case EventType.Layout: + return kDummyRect; + case EventType.Used: + return kDummyRect; + default: + return current.topLevel.GetLast (); + } + } + + /// *listonly* + CSRAW public static Rect GetAspectRect (float aspect) { return DoGetAspectRect (aspect, GUIStyle.none, null); } + /// *listonly* + CSRAW public static Rect GetAspectRect (float aspect, GUIStyle style) { return DoGetAspectRect (aspect, style, null); } + /// *listonly* + CSRAW public static Rect GetAspectRect (float aspect, params GUILayoutOption[] options) { return DoGetAspectRect (aspect, GUIStyle.none, options); } + // Reserve layout space for a rectangle with a specific aspect ratio. + CSRAW public static Rect GetAspectRect (float aspect, GUIStyle style, params GUILayoutOption[] options) { return DoGetAspectRect (aspect, GUIStyle.none, options); } + static Rect DoGetAspectRect (float aspect, GUIStyle style, GUILayoutOption[] options) { + switch (Event.current.type) { + case EventType.Layout: + current.topLevel.Add (new GUIAspectSizer (aspect, options)); + return kDummyRect; + case EventType.Used: + return kDummyRect; + default: + return current.topLevel.GetNext ().rect; + } + } + + // Style used by space elements so we can do special handling of spaces. + CSRAW internal static GUIStyle spaceStyle + { + get + { + if (s_SpaceStyle == null) s_SpaceStyle = new GUIStyle(); + s_SpaceStyle.stretchWidth = false; + return s_SpaceStyle; + } + } + static GUIStyle s_SpaceStyle; +END + + +// Basic layout element +NONSEALED_CLASS internal GUILayoutEntry + CSRAW + // The min and max sizes. Used during calculations... + CSRAW public float minWidth, maxWidth, minHeight, maxHeight; + + // The rectangle that this element ends up having + CSRAW public Rect rect = new Rect (0,0,0,0); + + // Can this element stretch? + CSRAW public int stretchWidth, stretchHeight; + + // The style to use. + CSRAW GUIStyle m_Style = GUIStyle.none; + CSRAW public GUIStyle style { get { return m_Style; } set { m_Style = value; ApplyStyleSettings (value); } } + + CSRAW internal static Rect kDummyRect = new Rect (0,0,1,1); + + // The margins of this element. + public virtual RectOffset margin { get { + return style.margin; + }} + + public GUILayoutEntry (float _minWidth, float _maxWidth, float _minHeight, float _maxHeight, GUIStyle _style) { + minWidth = _minWidth; + maxWidth = _maxWidth; + minHeight = _minHeight; + maxHeight = _maxHeight; + if (_style == null) + _style = GUIStyle.none; + style = _style; + } + + public GUILayoutEntry (float _minWidth, float _maxWidth, float _minHeight, float _maxHeight, GUIStyle _style, GUILayoutOption[] options) { + minWidth = _minWidth; + maxWidth = _maxWidth; + minHeight = _minHeight; + maxHeight = _maxHeight; + style = _style; + ApplyOptions (options); + } + + public virtual void CalcWidth () {} + public virtual void CalcHeight () {} + public virtual void SetHorizontal (float x, float width) { rect.x = x; rect.width = width; } + public virtual void SetVertical (float y, float height) { rect.y = y; rect.height = height; } + + protected virtual void ApplyStyleSettings (GUIStyle style) { + stretchWidth = (style.fixedWidth == 0 && style.stretchWidth) ? 1 : 0; + stretchHeight = (style.fixedHeight == 0 && style.stretchHeight) ? 1 : 0; + m_Style = style; + } + + public virtual void ApplyOptions (GUILayoutOption[] options) { + if (options == null) + return; + foreach (GUILayoutOption i in options) { + switch (i.type) { + case GUILayoutOption.Type.fixedWidth: minWidth = maxWidth = (float)i.value; stretchWidth = 0; break; + case GUILayoutOption.Type.fixedHeight: minHeight = maxHeight = (float)i.value; stretchHeight = 0; break; + case GUILayoutOption.Type.minWidth: minWidth = (float)i.value; if (maxWidth < minWidth) maxWidth = minWidth; break; + case GUILayoutOption.Type.maxWidth: maxWidth = (float)i.value; if (minWidth > maxWidth) minWidth = maxWidth; stretchWidth = 0; break; + case GUILayoutOption.Type.minHeight: minHeight = (float)i.value; if (maxHeight < minHeight) maxHeight = minHeight; break; + case GUILayoutOption.Type.maxHeight: maxHeight = (float)i.value; if (minHeight > maxHeight) minHeight = maxHeight; stretchHeight = 0; break; + case GUILayoutOption.Type.stretchWidth: stretchWidth = (int)i.value; break; + case GUILayoutOption.Type.stretchHeight: stretchHeight = (int)i.value; break; + } + } + if (maxWidth != 0 && maxWidth < minWidth) + maxWidth = minWidth; + if (maxHeight != 0 && maxHeight < minHeight) + maxHeight = minHeight; + + } + + protected static int indent = 0; + public override string ToString () { + string space = ""; + for (int i = 0; i < indent; i++) + space += " "; + return space + UnityString.Format ("{1}-{0} (x:{2}-{3}, y:{4}-{5})", style != null ? style.name : "NULL", GetType(), rect.x, rect.xMax, rect.y, rect.yMax) + + " - W: " + minWidth + "-" + maxWidth + (stretchWidth != 0 ? "+" : "") + ", H: " + minHeight + "-" + maxHeight + (stretchHeight != 0 ? "+" : ""); + } +END + +// *undocumented* +NONSEALED_CLASS internal GUILayoutGroup : GUILayoutEntry + CSRAW + public List<GUILayoutEntry> entries = new List<GUILayoutEntry>(); + public bool isVertical = true; // Is this group vertical + public bool resetCoords = false; // Reset coordinate for GetRect. Used for groups that are part of a window + public float spacing = 0; // Spacing between the elements contained within + public bool sameSize = true; // Are all subelements the same size + public bool isWindow = false; // Is this a window at all? + public int windowID = -1; // Optional window ID for toplevel windows. Used by Layout to tell GUI.Window of size changes... + int cursor = 0; + protected int stretchableCountX = 100, stretchableCountY = 100; + protected bool userSpecifiedWidth = false, userSpecifiedHeight = false; + // Should all elements be the same size? + // TODO: implement +// CSRAW bool equalSize = false; + + // The summed sizes of the children. This is used to determine whether or not the children should be stretched + CSRAW protected float childMinWidth = 100, childMaxWidth = 100, childMinHeight = 100, childMaxHeight = 100; + + // How are subelements justified along the minor direction? + // TODO: implement +// CSRAW enum Align { start, middle, end, justify } +// CSRAW Align align; + + RectOffset m_Margin = new RectOffset(); + public override RectOffset margin { get { + return m_Margin; + }} + + + public GUILayoutGroup () : base (0,0,0,0,GUIStyle.none) {} + +#if !UNITY_FLASH && !UNITY_WEBGL + public GUILayoutGroup (GUIStyle _style, GUILayoutOption[] options) : base (0,0,0,0, _style) { + if (options != null) + ApplyOptions (options); + m_Margin.left = _style.margin.left; + m_Margin.right = _style.margin.right; + m_Margin.top = _style.margin.top; + m_Margin.bottom = _style.margin.bottom; + } +#endif + + public override void ApplyOptions (GUILayoutOption[] options) { + if (options == null) + return; + base.ApplyOptions (options); + foreach (GUILayoutOption i in options) { + switch (i.type) { + case GUILayoutOption.Type.fixedWidth: + case GUILayoutOption.Type.minWidth: + case GUILayoutOption.Type.maxWidth: + userSpecifiedHeight = true; + break; + case GUILayoutOption.Type.fixedHeight: + case GUILayoutOption.Type.minHeight: + case GUILayoutOption.Type.maxHeight: + userSpecifiedWidth = true; + break; +// TODO: +// case GUILayoutOption.Type.alignStart: align = Align.start; break; +// case GUILayoutOption.Type.alignMiddle: align = Align.middle; break; +// case GUILayoutOption.Type.alignEnd: align = Align.end; break; +// case GUILayoutOption.Type.alignJustify: align = Align.justify; break; +// case GUILayoutOption.Type.equalSize: equalSize = true; break; + case GUILayoutOption.Type.spacing: spacing = (int)i.value; break; + } + } + } + + protected override void ApplyStyleSettings (GUIStyle style) { + base.ApplyStyleSettings (style); + RectOffset mar = style.margin; + m_Margin.left = mar.left; + m_Margin.right = mar.right; + m_Margin.top = mar.top; + m_Margin.bottom = mar.bottom; + } + + public void ResetCursor () { cursor = 0; } + + public Rect PeekNext () { + if(cursor < entries.Count) { + GUILayoutEntry e = (GUILayoutEntry)entries[cursor]; + return e.rect; + } else { + throw new ArgumentException("Getting control " + cursor + "'s position in a group with only " + entries.Count + " controls when doing " + Event.current.rawType + "\nAborting"); + } + } + + public GUILayoutEntry GetNext () { + if(cursor < entries.Count) { + GUILayoutEntry e = (GUILayoutEntry)entries[cursor]; + cursor++; + return e; + } else { + throw new ArgumentException("Getting control " + cursor + "'s position in a group with only " + entries.Count + " controls when doing " + Event.current.rawType + "\nAborting"); + } + } + + //* undocumented + public Rect GetLast () { + if (cursor == 0) { + Debug.LogError ("You cannot call GetLast immediately after beginning a group."); + return kDummyRect; + } + if(cursor <= entries.Count) { + GUILayoutEntry e = (GUILayoutEntry)entries[cursor - 1]; + return e.rect; + } else { + Debug.LogError ("Getting control " + cursor + "'s position in a group with only " + entries.Count + " controls when doing " + Event.current.type); + return kDummyRect; + } + } + + + public void Add (GUILayoutEntry e) { + entries.Add (e); + } + + CSRAW public override void CalcWidth () { + if (entries.Count == 0) { + maxWidth = minWidth = style.padding.horizontal; + return; + } + + childMinWidth = 0; childMaxWidth = 0; + int _leftMarginMin = 0, _rightMarginMin = 0; + stretchableCountX = 0; + bool first = true; + if (isVertical) { + foreach (GUILayoutEntry i in entries) { + i.CalcWidth (); + RectOffset margins = i.margin; + if (i.style != GUILayoutUtility.spaceStyle) { + if (!first) { + _leftMarginMin = Mathf.Min (margins.left, _leftMarginMin); + _rightMarginMin = Mathf.Min (margins.right, _rightMarginMin); + } else { + _leftMarginMin = margins.left; + _rightMarginMin = margins.right; + first = false; + } + childMinWidth = Mathf.Max (i.minWidth + margins.horizontal, childMinWidth); + childMaxWidth = Mathf.Max (i.maxWidth + margins.horizontal, childMaxWidth); + } + stretchableCountX += i.stretchWidth; + } + // Before, we added the margins to the width, now we want to suptract them again. + childMinWidth -= _leftMarginMin + _rightMarginMin; + childMaxWidth -= _leftMarginMin + _rightMarginMin; + + } else { + int lastMargin = 0; + foreach (GUILayoutEntry i in entries) { + i.CalcWidth (); + RectOffset m = i.margin; + int margin; + + // Specialcase spaceStyle - instead of handling margins normally, we just want to insert the size... + // This ensure that Space(1) adds ONE space, and doesn't prevent margin collapses + if (i.style != GUILayoutUtility.spaceStyle) { + if (!first) + margin = lastMargin > m.left ? lastMargin : m.left; + else { + // the first element's margins are handles _leftMarginMin and should not be added to the children's sizes + margin = 0; + first = false; + } + childMinWidth += i.minWidth + spacing + margin; + childMaxWidth += i.maxWidth + spacing + margin; + lastMargin = m.right; + stretchableCountX += i.stretchWidth; + } else { + childMinWidth += i.minWidth; + childMaxWidth += i.maxWidth; + stretchableCountX += i.stretchWidth; + } + } + childMinWidth -= spacing; + childMaxWidth -= spacing; + if (entries.Count != 0) { + _leftMarginMin = ((GUILayoutEntry)entries[0]).margin.left; + _rightMarginMin = lastMargin; + } else { + _leftMarginMin = _rightMarginMin = 0; + } + } + // Catch the cases where we have ONLY space elements in a group + + // calculated padding values. + float leftPadding = 0, rightPadding = 0; + + // If we have a style, the margins are handled i.r.t. padding. + if (style != GUIStyle.none || userSpecifiedWidth) { + // Add the padding of this group to the total min & max widths + leftPadding = Mathf.Max (style.padding.left, _leftMarginMin); + rightPadding = Mathf.Max (style.padding.right, _rightMarginMin); + } + else { + // If we don't have a GUIStyle, we pop the min of margins outward from children on to us. + m_Margin.left = _leftMarginMin; + m_Margin.right = _rightMarginMin; + leftPadding = rightPadding = 0; + } + + // If we have a specified minwidth, take that into account... + minWidth = Mathf.Max (minWidth, childMinWidth + leftPadding + rightPadding); + + if (maxWidth == 0) { // if we don't have a max width, take the one that was calculated + stretchWidth += stretchableCountX + (style.stretchWidth ? 1 : 0); + maxWidth = childMaxWidth + leftPadding + rightPadding; + } else { + // Since we have a maximum width, this element can't stretch width. + stretchWidth = 0; + } + // Finally, if our minimum width is greater than our maximum width, minWidth wins + maxWidth = Mathf.Max (maxWidth, minWidth); + + // If the style sets us to be a fixed width that wins completely + if (style.fixedWidth != 0) { + maxWidth = minWidth = style.fixedWidth; + stretchWidth = 0; + } + } + + public override void SetHorizontal (float x, float width) { + base.SetHorizontal (x, width); + + if (resetCoords) + x = 0; + + RectOffset padding = style.padding; + + if (isVertical) { + // If we have a GUIStyle here, spacing from our edges to children are max (our padding, their margins) + if (style != GUIStyle.none) { + foreach (GUILayoutEntry i in entries) { + // NOTE: we can't use .horizontal here (As that could make things like right button margin getting eaten by large left padding - so we need to split up in left and right + float leftMar = Mathf.Max (i.margin.left, padding.left); + float thisX = x + leftMar; + float thisWidth = width - Mathf.Max (i.margin.right, padding.right) - leftMar; + if (i.stretchWidth != 0) + i.SetHorizontal (thisX, thisWidth); + else + i.SetHorizontal (thisX, Mathf.Clamp (thisWidth, i.minWidth, i.maxWidth)); + } + } else { + // If not, PART of the subelements' margins have already been propagated upwards to this group, so we need to subtract that from what we apply + float thisX = x - margin.left; + float thisWidth = width + margin.horizontal; + foreach (GUILayoutEntry i in entries) { + if (i.stretchWidth != 0) { + i.SetHorizontal (thisX + i.margin.left, thisWidth - i.margin.horizontal); + } else + i.SetHorizontal (thisX + i.margin.left, Mathf.Clamp (thisWidth - i.margin.horizontal, i.minWidth, i.maxWidth)); + } + } + } else { // we're horizontally laid out: + // apply margins/padding here + // If we have a style, adjust the sizing to take care of padding (if we don't the horizontal margins have been propagated fully up the hierarchy)... + if (style != GUIStyle.none) { + float leftMar = padding.left, rightMar = padding.right; + if (entries.Count != 0) { + leftMar = Mathf.Max (leftMar, ((GUILayoutEntry)entries[0]).margin.left); + rightMar = Mathf.Max (rightMar, ((GUILayoutEntry)entries[entries.Count - 1]).margin.right); + } + x += leftMar; + width -= rightMar + leftMar; + } + + // Find out how much leftover width we should distribute. + float widthToDistribute = width - spacing * (entries.Count - 1); + // Where to place us in height between min and max + float minMaxScale = 0; + // How much height to add to stretchable elements + if (childMinWidth != childMaxWidth) + minMaxScale = Mathf.Clamp ((widthToDistribute - childMinWidth) / (childMaxWidth - childMinWidth), 0, 1); + + // Handle stretching + float perItemStretch = 0; + if (widthToDistribute > childMaxWidth) { // If we have too much space, we need to distribute it. + if (stretchableCountX > 0) { + perItemStretch = (widthToDistribute - childMaxWidth) / (float)stretchableCountX; + } + } + + // Set the positions + int lastMargin = 0; + bool firstMargin = true; +// Debug.Log ("" + x + ", " + width + " perItemStretch:" + perItemStretch); +// Debug.Log ("MinMaxScale"+ minMaxScale); + foreach (GUILayoutEntry i in entries) { + float thisWidth = Mathf.Lerp (i.minWidth, i.maxWidth, minMaxScale); +// Debug.Log (i.minWidth); + thisWidth += perItemStretch * i.stretchWidth; + + if (i.style != GUILayoutUtility.spaceStyle) { // Skip margins on spaces. + int leftMargin = i.margin.left; + if (firstMargin) { + leftMargin = 0; + firstMargin = false; + } + int margin = lastMargin > leftMargin ? lastMargin : leftMargin; + x += margin; + lastMargin = i.margin.right; + } + + i.SetHorizontal (Mathf.Round (x), Mathf.Round(thisWidth)); + x += thisWidth + spacing; + } + } + } + + public override void CalcHeight () { + if (entries.Count == 0) { + maxHeight = minHeight = style.padding.vertical; + return; + } + + childMinHeight = childMaxHeight = 0; + int _topMarginMin = 0, _bottomMarginMin = 0; + stretchableCountY = 0; + if (isVertical) { + int lastMargin = 0; + bool first = true; + foreach (GUILayoutEntry i in entries) { + i.CalcHeight (); + RectOffset m = i.margin; + int margin; + + // Specialcase spaces - it's a space, so instead of handling margins normally, we just want to insert the size... + // This ensure that Space(1) adds ONE space, and doesn't prevent margin collapses + if (i.style != GUILayoutUtility.spaceStyle) { + if (!first) + margin = Mathf.Max(lastMargin, m.top); + else { + margin = 0; + first = false; + } + + childMinHeight += i.minHeight + spacing + margin; + childMaxHeight += i.maxHeight + spacing + margin; + lastMargin = m.bottom; + stretchableCountY += i.stretchHeight; + } else { + childMinHeight += i.minHeight; + childMaxHeight += i.maxHeight; + stretchableCountY += i.stretchHeight; + } + } + + childMinHeight -= spacing; + childMaxHeight -= spacing; + if (entries.Count != 0) { + _topMarginMin = ((GUILayoutEntry)entries[0]).margin.top; + _bottomMarginMin = lastMargin; + } else { + _bottomMarginMin = _topMarginMin = 0; + } + } else { + bool first = true; + foreach (GUILayoutEntry i in entries) { + i.CalcHeight (); + RectOffset margins = i.margin; + if (i.style != GUILayoutUtility.spaceStyle) { + if (!first) { + _topMarginMin = Mathf.Min (margins.top, _topMarginMin); + _bottomMarginMin = Mathf.Min (margins.bottom, _bottomMarginMin); + } else { + _topMarginMin = margins.top; + _bottomMarginMin = margins.bottom; + first = false; + } + childMinHeight = Mathf.Max (i.minHeight, childMinHeight); + childMaxHeight = Mathf.Max (i.maxHeight, childMaxHeight); + } + stretchableCountY += i.stretchHeight; + } + } + float firstPadding = 0, lastPadding = 0; + + // If we have a style, the margins are handled i.r.t. padding. + if (style != GUIStyle.none || userSpecifiedHeight) { + // Add the padding of this group to the total min & max widths + firstPadding = Mathf.Max (style.padding.top, _topMarginMin); + lastPadding = Mathf.Max (style.padding.bottom, _bottomMarginMin); + } + else { + // If we don't have a GUIStyle, we bubble the margins outward from children on to us. + m_Margin.top = _topMarginMin; + m_Margin.bottom = _bottomMarginMin; + firstPadding = lastPadding = 0; + } + //Debug.Log ("Margins: " + _topMarginMin + ", " + _bottomMarginMin + " childHeights:" + childMinHeight + ", " + childMaxHeight); + // If we have a specified minheight, take that into account... + minHeight = Mathf.Max (minHeight, childMinHeight + firstPadding + lastPadding); + + if (maxHeight == 0) { // if we don't have a max height, take the one that was calculated + stretchHeight += stretchableCountY + (style.stretchHeight ? 1 : 0); + maxHeight = childMaxHeight + firstPadding + lastPadding; + } else { + // Since we have a maximum height, this element can't stretch height. + stretchHeight = 0; + } + // Finally, if out minimum height is greater than our maximum height, minHeight wins + maxHeight = Mathf.Max (maxHeight, minHeight); + + // If the style sets us to be a fixed height + if (style.fixedHeight != 0) { + maxHeight = minHeight = style.fixedHeight; + stretchHeight = 0; + } + } + + public override void SetVertical (float y, float height) { + base.SetVertical (y, height); + + if (entries.Count == 0) + return; + + RectOffset padding = style.padding; + + if (resetCoords) + y = 0; + + if (isVertical) { + // If we have a skin, adjust the sizing to take care of padding (if we don't have a skin the vertical margins have been propagated fully up the hierarchy)... + if (style != GUIStyle.none) { + float topMar = padding.top, bottomMar = padding.bottom; + if (entries.Count != 0) { + topMar = Mathf.Max (topMar, ((GUILayoutEntry)entries[0]).margin.top); + bottomMar = Mathf.Max (bottomMar, ((GUILayoutEntry)entries[entries.Count - 1]).margin.bottom); + } + y += topMar; + height -= bottomMar + topMar; + } + + // Find out how much leftover height we should distribute. + float heightToDistribute = height - spacing * (entries.Count - 1); + // Where to place us in height between min and max + float minMaxScale = 0; + // How much height to add to stretchable elements + if (childMinHeight != childMaxHeight) + minMaxScale = Mathf.Clamp ((heightToDistribute - childMinHeight) / (childMaxHeight - childMinHeight), 0, 1); + + // Handle stretching + float perItemStretch = 0; + if (heightToDistribute > childMaxHeight) { // If we have too much space - stretch any stretchable children + if (stretchableCountY > 0) + perItemStretch = (heightToDistribute - childMaxHeight) / (float)stretchableCountY; + } + + // Set the positions + int lastMargin = 0; + bool firstMargin = true; + foreach (GUILayoutEntry i in entries) { + float thisHeight = Mathf.Lerp (i.minHeight, i.maxHeight, minMaxScale); + thisHeight += perItemStretch * i.stretchHeight; + + if (i.style != GUILayoutUtility.spaceStyle) { // Skip margins on spaces. + int topMargin = i.margin.top; + if (firstMargin) { + topMargin = 0; + firstMargin = false; + } + int margin = lastMargin > topMargin ? lastMargin : topMargin; + y += margin; + lastMargin = i.margin.bottom; + } + i.SetVertical (Mathf.Round (y), Mathf.Round(thisHeight)); + y += thisHeight + spacing; + } + } else { + // If we have a GUIStyle here, we need to respect the subelements' margins + if (style != GUIStyle.none) { + foreach (GUILayoutEntry i in entries) { + float topMar = Mathf.Max (i.margin.top, padding.top); + float thisY = y + topMar; + float thisHeight = height - Mathf.Max (i.margin.bottom, padding.bottom) - topMar; + + if (i.stretchHeight != 0) + i.SetVertical (thisY, thisHeight); + else { + i.SetVertical (thisY, Mathf.Clamp (thisHeight, i.minHeight, i.maxHeight)); + } + } + } else { + // If not, the subelements' margins have already been propagated upwards to this group, so we can safely ignore them + float thisY = y - margin.top; + float thisHeight = height + margin.vertical; + foreach (GUILayoutEntry i in entries) { + if (i.stretchHeight != 0) + i.SetVertical (thisY +i.margin.top, thisHeight - i.margin.vertical); + else { + i.SetVertical (thisY + i.margin.top, Mathf.Clamp (thisHeight - i.margin.vertical, i.minHeight, i.maxHeight)); + } + } + + } + } + } + + public override string ToString () { + string str = "", space = ""; + for (int i = 0; i < indent; i++) + space += " "; + str += /* space + */ base.ToString () + " Margins: " + childMinHeight + " {\n"; + indent += 4; + foreach (GUILayoutEntry i in entries) { + str += i.ToString() + "\n"; + } + str += space + "}"; + indent -= 4; + return str; + } +END + +// Layout controller for content inside scroll views +CLASS internal GUIScrollGroup : GUILayoutGroup + CSRAW + public float calcMinWidth, calcMaxWidth, calcMinHeight, calcMaxHeight; + public float clientWidth, clientHeight; + public bool allowHorizontalScroll = true; + public bool allowVerticalScroll = true; + public bool needsHorizontalScrollbar, needsVerticalScrollbar; + public GUIStyle horizontalScrollbar, verticalScrollbar; + + public override void CalcWidth () { + // Save the size values & reset so we calc the sizes of children without any contraints + float _minWidth = minWidth; + float _maxWidth = maxWidth; + if (allowHorizontalScroll) { + minWidth = 0; + maxWidth = 0; + } + + base.CalcWidth(); + calcMinWidth = minWidth; + calcMaxWidth = maxWidth; + + // restore the stored constraints for our parent's sizing + if (allowHorizontalScroll) { + + // Set an explicit small minWidth so it will correctly scroll when place inside horizontal groups + if (minWidth > 32) + minWidth = 32; + + if (_minWidth != 0) + minWidth = _minWidth; + if (_maxWidth != 0) { + maxWidth = _maxWidth; + stretchWidth = 0; + } + } + } + + public override void SetHorizontal (float x, float width) { + float _cWidth = needsVerticalScrollbar ? width - verticalScrollbar.fixedWidth - verticalScrollbar.margin.left : width; + //if (allowVerticalScroll == false) + // Debug.Log ("width " + width); + // If we get a vertical scrollbar, the width changes, so we need to do a recalculation with the new width. + if (allowHorizontalScroll && _cWidth < calcMinWidth) { + // We're too small horizontally, so we need a horizontal scrollbar. + needsHorizontalScrollbar = true; + + // set the min and max width we calculated for the children so SetHorizontal works correctly + minWidth = calcMinWidth; + maxWidth = calcMaxWidth; + base.SetHorizontal (x, calcMinWidth); + + // SetHorizontal also sets our width, but we know better + rect.width = width; + + clientWidth = calcMinWidth; + } else { + // Got enough space. + needsHorizontalScrollbar = false; + + // set the min and max width we calculated for the children so SetHorizontal works correctly + if (allowHorizontalScroll) { + minWidth = calcMinWidth; + maxWidth = calcMaxWidth; + } + base.SetHorizontal (x, _cWidth); + rect.width = width; + + // Store the client width + clientWidth = _cWidth; + } + } + + public override void CalcHeight () { + // Save the values & reset so we calc the sizes of children without any contraints + float _minHeight = minHeight; + float _maxHeight = maxHeight; + if (allowVerticalScroll) + { + minHeight = 0; + maxHeight = 0; + } + + base.CalcHeight(); + + calcMinHeight = minHeight; + calcMaxHeight = maxHeight; + + // if we KNOW we need a horizontal scrollbar, claim space for it now + // otherwise we get a vertical scrollbar and leftover space beneath the scrollview. + if (needsHorizontalScrollbar) { + float scrollerSize = horizontalScrollbar.fixedHeight + horizontalScrollbar.margin.top; + minHeight += scrollerSize; + maxHeight += scrollerSize; + } + + // restore the stored constraints from user SetHeight calls. + if (allowVerticalScroll) + { + if (minHeight > 32) + minHeight = 32; + + if (_minHeight != 0) + minHeight = _minHeight; + if (_maxHeight != 0) + { + maxHeight = _maxHeight; + stretchHeight = 0; + } + } + } + + public override void SetVertical (float y, float height) { + // if we have a horizontal scrollbar, we have less space than we thought + float availableHeight = height; + if (needsHorizontalScrollbar) + availableHeight -= horizontalScrollbar.fixedHeight + horizontalScrollbar.margin.top; + + // Now we know how much height we have, and hence how much vertical space to distribute. + // If we get a vertical scrollbar, the width changes, so we need to do a recalculation with the new width. + if (allowVerticalScroll && availableHeight < calcMinHeight) + { + // We're too small vertically, so we need a vertical scrollbar. + // This means that we have less horizontal space, which can change the vertical size. + if (!needsHorizontalScrollbar && !needsVerticalScrollbar) { + // Subtract scrollbar width from the size... + clientWidth = rect.width - verticalScrollbar.fixedWidth - verticalScrollbar.margin.left; + + // ...But make sure we never get too small. + if (clientWidth < calcMinWidth) + clientWidth = calcMinWidth; + + // Set the new (smaller) size. + float outsideWidth = rect.width; // store a backup of our own width + SetHorizontal (rect.x, clientWidth); + + // This can have caused a reflow, so we need to recalclate from here on down + // (we already know we need a vertical scrollbar, so this size change cannot bubble upwards. + CalcHeight(); + + rect.width = outsideWidth; + } + + + // set the min and max height we calculated for the children so SetVertical works correctly + float origMinHeight = minHeight, origMaxHeight = maxHeight; + minHeight = calcMinHeight; + maxHeight = calcMaxHeight; + base.SetVertical (y, calcMinHeight); + minHeight = origMinHeight; + maxHeight = origMaxHeight; + + rect.height = height; + clientHeight = calcMinHeight; + } else { + + // set the min and max height we calculated for the children so SetVertical works correctly + if (allowVerticalScroll) + { + minHeight = calcMinHeight; + maxHeight = calcMaxHeight; + } + base.SetVertical (y, availableHeight); + rect.height = height; + clientHeight = availableHeight; + } + } +END + +// Layouter that makes elements which sizes will always conform to a specific aspect ratio. +CLASS internal GUIAspectSizer : GUILayoutEntry + CSRAW float aspect; + + public GUIAspectSizer (float aspect, GUILayoutOption[] options) : base (0,0,0,0,GUIStyle.none) { + this.aspect = aspect; + ApplyOptions (options); + } + + public override void CalcHeight () { + minHeight = maxHeight = rect.width / aspect; + } +END + +// Will layout a button grid so it can fit within the given rect. +// *undocumented* +CLASS internal GUIGridSizer : GUILayoutEntry + CSRAW + // Helper: Create the layout group and scale it to fit + public static Rect GetRect (GUIContent[] contents, int xCount, GUIStyle style, GUILayoutOption[] options) { + Rect r = new Rect (0,0,0,0); + switch (Event.current.type) { + case EventType.Layout: { + GUILayoutUtility.current.topLevel.Add (new GUIGridSizer (contents, xCount, style, options)); + break; + } + case EventType.Used: + return kDummyRect; + default: + r = GUILayoutUtility.current.topLevel.GetNext ().rect; + break; + } + return r; + } + int count; + int xCount; + float minButtonWidth = -1, maxButtonWidth = -1, minButtonHeight = -1, maxButtonHeight = -1; + + // Cache of the content for wordwrapping. + //GUIContent[] cachedContent; + + private GUIGridSizer (GUIContent[] contents, int _xCount, GUIStyle buttonStyle, GUILayoutOption[] options) : base (0,0,0,0,GUIStyle.none) { + count = contents.Length; + xCount = _xCount; + + // Most settings comes from the button style (can we stretch, etc). Hence, I apply the style here + ApplyStyleSettings (buttonStyle); + + // We can have custom options coming from userland. We apply this last so it overrides + ApplyOptions (options); + + if (_xCount == 0 || contents.Length == 0) + return; + + // if we don't have wordwrap, there is no funky width<->height relationship. Hence, we can calculate everything here: + // TODO: Actually make it work with wordwrapping stuff (that is pretty hard) +// if (!buttonStyle.wordWrap) { + + // internal horizontal spacing + float totalHorizSpacing = Mathf.Max (buttonStyle.margin.left,buttonStyle.margin.right) * (xCount - 1); +// Debug.Log (String.Format ("margins: {0}, {1} totalHoriz: {2}", buttonStyle.margin.left, buttonStyle.margin.right, totalHorizSpacing)); + // internal horizontal margins + float totalVerticalSpacing = Mathf.Max (buttonStyle.margin.top, buttonStyle.margin.bottom) * (rows - 1); + + + // Handle fixedSize buttons + if (buttonStyle.fixedWidth != 0) + minButtonWidth = maxButtonWidth = buttonStyle.fixedWidth; +// Debug.Log ("buttonStyle.fixedHeight " + buttonStyle.fixedHeight); + if (buttonStyle.fixedHeight != 0) + minButtonHeight = maxButtonHeight = buttonStyle.fixedHeight; + + // Apply GUILayout.Width/Height/whatever properties. + if (minButtonWidth == -1) { + if (minWidth != 0) + minButtonWidth = (minWidth - totalHorizSpacing) / xCount; + if (maxWidth != 0) + maxButtonWidth = (maxWidth - totalHorizSpacing) / xCount; + } + + if (minButtonHeight == -1) { + if (minHeight != 0) + minButtonHeight = (minHeight - totalVerticalSpacing) / rows; + if (maxHeight != 0) + maxButtonHeight = (maxHeight - totalVerticalSpacing) / rows; + } +// Debug.Log (String.Format ("minButtonWidth {0}, maxButtonWidth {1}, minButtonHeight {2}, maxButtonHeight{3}", minButtonWidth, maxButtonWidth, minButtonHeight, maxButtonHeight)); + + // if anything is left unknown, we need to iterate over all elements and figure out the sizes. + if (minButtonHeight == -1 || maxButtonHeight == -1 || minButtonWidth == -1 || maxButtonWidth == -1) { + // figure out the max size. Since the buttons are in a grid, the max size determines stuff. + float calcHeight = 0, calcWidth = 0; + foreach (GUIContent i in contents) { + Vector2 size = buttonStyle.CalcSize (i); + calcWidth = Mathf.Max (calcWidth, size.x); + calcHeight = Mathf.Max (calcHeight, size.y); + } + + // If the user didn't supply minWidth, we need to calculate that + if (minButtonWidth == -1) { + // if the user has supplied a maxButtonWidth, the buttons can never get larger. + if (maxButtonWidth != -1) + minButtonWidth = Mathf.Min (calcWidth, maxButtonWidth); + else + minButtonWidth = calcWidth; + } + + // If the user didn't supply maxWidth, we need to calculate that + if (maxButtonWidth == -1) { + // if the user has supplied a minButtonWidth, the buttons can never get smaler. + if (minButtonWidth != -1) + maxButtonWidth = Mathf.Max (calcWidth, minButtonWidth); + else + maxButtonWidth = calcWidth; + } + + // If the user didn't supply minWidth, we need to calculate that + if (minButtonHeight == -1) { + // if the user has supplied a maxButtonWidth, the buttons can never get larger. + if (maxButtonHeight != -1) + minButtonHeight = Mathf.Min (calcHeight, maxButtonHeight); + else + minButtonHeight = calcHeight; + } + + // If the user didn't supply maxWidth, we need to calculate that + if (maxButtonHeight == -1) { + // if the user has supplied a minButtonWidth, the buttons can never get smaler. + if (minButtonHeight != -1) + maxHeight = Mathf.Max (maxHeight, minButtonHeight); + maxButtonHeight = maxHeight; + } + + } + // We now know the button sizes. Calculate min & max values from that + minWidth = minButtonWidth * xCount + totalHorizSpacing; + maxWidth = maxButtonWidth * xCount + totalHorizSpacing; + minHeight = minButtonHeight * rows + totalVerticalSpacing; + maxHeight = maxButtonHeight * rows + totalVerticalSpacing; +// Debug.Log (String.Format ("minWidth {0}, maxWidth {1}, minHeight {2}, maxHeight{3}", minWidth, maxWidth, minHeight, maxHeight)); + +/* + } else { + // if we're wordwrapping, we need to copy the contents and then do the whole calculations a bit down the road. + cachedContent = new GUIContent [contents.Length]; + for (int i = 0; i < contents.Length; i++) { + cachedContent[i] = new GUIContent (contents[i]); + } + } +*/ + } + + int rows { + get { + int rows = count / xCount; + if (count % xCount != 0) + rows++; + return rows; + } + } +END + +// Class that can handle word-wrap sizing. this is specialcased as setting width can make the text wordwrap, which would then increase height... +CLASS internal GUIWordWrapSizer : GUILayoutEntry + CSRAW + GUIContent content; + // We need to differentiate between min & maxHeight we calculate for ourselves and one that is forced by the user + // (When inside a scrollview, we can be told to layout twice, so we need to know the difference) + float forcedMinHeight, forcedMaxHeight; + public GUIWordWrapSizer (GUIStyle _style, GUIContent _content, GUILayoutOption[] options) : base (0,0,0,0, _style) { + content = new GUIContent (_content); + base.ApplyOptions (options); + forcedMinHeight = minHeight; + forcedMaxHeight = maxHeight; + } + + public override void CalcWidth () { + if (minWidth == 0 || maxWidth == 0) { + float _minWidth, _maxWidth; + style.CalcMinMaxWidth (content, out _minWidth, out _maxWidth); + if (minWidth == 0) + minWidth = _minWidth; + if (maxWidth == 0) + maxWidth = _maxWidth; + } + } + + public override void CalcHeight () { + // When inside a scrollview, this can get called twice (as vertical scrollbar reduces width, which causes a reflow). + // Hence, we need to use the separately cached values for min & maxHeight coming from the user... + if (forcedMinHeight == 0 || forcedMaxHeight == 0) { + float height = style.CalcHeight (content, rect.width); + if (forcedMinHeight == 0) + minHeight = height; + else + minHeight = forcedMinHeight; + if (forcedMaxHeight == 0) + maxHeight = height; + else + maxHeight = forcedMaxHeight; + } + } +END + +// Class internally used to pass layout options into [[GUILayout]] functions. You don't use these directly, but construct them with the layouting functions in the [[GUILayout]] class. +CLASS GUILayoutOption + CSRAW + internal enum Type { + fixedWidth, fixedHeight, minWidth, maxWidth, minHeight, maxHeight, stretchWidth, stretchHeight, + // These are just for the spacing variables + alignStart, alignMiddle, alignEnd, alignJustify, equalSize, spacing + } + // *undocumented* + internal Type type; + // *undocumented* + internal object value; + // *undocumented* + internal GUILayoutOption (Type type, object value) { + this.type = type; + this.value = value; + } +END + + +CSRAW + +} diff --git a/Runtime/Export/GUISkinBindings.txt b/Runtime/Export/GUISkinBindings.txt new file mode 100644 index 0000000..bc6fcca --- /dev/null +++ b/Runtime/Export/GUISkinBindings.txt @@ -0,0 +1,341 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Misc/InputEvent.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEngine +{ + + + +// Which platform to emulate. +ENUM internal PlatformSelection + // The behaviour matches the platform the end user is running on. + Native = 0, + // The behaviour matches a Mac OS X machine. + Mac = 1, + // The behaviour matches a Windows machine. + Windows = 2, +END + +// General settings for how the GUI behaves +CSRAW [System.Serializable] +CLASS GUISettings + // Should double-clicking select words in text fields. + CSRAW public bool doubleClickSelectsWord { get { return m_DoubleClickSelectsWord; } set { m_DoubleClickSelectsWord = value; } } + CSRAW [SerializeField] + CSRAW bool m_DoubleClickSelectsWord = true; + + // Should triple-clicking select whole text in text fields. + CSRAW public bool tripleClickSelectsLine { get { return m_TripleClickSelectsLine; } set { m_TripleClickSelectsLine = value; } } + CSRAW [SerializeField] + CSRAW bool m_TripleClickSelectsLine = true; + + // The color of the cursor in text fields. + CSRAW public Color cursorColor { get { return m_CursorColor; } set { m_CursorColor = value; } } + CSRAW [SerializeField] + CSRAW Color m_CursorColor = Color.white; + + CUSTOM private static float Internal_GetCursorFlashSpeed () { + #if UNITY_OSX && !UNITY_64 + return 60.0f / GetCaretTime(); + #elif UNITY_WIN && !UNITY_WINRT + return 1000.0f / GetCaretBlinkTime(); + #elif UNITY_WII || UNITY_XENON || UNITY_PS3 || UNITY_IPHONE || UNITY_ANDROID || UNITY_PEPPER || UNITY_LINUX || UNITY_FLASH || UNITY_WEBGL || UNITY_WINRT || UNITY_OSX || UNITY_BB10 || UNITY_TIZEN + return 2.0f; + #else + #error "Unknown platform" + #endif + } + + // The speed of text field cursor flashes. + CSRAW public float cursorFlashSpeed { get { + if (m_CursorFlashSpeed >= 0) + return m_CursorFlashSpeed; + else { + return Internal_GetCursorFlashSpeed (); + } + } + set { m_CursorFlashSpeed = value; } } + CSRAW [SerializeField] + CSRAW float m_CursorFlashSpeed = -1; + + // The color of the selection rect in text fields. + CSRAW public Color selectionColor { get { return m_SelectionColor; } set { m_SelectionColor = value; } } + CSRAW [SerializeField] + CSRAW Color m_SelectionColor = new Color (.5f, .5f, 1f); + + // Which platform to match for keyboard focus rules. + // If keyboardFocus is Mac, only text entry labels will be able to revcieve the keyboard focus through tabbing. (GUI.TextField, GUI.TextArea, GUILayout.TextField, GUILayout.TextArea) + // If keyboardFocus is Windows, most controls can be tabbed through. If the end user presses the space bar, the focused control will recieve a mouse click. + // If keyboardFocus is Native, the focus rules will follow whatever platform the end user is running on. +// CSRAW public PlatformSelection keyboardFocus { get { return m_KeyboardFocus; } set { m_KeyboardFocus = value; } } +// CSRAW PlatformSelection m_KeyboardFocus = PlatformSelection.Native; +END + + + +// Defines how GUI looks and behaves. +CSRAW [System.Serializable] +CSRAW [ExecuteInEditMode] +CLASS GUISkin : ScriptableObject + CSRAW [SerializeField] + CSRAW Font m_Font; + + // *undocumented* + CSRAW public GUISkin() + { + m_CustomStyles = new GUIStyle[1]; + } + + CSRAW internal void OnEnable() + { + Apply (); + + foreach (var style in styles.Values) + style.CreateObjectReferences (); + } + + // The default font to use for all styles. + CSRAW public Font font { get { return m_Font; } set { m_Font = value; if (current == this) GUIStyle.SetDefaultFont(m_Font); Apply();} } + + CSRAW [SerializeField] //yes the attribute applies to all fields on the line below. + CSRAW GUIStyle m_box, m_button, m_toggle, m_label, m_textField, m_textArea, m_window; + + // Style used by default for GUI::ref::Box controls. + CSRAW public GUIStyle box { get { return m_box; } set { m_box = value; Apply (); } } + + // Style used by default for GUI::ref::Label controls. + CSRAW public GUIStyle label { get { return m_label; } set { m_label = value; Apply (); } } + + // Style used by default for GUI::ref::TextField controls. + CSRAW public GUIStyle textField { get { return m_textField; } set { m_textField = value; Apply (); } } + + // Style used by default for GUI::ref::TextArea controls. + CSRAW public GUIStyle textArea { get { return m_textArea; } set { m_textArea = value; Apply (); } } + + // Style used by default for GUI::ref::Button controls. + CSRAW public GUIStyle button { get { return m_button; } set { m_button = value; Apply (); } } + + // Style used by default for GUI::ref::Toggle controls. + CSRAW public GUIStyle toggle { get { return m_toggle; } set { m_toggle = value; Apply (); } } + + // Style used by default for Window controls (SA GUI::ref::Window). + CSRAW public GUIStyle window { get { return m_window; } set { m_window = value; Apply (); } } + + CSRAW + [SerializeField] + GUIStyle m_horizontalSlider; + [SerializeField] + GUIStyle m_horizontalSliderThumb; + [SerializeField] + GUIStyle m_verticalSlider; + [SerializeField] + GUIStyle m_verticalSliderThumb; + + // Style used by default for the background part of GUI::ref::HorizontalSlider controls. + CSRAW public GUIStyle horizontalSlider { get { return m_horizontalSlider; } set { m_horizontalSlider = value; Apply (); } } + + // Style used by default for the thumb that is dragged in GUI::ref::HorizontalSlider controls. + CSRAW public GUIStyle horizontalSliderThumb { get { return m_horizontalSliderThumb; } set { m_horizontalSliderThumb = value; Apply (); } } + + // Style used by default for the background part of GUI::ref::VerticalSlider controls. + CSRAW public GUIStyle verticalSlider { get { return m_verticalSlider; } set { m_verticalSlider = value; Apply (); } } + + // Style used by default for the thumb that is dragged in GUI::ref::VerticalSlider controls. + CSRAW public GUIStyle verticalSliderThumb { get { return m_verticalSliderThumb; } set { m_verticalSliderThumb = value; Apply (); } } + + CSRAW + [SerializeField] + GUIStyle m_horizontalScrollbar; + [SerializeField] + GUIStyle m_horizontalScrollbarThumb; + [SerializeField] + GUIStyle m_horizontalScrollbarLeftButton; + [SerializeField] + GUIStyle m_horizontalScrollbarRightButton; + + // Style used by default for the background part of GUI::ref::HorizontalScrollbar controls. + CSRAW public GUIStyle horizontalScrollbar { get { return m_horizontalScrollbar; } set { m_horizontalScrollbar = value; Apply (); } } + // Style used by default for the thumb that is dragged in GUI::ref::HorizontalScrollbar controls. + CSRAW public GUIStyle horizontalScrollbarThumb { get { return m_horizontalScrollbarThumb; } set { m_horizontalScrollbarThumb = value; Apply (); } } + // Style used by default for the left button on GUI::ref::HorizontalScrollbar controls. + CSRAW public GUIStyle horizontalScrollbarLeftButton { get { return m_horizontalScrollbarLeftButton; } set { m_horizontalScrollbarLeftButton = value; Apply (); } } + // Style used by default for the right button on GUI::ref::HorizontalScrollbar controls. + CSRAW public GUIStyle horizontalScrollbarRightButton { get { return m_horizontalScrollbarRightButton; } set { m_horizontalScrollbarRightButton = value; Apply (); } } + + CSRAW + [SerializeField] + GUIStyle m_verticalScrollbar; + [SerializeField] + GUIStyle m_verticalScrollbarThumb; + [SerializeField] + GUIStyle m_verticalScrollbarUpButton; + [SerializeField] + GUIStyle m_verticalScrollbarDownButton; + + // Style used by default for the background part of GUI::ref::VerticalScrollbar controls. + CSRAW public GUIStyle verticalScrollbar { get { return m_verticalScrollbar; } set { m_verticalScrollbar = value; Apply (); } } + // Style used by default for the thumb that is dragged in GUI::ref::VerticalScrollbar controls. + CSRAW public GUIStyle verticalScrollbarThumb { get { return m_verticalScrollbarThumb; } set { m_verticalScrollbarThumb = value; Apply (); } } + // Style used by default for the up button on GUI::ref::VerticalScrollbar controls. + CSRAW public GUIStyle verticalScrollbarUpButton { get { return m_verticalScrollbarUpButton; } set { m_verticalScrollbarUpButton = value; Apply (); } } + // Style used by default for the down button on GUI::ref::VerticalScrollbar controls. + CSRAW public GUIStyle verticalScrollbarDownButton { get { return m_verticalScrollbarDownButton; } set { m_verticalScrollbarDownButton = value; Apply (); } } + + // Background style for scroll views. + CSRAW [SerializeField] + CSRAW GUIStyle m_ScrollView; + + // Style used by default for the background of ScrollView controls (see GUI::ref::BeginScrollView). + CSRAW public GUIStyle scrollView { get { return m_ScrollView; } set { m_ScrollView = value; Apply (); } } + + CSRAW [SerializeField] + CSRAW internal GUIStyle[] m_CustomStyles; + + // Array of GUI styles for specific needs. + CSRAW public GUIStyle[] customStyles { get { return m_CustomStyles; } set { m_CustomStyles = value; Apply(); } } + + + CSRAW [SerializeField] + CSRAW private GUISettings m_Settings = new GUISettings (); + + // Generic settings for how controls should behave with this skin. + CSRAW public GUISettings settings { get { return m_Settings; } } + + CSRAW internal static GUIStyle ms_Error; + CSRAW internal static GUIStyle error { get { if(ms_Error == null) ms_Error = new GUIStyle(); return ms_Error; } } + + CSRAW private Dictionary<string, GUIStyle> styles = null; + + CSRAW internal void Apply () + { + if (m_CustomStyles == null) + Debug.Log("custom styles is null"); + + BuildStyleCache (); + } + + + CSRAW private void BuildStyleCache () { + + if (m_box == null) m_box = new GUIStyle(); + if (m_button == null) m_button = new GUIStyle(); + if (m_toggle == null) m_toggle = new GUIStyle(); + if (m_label == null) m_label = new GUIStyle(); + if (m_window == null) m_window = new GUIStyle(); + if (m_textField == null) m_textField = new GUIStyle(); + if (m_textArea == null) m_textArea = new GUIStyle(); + if (m_horizontalSlider == null) m_horizontalSlider = new GUIStyle(); + if (m_horizontalSliderThumb == null) m_horizontalSliderThumb = new GUIStyle(); + if (m_verticalSlider == null) m_verticalSlider = new GUIStyle(); + if (m_verticalSliderThumb == null) m_verticalSliderThumb = new GUIStyle(); + if (m_horizontalScrollbar == null) m_horizontalScrollbar = new GUIStyle(); + if (m_horizontalScrollbarThumb == null) m_horizontalScrollbarThumb = new GUIStyle(); + if (m_horizontalScrollbarLeftButton == null) m_horizontalScrollbarLeftButton = new GUIStyle(); + if (m_horizontalScrollbarRightButton == null) m_horizontalScrollbarRightButton = new GUIStyle(); + if (m_verticalScrollbar == null) m_verticalScrollbar = new GUIStyle(); + if (m_verticalScrollbarThumb == null) m_verticalScrollbarThumb = new GUIStyle(); + if (m_verticalScrollbarUpButton == null) m_verticalScrollbarUpButton = new GUIStyle(); + if (m_verticalScrollbarDownButton == null) m_verticalScrollbarDownButton = new GUIStyle(); + if (m_ScrollView == null) m_ScrollView = new GUIStyle(); + + styles = new Dictionary<string, GUIStyle>( +#if !UNITY_FLASH + System.StringComparer.OrdinalIgnoreCase +#endif + ); + + styles["box"] = m_box; m_box.name = "box"; + styles["button"] = m_button; m_button.name = "button"; + styles["toggle"] = m_toggle; m_toggle.name = "toggle"; + styles["label"] = m_label; m_label.name = "label"; + styles["window"] = m_window; m_window.name = "window"; + styles["textfield"] = m_textField; m_textField.name = "textfield"; + styles["textarea"] = m_textArea; m_textArea.name = "textarea"; + + styles["horizontalslider"] = m_horizontalSlider; m_horizontalSlider.name = "horizontalslider"; + styles["horizontalsliderthumb"] = m_horizontalSliderThumb; m_horizontalSliderThumb.name = "horizontalsliderthumb"; + styles["verticalslider"] = m_verticalSlider; m_verticalSlider.name = "verticalslider"; + styles["verticalsliderthumb"] = m_verticalSliderThumb; m_verticalSliderThumb.name = "verticalsliderthumb"; + + styles["horizontalscrollbar"] = m_horizontalScrollbar; m_horizontalScrollbar.name = "horizontalscrollbar"; + styles["horizontalscrollbarthumb"] = m_horizontalScrollbarThumb; m_horizontalScrollbarThumb.name = "horizontalscrollbarthumb"; + styles["horizontalscrollbarleftbutton"] = m_horizontalScrollbarLeftButton; m_horizontalScrollbarLeftButton.name = "horizontalscrollbarleftbutton"; + styles["horizontalscrollbarrightbutton"] = m_horizontalScrollbarRightButton; m_horizontalScrollbarRightButton.name = "horizontalscrollbarrightbutton"; + styles["verticalscrollbar"] = m_verticalScrollbar; m_verticalScrollbar.name = "verticalscrollbar"; + styles["verticalscrollbarthumb"] = m_verticalScrollbarThumb; m_verticalScrollbarThumb.name = "verticalscrollbarthumb"; + styles["verticalscrollbarupbutton"] = m_verticalScrollbarUpButton; m_verticalScrollbarUpButton.name = "verticalscrollbarupbutton"; + styles["verticalscrollbardownbutton"] = m_verticalScrollbarDownButton; m_verticalScrollbarDownButton.name = "verticalscrollbardownbutton"; + styles["scrollview"] = m_ScrollView; m_ScrollView.name = "scrollview"; + + if (m_CustomStyles != null) + { + for (int i=0;i<m_CustomStyles.Length;i++) + { + if (m_CustomStyles[i] == null) + continue; + styles[m_CustomStyles[i].name] = m_CustomStyles[i]; + } + } + error.stretchHeight = true; + error.normal.textColor = Color.red; + } + + // Get a named [[GUIStyle]]. + CSRAW public GUIStyle GetStyle (string styleName) { + GUIStyle s = FindStyle (styleName); + if (s != null) + return s; + Debug.LogWarning ("Unable to find style '" + styleName + "' in skin '" + name + "' " + Event.current.type); + return error; + } + + // Try to search for a [[GUIStyle]]. This functions returns NULL and does not give an error. + CSRAW public GUIStyle FindStyle (string styleName) { + if (this == null) { + Debug.LogError ("GUISkin is NULL"); + return null; + } + if (styles == null) + BuildStyleCache (); + + GUIStyle style; + if (styles.TryGetValue(styleName, out style)) + return style; + + return null; + } + + CSRAW + internal delegate void SkinChangedDelegate(); + internal static SkinChangedDelegate m_SkinChanged; + + // Make this the current skin used by the GUI + static internal GUISkin current; + CSRAW internal void MakeCurrent () { + current = this; + GUIStyle.SetDefaultFont (font); + if (m_SkinChanged != null) + m_SkinChanged(); + } + + //*undocumented* Documented separately + CSRAW public IEnumerator GetEnumerator () + { + if (styles == null) + BuildStyleCache (); + return (IEnumerator)styles.Values.GetEnumerator (); + } +END + + +} diff --git a/Runtime/Export/GUIStateObjects.cs b/Runtime/Export/GUIStateObjects.cs new file mode 100644 index 0000000..e37bc93 --- /dev/null +++ b/Runtime/Export/GUIStateObjects.cs @@ -0,0 +1,36 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEngine +{ + +internal class GUIStateObjects +{ + static Dictionary<int, object> s_StateCache = new Dictionary<int, object>(); + + [System.Security.SecuritySafeCritical] + static internal object GetStateObject (System.Type t, int controlID) + { + object o; + if (s_StateCache.TryGetValue(controlID, out o) == false || o.GetType() != t) + { + o = System.Activator.CreateInstance(t); + s_StateCache[controlID] = o; + } + return o; + } + + static internal object QueryStateObject (System.Type t, int controlID) + { + object o = s_StateCache[controlID]; + if (t.IsInstanceOfType (o)) + return o; + return null; + } + +} + +} // namespace diff --git a/Runtime/Export/GUIStyleBindings.txt b/Runtime/Export/GUIStyleBindings.txt new file mode 100644 index 0000000..76ac550 --- /dev/null +++ b/Runtime/Export/GUIStyleBindings.txt @@ -0,0 +1,922 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/IMGUI/GUIStyle.h" +#include "Runtime/IMGUI/GUIContent.h" +#include "Runtime/IMGUI/GUIState.h" +#include "Runtime/IMGUI/GUIManager.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Filters/Misc/Font.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +#if UNITY_EDITOR +//#include "Editor/Src/EditorHelper.h" +//#include "Editor/Mono/MonoEditorUtility.h" +//#include "Editor/Src/OptimizedGUIBlock.h" +//#include "Editor/Src/AssetPipeline/AssetDatabase.h" + +//#include "Editor/Src/EditorResources.h" +#endif + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + + + +// Specialized values for the given states used by [[GUIStyle]] objects. +CSRAW #if !UNITY_WINRT +CSRAW [StructLayout (LayoutKind.Sequential)] +CSRAW #endif +CSRAW [System.Serializable] +CLASS GUIStyleState + // Pointer to the GUIStyleState INSIDE a GUIStyle. + CSRAW [System.NonSerialized] [NotRenamed] + CSRAW internal IntPtr m_Ptr; + + // Pointer to the source GUIStyle so it doesn't get garbage collected. + // If NULL, it means we own m_Ptr and need to delete it when this gets displosed + CSRAW GUIStyle m_SourceStyle; + + // Pointer to the texture that is referenced from the GUIStyleState. + // Necessary for the Asset Garbage Collector to find the texture reference +CSRAW #pragma warning disable 414 + [System.NonSerialized] + CSRAW private Texture2D m_Background; +CSRAW #pragma warning restore 414 + + public GUIStyleState () + { + Init (); + } + + internal GUIStyleState (GUIStyle sourceStyle, IntPtr source) + { + m_SourceStyle = sourceStyle; + m_Ptr = source; + RefreshAssetReference(); + } + + internal void RefreshAssetReference () + { + m_Background = GetBackgroundInternal(); + } + + ~GUIStyleState () + { + if (m_SourceStyle == null) + Cleanup (); + } + + THREAD_SAFE + CUSTOM private void Init () { + self.SetPtr(new GUIStyleState()); + + } + + THREAD_SAFE + CUSTOM private void Cleanup () { + delete self.GetPtr(); + } + + // The background image used by GUI elements in this given state. + CUSTOM private void SetBackgroundInternal (Texture2D value) { + self->background = (Texture2D*) (value); + } + + CUSTOM private Texture2D GetBackgroundInternal () { + return Scripting::ScriptingWrapperFor (self->background); + } + + CSRAW public Texture2D background { + get { return GetBackgroundInternal(); } + set { SetBackgroundInternal (value); m_Background = value; } + } + + // The text color used by GUI elements in this state. + CUSTOM_PROP Color textColor { return self->textColor; } { self->textColor = value; } +END + + +// Offsets for rectangles, borders, etc. +CSRAW #if !UNITY_WINRT +CSRAW [StructLayout (LayoutKind.Sequential)] +CSRAW #endif +CSRAW [System.Serializable] +CLASS RectOffset + + // Pointer to the RectOffset INSIDE a GUIStyle. + CSRAW [System.NonSerialized] [NotRenamed] + CSRAW internal IntPtr m_Ptr; + + // Pointer to the source GUIStyle so it doesn't get garbage collected. + // If NULL, it means we own m_Ptr and need to delete it when this gets displosed + CSRAW GUIStyle m_SourceStyle; + + /// *listonly* + CSRAW public RectOffset () { + Init (); + } + + internal RectOffset (GUIStyle sourceStyle, IntPtr source) + { + m_SourceStyle = sourceStyle; + m_Ptr = source; + } + + ~RectOffset () + { + if (m_SourceStyle == null) + Cleanup (); + } + + THREAD_SAFE + CUSTOM private void Init () { + self.SetPtr(new RectOffset()); + } + + THREAD_SAFE + CUSTOM private void Cleanup () { + delete self.GetPtr(); + } + + + // Creates a new rectangle with offsets. + CSRAW public RectOffset (int left, int right, int top, int bottom) { + Init (); + this.left = left; + this.right = right; + this.top = top; + this.bottom = bottom; + } + + // Left edge size. + CUSTOM_PROP int left { return self->left; } { self->left = value; } + // Right edge size. + CUSTOM_PROP int right { return self->right; } { self->right = value; } + // Top edge size. + CUSTOM_PROP int top { return self->top; } { self->top = value; } + // Bottom edge size. + CUSTOM_PROP int bottom { return self->bottom; } { self->bottom = value; } + // shortcut for left + right (RO) + CUSTOM_PROP int horizontal { return self->left + self->right; } + // shortcut for top + bottom (RO) + CUSTOM_PROP public int vertical { return self->top + self->bottom; } + // Add the border offsets to a /rect/. + CUSTOM public Rect Add (Rect rect) + { return Rectf (rect.x - self->left, rect.y - self->top, rect.width + self->left + self->right, rect.height + self->top + self->bottom); } + // Remove the border offsets from a /rect/. + CUSTOM public Rect Remove (Rect rect) + { return Rectf (rect.x + self->left, rect.y + self->top, rect.width - self->left - self->right, rect.height - self->top - self->bottom); } + + CSRAW public override string ToString () { + return UnityString.Format ("RectOffset (l:{0} r:{1} t:{2} b:{3})", left, right, top, bottom); + } + +END + +// Font Style applied to GUI Texts, Text Meshes or GUIStyles. +ENUM FontStyle + // No special style is applied. + Normal = 0, + + // Bold style applied to your texts. + Bold = 1, + + // Italic style applied to your texts. + Italic = 2, + + // Bold and Italic styles applied to your texts. + BoldAndItalic = 3, +END + +C++RAW + +// Simple struct that contains all the arguments needed by Internal_Draw. +STRUCT internal Internal_DrawArguments + CSRAW public IntPtr target; + CSRAW public Rect position; + CSRAW public int isHover; + CSRAW public int isActive; + CSRAW public int on; + CSRAW public int hasKeyboardFocus; +END + +C++RAW + +struct MonoInternal_DrawArguments { + void* target; + const Rectf position; + int isHover; + int isActive; + int on; + int hasKeyboardFocus; +}; + +// Simple struct that contains all the arguments needed by Internal_DrawWithTextSelection. +STRUCT internal Internal_DrawWithTextSelectionArguments + CSRAW public IntPtr target; + CSRAW public Rect position; + CSRAW public int firstPos; + CSRAW public int lastPos; + CSRAW public Color cursorColor; + CSRAW public Color selectionColor; + CSRAW public int isHover; + CSRAW public int isActive; + CSRAW public int on; + CSRAW public int hasKeyboardFocus; + CSRAW public int drawSelectionAsComposition; + +END + +C++RAW + +struct MonoInternal_DrawWithTextSelectionArguments { + void* target; + Rectf position; + int firstPos; + int lastPos; + const ColorRGBAf cursorColor; + const ColorRGBAf selectionColor; + int isHover; + int isActive; + int on; + int hasKeyboardFocus; + int drawSelectionAsComposition; +}; + +// How image and text is placed inside [[GUIStyle]]. +ENUM ImagePosition + // Image is to the left of the text. + ImageLeft = 0, + // Image is above the text. + ImageAbove = 1, + // Only the image is displayed. + ImageOnly = 2, + // Only the text is displayed. + TextOnly = 3 +END + + +BEGIN DOC +Style settings for a GUI element. +This class contains all information for how a gui element should be rendered. It contains information for font, icon placement, background images, and spacing. +It does /not/ contain information for what it contains - just defines how any text rendered with this style should be displayed. +It does /not/ define what interactions can occur with the element, but defines the display settings commonly used in by the interactions. + +The settings of a [[GUIStyle]]. It is modelled after a CSS Style. It contains settings for the following items: +<dl> +<dt>Background images</dt> +<dd> These are rendered behind the contents. Different images can be assigned for normal display, when the user hovers the mouse over the element, + when the user presses it down - as well as alternatives for when the element has been turned on - like toggle butons do. Below, these are referred to as style /states/. + SA: ::ref::normal, ::ref::hover, ::ref::active, ::ref::onNormal, ::ref::onHover, ::ref::onActive - these contain the background image & text color properties for each state.</dd> +<dt>Text rendering</dt> +<dd> The style can define a font for text rendering, as well as alignment, wordwrap and clipping settings. It also defines colors for the text in the various states of the style element + SA: ::ref::font, ::ref::alignment, ::ref::wordWrap, ::ref::normal, ::ref::hover, ::ref::active, ::ref::onHover, ::ref::onActive</dd> +<dt>Icon Placement</dt> +<dd> GUIStyles can be rendered with either text, and icon or both. The GUIStyle defines where these two are rendered in relation to each other (or can force it to only display one of them). + SA: ::ref::imagePosition</dd> +<dt>Sizing and Spacing Options</dd> +<dd> GUIStyles contain padding, margins and borders. These corresponds loosely to the similar named CSS properties. A GUIStyle can optionally define a fixed width and height. + SA: ::ref::margin, ::ref::padding, ::ref::border, ::ref::fixedWidth, ::ref::fixedHeight</dd> +</dl> + + +END DOC + +C++RAW + static void CleanupGUIStyle(void* guiStyle){ delete ((GUIStyle*)guiStyle); } +CSRAW #if !UNITY_WINRT +CSRAW [StructLayout (LayoutKind.Sequential)] +CSRAW #endif +CSRAW [System.Serializable] +CLASS GUIStyle + +CSRAW + // Constructor for empty GUIStyle. + public GUIStyle () { + Init (); + } + + // Constructs GUIStyle identical to given other GUIStyle. + public GUIStyle (GUIStyle other) { + InitCopy (other); + } + + ~GUIStyle () { + Cleanup (); + } + + internal void CreateObjectReferences () { + m_FontInternal = GetFontInternal(); + normal.RefreshAssetReference (); + hover.RefreshAssetReference (); + active.RefreshAssetReference (); + focused.RefreshAssetReference (); + onNormal.RefreshAssetReference (); + onHover.RefreshAssetReference (); + onActive.RefreshAssetReference (); + onFocused.RefreshAssetReference (); + } + + [System.NonSerialized] [NotRenamed] + internal IntPtr m_Ptr; + + [System.NonSerialized] + GUIStyleState m_Normal, m_Hover, m_Active, m_Focused, m_OnNormal, m_OnHover, m_OnActive, m_OnFocused; + + [System.NonSerialized] + RectOffset m_Border, m_Padding, m_Margin, m_Overflow; + +CSRAW #pragma warning disable 414 + [System.NonSerialized] + private Font m_FontInternal; +CSRAW #pragma warning restore 414 + + THREAD_SAFE + CUSTOM private void Init () { + self.SetPtr(new GUIStyle(), CleanupGUIStyle); + } + + THREAD_SAFE + CUSTOM private void InitCopy (GUIStyle other) { + self.SetPtr(new GUIStyle (*other), CleanupGUIStyle); + } + + THREAD_SAFE + CUSTOM private void Cleanup () { + CleanupGUIStyle(self.GetPtr()); + } + + // The name of this GUIStyle. Used for getting them based on name.... + CUSTOM_PROP string name + { + return scripting_string_new(self->m_Name); + } + { self->m_Name = value.AsUTF8(); } + + // Rendering settings for when the component is displayed normally. + CSRAW public GUIStyleState normal { get { + if (m_Normal == null) + m_Normal = new GUIStyleState (this, GetStyleStatePtr (0)); + return m_Normal; + } + set { AssignStyleState (0, value.m_Ptr); } + } + + // Rendering settings for when the mouse is hovering over the control + CSRAW public GUIStyleState hover { get { + if (m_Hover == null) + m_Hover = new GUIStyleState (this, GetStyleStatePtr (1)); + return m_Hover; + } + set { AssignStyleState (1, value.m_Ptr); } + } + + // Rendering settings for when the control is pressed down. + CSRAW public GUIStyleState active { get { + if (m_Active == null) + m_Active = new GUIStyleState (this, GetStyleStatePtr (2)); + return m_Active; + } + set { AssignStyleState (2, value.m_Ptr); } + } + + // Rendering settings for when the control is turned on. + CSRAW public GUIStyleState onNormal { get { + if (m_OnNormal == null) + m_OnNormal = new GUIStyleState (this, GetStyleStatePtr (4)); + return m_OnNormal; + } + set { AssignStyleState (4, value.m_Ptr); } + } + + // Rendering settings for when the control is turned on and the mouse is hovering it. + CSRAW public GUIStyleState onHover { get { + if (m_OnHover == null) + m_OnHover = new GUIStyleState (this, GetStyleStatePtr (5)); + return m_OnHover; + } + set { AssignStyleState (5, value.m_Ptr); } + } + + // Rendering settings for when the element is turned on and pressed down. + CSRAW public GUIStyleState onActive { get { + if (m_OnActive == null) + m_OnActive = new GUIStyleState (this, GetStyleStatePtr (6)); + return m_OnActive; + } + set { AssignStyleState (6, value.m_Ptr); } + } + + // Rendering settings for when the element has keyboard focus. + CSRAW public GUIStyleState focused { get { + if (m_Focused == null) + m_Focused = new GUIStyleState (this, GetStyleStatePtr (3)); + return m_Focused; + } + set { AssignStyleState (3, value.m_Ptr); } + } + + // Rendering settings for when the element has keyboard and is turned on. + CSRAW public GUIStyleState onFocused { get { + if (m_OnFocused == null) + m_OnFocused = new GUIStyleState (this, GetStyleStatePtr (7)); + return m_OnFocused; + } + set { AssignStyleState (7, value.m_Ptr); } + } + + CUSTOM private IntPtr GetStyleStatePtr (int idx) + { + GUIStyleState* gss = &(self->m_Normal); + return gss+idx; + } + + CUSTOM private void AssignStyleState (int idx, IntPtr srcStyleState) + { + GUIStyleState* gss = &(self->m_Normal); + gss += idx; + *gss = *((GUIStyleState*)srcStyleState); + } + + + // RECT OFFSETS + // ================================================================================================================================================ + + + // The borders of all background images. + CSRAW public RectOffset border { get { + if (m_Border == null) + m_Border = new RectOffset (this, GetRectOffsetPtr (0)); + return m_Border; + } + set { AssignRectOffset (0, value.m_Ptr); } + } + + // The margins between elements rendered in this style and any other GUI elements + CSRAW public RectOffset margin { get { + if (m_Margin == null) + m_Margin = new RectOffset (this, GetRectOffsetPtr (1)); + return m_Margin; + } + set { AssignRectOffset (1, value.m_Ptr); } + } + + // Space from the edge of [[GUIStyle]] to the start of the contents. + CSRAW public RectOffset padding { get { + if (m_Padding == null) + m_Padding = new RectOffset (this, GetRectOffsetPtr (2)); + return m_Padding; + } + set { AssignRectOffset (2, value.m_Ptr); } + } + + // Extra space to be added to the background image. + CSRAW public RectOffset overflow { get { + if (m_Overflow == null) + m_Overflow = new RectOffset (this, GetRectOffsetPtr (3)); + return m_Overflow; + } + set { AssignRectOffset (3, value.m_Ptr); } + } + + CUSTOM private IntPtr GetRectOffsetPtr (int idx) + { + RectOffset* ro = &(self->m_Border); + return ro+idx; + } + + CUSTOM private void AssignRectOffset (int idx, IntPtr srcRectOffset) + { + RectOffset* ro = &(self->m_Border); + ro += idx; + *ro = *((RectOffset*)srcRectOffset); + } + + + // How image and text of the [[GUIContent]] is combined. + CUSTOM_PROP ImagePosition imagePosition + { return self->m_ImagePosition; } + { self->m_ImagePosition = value; } + + // Text alignment. + CUSTOM_PROP TextAnchor alignment + { return self->m_Alignment; } + { self->m_Alignment = value; } + + // Word wrap the text? + CUSTOM_PROP bool wordWrap { return self->m_WordWrap; } { self->m_WordWrap = value; } + + // What to do when the contents to be rendered is too large to fit within the area given. + CUSTOM_PROP TextClipping clipping { return self->m_Clipping; } { self->m_Clipping = value; } + + // Pixel offset to apply to the content of this GUIstyle + CUSTOM_PROP Vector2 contentOffset { return self->m_ContentOffset; } { self->m_ContentOffset = value; } + + // *undocumented* Clip offset to apply to the content of this GUIstyle + OBSOLETE warning Don't use clipOffset - put things inside begingroup instead. This functionality will be removed in a later version. + CSRAW public Vector2 clipOffset { get { return Internal_clipOffset; } set {Internal_clipOffset = value; } } + + CUSTOM_PROP internal Vector2 Internal_clipOffset { return self->m_ClipOffset; } { self->m_ClipOffset = value; } + + // If non-0, any GUI elements rendered with this style will have the width specified here. + CUSTOM_PROP float fixedWidth { return self->m_FixedWidth; } { self->m_FixedWidth = value; } + + // If non-0, any GUI elements rendered with this style will have the height specified here. + CUSTOM_PROP float fixedHeight { return self->m_FixedHeight; } { self->m_FixedHeight = value; } + + // Can GUI elements of this style be stretched horizontally for better layouting? + CUSTOM_PROP bool stretchWidth { return self->m_StretchWidth; } { self->m_StretchWidth = value; } + + // Can GUI elements of this style be stretched vertically for better layouting? + CUSTOM_PROP bool stretchHeight { return self->m_StretchHeight; } { self->m_StretchHeight = value; } + + CUSTOM private static float Internal_GetLineHeight (IntPtr target) { + GUIStyle *cache = reinterpret_cast<GUIStyle*> (target); + return cache->GetLineHeight (); + } + + CUSTOM private void SetFontInternal (Font value) { + self->m_Font = (Font*) (value); + } + + CUSTOM private Font GetFontInternal () { + return Scripting::ScriptingWrapperFor (self->m_Font); + } + + // The font to use for rendering. If null, the default font for the current [[GUISkin]] is used instead. + CSRAW public Font font { + get { return GetFontInternal(); } + set { SetFontInternal(value); m_FontInternal = value; } + } + + // The font size to use (for dynamic fonts) + CUSTOM_PROP int fontSize { return self->m_FontSize; } { self->m_FontSize = value; } + + // The font style to use (for dynamic fonts) + CUSTOM_PROP FontStyle fontStyle { return self->m_FontStyle; } { self->m_FontStyle = value; } + + // Enable HTML-style tags for Text Formatting Markup. + CUSTOM_PROP bool richText { return self->m_RichText; } { self->m_RichText = value; } + + // The height of one line of text with this style, measured in pixels. (RO) + CSRAW public float lineHeight { get { return Mathf.Round (Internal_GetLineHeight (m_Ptr)); } } + + + // Draw this GUIStyle on to the screen. + CSRAW private static void Internal_Draw (IntPtr target, Rect position, GUIContent content, bool isHover, bool isActive, bool on, bool hasKeyboardFocus) { + Internal_DrawArguments arguments = new Internal_DrawArguments (); + arguments.target = target; + arguments.position = position; + arguments.isHover = isHover ? 1 : 0; + arguments.isActive = isActive ? 1 : 0; + arguments.on = on ? 1 : 0; + arguments.hasKeyboardFocus = hasKeyboardFocus ? 1 : 0; + Internal_Draw (content, ref arguments); + } + + // Draw this GUIStyle on to the screen, internal version + CUSTOM private static void Internal_Draw (GUIContent content, ref Internal_DrawArguments arguments) { + reinterpret_cast<GUIStyle*> (arguments.target)->Draw (GetGUIState(), arguments.position, MonoGUIContentToTempNative(content), arguments.isHover, arguments.isActive, arguments.on, arguments.hasKeyboardFocus); + } + + // Draw plain GUIStyle without text nor image. + CSRAW public void Draw (Rect position, bool isHover, bool isActive, bool on, bool hasKeyboardFocus) { + #if UNITY_EDITOR + if (Event.current.type != EventType.Repaint) + { + Debug.LogError("Style.Draw may not be called if it is not a repaint event"); + return; + } + #endif + + Internal_Draw (m_Ptr, position, GUIContent.none, isHover, isActive, on, hasKeyboardFocus); + } + // Draw the GUIStyle with a text string inside. + CSRAW public void Draw (Rect position, string text, bool isHover, bool isActive, bool on, bool hasKeyboardFocus) { + #if UNITY_EDITOR + if (Event.current.type != EventType.Repaint) + { + Debug.LogError("Style.Draw may not be called if it is not a repaint event"); + return; + } + #endif + + Internal_Draw (m_Ptr, position, GUIContent.Temp(text), isHover, isActive, on, hasKeyboardFocus); + } + // Draw the GUIStyle with an image inside. If the image is too large to fit within the content area of the style it is scaled down. + CSRAW public void Draw (Rect position, Texture image, bool isHover, bool isActive, bool on, bool hasKeyboardFocus) { + #if UNITY_EDITOR + if (Event.current.type != EventType.Repaint) + { + Debug.LogError("Style.Draw may not be called if it is not a repaint event"); + return; + } + #endif + + Internal_Draw (m_Ptr, position, GUIContent.Temp(image), isHover, isActive, on, hasKeyboardFocus); + } + // Draw the GUIStyle with text and an image inside. If the image is too large to fit within the content area of the style it is scaled down. + CSRAW public void Draw (Rect position, GUIContent content, bool isHover, bool isActive, bool on, bool hasKeyboardFocus) { + #if UNITY_EDITOR + if (Event.current.type != EventType.Repaint) + { + Debug.LogError("Style.Draw may not be called if it is not a repaint event"); + return; + } + #endif + + Internal_Draw (m_Ptr, position, content, isHover, isActive, on, hasKeyboardFocus); + + #if UNITY_GUI_SUPPORT_TOOLTIP + if (content.tooltip != null && content.tooltip != "") { + if (isHover || isActive) + { + GUI.s_EditorTooltip = GUI.s_MouseTooltip = content.tooltip; + Vector2 v = GUIUtility.GUIToScreenPoint(new Vector2(position.x, position.y)); + GUI.s_ToolTipRect = new Rect (v.x, v.y, position.width, position.height); + } + if (hasKeyboardFocus) + GUI.s_KeyTooltip = content.tooltip; + + } + #endif + } + + CSRAW public void Draw (Rect position, GUIContent content, int controlID, bool on = false) + { + #if UNITY_EDITOR + if (Event.current.type != EventType.Repaint) + { + Debug.LogError("Style.Draw may not be called if it is not a repaint event."); + return; + } + #endif + + if (content != null) + Internal_Draw2 (m_Ptr, position, content, controlID, on); + else + Debug.LogError("Style.Draw may not be called with GUIContent that is null."); + } + + CUSTOM private static void Internal_Draw2 (IntPtr style, Rect position, GUIContent content, int controlID, bool on) + { + GUIStyle *_style = reinterpret_cast<GUIStyle*>(style); + _style->Draw (GetGUIState(), position, MonoGUIContentToTempNative (content), controlID, on); + } + +#if UNITY_EDITOR + // PrefixLabel has to be drawn with an alternative draw mathod. + // The normal draw methods use MonoGUIContentToTempNative which means they all share the same temp GUIContent on the native side. + // A native IMGUI control such as GUIButton is already using this temp GUIContent when it calls GetControlID, which, + // because of the delayed feature in PrefixLabel, can end up calling a style draw function again to draw the PrefixLabel. + // This draw call cannot use the same temp GUIContent that is already needed for the GUIButton control itself, + // so it has to use this alternative code path that uses a different GUIContent to store the content in. + // We can all agree this workaround is not nice at all. But nobody seemed to be able to come up with something better. + CSRAW internal void DrawPrefixLabel (Rect position, GUIContent content, int controlID) + { + if (content != null) + Internal_DrawPrefixLabel (m_Ptr, position, content, controlID, false); + else + Debug.LogError("Style.DrawPrefixLabel may not be called with GUIContent that is null."); + } + + C++RAW static GUIContent s_TempPrefixLabelGUIContent; + + CUSTOM private static void Internal_DrawPrefixLabel (IntPtr style, Rect position, GUIContent content, int controlID, bool on) + { + GUIStyle *_style = reinterpret_cast<GUIStyle*>(style); + MonoGUIContentToNative (content, s_TempPrefixLabelGUIContent); + _style->Draw (GetGUIState(), position, s_TempPrefixLabelGUIContent, controlID, on); + } +#endif + + + // Does the ID-based Draw function show keyboard focus? Disabled by windows when they don't have keyboard focus + CSRAW internal static bool showKeyboardFocus = true; + + CUSTOM private static float Internal_GetCursorFlashOffset () { + return GUIManager::GetCursorFlashTime (); + } + + CUSTOM private static void Internal_DrawCursor (IntPtr target, Rect position, GUIContent content, int pos, Color cursorColor) + { reinterpret_cast<GUIStyle*> (target)->DrawCursor (GetGUIState(), position, MonoGUIContentToTempNative (content), pos, cursorColor); } + + // Draw this GUIStyle with selected content. + CSRAW public void DrawCursor (Rect position, GUIContent content, int controlID, int Character) { + Event e = Event.current; + if (e.type == EventType.Repaint) { + + // Figure out the cursor color... + Color cursorColor = new Color (0,0,0,0); + float cursorFlashSpeed = GUI.skin.settings.cursorFlashSpeed; + float cursorFlashRel = ((Time.realtimeSinceStartup - GUIStyle.Internal_GetCursorFlashOffset()) % cursorFlashSpeed) / cursorFlashSpeed; + if (cursorFlashSpeed == 0 || cursorFlashRel < .5f) { + cursorColor = GUI.skin.settings.cursorColor; + } + + Internal_DrawCursor ( + m_Ptr, position, content, + Character, cursorColor); + } + } + + + CUSTOM private static void Internal_DrawWithTextSelection (GUIContent content, ref Internal_DrawWithTextSelectionArguments arguments) + { + reinterpret_cast<GUIStyle*> (arguments.target)->DrawWithTextSelection ( + GetGUIState (), + arguments.position, + MonoGUIContentToTempNative(content), + arguments.isHover, + arguments.isActive, + arguments.on, + arguments.hasKeyboardFocus, + arguments.drawSelectionAsComposition, + arguments.firstPos, + arguments.lastPos, + arguments.cursorColor, + arguments.selectionColor + ); + } + + CSRAW internal void DrawWithTextSelection (Rect position, GUIContent content, int controlID, int firstSelectedCharacter, int lastSelectedCharacter, bool drawSelectionAsComposition) { + + #if UNITY_EDITOR + if (Event.current.type != EventType.Repaint) + { + Debug.LogError("Style.Draw may not be called if it is not a repaint event"); + return; + } + #endif + + Event e = Event.current; + + // Figure out the cursor color... + Color cursorColor = new Color (0,0,0,0); + float cursorFlashSpeed = GUI.skin.settings.cursorFlashSpeed; + float cursorFlashRel = ((Time.realtimeSinceStartup - GUIStyle.Internal_GetCursorFlashOffset()) % cursorFlashSpeed) / cursorFlashSpeed; + if (cursorFlashSpeed == 0 || cursorFlashRel < .5f) + cursorColor = GUI.skin.settings.cursorColor; + + + Internal_DrawWithTextSelectionArguments arguments = new Internal_DrawWithTextSelectionArguments (); + arguments.target = m_Ptr; + arguments.position = position; + arguments.firstPos = firstSelectedCharacter; + arguments.lastPos = lastSelectedCharacter; + arguments.cursorColor = cursorColor; + arguments.selectionColor = GUI.skin.settings.selectionColor; + arguments.isHover = position.Contains (e.mousePosition) ? 1 : 0; + arguments.isActive = controlID == GUIUtility.hotControl ? 1 : 0; + arguments.on = 0; + arguments.hasKeyboardFocus = controlID == GUIUtility.keyboardControl && showKeyboardFocus ? 1 : 0; + arguments.drawSelectionAsComposition = drawSelectionAsComposition ? 1 : 0; + + Internal_DrawWithTextSelection (content, ref arguments); + } + + // Draw this GUIStyle with selected content. + CSRAW public void DrawWithTextSelection (Rect position, GUIContent content, int controlID, int firstSelectedCharacter, int lastSelectedCharacter) { + DrawWithTextSelection (position, content, controlID, firstSelectedCharacter, lastSelectedCharacter, false); + + } + + // Set the default font used if null is used. + CUSTOM static internal void SetDefaultFont (Font font) + { GUIStyle::SetDefaultFont (font); } + + // Get a named GUI style from the current skin. + CSRAW public static implicit operator GUIStyle(string str) + { + if (GUISkin.current == null) + { + Debug.LogError ("Unable to use a named GUIStyle without a current skin. Most likely you need to move your GUIStyle initialization code to OnGUI"); + return GUISkin.error; + } + return GUISkin.current.GetStyle (str); + } + + // Shortcut for an empty GUIStyle. + CSRAW public static GUIStyle none { get { if(s_None == null) s_None = new GUIStyle(); return s_None; } } + static GUIStyle s_None; + + // Get the pixel position of a given string index. + CSRAW public Vector2 GetCursorPixelPosition (Rect position, GUIContent content, int cursorStringIndex) + { Vector2 temp; Internal_GetCursorPixelPosition(m_Ptr, position, content, cursorStringIndex, out temp); return temp; } + + // *undoc* + CUSTOM internal static void Internal_GetCursorPixelPosition (IntPtr target, Rect position, GUIContent content, int cursorStringIndex, out Vector2 ret) + { + *ret = reinterpret_cast<GUIStyle*> (target)->GetCursorPixelPosition (position, MonoGUIContentToTempNative (content), cursorStringIndex); + } + + // Get the cursor position (indexing into contents.text) when the user clicked at cursorPixelPosition + CSRAW public int GetCursorStringIndex (Rect position, GUIContent content, Vector2 cursorPixelPosition) + { return Internal_GetCursorStringIndex (m_Ptr, position, content, cursorPixelPosition); } + + // *undoc* + CUSTOM internal static int Internal_GetCursorStringIndex (IntPtr target, Rect position, GUIContent content, Vector2 cursorPixelPosition) + { + return reinterpret_cast<GUIStyle*> (target)->GetCursorStringIndex (position, MonoGUIContentToTempNative (content), cursorPixelPosition); + } + + + // Returns number of characters that can fit within width, returns -1 if fails due to missing font + CSRAW internal int GetNumCharactersThatFitWithinWidth (string text, float width) + { + return Internal_GetNumCharactersThatFitWithinWidth (m_Ptr, text, width); + } + + // *undoc* + CUSTOM internal static int Internal_GetNumCharactersThatFitWithinWidth (IntPtr target, string text, float width) + { +#if UNITY_FLASH + return 5; +#else + return reinterpret_cast<GUIStyle*> (target)->GetNumCharactersThatFitWithinWidth (UTF16String (text.AsUTF8().c_str()), width); +#endif + } + + // Calculate the size of a some content if it is rendered with this style. + CSRAW public Vector2 CalcSize (GUIContent content) + { + Vector2 temp; Internal_CalcSize(m_Ptr, content, out temp); + return temp; + } + + // *undoc* + CUSTOM internal static void Internal_CalcSize (IntPtr target, GUIContent content, out Vector2 ret) + { + *ret = reinterpret_cast<GUIStyle*> (target)->CalcSize (MonoGUIContentToTempNative (content)); + } + + // Calculate the size of an element formatted with this style, and a given space to content. + CSRAW public Vector2 CalcScreenSize (Vector2 contentSize) { + return new Vector2 ( + (fixedWidth != 0.0f ? fixedWidth : Mathf.Ceil (contentSize.x + padding.left + padding.right)), + (fixedHeight != 0.0f ? fixedHeight : Mathf.Ceil (contentSize.y + padding.top + padding.bottom)) + ); + } + + // How tall this element will be when rendered with /content/ and a specific /width/. + CSRAW public float CalcHeight (GUIContent content, float width) { + return Internal_CalcHeight (m_Ptr, content, width); + } + + CUSTOM private static float Internal_CalcHeight (IntPtr target, GUIContent content, float width) { + return reinterpret_cast<GUIStyle*> (target)->CalcHeight (MonoGUIContentToTempNative (content), width); + } + + // *undocumented* + CSRAW public bool isHeightDependantOnWidth { get { + return fixedHeight == 0 && (wordWrap == true && imagePosition != ImagePosition.ImageOnly); + } } + + // Calculate the minimum and maximum widths for this style rendered with /content/. + CSRAW public void CalcMinMaxWidth (GUIContent content, out float minWidth, out float maxWidth) + { + Internal_CalcMinMaxWidth(m_Ptr, content, out minWidth, out maxWidth); + } + // *undoc* + CUSTOM private static void Internal_CalcMinMaxWidth (IntPtr target, GUIContent content, out float minWidth, out float maxWidth) + { + reinterpret_cast<GUIStyle*> (target)->CalcMinMaxWidth (MonoGUIContentToTempNative (content), minWidth, maxWidth); + } + + // *undocumented + CSRAW public override string ToString () { + return UnityString.Format ("GUIStyle '{0}'", name); + } + + C++RAW + #undef GET +END + + +// Different methods for how the GUI system handles text being too large to fit the rectangle allocated. +ENUM TextClipping + // Text flows freely outside the element. + Overflow = 0, + // Text gets clipped to be inside the element. + Clip = 1, + + // Text gets truncated with dots to show it is too long + // Truncate = 2 +END + + +CSRAW +} diff --git a/Runtime/Export/GUIUtility.txt b/Runtime/Export/GUIUtility.txt new file mode 100644 index 0000000..99fcbc9 --- /dev/null +++ b/Runtime/Export/GUIUtility.txt @@ -0,0 +1,476 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Misc/AssetBundle.h" +#include "Runtime/Misc/ResourceManager.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/IMGUI/GUIStyle.h" +#include "Runtime/Filters/Misc/Font.h" +#include "Runtime/Misc/InputEvent.h" +#include "Runtime/GfxDevice/GfxDevice.h" +#include "Runtime/Camera/CameraUtil.h" +#include "Runtime/IMGUI/GUIManager.h" +#include "Runtime/Utilities/CopyPaste.h" +#include "Runtime/IMGUI/GUIState.h" +#include "Runtime/IMGUI/GUIClip.h" +#include "Runtime/IMGUI/IMGUIUtils.h" +#include "Runtime/IMGUI/GUIWindows.h" +#include "Runtime/Input/InputManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#if UNITY_EDITOR + +#include "Editor/Src/EditorHelper.h" +#include "Editor/Mono/MonoEditorUtility.h" +#include "Editor/Src/OptimizedGUIBlock.h" +#include "Editor/Src/AssetPipeline/AssetDatabase.h" +#include "Editor/Src/Undo/UndoManager.h" + +extern float s_GUIStyleIconSizeX; +extern float s_GUIStyleIconSizeY; +#endif + +using namespace Unity; +using namespace std; + +CSRAW + +// Use this define to debug who grabs and releases hotcontrol +//#define DEBUG_HOTCONTROL + +// Use this define to debug controlID consistency together with 's_LogControlID' (default false) to enable logging in +// a codepath thats needs tested for consistency. E.g: +// if (Event.current.rawType == EventType.MouseUp) +// GUIUtility.s_LogControlID = true; +// And remember to set s_LogControlID to false at end of secion of interest. +//#define DEBUG_CONTROLID + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// Throw this to immediately exit from GUI code. +// *undocumented* +CLASS ExitGUIException : System.Exception +END + +// Used by GUIUtility.GetcontrolID to inform the UnityGUI system if a given control can get keyboard focus. +ENUM FocusType + // This control can get keyboard focus on Windows, but not on Mac. Used for buttons, checkboxes and other "pressable" things. + Native = 0, + // This is a proper keyboard control. It can have input focus on all platforms. Used for TextField and TextArea controls + Keyboard = 1, + // This control can never recieve keyboard focus. + Passive = 2 +END + +CSRAW + +// Utility class for making new GUI controls. +NONSEALED_CLASS GUIUtility + + /// *listonly* + CSRAW public static int GetControlID (FocusType focus) + { + return GetControlID (0, focus); + } + /// *listonly* + CUSTOM public static int GetControlID (int hint, FocusType focus) + { + return GetGUIState().GetControlID (hint, focus); + } + /// *listonly* + CSRAW public static int GetControlID (GUIContent contents,FocusType focus) + { + return GetControlID (contents.hash, focus); + } + /// *listonly* + CSRAW public static int GetControlID (FocusType focus, Rect position) + { + return Internal_GetNextControlID2 (0, focus, position); + } + /// *listonly* + CSRAW public static int GetControlID (int hint, FocusType focus, Rect position) + { + return Internal_GetNextControlID2 (hint, focus, position); + } + // Get a unique ID for a control. + CSRAW static public int GetControlID (GUIContent contents, FocusType focus, Rect position) + { + return Internal_GetNextControlID2 (contents.hash, focus, position); + } + + CUSTOM private static int Internal_GetNextControlID2 (int hint, FocusType focusType, Rect rect) + { + return GetGUIState().GetControlID (hint, focusType, rect); + } + + // Get a state object from a controlID. + CSRAW public static object GetStateObject (Type t, int controlID) { return GUIStateObjects.GetStateObject (t, controlID); } + + // Get an existing state object from a controlID. + CSRAW public static object QueryStateObject (Type t, int controlID) { return GUIStateObjects.QueryStateObject (t, controlID); } + + CUSTOM static internal int GetPermanentControlID () + { + return GetGUIState().m_EternalGUIState->GetNextUniqueID (); + } + +CSRAW + #if DEBUG_HOTCONTROL + static public string s_WhoGrabbedHotControl, s_WhoReleasedHotControl; + #endif + + #if DEBUG_CONTROLID + static public bool s_LogControlID = false; + #endif + + + // The controlID of the current hot control. + CSRAW public static int hotControl { get { return Internal_GetHotControl(); } + set { + #if DEBUG_HOTCONTROL + if (value != 0) + { + s_WhoGrabbedHotControl = StackTraceUtility.ExtractStackTrace(); + Debug.Log("GRABBED " + s_WhoGrabbedHotControl); + } + else + { + s_WhoReleasedHotControl = StackTraceUtility.ExtractStackTrace(); + Debug.Log("RELEASE: " + s_WhoReleasedHotControl); + } + #endif + + Internal_SetHotControl (value); + } } + + CUSTOM private static int Internal_GetHotControl () + { + return IMGUI::GetHotControl (GetGUIState()); + } + CUSTOM private static void Internal_SetHotControl (int value) + { + IMGUI::SetHotControl (GetGUIState(), value); + } + + CUSTOM internal static void UpdateUndoName () + { + #if UNITY_EDITOR + GetUndoManager().UpdateUndoName (); + #endif + } + + // The controlID of the control that has keyboard focus. + CUSTOM_PROP static int keyboardControl + { return IMGUI::GetKeyboardControl (GetGUIState()); } + { IMGUI::SetKeyboardControl (GetGUIState(), value); } + +// Keep for debugging keyboardControl (prints the callstack when keyboardControl changes) +// CSRAW public static int keyboardControl +// { +// get { return GetKeyboardControl (); } +// set { Debug.Log ("Set keyboardControl " + value); SetKeyboardControl (value);} +// } +// CUSTOM static int GetKeyboardControl () {return IMGUI::GetKeyboardControl (GetGUIState()); } +// CUSTOM static void SetKeyboardControl (int id) {IMGUI::SetKeyboardControl (GetGUIState(), id); } + + //*undocumented* + CSRAW public static void ExitGUI () + { + // We have to always throw the ExitGUIException otherwise the exiting out of recursive on GUI will not work. + throw new ExitGUIException (); + } + + CUSTOM internal static void SetDidGUIWindowsEatLastEvent (bool value) { + GUIManager::SetDidGUIWindowsEatLastEvent (value); + } + + // Get access to the system-wide pasteboard. + CUSTOM_PROP static internal string systemCopyBuffer { return scripting_string_new(GetCopyBuffer ()); } { SetCopyBuffer (value); } + + CSRAW internal static GUISkin GetDefaultSkin() { + return Internal_GetDefaultSkin (s_SkinMode); + } + + CUSTOM private static GUISkin Internal_GetDefaultSkin (int skinMode) { + return GetDefaultSkin (skinMode)->GetInstance (); + } + + CUSTOM private static Object Internal_GetBuiltinSkin (int skin) { + return GetBuiltinSkin (skin)->GetInstance (); + } + + // internal so we can get to it from EditorGUIUtility.GetBuiltinSkin + CSRAW internal static GUISkin GetBuiltinSkin (int skin) { + return Internal_GetBuiltinSkin (skin) as GUISkin; + } + + [NotRenamed] static internal int s_SkinMode; + [NotRenamed] static internal int s_OriginalID; + CSRAW internal static void BeginGUI (int skinMode, int instanceID, int useGUILayout ) { + s_SkinMode = skinMode; + s_OriginalID = instanceID; + GUI.skin = null; + + // Switch to the correct ID list & clear keyboard loop if we're about to layout (we rebuild it during layout, so we want it cleared beforehand) + if (useGUILayout != 0) + { + GUILayoutUtility.SelectIDList (instanceID, false); + GUILayoutUtility.Begin (instanceID); + } + + GUI.changed = false; + } + + CUSTOM private static void Internal_ExitGUI () + { + #if UNITY_EDITOR + OptimizedGUIBlock::Abandon (); + s_GUIStyleIconSizeX = 0.0f; + s_GUIStyleIconSizeY = 0.0f; + #endif + } + + // End the 2D GUI. + CSRAW internal static void EndGUI (int layoutType) + { + try + { + if (Event.current.type == EventType.Layout) + { + switch (layoutType) + { + case 0: // kNoLayout + break; + case 1: // kGameLayout + GUILayoutUtility.Layout (); + break; + case 2: // kEditorLayout + GUILayoutUtility.LayoutFromEditorWindow (); + break; + } + } + + GUILayoutUtility.SelectIDList (s_OriginalID, false); + GUIContent.ClearStaticCache(); + } + finally { + Internal_ExitGUI(); + } + } + + // End the 2D GUI. + CSRAW internal static bool EndGUIFromException (System.Exception exception) { + // Check if the exception is a ExitGUIException + if (exception == null) + return false; + if (exception as ExitGUIException == null +#if !UNITY_FLASH && !UNITY_WEBGL + && exception.InnerException as ExitGUIException == null +#endif + ) + return false; + + Internal_ExitGUI (); + + return true; + } + + // Only allow calling GUI functions from inside OnGUI + CSRAW static internal void CheckOnGUI() { + if (Internal_GetGUIDepth () <= 0) + { + throw new ArgumentException("You can only call GUI functions from inside OnGUI."); + } + } + + CUSTOM static internal int Internal_GetGUIDepth () + { + return GetGUIState().m_OnGUIDepth; + } + + CUSTOM_PROP static internal bool mouseUsed + { return GetGUIState().m_CanvasGUIState.m_IsMouseUsed != 0; } + { GetGUIState().m_CanvasGUIState.m_IsMouseUsed = value ? 1 : 0; } + + CSRAW + + static internal Vector2 s_EditorScreenPointOffset = Vector2.zero; + static internal bool s_HasKeyboardFocus = false; + + // Convert a point from GUI position to screen space. + CSRAW public static Vector2 GUIToScreenPoint (Vector2 guiPoint) + { + return GUIClip.Unclip (guiPoint) + s_EditorScreenPointOffset; + } + + // Convert a rect from GUI position to screen space. + CSRAW internal static Rect GUIToScreenRect (Rect guiRect) + { + Vector2 screenPoint = GUIToScreenPoint (new Vector2 (guiRect.x, guiRect.y)); + guiRect.x = screenPoint.x; + guiRect.y = screenPoint.y; + return guiRect; + } + + // Convert a point from screen space to GUI position. + CSRAW public static Vector2 ScreenToGUIPoint (Vector2 screenPoint) + { + return GUIClip.Clip (screenPoint) - s_EditorScreenPointOffset; + } + + // Convert a rect from screen space to GUI position. + CSRAW public static Rect ScreenToGUIRect (Rect screenRect) + { + Vector2 guiPoint = ScreenToGUIPoint (new Vector2 (screenRect.x, screenRect.y)); + screenRect.x = guiPoint.x; + screenRect.y = guiPoint.y; + return screenRect; + } + + // Helper function to rotate the GUI around a point. + public static void RotateAroundPivot (float angle, Vector2 pivotPoint) { + Matrix4x4 mat = GUI.matrix; + GUI.matrix = Matrix4x4.identity; + Vector2 point = GUIClip.Unclip(pivotPoint); + Matrix4x4 newMat = Matrix4x4.TRS (point, Quaternion.Euler (0,0,angle), Vector3.one) * Matrix4x4.TRS (-point, Quaternion.identity, Vector3.one); + GUI.matrix = newMat *mat; + } + + // Helper function to scale the GUI around a point. + public static void ScaleAroundPivot (Vector2 scale, Vector2 pivotPoint) { + Matrix4x4 mat = GUI.matrix; + Vector2 point = GUIClip.Unclip(pivotPoint); + Matrix4x4 newMat = Matrix4x4.TRS (point, Quaternion.identity, new Vector3 (scale.x, scale.y, 1)) * Matrix4x4.TRS (-point, Quaternion.identity, Vector3.one); + GUI.matrix = newMat * mat; + } + + // Check to see if there's a modal IMGUI window that's currently open + CUSTOM_PROP public static bool hasModalWindow + { + GUIState& state = GetGUIState(); + return state.m_MultiFrameGUIState.m_Windows != NULL && state.m_MultiFrameGUIState.m_Windows->m_ModalWindow != NULL; + } + + //*undocumented* + CUSTOM_PROP static internal bool textFieldInput + { return GetInputManager().GetTextFieldInput (); } + { GetInputManager().SetTextFieldInput (value); } +END + + +CLASS internal GUIClip + // Push a clip rect to the stack with pixel offsets. + CUSTOM internal static void Push (Rect screenRect, Vector2 scrollOffset, Vector2 renderOffset, bool resetOffset) + { + GetGUIState().m_CanvasGUIState.m_GUIClipState.Push (IMGUI::GetCurrentEvent(GetGUIState()), screenRect, scrollOffset, renderOffset, resetOffset); + } + + // Removes the topmost clipping rectangle, undoing the effect of the latest GUIClip.Push + CUSTOM internal static void Pop () + { + GetGUIState().m_CanvasGUIState.m_GUIClipState.Pop (IMGUI::GetCurrentEvent(GetGUIState())); + } + + // Get the topmost rectangle + CUSTOM internal static Rect GetTopRect () + { + return GetGUIState().m_CanvasGUIState.m_GUIClipState.GetTopRect (); + } + + + CUSTOM_PROP static bool enabled + { return GetGUIState().m_CanvasGUIState.m_GUIClipState.GetEnabled(); } + + + // Unclips /pos/ to physical device coordinates. + CSRAW static public Vector2 Unclip (Vector2 pos) + { + Unclip_Vector2(ref pos); + return pos; + } + + CUSTOM private static void Unclip_Vector2 (ref Vector2 pos) + { + pos = GetGUIState().m_CanvasGUIState.m_GUIClipState.Unclip (pos); + } + + // The topmost physical rect in unclipped coordinates + // Used in editor to clip cursor rects inside scrollviews + CUSTOM_PROP static Rect topmostRect + { return GetGUIState().m_CanvasGUIState.m_GUIClipState.GetTopMostPhysicalRect (); } + + + // Unclips /rect/ to physical device coordinates. + CSRAW public static Rect Unclip (Rect rect) + { + Unclip_Rect(ref rect); + return rect; + } + CUSTOM private static void Unclip_Rect (ref Rect rect) + { + rect = GetGUIState().m_CanvasGUIState.m_GUIClipState.Unclip(rect); + } + + // Clips /absolutePos/ to drawing coordinates + CSRAW static public Vector2 Clip (Vector2 absolutePos) + { + Clip_Vector2 (ref absolutePos); + return absolutePos; + } + + CUSTOM private static void Clip_Vector2 (ref Vector2 absolutePos) + { + absolutePos = GetGUIState().m_CanvasGUIState.m_GUIClipState.Clip(absolutePos); + } + + // Convert /absoluteRect/ to drawing coordinates + CSRAW static public Rect Clip (Rect absoluteRect) + { + Internal_Clip_Rect (ref absoluteRect); + return absoluteRect; + } + + CUSTOM static private void Internal_Clip_Rect (ref Rect absoluteRect) + { + absoluteRect = GetGUIState().m_CanvasGUIState.m_GUIClipState.Clip (absoluteRect); + } + + // Reapply the clipping info. + CUSTOM internal static void Reapply () + { + GetGUIState().m_CanvasGUIState.m_GUIClipState.Reapply (IMGUI::GetCurrentEvent(GetGUIState())); + } + + // Set the GUIMatrix. This is here as this class handles all coordinate transforms anyways. + CUSTOM internal static Matrix4x4 GetMatrix() + { + return GetGUIState().m_CanvasGUIState.m_GUIClipState.GetMatrix(); + } + + CUSTOM internal static void SetMatrix (Matrix4x4 m) + { + GetGUIState().m_CanvasGUIState.m_GUIClipState.SetMatrix(IMGUI::GetCurrentEvent(GetGUIState()), m); + } + + // The visible rectangle. + CUSTOM_PROP static Rect visibleRect + { return GetGUIState().m_CanvasGUIState.m_GUIClipState.GetVisibleRect (); } + + CSRAW public static Vector2 GetAbsoluteMousePosition () + { + Vector2 vec; + Internal_GetAbsoluteMousePosition(out vec); + return vec; + } + CUSTOM private static void Internal_GetAbsoluteMousePosition (out Vector2 output) + { + *output = GetGUIState().m_CanvasGUIState.m_GUIClipState.GetAbsoluteMousePosition(); + } +END + +CSRAW } diff --git a/Runtime/Export/GameCenterServices.cs b/Runtime/Export/GameCenterServices.cs new file mode 100644 index 0000000..2a140c3 --- /dev/null +++ b/Runtime/Export/GameCenterServices.cs @@ -0,0 +1,451 @@ +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; + +namespace UnityEngine.SocialPlatforms.GameCenter +{ +#if ENABLE_GAMECENTER + using UnityEngine.SocialPlatforms.Impl; + + [StructLayout (LayoutKind.Sequential)] + internal struct GcUserProfileData + { + public string userName; + public string userID; + public int isFriend; + public Texture2D image; + + public UserProfile ToUserProfile() + { + return new UserProfile(userName, userID, (isFriend==1?true:false), UserState.Offline, image); + } + + public void AddToArray(ref UserProfile[] array, int number) + { + if (array.Length > number && number >= 0) + array[number] = ToUserProfile(); + else + Debug.Log("Index number out of bounds when setting user data"); + } + } + + [StructLayout (LayoutKind.Sequential)] + internal struct GcAchievementDescriptionData + { + public string m_Identifier; + public string m_Title; + public Texture2D m_Image; + public string m_AchievedDescription; + public string m_UnachievedDescription; + public int m_Hidden; + public int m_Points; + + public AchievementDescription ToAchievementDescription() + { + return new AchievementDescription( + m_Identifier, + m_Title, + m_Image, + m_AchievedDescription, + m_UnachievedDescription, + m_Hidden == 0 ? false : true, + m_Points); + } + } + + [StructLayout (LayoutKind.Sequential)] + internal struct GcAchievementData + { + public string m_Identifier; + public double m_PercentCompleted; + public int m_Completed; + public int m_Hidden; + public int m_LastReportedDate; + + public Achievement ToAchievement() + { + return new Achievement( + m_Identifier, + m_PercentCompleted, + m_Completed == 0 ? false : true, + m_Hidden == 0 ? false : true, + new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(m_LastReportedDate)); + } + } + + [StructLayout (LayoutKind.Sequential)] + internal struct GcScoreData + { + public string m_Category; + public int m_ValueLow; + public int m_ValueHigh; + public int m_Date; + public string m_FormattedValue; + public string m_PlayerID; + public int m_Rank; + + public Score ToScore() + { + return new Score( + m_Category, + (((Int64)m_ValueHigh) << 32) + m_ValueLow, + m_PlayerID, + new DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds(m_Date), + m_FormattedValue, + m_Rank); + } + } + + public partial class GameCenterPlatform : ISocialPlatform + { + static Action<bool> s_AuthenticateCallback; + static Action<bool> s_FriendsCallback; + static Action<IAchievementDescription[]> s_AchievementDescriptionLoaderCallback; + static Action<IAchievement[]> s_AchievementLoaderCallback; + static Action<bool> s_ProgressCallback; + static Action<bool> s_ScoreCallback; + static Action<IScore[]> s_ScoreLoaderCallback; + static Action<bool> s_LeaderboardCallback; + static Action<IUserProfile[]> s_UsersCallback; + static AchievementDescription[] s_adCache = new AchievementDescription[0]; + static UserProfile[] s_friends = new UserProfile[0]; + static UserProfile[] s_users = new UserProfile[0]; + static Action<bool> s_ResetAchievements; + private static LocalUser m_LocalUser; + private static List<GcLeaderboard> m_GcBoards = new List<GcLeaderboard>(); + + static void ClearAchievementDescriptions(int size) + { + if (s_adCache == null || s_adCache.Length != size) + s_adCache = new AchievementDescription[size]; + } + + static void SetAchievementDescription(GcAchievementDescriptionData data, int number) + { + s_adCache[number] = data.ToAchievementDescription(); + } + + static void SetAchievementDescriptionImage(Texture2D texture, int number) + { + if (s_adCache.Length <= number || number < 0) + { + Debug.Log("Achievement description number out of bounds when setting image"); + return; + } + s_adCache[number].SetImage(texture); + } + + static void TriggerAchievementDescriptionCallback() + { + if (s_AchievementDescriptionLoaderCallback != null && s_adCache != null) + { + if (s_adCache.Length == 0) + Debug.Log("No achivevement descriptions returned"); + s_AchievementDescriptionLoaderCallback(s_adCache); + } + } + + static void AuthenticateCallbackWrapper(int result) + { + if (s_AuthenticateCallback != null) + { + PopulateLocalUser(); + s_AuthenticateCallback((result == 1 ? true : false)); + } + } + + static void ClearFriends(int size) + { + SafeClearArray(ref s_friends, size); + } + + static void SetFriends(GcUserProfileData data, int number) + { + data.AddToArray(ref s_friends, number); + } + + static void SetFriendImage(Texture2D texture, int number) + { + SafeSetUserImage(ref s_friends, texture, number); + } + + static void TriggerFriendsCallbackWrapper(int result) + { + if (s_friends != null) + m_LocalUser.SetFriends(s_friends); + if (s_FriendsCallback != null) + s_FriendsCallback((result == 1 ? true : false)); + } + + static void AchievementCallbackWrapper(GcAchievementData[] result) + { + if (s_AchievementLoaderCallback != null) + { + if (result.Length == 0) + Debug.Log("No achivevements returned"); + Achievement[] migrated = new Achievement[result.Length]; + for (int i = 0; i < result.Length; ++i) + migrated[i] = result[i].ToAchievement(); + s_AchievementLoaderCallback(migrated); + } + } + + static void ProgressCallbackWrapper(bool success) + { + if (s_ProgressCallback != null) + s_ProgressCallback(success); + } + + static void ScoreCallbackWrapper(bool success) + { + if (s_ScoreCallback != null) + s_ScoreCallback(success); + } + + static void ScoreLoaderCallbackWrapper(GcScoreData[] result) + { + if (s_ScoreLoaderCallback != null) + { + Score[] migrated = new Score[result.Length]; + for (int i = 0; i < result.Length; ++i) + migrated[i] = result[i].ToScore(); + s_ScoreLoaderCallback(migrated); + } + } + + void ISocialPlatform.LoadFriends(ILocalUser user, Action<bool> callback) + { + s_FriendsCallback = callback; + Internal_LoadFriends(); + } + + void ISocialPlatform.Authenticate(ILocalUser user, Action<bool> callback) + { + s_AuthenticateCallback = callback; + Internal_Authenticate(); + } + + public ILocalUser localUser + { + get + { + if (m_LocalUser == null) + m_LocalUser = new LocalUser(); + + if (Internal_Authenticated() && m_LocalUser.id == "0") + PopulateLocalUser(); + return m_LocalUser; + } + } + + private static void PopulateLocalUser() + { + m_LocalUser.SetAuthenticated(Internal_Authenticated()); + m_LocalUser.SetUserName(Internal_UserName()); + m_LocalUser.SetUserID(Internal_UserID()); + m_LocalUser.SetUnderage(Internal_Underage()); + m_LocalUser.SetImage(Internal_UserImage()); + } + + public void LoadAchievementDescriptions(Action<IAchievementDescription[]> callback) + { + if (!VerifyAuthentication()) + { + callback(new AchievementDescription[0]); + return; + } + s_AchievementDescriptionLoaderCallback = callback; + Internal_LoadAchievementDescriptions(); + } + + // TODO: This doesn't really work with the static callback wrapper, multiple progresses + // could be reported at the same time. + public void ReportProgress(string id, double progress, Action<bool> callback) + { + if (!VerifyAuthentication()) + { + callback(false); + return; + } + s_ProgressCallback = callback; + Internal_ReportProgress(id, progress); + } + + public void LoadAchievements(Action<IAchievement[]> callback) + { + if (!VerifyAuthentication()) + { + callback(new Achievement[0]); + return; + } + s_AchievementLoaderCallback = callback; + Internal_LoadAchievements(); + } + + public void ReportScore(Int64 score, string board, Action<bool> callback) + { + if (!VerifyAuthentication()) + { + callback(false); + return; + } + s_ScoreCallback = callback; + Internal_ReportScore(score, board); + } + + public void LoadScores(string category, Action<IScore[]> callback) + { + if (!VerifyAuthentication()) + { + callback(new Score[0]); + return; + } + s_ScoreLoaderCallback = callback; + Internal_LoadScores(category); + } + + public void LoadScores(ILeaderboard board, Action<bool> callback) + { + if (!VerifyAuthentication()) + { + callback(false); + return; + } + s_LeaderboardCallback = callback; + Leaderboard genericBoard = (Leaderboard)board; + GcLeaderboard gcBoard = new GcLeaderboard(genericBoard); + m_GcBoards.Add(gcBoard); + if (genericBoard.GetUserFilter().Length > 0) + gcBoard.Internal_LoadScoresWithUsers(board.id, (int)board.timeScope, genericBoard.GetUserFilter()); + else + gcBoard.Internal_LoadScores(board.id, board.range.from, board.range.count, (int)board.userScope, (int)board.timeScope); + } + + static void LeaderboardCallbackWrapper(bool success) + { + if (s_LeaderboardCallback != null) + s_LeaderboardCallback(success); + } + + public bool GetLoading(ILeaderboard board) + { + if (!VerifyAuthentication()) return false; + foreach (GcLeaderboard gcBoard in m_GcBoards) + if (gcBoard.Contains((Leaderboard)board)) + return gcBoard.Loading(); + return false; + } + + private bool VerifyAuthentication() + { + if (!localUser.authenticated) + { + Debug.Log ("Must authenticate first"); + return false; + } + return true; + } + + public void ShowAchievementsUI() + { + Internal_ShowAchievementsUI(); + } + + public void ShowLeaderboardUI() + { + Internal_ShowLeaderboardUI(); + } + + static void ClearUsers(int size) + { + SafeClearArray(ref s_users, size); + } + + static void SetUser(GcUserProfileData data, int number) + { + data.AddToArray(ref s_users, number); + } + + static void SetUserImage(Texture2D texture, int number) + { + SafeSetUserImage(ref s_users, texture, number); + } + + static void TriggerUsersCallbackWrapper() + { + if (s_UsersCallback != null) + s_UsersCallback(s_users); + } + + public void LoadUsers(string[] userIds, Action<IUserProfile[]> callback) + { + if (!VerifyAuthentication()) + { + callback(new UserProfile[0]); + return; + } + s_UsersCallback = callback; + Internal_LoadUsers(userIds); + } + + private static void SafeSetUserImage(ref UserProfile[] array, Texture2D texture, int number) + { + if (array.Length <= number || number < 0) + { + Debug.Log("Invalid texture when setting user image"); + texture = new Texture2D(76, 76); + } + if (array.Length > number && number >= 0) + array[number].SetImage(texture); + else + Debug.Log("User number out of bounds when setting image"); + } + + private static void SafeClearArray(ref UserProfile[] array, int size) + { + if (array == null || array.Length != size) + array = new UserProfile[size]; + } + + public ILeaderboard CreateLeaderboard() + { + Leaderboard lb = new Leaderboard(); + return (ILeaderboard)lb; + } + + public IAchievement CreateAchievement() + { + Achievement achoo = new Achievement(); + return (IAchievement)achoo; + } + + static void TriggerResetAchievementCallback(bool result) + { + if (s_ResetAchievements != null) + s_ResetAchievements(result); + } + + + } +#else + public class GameCenterPlatform : UnityEngine.SocialPlatforms.Local + { + static public void ResetAllAchievements(Action<bool> callback) + { + Debug.Log ("ResetAllAchievements - no effect in editor"); + callback(true); + } + + static public void ShowDefaultAchievementCompletionBanner(bool value) + { + Debug.Log ("ShowDefaultAchievementCompletionBanner - no effect in editor"); + } + + static public void ShowLeaderboardUI(string leaderboardID, TimeScope timeScope) + { + Debug.Log ("ShowLeaderboardUI - no effect in editor"); + } + } +#endif +} + diff --git a/Runtime/Export/GameCenterServices.txt b/Runtime/Export/GameCenterServices.txt new file mode 100644 index 0000000..b19ad5f --- /dev/null +++ b/Runtime/Export/GameCenterServices.txt @@ -0,0 +1,367 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Utilities/Utility.h" +#include <vector> + +#if ENABLE_GAMECENTER +#include "External/GameKit/GameCenter.h" +#endif + + +CSRAW +using System; +using System.Runtime.InteropServices; + +#if ENABLE_GAMECENTER +namespace UnityEngine.SocialPlatforms.GameCenter +{ + using UnityEngine.SocialPlatforms.Impl; + + /// GameCenter implementation for network services. + /// An application bundle ID must be registered on iTunes Connect + /// before it can access GameCenter. This ID must be properly set in + /// the iOS player properties in Unity, or in the Info.plist file inside your + /// application bundle for OS X Standalone builds. When debugging you can use the GameCenter + /// sandbox (a text displaying this is shown when logging on). You + /// must log on in the application to get into sandbox mode, logging + /// on in the GameCenter application will always use the production version. + /// + + // Remove this note if apple gets to fix it! + /// Note: Mac OS X (as of version 10.8.2) has a bug where it will not allow you to enter + /// Game Center sandbox mode unless you use the following workaround as suggested by Apple: + /// https://devforums.apple.com/message/763000 + /// It does not seem to be possible to create Game Center sandbox accounts using this workaround, + /// though, so if you don't have an existing sandbox account, you need to create one using iOS. + /// + + /// For testing Game Center on OS X, you need to first set up your Info.plist file to contain + /// the correct application bundle ID and version to match the app set up in iTunes Connect. + /// Then, you need to set up the correct entitlements for Game Center. Create an entitlements file + /// with the following contents: + + BEGIN EX + <?xml version="1.0" encoding="UTF-8"?> + <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> + <plist version="1.0"> + <dict> + <key>com.apple.security.app-sandbox</key> + <true/> + <key>com.apple.security.temporary-exception.mach-lookup.global-name</key> + <array> + <string>com.apple.gamed.osx</string> + <string>com.apple.gamed.xpc</string> + <string>com.apple.developer.game-center</string> + </array> + </dict> + </plist> + END EX + + /// Finally, you need to sign you application using the entitlements file like this: + + BEGIN EX + codesign -f -s "<Your code signing certificate>" --entitlements <path to your entitlements file> <path to your created unity standalone app> + END EX + + /// When using the GameCenterPlatform class in C# you need to include the + /// UnityEngine.SocialPlatforms.GameCenter namespace. + /// + /// Some things to be aware of when using the generic API: + /// + /// __Authenticate()__ \\ + /// If the user is not logged in, a standard GameKit UI is shown + /// where he can log on or create a new user. It is recommended + /// this is done as early as possible. + /// + /// __Achievement descriptions and Leaderboards__ \\ + /// The achivements descriptions and leaderboard configurations can be configured in the + /// iTunes Connect portal. Achievements get unique identifiers and the + /// leaderboards use category names as identifiers. + /// + /// __GameCenter Sandbox__ \\ + /// Development applications use the GameCenter Sandbox. This is a seperate GameCenter + /// than the live one, nothing is shared between them. It is recommended that you + /// create a seperate user for testing with the GameCenter Sandbox, you should not use + /// your real Apple ID for this. You can only log on to the sandbox through a development + /// application, make sure you are not logged into GameCenter using the GameCenter app before + /// testing begins. You should see ''*** Sandbox ***'' in the login dialog, if you don't see this + /// then you are logging on to the real one. Sometime it happens that the OS forgets that the + /// application is using the sandbox and you will be logged on to the real one. If the application + /// has not be submitted to Apple already then this will probably result in an error. To fix this + /// all that needs to be done is to delete the app and redeploy with Xcode. To make another apple + /// ID a friend of a sandbox user it needs to be a sandbox user as well. + /// + /// If you start getting errors when accessing GameCenter stating that the + /// application is not recognized you'll need to delete the application complately and re-deploy. + /// Make sure you are not logged on when starting the newly installed application again. + CONDITIONAL ENABLE_GAMECENTER + CLASS GameCenterPlatform : ISocialPlatform + + CUSTOM internal static void Internal_Authenticate() + { + #if ENABLE_GAMECENTER + GameCenter::GcLocalUser::GetInstance()->Authenticate(); + #endif + } + + CUSTOM internal static bool Internal_Authenticated() + { + #if ENABLE_GAMECENTER + return GameCenter::GcLocalUser::GetInstance()->GetAuthenticated(); + #else + return false; + #endif + } + + CUSTOM internal static string Internal_UserName() + { + #if ENABLE_GAMECENTER + GameCenter::GcLocalUser *user = GameCenter::GcLocalUser::GetInstance(); + std::string name = user->GetUserName(); + return scripting_string_new(name); + #else + return scripting_string_new(""); + #endif + } + + CUSTOM internal static string Internal_UserID() + { + #if ENABLE_GAMECENTER + return scripting_string_new(GameCenter::GcLocalUser::GetInstance()->GetUserID()); + #else + return scripting_string_new(""); + #endif + } + + CUSTOM internal static bool Internal_Underage() + { + #if ENABLE_GAMECENTER + return GameCenter::GcLocalUser::GetInstance()->GetIsUnderage(); + #else + return false; + #endif + } + + CUSTOM internal static Texture2D Internal_UserImage() + { + #if ENABLE_GAMECENTER + return GameCenter::GcLocalUser::GetInstance()->GetUserImage(); + #else + return SCRIPTING_NULL; + #endif + } + + CUSTOM internal static void Internal_LoadFriends() + { + #if ENABLE_GAMECENTER + GameCenter::GcLocalUser::GetInstance()->LoadFriends(); + #endif + } + + CUSTOM internal static void Internal_LoadAchievementDescriptions() + { + #if ENABLE_GAMECENTER + GameCenter::GcAchievementDescription::LoadAchievementDescriptions(); + #endif + } + + CUSTOM internal static void Internal_LoadAchievements() + { + #if ENABLE_GAMECENTER + GameCenter::GcAchievement::LoadAchievements(); + #endif + } + + CUSTOM internal static void Internal_ReportProgress(string id, double progress) + { + #if ENABLE_GAMECENTER + GameCenter::GcAchievement::ReportProgress(id, progress); + #endif + } + + CUSTOM internal static void Internal_ReportScore(Int64 score, string category) + { + #if ENABLE_GAMECENTER + GameCenter::GcScore::ReportScore(score, category); + #endif + } + + CUSTOM internal static void Internal_LoadScores(string category) + { + #if ENABLE_GAMECENTER + GameCenter::GcScore::LoadScores(category); + #endif + } + + CUSTOM internal static void Internal_ShowAchievementsUI() + { + #if ENABLE_GAMECENTER + GameCenter::GcAchievementDescription::ShowAchievementsUI(); + #endif + } + + CUSTOM internal static void Internal_ShowLeaderboardUI() + { + #if ENABLE_GAMECENTER + GameCenter::GcLeaderboard::ShowLeaderboardUI(); + #endif + } + + CUSTOM internal static void Internal_LoadUsers(string[] userIds) + { + #if ENABLE_GAMECENTER + GameCenter::GcLocalUser::LoadUsers(userIds); + #endif + } + + CUSTOM internal static void Internal_ResetAllAchievements() + { + #if ENABLE_GAMECENTER + GameCenter::GcAchievement::ResetAllAchievements(); + #endif + } + + CUSTOM internal static void Internal_ShowDefaultAchievementBanner(bool value) + { + #if ENABLE_GAMECENTER + GameCenter::GcAchievement::ShowDefaultAchievementBanner(value); + #endif + } + + // Reset all the achievements for the local user. + CSRAW static public void ResetAllAchievements(Action<bool> callback) + { + s_ResetAchievements = callback; + Internal_ResetAllAchievements(); + } + + // Show the default iOS banner when achievements are completed. + CSRAW static public void ShowDefaultAchievementCompletionBanner(bool value) + { + Internal_ShowDefaultAchievementBanner(value); + } + + // Show the leaderboard UI with a specific leaderboard shown initially with a specific time scope selected. + CSRAW static public void ShowLeaderboardUI(string leaderboardID, TimeScope timeScope) + { + Internal_ShowSpecificLeaderboardUI(leaderboardID, (int)timeScope); + } + + CUSTOM internal static void Internal_ShowSpecificLeaderboardUI(string leaderboardID, int timeScope) + { + #if ENABLE_GAMECENTER + GameCenter::GcLeaderboard::ShowLeaderboardUI(leaderboardID, timeScope); + #endif + } + END + + // This class cannot inherit from the generic Leaderboard class as it will break the marshaling of the pointer + // *undocumented* + CSRAW [StructLayout (LayoutKind.Sequential)] + CONDITIONAL ENABLE_GAMECENTER + CLASS internal GcLeaderboard + C++RAW + #if ENABLE_GAMECENTER + struct GcLeaderboardToMono + { + GameCenter::GcLeaderboard* leaderboard; + ScriptingObjectPtr genericLeaderboard; + }; + #endif + + CSRAW + private IntPtr m_InternalLeaderboard; + Leaderboard m_GenericLeaderboard; + + internal GcLeaderboard(Leaderboard board) + { + m_GenericLeaderboard = board; + } + + ~GcLeaderboard() + { + Dispose(); + } + + internal bool Contains(Leaderboard board) + { + return m_GenericLeaderboard == board; + } + + internal void SetScores(GcScoreData[] scoreDatas) + { + if (m_GenericLeaderboard != null) + { + Score[] scores = new Score[scoreDatas.Length]; + for(int i = 0; i < scoreDatas.Length; ++i) + scores[i] = scoreDatas[i].ToScore(); + m_GenericLeaderboard.SetScores(scores); + } + } + + internal void SetLocalScore(GcScoreData scoreData) + { + if (m_GenericLeaderboard != null) + m_GenericLeaderboard.SetLocalUserScore(scoreData.ToScore()); + } + + internal void SetMaxRange(uint maxRange) + { + if (m_GenericLeaderboard != null) + m_GenericLeaderboard.SetMaxRange(maxRange); + } + + internal void SetTitle(string title) + { + if (m_GenericLeaderboard != null) + m_GenericLeaderboard.SetTitle(title); + } + + CUSTOM internal void Internal_LoadScores(string category, int from, int count, int playerScope, int timeScope) + { + #if ENABLE_GAMECENTER + GcLeaderboardToMono& monoBoard = ExtractMonoObjectData<GcLeaderboardToMono>(self); + monoBoard.leaderboard = new GameCenter::GcLeaderboard(); + monoBoard.leaderboard->Create(); + monoBoard.leaderboard->RegisterManagedSelf(self); + monoBoard.leaderboard->LoadScores(category, from, count, playerScope, timeScope); + #endif + } + + CUSTOM internal void Internal_LoadScoresWithUsers(string category, int timeScope, string[] userIDs) + { + #if ENABLE_GAMECENTER + GcLeaderboardToMono& monoBoard = ExtractMonoObjectData<GcLeaderboardToMono>(self); + monoBoard.leaderboard = new GameCenter::GcLeaderboard(); + monoBoard.leaderboard->Create(userIDs); + monoBoard.leaderboard->RegisterManagedSelf(self); + monoBoard.leaderboard->LoadScores(category, 1, 10, 0, timeScope); + #endif + } + + CUSTOM internal bool Loading() + { + #if ENABLE_GAMECENTER + GcLeaderboardToMono& monoBoard = ExtractMonoObjectData<GcLeaderboardToMono>(self); + return monoBoard.leaderboard->Loading(); + #else + return false; + #endif + } + + THREAD_SAFE + CUSTOM internal void Dispose() + { + #if ENABLE_GAMECENTER + GcLeaderboardToMono& monoBoard = ExtractMonoObjectData<GcLeaderboardToMono>(self); + delete monoBoard.leaderboard; + monoBoard.leaderboard = NULL; + #endif + } + END + +CSRAW +} +#endif diff --git a/Runtime/Export/GameObjectExport.cpp b/Runtime/Export/GameObjectExport.cpp new file mode 100644 index 0000000..1613f56 --- /dev/null +++ b/Runtime/Export/GameObjectExport.cpp @@ -0,0 +1,89 @@ +#include "UnityPrefix.h" +#include "Runtime/Scripting/Backend/ScriptingTypes.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/BaseClasses/GameObject.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/Backend/ScriptingBackendApi.h" +#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h" +#include "Runtime/Scripting/Scripting.h" + +#if ENABLE_SCRIPTING + +GameObject* MonoCreateGameObject (const char* name) +{ + string cname; + if (!name) + { + cname = "New Game Object"; + } + else + { + cname = name; + } + return &CreateGameObject (cname, "Transform", NULL); +} + +ScriptingObjectPtr MonoAddComponent (GameObject& go, const char* name) +{ + string error; + Unity::Component* component = AddComponent (go, name, &error); + + if (component) + return Scripting::ScriptingWrapperFor (component); + else + { + LogStringObject (error, &go); + return SCRIPTING_NULL; + } +} + +static bool IsNonMonoBehaviourUnityEngineType(ScriptingClassPtr klass) +{ + return !scripting_class_is_subclass_of(klass, MONO_COMMON.monoBehaviour); +} + +ScriptingObjectPtr MonoAddComponentWithType (GameObject& go, ScriptingObjectPtr systemTypeInstance, bool dontShareMonoScript) +{ + string error; + + + Unity::Component* component = NULL; + ScriptingClassPtr klass = GetScriptingTypeRegistry().GetType(systemTypeInstance); + + if (klass == SCRIPTING_NULL) + { +#if MONO_QUALITY_ERRORS + ScriptWarning("AddComponent asking for invalid type", &go); +#endif + return SCRIPTING_NULL; + } + int instanceID = go.GetInstanceID(); + if (IsNonMonoBehaviourUnityEngineType(klass)) + { + int classID = Object::StringToClassID (scripting_class_get_name (klass)); + component = AddComponent (go, classID, NULL, &error); + } + else + { + MonoScript* script = NULL; + if (!dontShareMonoScript) + script = GetMonoScriptManager().FindRuntimeScript (klass); + if (!script) + script = CreateMonoScriptFromScriptingType(klass); + if (script) + component = AddComponent (go, ClassID (MonoBehaviour), script, &error); + } + + if (component) + return Scripting::ScriptingWrapperFor(component); + else + { + // Check if the object is still valid ( could have been destroyed in Awake.) + LogStringObject (error, PPtr<Object> (instanceID)); + return SCRIPTING_NULL; + } +} +#endif diff --git a/Runtime/Export/GameObjectExport.h b/Runtime/Export/GameObjectExport.h new file mode 100644 index 0000000..69e07f4 --- /dev/null +++ b/Runtime/Export/GameObjectExport.h @@ -0,0 +1,17 @@ +#ifndef _GAMEOBJECTEXPORT_H_ +#define _GAMEOBJECTEXPORT_H_ + +#include "UnityPrefix.h" + +#include "Runtime/Scripting/Backend/ScriptingTypes.h" + +namespace Unity +{ + class GameObject; +} + +ScriptingObjectPtr MonoAddComponent(Unity::GameObject& go, const char* name); +ScriptingObjectPtr MonoAddComponentWithType(Unity::GameObject& go, ScriptingObjectPtr reflectionTypeObject, bool dontShareMonoScript = false); +Unity::GameObject* MonoCreateGameObject(const char* name); + +#endif diff --git a/Runtime/Export/GizmoBindings.txt b/Runtime/Export/GizmoBindings.txt new file mode 100644 index 0000000..ed3266c --- /dev/null +++ b/Runtime/Export/GizmoBindings.txt @@ -0,0 +1,180 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Math/Vector3.h" +#include "Runtime/Geometry/Ray.h" +#include "Runtime/Math/Rect.h" +#include "Runtime/Math/Matrix4x4.h" +#include "Runtime/Graphics/Texture.h" +#include "Runtime/Filters/Misc/Font.h" +#include "Runtime/Shaders/Material.h" +#include "Runtime/IMGUI/TextUtil.h" +#include "Runtime/Camera/RenderLayers/GUITexture.h" +#include "Runtime/Misc/InputEvent.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +#if UNITY_EDITOR +#include "Editor/Src/Gizmos/GizmoManager.h" +#include "Editor/Src/Gizmos/GizmoUtil.h" +#include "Editor/Src/Gizmos/GizmoRenderer.h" +#endif + +using namespace Unity; + +/* + Mono defines a bool as either 1 or 2 bytes. + On windows a bool on the C++ side needs to be 2 bytes. + We use the typemap to map bool's to short's. + When using the C++ keyword and you want to export a bool value + to mono you have to use a short on the C++ side. +*/ + + +void PauseEditor (); +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + + +// Gizmos are used to give visual debugging or setup aids in the scene view. +CLASS Gizmos + + C++RAW + + static void CheckGizmoDrawing (); + static void CheckGizmoDrawing () + { + #if !GAMERELEASE + if (!GizmoManager::Get ().IsDrawingGizmos ()) + Scripting::RaiseMonoException ("Gizmo drawing functions can only be used in OnDrawGizmos and OnDrawGizmosSelected."); + #endif + } + + + /// *listonly* + CSRAW public static void DrawRay (Ray r) + { + Gizmos.DrawLine (r.origin, r.origin + r.direction); + } + // Draws a ray starting at /from/ to /from/ + /direction/. + CSRAW public static void DrawRay (Vector3 from, Vector3 direction) + { + Gizmos.DrawLine (from, from + direction); + } + + + + // Draws a line starting at /from/ towards /to/. + CUSTOM static void DrawLine (Vector3 from, Vector3 to) + { + CheckGizmoDrawing (); + #if !GAMERELEASE + DrawLine (from, to); + #endif + } + + // Draws a wireframe sphere with /center/ and /radius/. + CUSTOM static void DrawWireSphere (Vector3 center, float radius) + { + #if !GAMERELEASE + CheckGizmoDrawing (); + DrawWireSphere (center, radius); + #endif + } + + // Draws a solid sphere with /center/ and /radius/. + CUSTOM static void DrawSphere (Vector3 center, float radius) + { + #if !GAMERELEASE + CheckGizmoDrawing (); + DrawSphere (center, radius); + #endif + } + + // Draw a wireframe box with /center/ and /size/. + CUSTOM static void DrawWireCube (Vector3 center, Vector3 size) + { + #if !GAMERELEASE + CheckGizmoDrawing (); + DrawWireCube (center, size); + #endif + } + + // Draw a solid box with /center/ and /size/. + CUSTOM static void DrawCube (Vector3 center, Vector3 size) + { + #if !GAMERELEASE + CheckGizmoDrawing (); + DrawCube (center, size); + #endif + } + + + // Draw an icon at a position in the scene view. + CUSTOM static void DrawIcon (Vector3 center, string name, bool allowScaling = true) + { + #if !GAMERELEASE + CheckGizmoDrawing (); + DrawIcon (center, name, allowScaling); + #endif + } + + + /// *listonly* + CSRAW public static void DrawGUITexture (Rect screenRect, Texture texture, Material mat = null) { DrawGUITexture (screenRect, texture,0,0,0,0, mat); } + // Draw a texture in screen coordinates. Useful for GUI backgrounds. + CUSTOM static void DrawGUITexture (Rect screenRect, Texture texture, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Material mat = null) { + #if !GAMERELEASE + CheckGizmoDrawing (); + DrawGUITexture (screenRect, texture, leftBorder, rightBorder, topBorder, bottomBorder, ColorRGBA32(128,128,128,128), mat); + #endif + } + + + // Sets the color for the gizmos that will be drawn next. + CUSTOM_PROP static Color color + { + #if !GAMERELEASE + return gizmos::g_GizmoColor; + #endif + return ColorRGBAf (1,1,1,1); + } + { + #if !GAMERELEASE + gizmos::g_GizmoColor = value; + #endif + } + + // Set the gizmo matrix used to draw all gizmos. + CUSTOM_PROP static Matrix4x4 matrix + { + #if !GAMERELEASE + return GetGizmoMatrix (); + #endif + return Matrix4x4f::identity; + } + { + #if !GAMERELEASE + SetGizmoMatrix (value); + #endif + } + + + CUSTOM static void DrawFrustum (Vector3 center, float fov, float maxRange, float minRange, float aspect) { + #if !GAMERELEASE + DrawFrustum (center, fov, maxRange, minRange, aspect); + #endif + } +END + + + +CSRAW } diff --git a/Runtime/Export/GradientBindings.txt b/Runtime/Export/GradientBindings.txt new file mode 100644 index 0000000..1e4671b --- /dev/null +++ b/Runtime/Export/GradientBindings.txt @@ -0,0 +1,231 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Math/Gradient.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +using namespace Unity; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngine; + +namespace UnityEngine +{ + +// Color key used by Gradient +STRUCT public GradientColorKey + + // Gradient color key + CSRAW public GradientColorKey (Color col, float time) + { + color = col; + this.time = time; + } + // color of key + CSRAW public Color color; + + // time of the key (0 - 1) + CSRAW public float time; +END + +C++RAW + +struct MonoGradientColorKey +{ + ColorRGBAf color; + float time; +}; + +// Alpha key used by Gradient +STRUCT public GradientAlphaKey + + // Gradient alpha key + CSRAW public GradientAlphaKey (float alpha, float time) + { + this.alpha = alpha; + this.time = time; + } + + // alpha alpha of key + CSRAW public float alpha; + + // time of the key (0 - 1) + CSRAW public float time; +END + + +C++RAW + +struct MonoGradientAlphaKey +{ + float alpha; + float time; +}; + +C++RAW + static void CleanupGradientNEW(void* gradient){ delete ((GradientNEW*)gradient); } ; + +// Gradient used for animating colors +CSRAW [StructLayout (LayoutKind.Sequential)] + +THREAD_SAFE +CLASS public Gradient + CSRAW internal IntPtr m_Ptr; + + THREAD_SAFE + CUSTOM private void Init () { + self.SetPtr(new GradientNEW(), CleanupGradientNEW); + } + + THREAD_SAFE + CUSTOM private void Cleanup () { CleanupGradientNEW(self.GetPtr()); } + + CSRAW public Gradient () { + Init (); + } + + CSRAW ~Gradient() { + Cleanup (); + } + + + // Calculate color at a given time + CUSTOM Color Evaluate (float time) + { + time = clamp01(time); + return self->Evaluate (time); + } + + // Returns num keys converted or -1 if invalid conversion + C++RAW + int ConvertColorKeyArray (ScriptingArrayPtr scriptColorKeys, GradientNEW::ColorKey* colorKeys) + { + if (scriptColorKeys == SCRIPTING_NULL) + { + ErrorString("SetKeys: Invalid input ColorKey array"); + return -1; + } + + int size = GetScriptingArraySize (scriptColorKeys); + if (size > kGradientMaxNumKeys) + { + ErrorString(Format("Max number of color keys is %d (given %d)", kGradientMaxNumKeys, size)); + return -1; + } + + for (int i=0; i < size ; i++) + { + MonoGradientColorKey &key = Scripting::GetScriptingArrayElement<MonoGradientColorKey> (scriptColorKeys, i); + colorKeys[i].m_Color = key.color; + colorKeys[i].m_Time = key.time; + } + + return size; + } + + // Returns num keys converted or -1 if invalid conversion + C++RAW + int ConvertAlphaKeyArray (ScriptingArrayPtr scriptAlphaKeys, GradientNEW::AlphaKey* alphaKeys) + { + if (scriptAlphaKeys == SCRIPTING_NULL) + { + ErrorString("SetKeys: Invalid input AlphaKey array"); + return -1; + } + + int size = GetScriptingArraySize (scriptAlphaKeys); + if (size > kGradientMaxNumKeys) + { + ErrorString(Format("Max number of alpha keys is %d (given %d)", kGradientMaxNumKeys, size)); + return -1; + } + + for (int i=0; i < size ; i++) + { + MonoGradientAlphaKey &key = Scripting::GetScriptingArrayElement<MonoGradientAlphaKey> (scriptAlphaKeys, i); + alphaKeys[i].m_Alpha = key.alpha; + alphaKeys[i].m_Time = key.time; + } + + return size; + } + + CUSTOM_PROP GradientColorKey[] colorKeys + { + int numColorKeys = self->GetNumColorKeys (); + GradientNEW::ColorKey colorKeys[kGradientMaxNumKeys]; + ColorRGBA32& firstKey = self->GetKey(0); + UInt16& firstColorTime = self->GetColorTime(0); + for(int i = 0; i < kGradientMaxNumKeys; i++) + { + colorKeys[i].m_Color = (&firstKey)[i]; + colorKeys[i].m_Color.a = 255; // See alphaKeys for alpha values + colorKeys[i].m_Time = WordToNormalized((&firstColorTime)[i]); + } + return CreateScriptingArray (colorKeys, numColorKeys, MONO_COMMON.gradientColorKey); + } + { + GradientNEW::ColorKey colorKeys[kGradientMaxNumKeys]; + int numColorKeys = ConvertColorKeyArray (value, colorKeys); + if (numColorKeys == -1) + return; + self->SetColorKeys(&colorKeys[0], numColorKeys); + } + + CUSTOM_PROP GradientAlphaKey[] alphaKeys + { + int numAlphaKeys = self->GetNumAlphaKeys (); + GradientNEW::AlphaKey alphaKeys[kGradientMaxNumKeys]; + const ColorRGBA32& firstKey = self->GetKey(0); + const UInt16& firstAlphaTime = self->GetAlphaTime(0); + for(int i = 0; i < kGradientMaxNumKeys; i++) + { + alphaKeys[i].m_Alpha = ByteToNormalized((&firstKey)[i].a); + alphaKeys[i].m_Time = WordToNormalized((&firstAlphaTime)[i]); + } + + return CreateScriptingArray (alphaKeys, numAlphaKeys, MONO_COMMON.gradientAlphaKey); + } + { + GradientNEW::AlphaKey alphaKeys[kGradientMaxNumKeys]; + int numAlphaKeys = ConvertAlphaKeyArray (value, alphaKeys); + if (numAlphaKeys == -1) + return; + self->SetAlphaKeys(&alphaKeys[0], numAlphaKeys); + } + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP internal Color constantColor + { + return self->GetConstantColor (); + } + { + self->SetConstantColor (value); + } + + // Setup Gradient with an array of color keys and alpha keys + CUSTOM void SetKeys (GradientColorKey[] colorKeys, GradientAlphaKey[] alphaKeys) + { + GradientNEW::ColorKey colors[kGradientMaxNumKeys]; + int numColorKeys = ConvertColorKeyArray (colorKeys, colors); + if (numColorKeys == -1) + return; + + GradientNEW::AlphaKey alphas[kGradientMaxNumKeys]; + int numAlphaKeys = ConvertAlphaKeyArray (alphaKeys, alphas); + if (numAlphaKeys == -1) + return; + + return self->SetKeys (&colors[0], numColorKeys, &alphas[0], numAlphaKeys); + } +END + +CSRAW } // end of UnityEngine + diff --git a/Runtime/Export/GradientUtility.txt b/Runtime/Export/GradientUtility.txt new file mode 100644 index 0000000..4aefd8a --- /dev/null +++ b/Runtime/Export/GradientUtility.txt @@ -0,0 +1,30 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Animation/Animation.h" +#include "Runtime/Animation/AnimationClip.h" +#include "Runtime/Animation/AnimationManager.h" +#include "Runtime/Animation/AnimationState.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Animation/AnimationCurveUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Mono/MonoScript.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Math/Gradient.h" + +using namespace Unity; + + +CSRAW + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// TODO: move Gradient here... + +CSRAW } // Namespace diff --git a/Runtime/Export/Graphics.txt b/Runtime/Export/Graphics.txt new file mode 100644 index 0000000..f8bdb76 --- /dev/null +++ b/Runtime/Export/Graphics.txt @@ -0,0 +1,3325 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoExportUtility.h" +#include "Runtime/Camera/Camera.h" +#include "Runtime/Camera/ImageFilters.h" +#include "Runtime/Camera/Light.h" +#include "Runtime/Camera/Skybox.h" +#include "Runtime/Graphics/LightmapSettings.h" +#include "Runtime/Filters/Renderer.h" +#include "Runtime/Camera/IntermediateRenderer.h" +#include "Runtime/Graphics/GraphicsHelper.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Shaders/Material.h" +#include "Runtime/Filters/Misc/TextMesh.h" +#include "Runtime/Filters/Particles/EllipsoidParticleEmitter.h" +#include "Runtime/Filters/Particles/MeshParticleEmitter.h" +#include "Runtime/Shaders/Shader.h" +#include "External/shaderlab/Library/intshader.h" +#include "Runtime/Camera/Renderqueue.h" +#include "Runtime/Filters/Deformation/SkinnedMeshFilter.h" +#include "Runtime/Camera/Flare.h" +#include "Runtime/GfxDevice/GfxDevice.h" +#include "External/shaderlab/Library/texenv.h" +#include "External/shaderlab/Library/properties.h" +#include "Runtime/Geometry/Ray.h" +#include "Runtime/Graphics/Texture2D.h" +#include "Runtime/Graphics/CubemapTexture.h" +#include "Runtime/Graphics/Texture3D.h" +#include "Runtime/Graphics/SpriteFrame.h" +#include "Runtime/Video/VideoTexture.h" +#include "Runtime/Camera/Projector.h" +#include "Runtime/Camera/RenderLayers/GUITexture.h" +#include "Runtime/Camera/RenderLayers/GUIText.h" +#include "Runtime/Camera/RenderLayers/GUILayer.h" +#include "Runtime/Filters/Misc/LineRenderer.h" +#include "Runtime/Graphics/DrawUtil.h" +#include "Runtime/Math/Quaternion.h" +#include "Runtime/Filters/Mesh/LodMesh.h" +#include "Runtime/Filters/Mesh/LodMeshFilter.h" +#include "Runtime/Graphics/RenderTexture.h" +#include "Runtime/Graphics/MatrixStack.h" +#include "Runtime/Filters/Misc/TrailRenderer.h" +#include "Runtime/Camera/LODGroupManager.h" +#include "Runtime/Graphics/RenderBufferManager.h" +#include "Runtime/Camera/RenderManager.h" +#include "Runtime/Shaders/GraphicsCaps.h" +#include "Runtime/Graphics/ScreenManager.h" +#include "Runtime/Misc/ResourceManager.h" +#include "Runtime/Geometry/Plane.h" +#include "Runtime/Filters/Particles/ParticleAnimator.h" +#include "Runtime/Filters/Particles/ParticleRenderer.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Filters/AABBUtility.h" +#include <list> +#include <vector> +#include "Runtime/Misc/QualitySettings.h" +#include "Runtime/Filters/Misc/Font.h" +#include "Runtime/Camera/RenderSettings.h" +#include "Runtime/Geometry/Intersection.h" +#include "Runtime/Shaders/ShaderNameRegistry.h" +#include "Runtime/Shaders/ShaderKeywords.h" +#include "Runtime/Shaders/ComputeShader.h" +#include "Runtime/Geometry/TextureAtlas.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Camera/CameraUtil.h" +#include "Runtime/Misc/Player.h" +#include "Runtime/Graphics/ImageConversion.h" +#include "Runtime/Filters/Mesh/MeshCombiner.h" +#include "Runtime/Filters/Mesh/MeshOptimizer.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Camera/Culler.h" +#include "Runtime/Threads/Mutex.h" +#include "Runtime/Threads/AtomicRefCounter.h" +#include "Runtime/Camera/OcclusionArea.h" +#include "Runtime/Camera/OcclusionPortal.h" +#include "Runtime/Graphics/DrawSplashScreenAndWatermarks.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Utilities/BitUtility.h" +#include "Runtime/Profiler/Profiler.h" +#include "Runtime/IMGUI/GUIStyle.h" +#include "Runtime/Scripting/Backend/ScriptingBackendApi.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" +#include "Runtime/Graphics/TriStripper.h" +#include "Runtime/Misc/GraphicsScriptingUtility.h" + +#if ENABLE_TEXTUREID_MAP + #include "Runtime/GfxDevice/TextureIdMap.h" +#endif + + +#if !GAMERELEASE +#include "Editor/Src/Gizmos/GizmoManager.h" +#include "Editor/Src/Gizmos/GizmoUtil.h" +#endif + + +// matrix stacks to be able to support GL style Push/Pop +static MatrixStack g_WorldMatrixStack; +static MatrixStack g_ViewMatrixStack; +static MatrixStack g_ProjectionMatrixStack; +// + +C++RAW + + +class MonoMaterialPropertyBlock : public MaterialPropertyBlock { +public: + MonoMaterialPropertyBlock() : m_Counter() { } + + void Retain() + { + m_Counter.Retain(); + } + + void Release() + { + if( m_Counter.Release() ) { + delete this; + } + } + + static void CleanupMonoMaterialPropertyBlock(void* mmpb) + { + if (NULL != mmpb) + ((MonoMaterialPropertyBlock*)mmpb)->Release(); + } + +private: + AtomicRefCounter m_Counter; +}; + + +extern PPtr<Shader> s_ScriptingCurrentShader; +extern const ChannelAssigns* s_ScriptingCurrentChannels; + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// The type of a [[Light]]. +ENUM LightType + // The light is a spot light. + Spot = 0, + + // The light is a directional light. + Directional = 1, + + // The light is a point light. + Point = 2, + + // The light is an area light. It affects only lightmaps and lightprobes. + Area = 3 +END + +// How the [[Light]] is rendered. +ENUM LightRenderMode + // Automatically choose the render mode. + Auto = 0, + // Force the [[Light]] to be a pixel light. + ForcePixel = 1, + // Force the [[Light]] to be a vertex light. + ForceVertex = 2 +END + +// Shadow casting options for a [[Light]]. +ENUM LightShadows + // Do not cast shadows (default). + None = 0, + // Cast "hard" shadows (with no shadow filtering). + Hard = 1, + // Cast "soft" shadows (with 4x PCF filtering). + Soft = 2, +END + + +// OcclusionArea is an area in which occlusion culling is performed +CLASS OcclusionArea : Component + + // Center of the occlusion area relative to the transform + AUTO_PROP Vector3 center GetCenter SetCenter + + // Size that the occlusion area will have + AUTO_PROP Vector3 size GetSize SetSize + +END + +//The portal for dynamically changing occlusion at runtime. +CLASS OcclusionPortal : Component + //gets / sets the portal's open state + CUSTOM_PROP bool open { return self->GetIsOpen(); } { self->SetIsOpen(value); } +END + + +// Fog mode to use. +ENUM FogMode + // Linear fog. + Linear = 1, + + // Exponential fog. + Exponential = 2, + + // Exponential squared fog (default). + ExponentialSquared = 3 +END + + +// The Render Settings contain values for a range of visual elements in your scene, like fog and ambient light. +CLASS RenderSettings : Object + // Is fog enabled? + CUSTOM_PROP static bool fog { return GetRenderSettings().GetUseFog(); } { return GetRenderSettings().SetUseFog(value); } + + // Fog mode to use. + CUSTOM_PROP static FogMode fogMode { return GetRenderSettings().GetFogMode(); } { return GetRenderSettings().SetFogMode(value); } + + // The color of the fog. + CUSTOM_PROP static Color fogColor { return GetRenderSettings().GetFogColor(); } { GetRenderSettings().SetFogColor(value); } + + // The density of the exponential fog. + CUSTOM_PROP static float fogDensity { return GetRenderSettings().GetFogDensity(); } { GetRenderSettings().SetFogDensity(value); } + + + // The starting distance of linear fog. + CUSTOM_PROP static float fogStartDistance { return GetRenderSettings().GetLinearFogStart(); } { GetRenderSettings().SetLinearFogStart(value); } + + // The ending distance of linear fog. + CUSTOM_PROP static float fogEndDistance { return GetRenderSettings().GetLinearFogEnd(); } { GetRenderSettings().SetLinearFogEnd(value); } + + + // Color of the scene's ambient light. + CUSTOM_PROP static Color ambientLight { return GetRenderSettings().GetAmbientLight(); } { GetRenderSettings().SetAmbientLight(value); } + + // Size of the [[Light]] halos. + CUSTOM_PROP static float haloStrength { return GetRenderSettings().GetHaloStrength(); } { GetRenderSettings().SetHaloStrength(value); } + + // The intensity of all flares in the scene. + CUSTOM_PROP static float flareStrength { return GetRenderSettings().GetFlareStrength(); } { GetRenderSettings().SetFlareStrength(value); } + + // The fade speed of all flares in the scene. + CUSTOM_PROP static float flareFadeSpeed { return GetRenderSettings().GetFlareFadeSpeed(); } { GetRenderSettings().SetFlareFadeSpeed(value); } + + // The global skybox to use. + CUSTOM_PROP static Material skybox { return Scripting::ScriptingWrapperFor(GetRenderSettings().GetSkyboxMaterial()); } { GetRenderSettings().SetSkyboxMaterial(value); } +END + +OBSOLETE warning See QualitySettings.names, QualitySettings.SetQualityLevel, and QualitySettings.GetQualityLevel +ENUM QualityLevel + // The "fastest" quality level. + Fastest = 0, + // The "fast" quality level. + Fast = 1, + // The "simple" quality level. + Simple = 2, + // The "good" quality level. + Good = 3, + // The "beautiful" quality level. + Beautiful = 4, + // The "fantastic" quality level. + Fantastic = 5, +END + +// Shadow projection type for [[wiki:class-QualitySettings|Quality Settings]]. +ENUM ShadowProjection + // Close fit shadow maps with linear fadeout. + CloseFit = 0, + + // Stable shadow maps with spherical fadeout. + StableFit = 1, +END + + +// Script interface for [[wiki:class-QualitySettings|Quality Settings]]. +CLASS QualitySettings : Object + // The indexed list of available Quality Settings + CONDITIONAL ENABLE_MONO || UNITY_WINRT + CUSTOM_PROP static string[] names + { + return Scripting::StringVectorToMono(GetQualitySettings().GetQualitySettingsNames ()); + } + + // Returns the current graphics quality level. + CUSTOM static int GetQualityLevel () + { + return GetQualitySettings().GetCurrentIndex(); + } + + // Sets a new graphics quality level. + CUSTOM static void SetQualityLevel (int index, bool applyExpensiveChanges = true) + { + GetQualitySettings().SetCurrentIndex (index, applyExpensiveChanges); + } + + OBSOLETE warning Use GetQualityLevel and SetQualityLevel + CUSTOM_PROP static QualityLevel currentLevel { return GetQualitySettings().GetCurrentIndex(); } { GetQualitySettings().SetCurrentIndex( value, true ); } + + // Increase the current quality level. + CUSTOM static void IncreaseLevel(bool applyExpensiveChanges = false) + { + QualitySettings& q = GetQualitySettings(); + q.SetCurrentIndex( q.GetCurrentIndex() + 1, applyExpensiveChanges ); // will clamp internally + } + + // Decrease the current quality level. + CUSTOM static void DecreaseLevel(bool applyExpensiveChanges = false) + { + QualitySettings& q = GetQualitySettings(); + q.SetCurrentIndex( q.GetCurrentIndex() - 1, applyExpensiveChanges ); // will clamp internally + } + + // The maximum number of pixel lights that should affect any object. + CUSTOM_PROP static int pixelLightCount { return GetQualitySettings().GetCurrent().pixelLightCount; } { GetQualitySettings().SetPixelLightCount(value); } + + // Directional light shadow projection. + CUSTOM_PROP static ShadowProjection shadowProjection { return (ShadowProjection)GetQualitySettings().GetCurrent().shadowProjection; } { GetQualitySettings().SetShadowProjection((ShadowProjection)value); } + + // Number of cascades to use for directional light shadows. + CUSTOM_PROP static int shadowCascades { return GetQualitySettings().GetCurrent().shadowCascades; } { GetQualitySettings().SetShadowCascades(value); } + + // Shadow drawing distance. + CUSTOM_PROP static float shadowDistance { return GetQualitySettings().GetCurrent().shadowDistance; } { GetQualitySettings().SetShadowDistance(value); } + + + // A texture size limit applied to all textures. + CUSTOM_PROP static int masterTextureLimit { return GetQualitySettings().GetCurrent().textureQuality; } { GetQualitySettings().SetMasterTextureLimit(value); } + + // Global anisotropic filtering mode. + CUSTOM_PROP static AnisotropicFiltering anisotropicFiltering { return GetQualitySettings().GetCurrent().anisotropicTextures; } { GetQualitySettings().SetAnisotropicTextures(value); } + + // Global multiplier for the LOD's switching distance. + CUSTOM_PROP static float lodBias { return GetQualitySettings().GetCurrent().lodBias; } { GetQualitySettings().SetLODBias (value); } + + // A maximum LOD level. All LOD groups + CUSTOM_PROP static int maximumLODLevel { return GetQualitySettings().GetCurrent().maximumLODLevel; } { GetQualitySettings().SetMaximumLODLevel (value); } + + // Budget for how many ray casts can be performed per frame for approximate collision testing. + CUSTOM_PROP static int particleRaycastBudget { return GetQualitySettings().GetCurrent().particleRaycastBudget; } { GetQualitySettings().SetParticleRaycastBudget (value); } + + // Use a two-pass shader for the vegetation in the terrain engine. + CUSTOM_PROP static bool softVegetation { return GetQualitySettings().GetCurrent().softVegetation; } { GetQualitySettings().SetSoftVegetation (value); } + + + // Maximum number of frames queued up by graphics driver. + CUSTOM_PROP static int maxQueuedFrames { return GetGfxDevice().GetMaxBufferedFrames(); } { GetGfxDevice().SetMaxBufferedFrames (clamp(value, -1, 10)); } + + // The VSync Count. + CUSTOM_PROP static int vSyncCount { return GetQualitySettings().GetCurrent().vSyncCount; } { GetQualitySettings().SetVSyncCount(value); } + + // Set The AA Filtering option. + CUSTOM_PROP static int antiAliasing { return GetQualitySettings().GetCurrent().antiAliasing; } { GetQualitySettings().SetAntiAliasing(value); } + + // Desired color space + CUSTOM_PROP static ColorSpace desiredColorSpace { return GetPlayerSettings().GetDesiredColorSpace (); } + + // Active color space + CUSTOM_PROP static ColorSpace activeColorSpace { return GetPlayerSettings().GetValidatedColorSpace (); } + + // Blend weights. + CUSTOM_PROP static BlendWeights blendWeights { return GetQualitySettings().GetCurrent().blendWeights; } { GetQualitySettings().SetBlendWeights(value); } +END + + + +// Values for Camera.clearFlags, determining what to clear when rendering a [[Camera]]. +ENUM CameraClearFlags + // Clear with the skybox. + Skybox = 1, + + OBSOLETE planned Use CameraClearFlags.SolidColor + Color = 2, + + // Clear with a background color. + SolidColor = 2, + + // Clear only the depth buffer. + Depth = 3, + + // Don't clear anything. + Nothing = 4 +END + + +// Depth texture generation mode for [[Camera]]. +CSRAW [Flags] +ENUM DepthTextureMode + // Do not generate depth texture (Default). + None = 0, + + // Generate a depth texture. + Depth = 1, + + // Generate a depth + normals texture. + DepthNormals = 2, +END + +//*undocumented* +ENUM TexGenMode + // the texture gets its coordinates from UV + None = 0, + // The texture uses spherical reflection mappping + SphereMap = 1, + // The texture is applied in object space + Object = 2, + // Projected Eye space + EyeLinear = 3, + // Cubemap reflection calculation + CubeReflect = 4, + // Cubemap normal calculation + CubeNormal = 5 +END + + + +// Anisotropic filtering mode. +ENUM AnisotropicFiltering + // Disable anisotropic filtering for all textures. + Disable = 0, + // Enable anisotropic filtering, as set for each texture. + Enable = 1, + // Enable anisotropic filtering for all textures. + ForceEnable = 2 +END + +// Blend weights. +ENUM BlendWeights + // One bone affects each vertex. + OneBone = 1, + // Two bones affect each vertex. + TwoBones = 2, + // Four bones affect each vertex. + FourBones = 4 +END + + +CONDITIONAL UNITY_EDITOR +// Compression Quality. Corresponds to the settings in a [[wiki:class-Texture2D|texture inspector]]. +ENUM TextureCompressionQuality + // Fast compression + Fast = 0, + // Normal compression (default) + Normal = 50, + // Best compression + Best = 100 +END + + + +// A class to access the [[Mesh]] of the [[wiki:class-MeshFilter|mesh filter]]. +CLASS MeshFilter : Component + + // Returns the instantiated [[Mesh]] assigned to the mesh filter. + AUTO_PTR_PROP Mesh mesh GetInstantiatedMesh SetInstantiatedMesh + + // Returns the shared mesh of the mesh filter. + AUTO_PTR_PROP Mesh sharedMesh GetSharedMesh SetSharedMesh +END + + +// Struct used to describe meshes to be combined using Mesh.CombineMeshes. +STRUCT CombineInstance + + // [[Mesh]] to combine + CSRAW public Mesh mesh { get { return InternalGetMesh(m_MeshInstanceID); } set { m_MeshInstanceID = value != null ? value.GetInstanceID() : 0; } } + + // Submesh index of the mesh + CSRAW public int subMeshIndex { get { return m_SubMeshIndex; } set { m_SubMeshIndex = value; } } + + // Matrix to transform the mesh with before combining + CSRAW public Matrix4x4 transform { get { return m_Transform; } set { m_Transform = value; } } + + CSRAW private int m_MeshInstanceID; + CUSTOM private Mesh InternalGetMesh(int instanceID) + { + if(instanceID == 0) + return SCRIPTING_NULL; + return Scripting::ScriptingWrapperFor(PPtr<Mesh>(instanceID)); + } + + CSRAW private int m_SubMeshIndex; + CSRAW private Matrix4x4 m_Transform; +END + +C++RAW + +struct MonoCombineInstance +{ + int meshInstanceID; + int subMeshIndex; + Matrix4x4f transform; +}; + +// Topology of [[Mesh]] faces. +ENUM MeshTopology + + // Mesh is made from triangles. + Triangles = 0, + + // Mesh is made from quads. + Quads = 2, + + // Mesh is made from lines. + Lines = 3, + + // Mesh is a line strip. + LineStrip = 4, + + // Mesh is made from points. + Points = 5, +END + + +// A class that allows creating or modifying meshes from scripts. + +CLASS Mesh : Object + + // Creates an empty mesh + CSRAW public Mesh () + { + Internal_Create(this); + } + + CUSTOM private static void Internal_Create ([Writable]Mesh mono) + { + Mesh* mesh = NEW_OBJECT_MAIN_THREAD (Mesh); + mesh->Reset(); + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), mesh); + mesh->AwakeFromLoad(kInstantiateOrCreateFromCodeAwakeFromLoad); + } + + // Clears all vertex data and all triangle indices. + CUSTOM void Clear (bool keepVertexLayout = true) + { + self->Clear (keepVertexLayout); + } + + // Returns state of the Read/Write Enabled checkbox when model was imported. + AUTO_PROP bool isReadable GetIsReadable + + // Works like isReadable, except it also returns true in editor outside the game loop. + CUSTOM_PROP internal bool canAccess { return self->CanAccessFromScript(); } + + // Returns a copy of the vertex positions or assigns a new vertex positions array. + CUSTOM_PROP Vector3[] vertices + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().vector3; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelVertex)) + return CreateScriptingArrayStride<Vector3f>(self->GetChannelPointer(kShaderChannelVertex), self->GetVertexCount(), klass, self->GetStride(kShaderChannelVertex)); + } + else + ErrorStringMsg("Not allowed to access vertices on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetVertices (Scripting::GetScriptingArrayStart<Vector3f>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access vertices on mesh '%s'", self->GetName()); + } + + // The normals of the mesh. + CUSTOM_PROP Vector3[] normals + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().vector3; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelNormal)) + return CreateScriptingArrayStride<Vector3f>(self->GetChannelPointer(kShaderChannelNormal), self->GetVertexCount(), klass, self->GetStride(kShaderChannelNormal)); + } + else + ErrorStringMsg("Not allowed to access normals on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetNormals (Scripting::GetScriptingArrayStart<Vector3f>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access normals on mesh '%s'", self->GetName()); + } + + // The tangents of the mesh. + CUSTOM_PROP Vector4[] tangents + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().vector4; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelTangent)) + return CreateScriptingArrayStride<Vector4f>(self->GetChannelPointer(kShaderChannelTangent), self->GetVertexCount(), klass, self->GetStride(kShaderChannelTangent)); + } + else + ErrorStringMsg("Not allowed to access tangents on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetTangents (Scripting::GetScriptingArrayStart<Vector4f>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access tangents on mesh '%s'", self->GetName()); + } + + // The base texture coordinates of the mesh. + CUSTOM_PROP Vector2[] uv + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().vector2; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelTexCoord0)) + return CreateScriptingArrayStride<Vector2f>(self->GetChannelPointer(kShaderChannelTexCoord0), self->GetVertexCount(), klass, self->GetStride(kShaderChannelTexCoord0)); + } + else + ErrorStringMsg("Not allowed to access uv on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetUv (0, Scripting::GetScriptingArrayStart<Vector2f>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access uv on mesh '%s'", self->GetName()); + } + + // The second texture coordinate set of the mesh, if present. + CUSTOM_PROP Vector2[] uv2 + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().vector2; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelTexCoord1)) + return CreateScriptingArrayStride<Vector2f>(self->GetChannelPointer(kShaderChannelTexCoord1), self->GetVertexCount(), klass, self->GetStride(kShaderChannelTexCoord1)); + } + else + ErrorStringMsg("Not allowed to access uv2 on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetUv (1, Scripting::GetScriptingArrayStart<Vector2f>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access uv2 on mesh '%s'", self->GetName()); + } + + OBSOLETE planned Use uv2 instead + CSRAW public Vector2[] uv1 { get { return uv2; } set { uv2 = value; } } + + // The bounding volume of the mesh. + AUTO_PROP Bounds bounds GetBounds SetBounds + + + // Vertex colors of the mesh. + CUSTOM_PROP Color[] colors + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().color; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelColor)) + { + ScriptingArrayPtr array = CreateScriptingArray<ColorRGBAf>(klass, self->GetVertexCount()); + self->ExtractColorArrayConverting (Scripting::GetScriptingArrayStart<ColorRGBAf>(array)); + return array; + } + } + else + ErrorStringMsg("Not allowed to access colors on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetColorsConverting (Scripting::GetScriptingArrayStart<ColorRGBAf>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access colors on mesh '%s'", self->GetName()); + } + + // Vertex colors of the mesh. + CUSTOM_PROP Color32[] colors32 + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().color32; + if (self->CanAccessFromScript()) + { + if (self->IsAvailable(kShaderChannelColor)) + { + ScriptingArrayPtr array = CreateScriptingArray<ColorRGBA32>(klass, self->GetVertexCount()); + self->ExtractColorArray (Scripting::GetScriptingArrayStart<ColorRGBA32>(array)); + return array; + } + } + else + ErrorStringMsg("Not allowed to access colors on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + self->SetColors (Scripting::GetScriptingArrayStart<ColorRGBA32>(value), GetScriptingArraySize(value)); + else + ErrorStringMsg("Not allowed to access colors on mesh '%s'", self->GetName()); + } + + // Recalculate the bounding volume of the mesh from the vertices. + CUSTOM void RecalculateBounds () + { + if (self->CanAccessFromScript()) + self->RecalculateBounds(); + else + ErrorStringMsg("Not allowed to call RecalculateBounds() on mesh '%s'", self->GetName()); + } + + // Recalculates the normals of the mesh from the triangles and vertices. + CUSTOM void RecalculateNormals () + { + if (self->CanAccessFromScript()) + self->RecalculateNormals(); + else + ErrorStringMsg("Not allowed to call RecalculateNormals() on mesh '%s'", self->GetName()); + } + + + // Optimizes the mesh for display. + CUSTOM void Optimize () + { + } + + // An array containing all triangles in the mesh. + // + // If the mesh contains multiple sub meshes (materials) the triangle list will contain all triangles of all submeshes. + CUSTOM_PROP int[] triangles + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().int_32; + if (self->CanAccessFromScript()) + { + Mesh::TemporaryIndexContainer triangles; + self->GetTriangles(triangles); + return CreateScriptingArray(&triangles[0], triangles.size(), klass); + } + else + ErrorStringMsg("Not allowed to access triangles on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + { + if (self->CanAccessFromScript()) + { + self->SetSubMeshCount(1); + self->SetIndices (Scripting::GetScriptingArrayStart<UInt32>(value), GetScriptingArraySize(value), 0, kPrimitiveTriangles); + } + else + ErrorStringMsg("Not allowed to access triangles on mesh '%s'", self->GetName()); + } + + + // Returns the triangle list for the submesh. + CUSTOM int[] GetTriangles (int submesh) + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().int_32; + if (self->CanAccessFromScript()) + { + Mesh::TemporaryIndexContainer triangles; + self->GetTriangles(triangles, submesh); + return CreateScriptingArray(&triangles[0], triangles.size(), klass); + } + else + ErrorStringMsg("Not allowed to call GetTriangles() on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + + // Sets the triangle list for the submesh. + CUSTOM void SetTriangles(int[] triangles, int submesh) + { + if (self->CanAccessFromScript()) + { + self->SetIndices(Scripting::GetScriptingArrayStart<UInt32>(triangles), GetScriptingArraySize(triangles), submesh, kPrimitiveTriangles); + } + else + ErrorStringMsg("Not allowed to call SetTriangles() on mesh '%s'", self->GetName()); + } + + + // Returns the index buffer for the submesh. + CUSTOM int[] GetIndices (int submesh) + { + ScriptingClassPtr klass = GetScriptingManager().GetCommonClasses().int_32; + if (self->CanAccessFromScript()) + { + Mesh::TemporaryIndexContainer indices; + self->GetIndices (indices, submesh); + return CreateScriptingArray(&indices[0], indices.size(), klass); + } + else + ErrorStringMsg("Not allowed to call GetIndices() on mesh '%s'", self->GetName()); + + return CreateEmptyStructArray(klass); + } + + // Sets the index buffer for the submesh. + CUSTOM void SetIndices (int[] indices, MeshTopology topology, int submesh) + { + if (self->CanAccessFromScript()) + { + self->SetIndices(Scripting::GetScriptingArrayStart<UInt32>(indices), GetScriptingArraySize(indices), submesh, topology); + } + else + ErrorStringMsg("Not allowed to call SetIndices() on mesh '%s'", self->GetName()); + } + + // Gets the topology of a submesh. + CUSTOM MeshTopology GetTopology (int submesh) + { + if ((unsigned)submesh >= self->GetSubMeshCount()) + { + ErrorString("Failed getting topology. Submesh index is out of bounds."); + return kPrimitiveTriangles; + } + return self->GetSubMeshFast(submesh).topology; + } + + // Returns the number of vertices in the mesh (RO). + AUTO_PROP int vertexCount GetVertexCount + + // The number of submeshes. Every material has a separate triangle list. + CUSTOM_PROP int subMeshCount + { + return self->GetSubMeshCount(); + } + { + if(value < 0) + { + ErrorString ("subMeshCount can't be set to negative value"); + return; + } + self->SetSubMeshCount(value); + } + + //*undocumented* Internal api not really generally useful + OBSOLETE warning Use SetTriangles instead. Internally this function will convert the triangle strip to a list of triangles anyway. + CUSTOM void SetTriangleStrip (int[] triangles, int submesh) + { + UInt32* triStrip = Scripting::GetScriptingArrayStart<UInt32>(triangles); + UNITY_TEMP_VECTOR(UInt32) newTriangles; + Destripify(triStrip, GetScriptingArraySize(triangles), newTriangles); + self->SetIndices (&newTriangles[0], newTriangles.size(), submesh, kPrimitiveTriangles); + } + + //*undocumented* Internal api not really generally useful + OBSOLETE warning Use GetTriangles instead. Internally this function converts a list of triangles to a strip, so it might be slow, it might be a mess. + CUSTOM int[] GetTriangleStrip (int submesh) + { + Mesh::TemporaryIndexContainer triangles; + self->GetTriangles(triangles, submesh); + + UNITY_TEMP_VECTOR(UInt32) strip; + Stripify(&triangles[0], triangles.size(), strip); + + return CreateScriptingArray(&strip[0], strip.size(), GetScriptingManager().GetCommonClasses().int_32); + } + + // Combines several meshes into this mesh. + CUSTOM void CombineMeshes(CombineInstance[] combine, bool mergeSubMeshes = true, bool useMatrices = true) + { + CombineInstances combineVec; + combineVec.resize(GetScriptingArraySize(combine)); + MonoCombineInstance* mono = Scripting::GetScriptingArrayStart<MonoCombineInstance>(combine); + for (int i=0;i<combineVec.size();i++) + { + combineVec[i].transform = mono[i].transform; + combineVec[i].subMeshIndex = mono[i].subMeshIndex; + combineVec[i].mesh = PPtr<Mesh>(mono[i].meshInstanceID); + } + CombineMeshes(combineVec, *self, mergeSubMeshes, useMatrices); + } + + + // The bone weights of each vertex + CUSTOM_PROP BoneWeight[] boneWeights + { + int size = self->GetVertexCount(); + BoneInfluence* weights = self->GetBoneWeights(); + return CreateScriptingArray(weights, size, MONO_COMMON.boneWeight); + } + { + self->SetBoneWeights(Scripting::GetScriptingArrayStart<BoneInfluence> (value), GetScriptingArraySize(value)); + } + + // The bind poses. The bind pose at each index refers to the bone with the same index. + CUSTOM_PROP Matrix4x4[] bindposes + { + return CreateScriptingArray(self->GetBindposes(), self->GetBindposeCount(), MONO_COMMON.matrix4x4); + } + { + self->SetBindposes(Scripting::GetScriptingArrayStart<Matrix4x4f> (value), GetScriptingArraySize(value)); + } + + // Optimize mesh for frequent updates. + CUSTOM void MarkDynamic () + { + if (self->CanAccessFromScript()) + self->MarkDynamic(); + } + + CUSTOM void UploadMeshData(bool markNoLogerReadable) + { + if (self->CanAccessFromScript()) + self->UploadMeshData(markNoLogerReadable); + } + + // Returns BlendShape count on this mesh. + CUSTOM_PROP int blendShapeCount + { + return self->GetBlendShapeChannelCount(); + } + + // Returns name of BlendShape by given index. + CUSTOM string GetBlendShapeName (int index) + { + return scripting_string_new(GetChannelName (self->GetBlendShapeData(), index)); + } + + // Calculates the index of the blendShape name + CUSTOM int GetBlendShapeIndex(string blendShapeName) + { + return GetChannelIndex (self->GetBlendShapeData(), blendShapeName.AsUTF8().c_str()); + } + +END + +// Skinning bone weights of a vertex in the mesh. +STRUCT BoneWeight + CSRAW private float m_Weight0; + CSRAW private float m_Weight1; + CSRAW private float m_Weight2; + CSRAW private float m_Weight3; + + CSRAW private int m_BoneIndex0; + CSRAW private int m_BoneIndex1; + CSRAW private int m_BoneIndex2; + CSRAW private int m_BoneIndex3; + + // Skinning weight for first bone. + CSRAW public float weight0 { get { return m_Weight0; } set { m_Weight0 = value; } } + // Skinning weight for second bone. + CSRAW public float weight1 { get { return m_Weight1; } set { m_Weight1 = value; } } + // Skinning weight for third bone. + CSRAW public float weight2 { get { return m_Weight2; } set { m_Weight2 = value; } } + // Skinning weight for fourth bone. + CSRAW public float weight3 { get { return m_Weight3; } set { m_Weight3 = value; } } + + // Index of first bone. + CSRAW public int boneIndex0 { get { return m_BoneIndex0; } set { m_BoneIndex0 = value; } } + // Index of second bone. + CSRAW public int boneIndex1 { get { return m_BoneIndex1; } set { m_BoneIndex1 = value; } } + // Index of third bone. + CSRAW public int boneIndex2 { get { return m_BoneIndex2; } set { m_BoneIndex2 = value; } } + // Index of fourth bone. + CSRAW public int boneIndex3 { get { return m_BoneIndex3; } set { m_BoneIndex3 = value; } } + + // used to allow BoneWeights to be used as keys in hash tables + public override int GetHashCode() { + return boneIndex0.GetHashCode() ^ (boneIndex1.GetHashCode()<<2) ^ (boneIndex2.GetHashCode()>>2) ^ (boneIndex3.GetHashCode()>>1) + ^ (weight0.GetHashCode() << 5) ^ (weight1.GetHashCode()<<4) ^ (weight2.GetHashCode()>>4) ^ (weight3.GetHashCode()>>3); + } + + // also required for being able to use BoneWeights as keys in hash tables + public override bool Equals(object other) { + if(!(other is BoneWeight)) return false; + + BoneWeight rhs=(BoneWeight)other; + return boneIndex0.Equals(rhs.boneIndex0) + && boneIndex1.Equals(rhs.boneIndex1) + && boneIndex2.Equals(rhs.boneIndex2) + && boneIndex3.Equals(rhs.boneIndex3) + && (new Vector4(weight0,weight1,weight2,weight3)).Equals(new Vector4(rhs.weight0,rhs.weight1,rhs.weight2,rhs.weight3)); + } + + //*undoc* + CSRAW public static bool operator == (BoneWeight lhs, BoneWeight rhs) + { + return lhs.boneIndex0 == rhs.boneIndex0 + && lhs.boneIndex1 == rhs.boneIndex1 + && lhs.boneIndex2 == rhs.boneIndex2 + && lhs.boneIndex3 == rhs.boneIndex3 + && (new Vector4( lhs.weight0, lhs.weight1, lhs.weight2, lhs.weight3 ) + == new Vector4( rhs.weight0, rhs.weight1, rhs.weight2, rhs.weight3 )); + } + + //*undoc* + CSRAW public static bool operator != (BoneWeight lhs, BoneWeight rhs) + { + return !(lhs == rhs); + } +END + +/// The maximum number of bones affecting a single vertex +ENUM SkinQuality + // Chooses the number of bones from the number current [[QualitySettings]] (Default) + Auto = 0, + // Use only 1 bone to deform a single vertex. (The most important bone will be used) + Bone1 = 1, + // Use 2 bones to deform a single vertex. (The most important bones will be used) + Bone2 = 2, + // Use 4 bones to deform a single vertex. + Bone4 = 4 +END + +// The Skinned Mesh filter +NONSEALED_CLASS SkinnedMeshRenderer : Renderer + + // The bones used to skin the mesh. + CUSTOM_PROP Transform[] bones + { + return CreateScriptingArrayFromUnityObjects(self->GetBones(), ClassID(Transform)); + } + { + dynamic_array<PPtr<Transform> > transforms; + if (value != SCRIPTING_NULL) + { + int size = GetScriptingArraySize(value); + transforms.resize_uninitialized(size); + + for (int i=0;i<size;i++) + { + int instanceID = Scripting::GetInstanceIDFromScriptingWrapper(Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(value, i)); + transforms[i] = PPtr<Transform> (instanceID); + } + } + + self->SetBones(transforms); + } + + AUTO_PTR_PROP Transform rootBone GetRootBone SetRootBone + + // The maximum number of bones affecting a single vertex + AUTO_PROP SkinQuality quality GetQuality SetQuality + + // The mesh used for skinning + AUTO_PTR_PROP Mesh sharedMesh GetMesh SetMesh + + OBSOLETE warning Has no effect. + CSRAW public bool skinNormals { get { return true; } set {} } + + // If enabled, the Skinned Mesh will be updated when offscreen. If disabled, this also disables updating animations. + AUTO_PROP bool updateWhenOffscreen GetUpdateWhenOffscreen SetUpdateWhenOffscreen + + // AABB of this Skinned Mesh in its local space. + CUSTOM_PROP Bounds localBounds + { + AABB result; + self->GetSkinnedMeshLocalAABB(result); + return result; + } + { + self->SetLocalAABB(value); + } + + // Creates a snapshot of SkinnedMeshRenderer and stores it in mesh. + CUSTOM void BakeMesh (Mesh mesh) + { + self->BakeMesh(*mesh); + } + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP internal Transform actualRootBone { return Scripting::ScriptingWrapperFor(&self->GetActualRootBone()); } + + // Returns weight of BlendShape on this renderer. + CUSTOM float GetBlendShapeWeight(int index) { return self->GetBlendShapeWeight(index); } + + // Sets weight of BlendShape on this renderer. + CUSTOM void SetBlendShapeWeight(int index, float value) { self->SetBlendShapeWeight(index, value); } + +END + + +// A flare asset. Read more about flares in the [[wiki:class-Flare|components reference]]. +CLASS Flare : Object + +END + + +// Script interface for a [[wiki:class-LensFlare|Lens flare component]]. +CLASS LensFlare : Behaviour + // The [[wiki:class-Flare|flare asset]] to use. + AUTO_PTR_PROP Flare flare GetFlare SetFlare + + // The strength of the flare. + AUTO_PROP float brightness GetBrightness SetBrightness + + // The fade speed of the flare. + AUTO_PROP float fadeSpeed GetFadeSpeed SetFadeSpeed + + // The color of the flare. + AUTO_PROP Color color GetColor SetColor +END + + +// General functionality for all renderers. +NONSEALED_CLASS Renderer : Component + + CUSTOM_PROP internal Transform staticBatchRootTransform { return Scripting::ScriptingWrapperFor (self->GetStaticBatchRoot ()); } { self->SetStaticBatchRoot (value); } + + CUSTOM_PROP internal int staticBatchIndex { return self->GetStaticBatchIndex(); } + + CUSTOM internal void SetSubsetIndex (int index, int subSetIndexForMaterial) + { + self->SetMaterialCount (std::max(index+1, self->GetMaterialCount())); + self->SetSubsetIndex(index, subSetIndexForMaterial); + } + + // Has this renderer been statically batched with any other renderers? + CUSTOM_PROP bool isPartOfStaticBatch { return self->GetStaticBatchIndex() != 0; } + + // Matrix that transforms a point from world space into local space (RO). + AUTO_PROP Matrix4x4 worldToLocalMatrix GetWorldToLocalMatrix + // Matrix that transforms a point from local space into world space (RO). + AUTO_PROP Matrix4x4 localToWorldMatrix GetLocalToWorldMatrix + + + // Makes the rendered 3D object visible if enabled. + AUTO_PROP bool enabled GetEnabled SetEnabled + + + // Does this object cast shadows? + AUTO_PROP bool castShadows GetCastShadows SetCastShadows + + + // Does this object receive shadows? + AUTO_PROP bool receiveShadows GetReceiveShadows SetReceiveShadows + + + // The material of this object. + + CUSTOM_PROP Material material + { + return Scripting::ScriptingWrapperFor (self->GetAndAssignInstantiatedMaterial (0, false)); + } + { + self->SetMaterialCount (std::max(1, self->GetMaterialCount())); + self->SetMaterial (value, 0); + } + + + // The shared material of this object. + CUSTOM_PROP Material sharedMaterial + { + if (self->GetMaterialCount ()) + return Scripting::ScriptingWrapperFor (self->GetMaterial (0)); + else + return Scripting::ScriptingObjectNULL (ScriptingClassFor (Material)); + } + { + self->SetMaterialCount (std::max(1, self->GetMaterialCount())); + self->SetMaterial (value, 0); + } + + + // All the shared materials of this object. + CUSTOM_PROP Material[] sharedMaterials + { + return CreateScriptingArrayFromUnityObjects(self->GetMaterialArray(), ClassID(Material)); + } + { +#if ENABLE_MONO + if (value == SCRIPTING_NULL) + Scripting::RaiseNullException("material array is null"); +#endif + + int size = GetScriptingArraySize(value); + self->SetMaterialCount (size); + for (int i=0;i<size;i++) + self->SetMaterial (ScriptingObjectToObject<Material> (Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(value, i)), i); + } + + // All the materials of this object. + CUSTOM_PROP Material[] materials + { + int length = self->GetMaterialCount(); + ScriptingArrayPtr array = CreateScriptingArray<ScriptingObjectPtr> (ScriptingClassFor(Material), length); + + for (int i=0;i<length;i++) + { + Material* instantiated = self->GetAndAssignInstantiatedMaterial(i, false); + Scripting::SetScriptingArrayElement<ScriptingObjectPtr>(array,i,Scripting::ScriptingWrapperFor(instantiated)); + } + + return array; + } + { + if (value == SCRIPTING_NULL) + Scripting::RaiseNullException("material array is null"); + + int size = GetScriptingArraySize(value); + self->SetMaterialCount (size); + for (int i=0;i<size;i++) + { + ScriptingObjectPtr o = Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(value,i); + self->SetMaterial (ScriptingObjectToObject<Material> (o), i); + } + } + + // The bounding volume of the renderer (RO). + CUSTOM_PROP Bounds bounds { return CalculateWorldAABB (self->GetGameObject ()); } + + // The index of the lightmap applied to this renderer. + CUSTOM_PROP int lightmapIndex { return self->GetLightmapIndexInt(); } { return self->SetLightmapIndexInt(value); } + + // The tiling & offset used for lightmap. + CUSTOM_PROP Vector4 lightmapTilingOffset + { + Vector4f st = self->GetLightmapST(); + return Vector4f(st.x, st.y, st.z, st.w); + } + { + Vector4f st( value.x, value.y, value.z, value.w ); + self->SetLightmapST( st ); + } + + // ''OnBecameVisible'' is called when the object became visible by any camera. + CSNONE void OnBecameVisible(); + + + // ''OnBecameInvisible'' is called when the object is no longer visible by any camera. + CSNONE void OnBecameInvisible(); + + // Is this renderer visible in any camera? (RO) + AUTO_PROP bool isVisible IsVisibleInScene + + // If enabled and baked light probes are present in the scene, an interpolated light probe + AUTO_PROP bool useLightProbes GetUseLightProbes SetUseLightProbes + + // If set, Renderer will use this Transform's position to find the interpolated light probe; + AUTO_PTR_PROP Transform lightProbeAnchor GetLightProbeAnchor SetLightProbeAnchor + + // Lets you add per-renderer material parameters without duplicating a material. + CUSTOM void SetPropertyBlock (MaterialPropertyBlock properties) + { + if (properties.GetPtr()) + self->SetPropertyBlock (*properties); + else + self->ClearPropertyBlock (); + } + + CUSTOM void GetPropertyBlock (MaterialPropertyBlock dest) + { + if (!dest.GetPtr()) + Scripting::RaiseNullException("dest property block is null"); + self->GetPropertyBlock (*dest); + } + + + CUSTOM_PROP string sortingLayerName + { + DISALLOW_IN_CONSTRUCTOR + return scripting_string_new(self->GetSortingLayerName()); + } + { + DISALLOW_IN_CONSTRUCTOR + self->SetSortingLayerName(value); + } + AUTO_PROP int sortingLayerID GetSortingLayerUserID SetSortingLayerUserID + AUTO_PROP int sortingOrder GetSortingOrder SetSortingOrder + + + OBSOLETE planned No longer available + CUSTOM void Render (int material) + { + Shader* shader = s_ScriptingCurrentShader; + if (!shader) { + ErrorString ("Render requires material.SetPass before!"); + return; + } + + GfxDevice& device = GetGfxDevice(); + + // D3D needs begin/end when rendering is called out-of-band + #if UNITY_EDITOR + bool outsideOfFrame = !device.IsInsideFrame(); + if( outsideOfFrame ) + device.BeginFrame(); + #endif + + float matWorld[16], matView[16]; + + CopyMatrix(device.GetViewMatrix(), matView); + CopyMatrix(device.GetWorldMatrix(), matWorld); + + Matrix4x4f transformMatrix; + Matrix4x4f scaleOnly; + float scale; + TransformType matrixType = self->GetTransform().CalculateTransformMatrixDisableNonUniformScale (transformMatrix, scaleOnly, scale); + SetupObjectMatrix (transformMatrix, matrixType); + + self->Render (material, *s_ScriptingCurrentChannels); + device.SetViewMatrix(matView); + device.SetWorldMatrix(matWorld); + + #if UNITY_EDITOR + if( outsideOfFrame ) + device.EndFrame(); + #endif + } +END + + + +// A script interface for a [[wiki:class-Projector|projector component]]. +CLASS Projector : Behaviour + + // The near clipping plane distance. + AUTO_PROP float nearClipPlane GetNearClipPlane SetNearClipPlane + + // The far clipping plane distance. + AUTO_PROP float farClipPlane GetFarClipPlane SetFarClipPlane + + // The field of view of the projection in degrees. + AUTO_PROP float fieldOfView GetFieldOfView SetFieldOfView + + // The aspect ratio of the projection. + AUTO_PROP float aspectRatio GetAspectRatio SetAspectRatio + + OBSOLETE planned Use orthographic instead + CSRAW public bool isOrthoGraphic { get { return orthographic; } set { orthographic = value; } } + + // Is the projection orthographic (''true'') or perspective (''false'')? + AUTO_PROP bool orthographic GetOrthographic SetOrthographic + + // Projection's half-size when in orthographic mode. + AUTO_PROP float orthographicSize GetOrthographicSize SetOrthographicSize + + OBSOLETE planned use orthographicSize + CSRAW public float orthoGraphicSize { get { return orthographicSize; } set { orthographicSize = value; } } + + // Which object layers are ignored by the projector. + AUTO_PROP int ignoreLayers GetIgnoreLayers SetIgnoreLayers + + // The material that will be projected onto every object. + AUTO_PTR_PROP Material material GetMaterial SetMaterial +END + +// A script interface for the [[wiki:class-Skybox|skybox component]]. +CLASS Skybox : Behaviour + // The material used by the skybox. + CUSTOM_PROP Material material { return Scripting::ScriptingWrapperFor (self->GetMaterial ()); } { self->SetMaterial (value); } +END + + +// A script interface for the [[wiki:class-TextMesh|text mesh component]]. +CLASS TextMesh : Component + + // The text that is displayed. + CUSTOM_PROP string text { return scripting_string_new (self->GetText ()); } { self->SetText (value); } + + // The [[Font]] used. + AUTO_PTR_PROP Font font GetFont SetFont + + + // The font size to use (for dynamic fonts) + AUTO_PROP int fontSize GetFontSize SetFontSize + + // The font style to use (for dynamic fonts) + AUTO_PROP FontStyle fontStyle GetFontStyle SetFontStyle + + // How far should the text be offset from the transform.position.z when drawing + AUTO_PROP float offsetZ GetOffsetZ SetOffsetZ + + // How lines of text are aligned (Left, Right, Center) + AUTO_PROP TextAlignment alignment GetAlignment SetAlignment + + // Which point of the text shares the position of the Transform + AUTO_PROP TextAnchor anchor GetAnchor SetAnchor + + // The size of each character (This scales the whole text) + AUTO_PROP float characterSize GetCharacterSize SetCharacterSize + + // How much space will be in-between lines of text + AUTO_PROP float lineSpacing GetLineSpacing SetLineSpacing + + // How much space will be inserted for a tab '\t' character. This is a multiplum of the 'spacebar' character offset + AUTO_PROP float tabSize GetTabSize SetTabSize + + // Enable HTML-style tags for Text Formatting Markup. + AUTO_PROP bool richText GetRichText SetRichText + + // Base color in which to render the text + AUTO_PROP Color color GetColor SetColor +END + +//(Legacy Particle system) +STRUCT Particle + CSRAW + private Vector3 m_Position; + private Vector3 m_Velocity; + private float m_Size; + private float m_Rotation; + private float m_AngularVelocity; + private float m_Energy; + private float m_StartEnergy; + private Color m_Color; + + // The position of the particle. + CSRAW public Vector3 position { get { return m_Position; } set { m_Position = value; } } + + // The velocity of the particle. + CSRAW public Vector3 velocity { get { return m_Velocity; } set { m_Velocity = value; } } + + // The energy of the particle. + CSRAW public float energy { get { return m_Energy; } set { m_Energy = value; } } + + // The starting energy of the particle. + CSRAW public float startEnergy { get { return m_StartEnergy; } set { m_StartEnergy = value; } } + + // The size of the particle. + CSRAW public float size { get { return m_Size; } set { m_Size = value; } } + + // The rotation of the particle. + CSRAW public float rotation { get { return m_Rotation; } set { m_Rotation = value; } } + + // The angular velocity of the particle. + CSRAW public float angularVelocity { get { return m_AngularVelocity; } set { m_AngularVelocity = value; } } + + // The color of the particle. + CSRAW public Color color { get { return m_Color; } set { m_Color = value; } } +END + +// Simple struct that contains all the arguments needed by the internal DrawTexture. +STRUCT internal InternalEmitParticleArguments + CSRAW public Vector3 pos; + CSRAW public Vector3 velocity; + CSRAW public float size; + CSRAW public float energy; + CSRAW public Color color; + CSRAW public float rotation; + CSRAW public float angularVelocity; +END + +C++RAW + +struct MonoInternalEmitParticleArguments { + Vector3f pos; + Vector3f velocity; + float size; + float energy; + ColorRGBAf color; + float rotation; + float angularVelocity; +}; + +// (Legacy Particles) Script interface for particle emitters. +CLASS ParticleEmitter : Component + + // Should particles be automatically emitted each frame? + AUTO_PROP bool emit IsEmitting SetEmit + + // The minimum size each particle can be at the time when it is spawned. + AUTO_PROP float minSize GetMinSize SetMinSize + + // The maximum size each particle can be at the time when it is spawned. + AUTO_PROP float maxSize GetMaxSize SetMaxSize + + // The minimum lifetime of each particle, measured in seconds. + AUTO_PROP float minEnergy GetMinEnergy SetMinEnergy + + // The maximum lifetime of each particle, measured in seconds. + AUTO_PROP float maxEnergy GetMaxEnergy SetMaxEnergy + + // The minimum number of particles that will be spawned every second. + AUTO_PROP float minEmission GetMinEmission SetMinEmission + + // The maximum number of particles that will be spawned every second. + AUTO_PROP float maxEmission GetMaxEmission SetMaxEmission + + // he amount of the emitter's speed that the particles inherit. + AUTO_PROP float emitterVelocityScale GetEmitterVelocityScale SetEmitterVelocityScale + + // The starting speed of particles in world space, along X, Y, and Z. + AUTO_PROP Vector3 worldVelocity GetWorldVelocity SetWorldVelocity + + // The starting speed of particles along X, Y, and Z, measured in the object's orientation. + AUTO_PROP Vector3 localVelocity GetLocalVelocity SetLocalVelocity + + // A random speed along X, Y, and Z that is added to the velocity. + AUTO_PROP Vector3 rndVelocity GetRndVelocity SetRndVelocity + + // If enabled, the particles don't move when the emitter moves. If false, when you move the emitter, the particles follow it around. + AUTO_PROP bool useWorldSpace GetUseWorldSpace SetUseWorldSpace + + // If enabled, the particles will be spawned with random rotations. + AUTO_PROP bool rndRotation GetRndRotation SetRndRotation + + // The angular velocity of new particles in degrees per second. + AUTO_PROP float angularVelocity GetAngularVelocity SetAngularVelocity + + // A random angular velocity modifier for new particles. + AUTO_PROP float rndAngularVelocity GetRndAngularVelocity SetRndAngularVelocity + + // Returns a copy of all particles and assigns an array of all particles to be the current particles. + CUSTOM_PROP Particle[] particles + { + int size = self->GetParticleCount(); + ScriptingArrayPtr array = CreateScriptingArray<SimpleParticle> (GetScriptingManager().GetCommonClasses().particle, self->GetParticleCount()); + self->ReadParticles(Scripting::GetScriptingArrayStart<SimpleParticle>(array), 0, size); + return array; + } + { + self->WriteParticles(Scripting::GetScriptingArrayStart<SimpleParticle>(value), GetScriptingArraySize(value)); + } + + // The current number of particles (RO). + AUTO_PROP int particleCount GetParticleCount + + // Removes all particles from the particle emitter. + AUTO void ClearParticles(); + + // Emit a number of particles. + CSRAW public void Emit () { Emit2 ( (int)Random.Range (minEmission, maxEmission) ); } + + // Emit /count/ particles immediately + + CSRAW public void Emit (int count) { Emit2 (count);} + + // Emit a single particle with given parameters. + CSRAW public void Emit (Vector3 pos, Vector3 velocity, float size, float energy, Color color) + { + InternalEmitParticleArguments args = new InternalEmitParticleArguments(); + args.pos = pos; + args.velocity = velocity; + args.size = size; + args.energy = energy; + args.color = color; + args.rotation = 0; + args.angularVelocity = 0; + Emit3 (ref args); + } + // + CSRAW public void Emit (Vector3 pos, Vector3 velocity, float size, float energy, Color color, float rotation, float angularVelocity) + { + InternalEmitParticleArguments args = new InternalEmitParticleArguments(); + args.pos = pos; + args.velocity = velocity; + args.size = size; + args.energy = energy; + args.color = color; + args.rotation = rotation; + args.angularVelocity = angularVelocity; + Emit3 (ref args); + } + + CUSTOM private void Emit2 (int count) + { + self->EmitResetEmitterPos (count, 0.0F); + } + + CUSTOM private void Emit3 (ref InternalEmitParticleArguments args) + { + self->Emit (args.pos, args.velocity, args.size, args.energy, args.color, args.rotation, args.angularVelocity); + } + + // Advance particle simulation by given time. + CUSTOM void Simulate (float deltaTime) + { + self->UpdateParticleSystem(deltaTime); + } + + // Turns the ParticleEmitter on or off. + AUTO_PROP bool enabled GetEnabled SetEnabled +END + + +// (Legacy Particles) Particle animators move your particles over time, you use them to apply wind, drag & color cycling to your particle emitters. +CLASS ParticleAnimator : Component + // Do particles cycle their color over their lifetime? + AUTO_PROP bool doesAnimateColor GetDoesAnimateColor SetDoesAnimateColor + + // World space axis the particles rotate around. + AUTO_PROP Vector3 worldRotationAxis GetWorldRotationAxis SetWorldRotationAxis + + // Local space axis the particles rotate around. + AUTO_PROP Vector3 localRotationAxis GetLocalRotationAxis SetLocalRotationAxis + + // How the particle sizes grow over their lifetime. + AUTO_PROP float sizeGrow GetSizeGrow SetSizeGrow + + // A random force added to particles every frame. + AUTO_PROP Vector3 rndForce GetRndForce SetRndForce + + // The force being applied to particles every frame. + AUTO_PROP Vector3 force GetForce SetForce + + // How much particles are slowed down every frame. + AUTO_PROP float damping GetDamping SetDamping + + // Does the [[GameObject]] of this particle animator auto destructs? + AUTO_PROP bool autodestruct GetAutodestruct SetAutodestruct + + // Colors the particles will cycle through over their lifetime. + + CUSTOM_PROP Color[] colorAnimation + { + ColorRGBAf col[ParticleAnimator::kColorKeys]; + self->GetColorAnimation(col); + return CreateScriptingArray(col, ParticleAnimator::kColorKeys, GetScriptingManager().GetCommonClasses().color); + } + { + Scripting::RaiseIfNull(value); + if(GetScriptingArraySize(value) != ParticleAnimator::kColorKeys) + { + Scripting::RaiseMonoException(" Array needs to contain exactly 5 Colors for colorAnimation."); + return; + } + self->SetColorAnimation(Scripting::GetScriptingArrayStart<ColorRGBAf> (value)); + } +END + + +// The trail renderer is used to make trails behind objects in the scene as they move about. +CLASS TrailRenderer : Renderer + + // How long does the trail take to fade out. + AUTO_PROP float time GetTime SetTime + + // The width of the trail at the spawning point. + AUTO_PROP float startWidth GetStartWidth SetStartWidth + + // The width of the trail at the end of the trail. + AUTO_PROP float endWidth GetEndWidth SetEndWidth + + // Does the [[GameObject]] of this trail renderer auto destructs? + AUTO_PROP bool autodestruct GetAutodestruct SetAutodestruct + +END + + + +// The rendering mode for legacy particles. +ENUM ParticleRenderMode + // Render the particles as billboards facing the player. (Default) + Billboard = 0, + // Stretch particles in the direction of motion. + Stretch = 3, + // Sort the particles back-to-front and render as billboards. + SortedBillboard = 2, + // Render the particles as billboards always facing up along the y-Axis. + HorizontalBillboard = 4, + // Render the particles as billboards always facing the player, but not pitching along the x-Axis. + VerticalBillboard = 5 +END + +// (Legacy Particles) Renders particles on to the screen. +CLASS ParticleRenderer : Renderer + // How particles are drawn. + AUTO_PROP ParticleRenderMode particleRenderMode GetRenderMode SetRenderMode + + // How much are the particles stretched in their direction of motion. + AUTO_PROP float lengthScale GetLengthScale SetLengthScale + + // How much are the particles strectched depending on "how fast they move" + AUTO_PROP float velocityScale GetVelocityScale SetVelocityScale + + // How much are the particles strected depending on the [[Camera]]'s speed. + AUTO_PROP float cameraVelocityScale GetCameraVelocityScale SetCameraVelocityScale + + // Clamp the maximum particle size. + AUTO_PROP float maxParticleSize GetMaxParticleSize SetMaxParticleSize + + // Set horizontal tiling count. + AUTO_PROP int uvAnimationXTile GetUVAnimationXTile SetUVAnimationXTile + // Set vertical tiling count. + AUTO_PROP int uvAnimationYTile GetUVAnimationYTile SetUVAnimationYTile + + // Set uv animation cycles + AUTO_PROP float uvAnimationCycles GetUVAnimationCycles SetUVAnimationCycles + + OBSOLETE warning animatedTextureCount has been replaced by uvAnimationXTile and uvAnimationYTile. + CSRAW public int animatedTextureCount { get { return uvAnimationXTile; } set { uvAnimationXTile = value; } } + + //*undocumented fixed typo + CSRAW public float maxPartileSize { get { return maxParticleSize; } set { maxParticleSize = value; } } + + //*undocumented UV Rect access + CUSTOM_PROP Rect[] uvTiles { return CreateScriptingArray(self->GetUVFrames(), self->GetNumUVFrames(), GetScriptingManager().GetCommonClasses().rect); } { Scripting::RaiseIfNull(value); self->SetUVFrames(Scripting::GetScriptingArrayStart<Rectf> (value), GetScriptingArraySize(value)); } + +CSRAW #if ENABLE_MONO + OBSOLETE error This function has been removed. + CSRAW public AnimationCurve widthCurve { get { return null; } set { } } + + OBSOLETE error This function has been removed. + CSRAW public AnimationCurve heightCurve { get { return null; } set { } } + + OBSOLETE error This function has been removed. + CSRAW public AnimationCurve rotationCurve { get { return null; } set { } } + +CSRAW #endif +END + + +// The line renderer is used to draw free-floating lines in 3D space. +CLASS LineRenderer : Renderer + // Set the line width at the start and at the end. + AUTO void SetWidth(float start, float end); + + // Set the line color at the start and at the end. + AUTO void SetColors(Color start, Color end); + + // Set the number of line segments. + AUTO void SetVertexCount(int count); + + // Set the position of the vertex in the line. + AUTO void SetPosition(int index, Vector3 position); + + // If enabled, the lines are defined in world space. + AUTO_PROP bool useWorldSpace GetUseWorldSpace SetUseWorldSpace + +END + + + +// A block of material values to apply. +CLASS MaterialPropertyBlock + // Just wraps a pointer to native property block object + CSRAW internal IntPtr m_Ptr; + + //*undocumented* + CUSTOM internal void InitBlock() + { + MonoMaterialPropertyBlock* block = new MonoMaterialPropertyBlock(); + self.SetPtr(block, MonoMaterialPropertyBlock::CleanupMonoMaterialPropertyBlock); + } + //*undocumented* + THREAD_SAFE + CUSTOM internal void DestroyBlock() + { + MonoMaterialPropertyBlock::CleanupMonoMaterialPropertyBlock((MonoMaterialPropertyBlock*)self.GetPtr()); + } + + //*undocumented* + CSRAW public MaterialPropertyBlock() { InitBlock(); } + CSRAW ~MaterialPropertyBlock() { DestroyBlock(); } + + ///*listonly* + CSRAW public void AddFloat (string name, float value) + { + AddFloat( Shader.PropertyToID(name), value ); + } + // Add a float material property. + CUSTOM void AddFloat (int nameID, float value) + { + ShaderLab::FastPropertyName name; + name.index = nameID; + self->AddProperty( name, &value, 1, 1, 1 ); + } + + ///*listonly* + CSRAW public void AddVector (string name, Vector4 value) { AddVector( Shader.PropertyToID(name), value ); } + // Add a vector material property. + CUSTOM void AddVector (int nameID, Vector4 value) + { + ShaderLab::FastPropertyName name; + name.index = nameID; +#if ENABLE_MONO + self->AddProperty( name, value.GetPtr(), 1, 4, 1 ); +#endif + } + + ///*listonly* + CSRAW public void AddColor (string name, Color value) + { + AddColor( Shader.PropertyToID(name), value ); + } + // Add a color material property. + CUSTOM void AddColor (int nameID, Color value) + { + ShaderLab::FastPropertyName name; + name.index = nameID; +#if ENABLE_MONO + self->AddPropertyColor( name, value ); +#endif + } + + ///*listonly* + CSRAW public void AddMatrix (string name, Matrix4x4 value) { AddMatrix( Shader.PropertyToID(name), value ); } + // Add a matrix material property. + CUSTOM void AddMatrix (int nameID, Matrix4x4 value) + { + ShaderLab::FastPropertyName name; + name.index = nameID; +#if ENABLE_MONO + self->AddProperty( name, value.GetPtr(), 4, 4, 1 ); +#endif + } + + ///*listonly* + CSRAW public void AddTexture (string name, Texture value) + { + AddTexture (Shader.PropertyToID(name), value); + } + CUSTOM void AddTexture (int nameID, Texture value) + { + Texture* tex = value; + if (!tex) + { + ErrorString ("Invalid argument for AddTexture()"); + return; + } + ShaderLab::FastPropertyName name; + name.index = nameID; + self->AddPropertyTexture (name, tex->GetDimension(), tex->GetTextureID()); + } + + CSRAW public float GetFloat (string name) { return GetFloat (Shader.PropertyToID(name)); } + CUSTOM float GetFloat (int nameID) + { + ShaderLab::FastPropertyName name; + name.index = nameID; + const float* v = self->FindFloat (name); + return v ? *v : 0.0f; + } + + CSRAW public Vector4 GetVector (string name) { return GetVector (Shader.PropertyToID(name)); } + CUSTOM Vector4 GetVector (int nameID) + { + ShaderLab::FastPropertyName name; + name.index = nameID; + const Vector4f* v = self->FindVector (name); + return v ? *v : Vector4f(0,0,0,0); + } + + CSRAW public Matrix4x4 GetMatrix (string name) { return GetMatrix (Shader.PropertyToID(name)); } + CUSTOM Matrix4x4 GetMatrix (int nameID) + { + ShaderLab::FastPropertyName name; + name.index = nameID; + const Matrix4x4f* v = self->FindMatrix (name); + return v ? *v : Matrix4x4f::identity; + } + + CSRAW public Texture GetTexture (string name) { return GetTexture (Shader.PropertyToID(name)); } + CUSTOM Texture GetTexture (int nameID) + { + ShaderLab::FastPropertyName name; + name.index = nameID; + TextureID v = self->FindTexture (name); + if (v.m_ID == 0) + return SCRIPTING_NULL; + Texture* tex = Texture::FindTextureByID (v); + return Scripting::ScriptingWrapperFor (tex); + } + + // Clear material property values. + CUSTOM void Clear() { +#if ENABLE_MONO + self->Clear(); +#endif + } + +END + + +// Color or depth buffer part of a [[RenderTexture]]. +STRUCT RenderBuffer + CSRAW internal int m_RenderTextureInstanceID; + CSRAW internal IntPtr m_BufferPtr; +END + +// Simple struct that contains all the arguments needed by the internal DrawTexture. +STRUCT internal InternalDrawTextureArguments + CSRAW public Rect screenRect; + #if UNITY_WINRT + CSRAW public int textureInstanceId; + #else + CSRAW public Texture texture; + #endif + CSRAW public Rect sourceRect; + CSRAW public int leftBorder; + CSRAW public int rightBorder; + CSRAW public int topBorder; + CSRAW public int bottomBorder; + CSRAW public Color32 color; + #if UNITY_WINRT + CSRAW public int matInstanceId; + #else + CSRAW public Material mat; + #endif +END + +C++RAW + +struct MonoInternalDrawTextureArguments { + Rectf screenRect; + #if UNITY_WINRT + int textureInstanceId; + #else + ScriptingObjectOfType<Texture> texture; + #endif + Rectf sourceRect; + int leftBorder; + int rightBorder; + int topBorder; + int bottomBorder; + ColorRGBA32 color; + #if UNITY_WINRT + int matInstanceId; + #else + ScriptingObjectOfType<Material> mat; + #endif +}; + +// Simple struct that contains the arguments needed by Internal_DrawMeshTR. +STRUCT internal Internal_DrawMeshTRArguments + CSRAW public int layer; + CSRAW public int submeshIndex; + CSRAW public Quaternion rotation; + CSRAW public Vector3 position; + CSRAW public int castShadows; + CSRAW public int receiveShadows; +END + +C++RAW + +struct MonoInternal_DrawMeshTRArguments { + int layer; + int submeshIndex; + Quaternionf rotation; + Vector3f position; + int castShadows; + int receiveShadows; +}; + +// Simple struct that contains all the arguments needed by Internal_DrawMeshMatrix. +STRUCT internal Internal_DrawMeshMatrixArguments + CSRAW public int layer; + CSRAW public int submeshIndex; + CSRAW public Matrix4x4 matrix; + CSRAW public int castShadows; + CSRAW public int receiveShadows; +END + +C++RAW + +struct MonoInternal_DrawMeshMatrixArguments { + int layer; + int submeshIndex; + Matrix4x4f matrix; + int castShadows; + int receiveShadows; +}; + +// Raw interface to Unity's drawing functions. +CLASS Graphics + + /// *listonly* + CSRAW static public void DrawMesh (Mesh mesh, Vector3 position, Quaternion rotation, Material material, int layer, Camera camera = null, int submeshIndex = 0, MaterialPropertyBlock properties = null) { + Internal_DrawMeshTRArguments arguments = new Internal_DrawMeshTRArguments (); + arguments.position = position; + arguments.rotation = rotation; + arguments.layer = layer; + arguments.submeshIndex = submeshIndex; + arguments.castShadows = 1; + arguments.receiveShadows = 1; + Internal_DrawMeshTR(ref arguments, properties, material, mesh, camera); + } + // Draw a mesh. + CSRAW static public void DrawMesh (Mesh mesh, Matrix4x4 matrix, Material material, int layer, Camera camera = null, int submeshIndex = 0, MaterialPropertyBlock properties = null) { + Internal_DrawMeshMatrixArguments arguments = new Internal_DrawMeshMatrixArguments (); + arguments.matrix = matrix; + arguments.layer = layer; + arguments.submeshIndex = submeshIndex; + arguments.castShadows = 1; + arguments.receiveShadows = 1; + + Internal_DrawMeshMatrix(ref arguments, properties, material, mesh, camera); + } + //*undocumented* + CSRAW static public void DrawMesh (Mesh mesh, Vector3 position, Quaternion rotation, Material material, int layer, Camera camera, int submeshIndex, MaterialPropertyBlock properties, bool castShadows, bool receiveShadows) { + Internal_DrawMeshTRArguments arguments = new Internal_DrawMeshTRArguments (); + arguments.position = position; + arguments.rotation = rotation; + arguments.layer = layer; + arguments.submeshIndex = submeshIndex; + arguments.castShadows = castShadows ? 1 : 0; + arguments.receiveShadows = receiveShadows ? 1 : 0; + + Internal_DrawMeshTR(ref arguments, properties, material, mesh, camera); + } + //*undocumented* + CSRAW static public void DrawMesh (Mesh mesh, Matrix4x4 matrix, Material material, int layer, Camera camera, int submeshIndex, MaterialPropertyBlock properties, bool castShadows, bool receiveShadows) { + Internal_DrawMeshMatrixArguments arguments = new Internal_DrawMeshMatrixArguments (); + arguments.matrix = matrix; + arguments.layer = layer; + arguments.submeshIndex = submeshIndex; + arguments.castShadows = castShadows ? 1 : 0; + arguments.receiveShadows = receiveShadows ? 1 : 0; + + Internal_DrawMeshMatrix(ref arguments, properties, material, mesh, camera); + } + CUSTOM private static void Internal_DrawMeshTR (ref Internal_DrawMeshTRArguments arguments, MaterialPropertyBlock properties, Material material, Mesh mesh, Camera camera) { + Camera* cameraPointer = camera; + Matrix4x4f matrix; + matrix.SetTR( arguments.position, arguments.rotation ); + + IntermediateRenderer* r = AddMeshIntermediateRenderer( matrix, mesh, material, arguments.layer, arguments.castShadows != 0, arguments.receiveShadows != 0, arguments.submeshIndex, cameraPointer ); + MaterialPropertyBlock* propertiesPtr = properties.GetPtr(); + if (propertiesPtr) + r->SetPropertyBlock (*propertiesPtr); + } + CUSTOM private static void Internal_DrawMeshMatrix (ref Internal_DrawMeshMatrixArguments arguments, MaterialPropertyBlock properties, Material material, Mesh mesh, Camera camera) { + Camera* cameraPointer = camera; + IntermediateRenderer* r = AddMeshIntermediateRenderer( arguments.matrix, mesh, material, arguments.layer, arguments.castShadows != 0, arguments.receiveShadows != 0, arguments.submeshIndex, cameraPointer); + + MaterialPropertyBlock* propertiesPtr = properties.GetPtr(); + if (propertiesPtr) + r->SetPropertyBlock (*propertiesPtr); + } + + /// *listonly* + CSRAW static public void DrawMeshNow (Mesh mesh, Vector3 position, Quaternion rotation) { Internal_DrawMeshNow1(mesh, position, rotation, -1); } + /// *listonly* + CSRAW static public void DrawMeshNow (Mesh mesh, Vector3 position, Quaternion rotation, int materialIndex) { Internal_DrawMeshNow1(mesh, position, rotation, materialIndex); } + /// *listonly* + CSRAW static public void DrawMeshNow (Mesh mesh, Matrix4x4 matrix) { Internal_DrawMeshNow2(mesh, matrix, -1); } + + // Draw a mesh immediately. + CSRAW static public void DrawMeshNow (Mesh mesh, Matrix4x4 matrix, int materialIndex) { Internal_DrawMeshNow2(mesh, matrix, materialIndex); } + + CUSTOM private static void Internal_DrawMeshNow1 (Mesh mesh, Vector3 position, Quaternion rotation, int materialIndex) { + Shader* shader = s_ScriptingCurrentShader; + if (!shader) { + ErrorString ("DrawMesh requires material.SetPass before!"); + return; + } + DrawUtil::DrawMesh (*s_ScriptingCurrentChannels, *mesh, position, rotation); + } + CUSTOM private static void Internal_DrawMeshNow2 (Mesh mesh, Matrix4x4 matrix, int materialIndex) { + Shader* shader = s_ScriptingCurrentShader; + if (!shader) { + ErrorString ("DrawMesh requires material.SetPass before!"); + return; + } + DrawUtil::DrawMesh (*s_ScriptingCurrentChannels, *mesh, matrix, materialIndex); + } + + + // Draws a fully procedural geometry on the GPU. + CUSTOM static public void DrawProcedural (MeshTopology topology, int vertexCount, int instanceCount = 1) { + DrawUtil::DrawProcedural (topology, vertexCount, instanceCount); + } + + // Draws a fully procedural geometry on the GPU. + CONDITIONAL !UNITY_FLASH + CUSTOM static public void DrawProceduralIndirect (MeshTopology topology, ComputeBuffer bufferWithArgs, int argsOffset = 0) { + DrawUtil::DrawProceduralIndirect (topology, bufferWithArgs.GetPtr(), argsOffset); + } + + + CONDITIONAL UNITY_EDITOR + CUSTOM static internal void DrawSprite (Sprite sprite, Matrix4x4 matrix, Material material, int layer, Camera camera, Color color, MaterialPropertyBlock properties) + { + Camera* cameraPointer = camera; + IntermediateRenderer* r = AddSpriteIntermediateRenderer(matrix, sprite, material, layer, color, cameraPointer); + + MaterialPropertyBlock* propertiesPtr = properties.GetPtr(); + if (propertiesPtr) + r->SetPropertyBlock (*propertiesPtr); + } + + + + FLUSHCONDITIONS + + OBSOLETE warning Use Graphics.DrawMeshNow instead. + CSRAW static public void DrawMesh (Mesh mesh, Vector3 position, Quaternion rotation) { Internal_DrawMeshNow1(mesh, position, rotation, -1); } + OBSOLETE warning Use Graphics.DrawMeshNow instead. + CSRAW static public void DrawMesh (Mesh mesh, Vector3 position, Quaternion rotation, int materialIndex) { Internal_DrawMeshNow1(mesh, position, rotation, materialIndex); } + OBSOLETE warning Use Graphics.DrawMeshNow instead. + CSRAW static public void DrawMesh (Mesh mesh, Matrix4x4 matrix) { Internal_DrawMeshNow2(mesh, matrix, -1); } + OBSOLETE warning Use Graphics.DrawMeshNow instead. + CSRAW static public void DrawMesh (Mesh mesh, Matrix4x4 matrix, int materialIndex) { Internal_DrawMeshNow2(mesh, matrix, materialIndex); } + + + ///*listonly* + CSRAW public static void DrawTexture (Rect screenRect, Texture texture, Material mat = null) { + DrawTexture (screenRect, texture, 0,0,0,0, mat); + } + ///*listonly* + CSRAW public static void DrawTexture (Rect screenRect, Texture texture, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Material mat = null) { + DrawTexture (screenRect, texture, new Rect (0,0,1,1), leftBorder, rightBorder, topBorder, bottomBorder, mat); + } + ///*listonly* + CSRAW public static void DrawTexture (Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Material mat = null) { + InternalDrawTextureArguments arguments = new InternalDrawTextureArguments (); + arguments.screenRect = screenRect; + #if UNITY_WINRT + arguments.textureInstanceId = texture != null ? texture.GetInstanceID() : 0; + #else + arguments.texture = texture; + #endif + arguments.sourceRect = sourceRect; + arguments.leftBorder = leftBorder; + arguments.rightBorder = rightBorder; + arguments.topBorder = topBorder; + arguments.bottomBorder = bottomBorder; + Color32 c = new Color32(); + c.r = c.g = c.b = c.a = 128; + arguments.color = c; + #if UNITY_WINRT + arguments.matInstanceId = mat != null ? mat.GetInstanceID() : 0; + #else + arguments.mat = mat; + #endif + DrawTexture (ref arguments); + } + // Draw a texture in screen coordinates. + CSRAW public static void DrawTexture (Rect screenRect, Texture texture, Rect sourceRect, int leftBorder, int rightBorder, int topBorder, int bottomBorder, Color color, Material mat = null) { + InternalDrawTextureArguments arguments = new InternalDrawTextureArguments (); + arguments.screenRect = screenRect; + #if UNITY_WINRT + arguments.textureInstanceId = texture != null ? texture.GetInstanceID() : 0; + #else + arguments.texture = texture; + #endif + arguments.sourceRect = sourceRect; + arguments.leftBorder = leftBorder; + arguments.rightBorder = rightBorder; + arguments.topBorder = topBorder; + arguments.bottomBorder = bottomBorder; + arguments.color = color; + #if UNITY_WINRT + arguments.matInstanceId = mat != null ? mat.GetInstanceID() : 0; + #else + arguments.mat = mat; + #endif + DrawTexture (ref arguments); + } + + CUSTOM internal static void DrawTexture (ref InternalDrawTextureArguments arguments) { + #if UNITY_WINRT + DrawGUITexture ( + arguments.screenRect, + PPtr<Texture>(arguments.textureInstanceId), + arguments.sourceRect, + arguments.leftBorder, + arguments.rightBorder, + arguments.topBorder, + arguments.bottomBorder, + ColorRGBA32(arguments.color), + PPtr<Material>(arguments.matInstanceId)); + #else + DrawGUITexture (arguments.screenRect, arguments.texture, arguments.sourceRect, arguments.leftBorder, arguments.rightBorder, arguments.topBorder, arguments.bottomBorder, ColorRGBA32(arguments.color), arguments.mat); + #endif + } + + /// *listonly* + CUSTOM static void Blit (Texture source, RenderTexture dest) + { + ImageFilters::Blit (source, dest); + } + + // Copies source texture into destination render texture. + CSRAW public static void Blit (Texture source, RenderTexture dest, Material mat, int pass = -1) + { + Internal_BlitMaterial (source, dest, mat, pass, true); + } + + CSRAW public static void Blit (Texture source, Material mat, int pass = -1) + { + Internal_BlitMaterial (source, null, mat, pass, false); + } + + CUSTOM private static void Internal_BlitMaterial (Texture source, RenderTexture dest, Material mat, int pass, bool setRT) + { + Material* m = mat; + if (m == NULL) + { + ErrorString ("Graphics.Blit: material is null"); + return; + } + ImageFilters::Blit (source, dest, m, pass, setRT); + } + + // Copies source texture into destination, for multi-tap shader. + CSRAW public static void BlitMultiTap (Texture source, RenderTexture dest, Material mat, params Vector2[] offsets) + { + Internal_BlitMultiTap (source, dest, mat, offsets); + } + + CUSTOM private static void Internal_BlitMultiTap (Texture source, RenderTexture dest, Material mat, Vector2[] offsets) + { + Material* m = mat; + if (m == NULL) + { + ErrorString ("Graphics.BlitMultiTap: material is null"); + return; + } + int size = GetScriptingArraySize (offsets); + const Vector2f* arr = Scripting::GetScriptingArrayStart<Vector2f> (offsets); + ImageFilters::BlitMultiTap (source, dest, m, size, arr); + } + + + CSRAW public static void SetRenderTarget (RenderTexture rt) { + Internal_SetRT (rt, 0, -1); + } + CSRAW public static void SetRenderTarget (RenderTexture rt, int mipLevel) { + Internal_SetRT (rt, mipLevel, -1); + } + CSRAW public static void SetRenderTarget (RenderTexture rt, int mipLevel, CubemapFace face) { + Internal_SetRT (rt, mipLevel, (int)face); + } + + ///*listonly* + CSRAW public static void SetRenderTarget (RenderBuffer colorBuffer, RenderBuffer depthBuffer) { + Internal_SetRTBuffer (out colorBuffer, out depthBuffer); + } + + // Sets current render target. + CSRAW public static void SetRenderTarget (RenderBuffer[] colorBuffers, RenderBuffer depthBuffer) { + Internal_SetRTBuffers (colorBuffers, out depthBuffer); + } + + CUSTOM private static void Internal_SetRT (RenderTexture rt, int mipLevel, int face) { + RenderTexture::SetActive (rt, mipLevel, (CubemapFace)face); + } + + CUSTOM private static void Internal_SetRTBuffer (out RenderBuffer colorBuffer, out RenderBuffer depthBuffer) { + RenderTexture* rtC = PPtr<RenderTexture>(colorBuffer->m_RenderTextureInstanceID); + RenderTexture* rtD = PPtr<RenderTexture>(depthBuffer->m_RenderTextureInstanceID); + if (rtC && !rtD) + { + ErrorString ("SetRenderTarget can only mix color & depth buffers from RenderTextures. You're trying to set depth buffer from the screen."); + return; + } + if (!rtC && rtD) + { + ErrorString ("SetRenderTarget can only mix color & depth buffers from RenderTextures. You're trying to set color buffer from the screen."); + return; + } + if (rtC) + { + RenderSurfaceHandle rsHandle(colorBuffer->m_BufferPtr); + RenderTexture::SetActive (1, &rsHandle, RenderSurfaceHandle(depthBuffer->m_BufferPtr), rtC); + } + else + { + RenderTexture::SetActive (NULL); + } + } + + CUSTOM private static void Internal_SetRTBuffers (RenderBuffer[] colorBuffers, out RenderBuffer depthBuffer) { + int size = GetScriptingArraySize (colorBuffers); + if (size < 1 || size > kMaxSupportedRenderTargets) + { + ErrorString ("Invalid color buffer count for SetRenderTarget"); + return; + } + + const ScriptingRenderBuffer* arr = Scripting::GetScriptingArrayStart<ScriptingRenderBuffer> (colorBuffers); + RenderTexture* rtC = PPtr<RenderTexture>(arr[0].m_RenderTextureInstanceID); + RenderTexture* rtD = PPtr<RenderTexture>(depthBuffer->m_RenderTextureInstanceID); + if (rtC && !rtD) + { + ErrorString ("SetRenderTarget can only mix color & depth buffers from RenderTextures. You're trying to set depth buffer from the screen."); + return; + } + if (!rtC && rtD) + { + ErrorString ("SetRenderTarget can only mix color & depth buffers from RenderTextures. You're trying to set color buffer from the screen."); + return; + } + if (rtC) + { + RenderSurfaceHandle colorHandles[kMaxSupportedRenderTargets]; + for (int i = 0; i < size; ++i) + colorHandles[i].object = arr[i].m_BufferPtr; + RenderTexture::SetActive (size, colorHandles, RenderSurfaceHandle(depthBuffer->m_BufferPtr), rtC); + } + else + { + RenderTexture::SetActive (NULL); + } + } + + // Currently active color buffer (RO). + CSRAW public static RenderBuffer activeColorBuffer { get { RenderBuffer res; GetActiveColorBuffer (out res); return res; } } + + // Currently active depth buffer (RO). + CSRAW public static RenderBuffer activeDepthBuffer { get { RenderBuffer res; GetActiveDepthBuffer (out res); return res; } } + + CUSTOM private static void GetActiveColorBuffer (out RenderBuffer res) { + GfxDevice& device = GetGfxDevice(); + RenderTexture* rt = device.GetActiveRenderTexture(); + res->m_RenderTextureInstanceID = rt ? rt->GetInstanceID() : 0; + res->m_BufferPtr = rt ? device.GetActiveRenderColorSurface(0).object : NULL; + } + CUSTOM private static void GetActiveDepthBuffer (out RenderBuffer res) { + GfxDevice& device = GetGfxDevice(); + RenderTexture* rt = device.GetActiveRenderTexture(); + res->m_RenderTextureInstanceID = rt ? rt->GetInstanceID() : 0; + res->m_BufferPtr = rt ? device.GetActiveRenderDepthSurface().object : NULL; + } + + CSRAW public static void SetRandomWriteTarget (int index, RenderTexture uav) { + Internal_SetRandomWriteTargetRT (index, uav); + } + + CONDITIONAL !UNITY_FLASH + CSRAW public static void SetRandomWriteTarget (int index, ComputeBuffer uav) { + Internal_SetRandomWriteTargetBuffer (index, uav); + } + CUSTOM public static void ClearRandomWriteTargets () { + GetGfxDevice().ClearRandomWriteTargets(); + } + + CUSTOM private static void Internal_SetRandomWriteTargetRT (int index, RenderTexture uav) { + RenderTexture* rt = uav; + TextureID tid = rt ? rt->GetTextureID() : TextureID(); + GetGfxDevice().SetRandomWriteTargetTexture(index, tid); + } + + CONDITIONAL !UNITY_FLASH + CUSTOM private static void Internal_SetRandomWriteTargetBuffer (int index, ComputeBuffer uav) { + GetGfxDevice().SetRandomWriteTargetBuffer(index, uav->GetBufferHandle()); + } + + FLUSHCONDITIONS + + OBSOLETE warning Use SystemInfo.graphicsDeviceName instead. + CSRAW static public string deviceName { get { return SystemInfo.graphicsDeviceName; } } + + OBSOLETE warning Use SystemInfo.graphicsDeviceVendor instead. + CSRAW static public string deviceVendor { get { return SystemInfo.graphicsDeviceVendor; } } + + OBSOLETE warning Use SystemInfo.graphicsDeviceVersion instead. + CSRAW static public string deviceVersion { get { return SystemInfo.graphicsDeviceVersion; } } + + OBSOLETE warning Use SystemInfo.supportsVertexPrograms instead. + CSRAW static public bool supportsVertexProgram { get { return SystemInfo.supportsVertexPrograms; } } + + //*undocumented* + CUSTOM internal static void SetupVertexLights (Light[] lights) + { + const int size = GetScriptingArraySize(lights); + std::vector<Light*> lightsVec(size); + for (int i = 0; i < size; ++i) + lightsVec[i] = ScriptingObjectToObject<Light>(Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr> (lights, i)); + + SetupVertexLights(lightsVec); + } + +END + + + +// Represents a display resolution. +STRUCT Resolution + // Keep in sync with ScreenManager::Resolution + CSRAW private int m_Width; + CSRAW private int m_Height; + CSRAW private int m_RefreshRate; + + // Resolution width in pixels. + CSRAW public int width { get { return m_Width; } set { m_Width = value; } } + // Resolution height in pixels. + CSRAW public int height { get { return m_Height; } set { m_Height = value; } } + // Resolution's vertical refresh rate in Hz. + CSRAW public int refreshRate { get { return m_RefreshRate; } set { m_RefreshRate = value; } } +END + + + +// Data of a lightmap. +CSRAW [StructLayout (LayoutKind.Sequential)] +CLASS LightmapData + CSRAW internal Texture2D m_Lightmap; + CSRAW internal Texture2D m_IndirectLightmap; + + // Lightmap storing the full incoming light. + CSRAW public Texture2D lightmapFar { get { return m_Lightmap; } set { m_Lightmap = value; } } + + OBSOLETE warning Use lightmapFar instead + CSRAW public Texture2D lightmap { get { return m_Lightmap; } set { m_Lightmap = value; } } + + // Lightmap storing only the indirect incoming light. + CSRAW public Texture2D lightmapNear { get { return m_IndirectLightmap; } set { m_IndirectLightmap = value; } } +END + +// Single, dual, or directional lightmaps rendering mode. +ENUM LightmapsMode + // Single, traditional lightmap rendering mode. + Single = 0, + + // Dual lightmap rendering mode. + Dual = 1, + + // Directional rendering mode. + Directional = 2, +END + +// Valid color spaces +ENUM ColorSpace + // Uninitialized colorspace + Uninitialized = -1, + + // Lightmap has been baked for gamma rendering + Gamma = 0, + + // Lightmap has been baked for linear rendering + Linear = 1 +END + + +// Stores light probes for the scene. +CONDITIONAL ENABLE_MONO || UNITY_WINRT +CLASS LightProbes : Object + // Returns spherical harmonics coefficients of a light probe at the given position. The light probe is interpolated from the light probes baked + CUSTOM void GetInterpolatedLightProbe(Vector3 position, Renderer renderer, float[] coefficients) + { + if (GetScriptingArraySize(coefficients) != kLightProbeBasisCount * 3) + Scripting::RaiseArgumentException("Coefficients array must have 9*3 elements"); + + self->GetInterpolatedLightProbe(position, renderer, &Scripting::GetScriptingArrayElement<float> (coefficients, 0)); + } + + // Positions of the baked light probes. + CUSTOM_PROP Vector3[] positions + { + return CreateScriptingArray(self->GetPositions(), self->GetPositionsSize(), MONO_COMMON.vector3); + } + + // Coefficients of the baked light probes. The coefficients represent a 3-band RGB spherical harmonics probe, with a total of 27 floats per light probe, laid out: rgbrgbrgb... + + CUSTOM_PROP float[] coefficients + { + return CreateScriptingArray(reinterpret_cast<float*>(self->GetCoefficients()), self->GetPositionsSize()*kLightProbeCoefficientCount, MONO_COMMON.floatSingle); + } + { + if (GetScriptingArraySize(value) != self->GetPositionsSize() * kLightProbeBasisCount * 3) + Scripting::RaiseArgumentException("Coefficients array must have probeCount*9*3 elements"); + + self->SetCoefficients(&Scripting::GetScriptingArrayElement<float> (value, 0), GetScriptingArraySize(value)); + } + + // The number of light probes. + CUSTOM_PROP int count + { + return self->GetPositionsSize(); + } + + // The number of cells (tetrahedra + outer cells) the space is divided to. + CUSTOM_PROP int cellCount + { + return self->GetTetrahedraSize(); + } +END + +// Stores lightmaps of the scene. +CONDITIONAL ENABLE_MONO || UNITY_WINRT +CLASS LightmapSettings : Object + + // Lightmap array. + CUSTOM_PROP static LightmapData[] lightmaps + { return VectorToScriptingClassArray<LightmapData, LightmapDataMono> (GetLightmapSettings().GetLightmaps(), GetScriptingTypeRegistry().GetType("UnityEngine", "LightmapData"), LightmapDataToMono); } + { GetLightmapSettings().SetLightmaps (ScriptingClassArrayToVector<LightmapData, LightmapDataMono> (value, LightmapDataToCpp)); } + + // Single, Dual or Directional lightmaps rendering mode. + CUSTOM_PROP static LightmapsMode lightmapsMode + { return GetLightmapSettings().GetLightmapsMode (); } + { GetLightmapSettings().SetLightmapsMode (value); } + + // Color space of the lightmap + CUSTOM_PROP static ColorSpace bakedColorSpace + { return GetLightmapSettings().GetBakedColorSpace (); } + { } + + // Holds all data needed by the light probes. + CUSTOM_PROP static LightProbes lightProbes + { + return Scripting::ScriptingWrapperFor(GetLightmapSettings().GetLightProbes()); + } + { + GetLightmapSettings().SetLightProbes(value); + } +END + +// Utility class for common geometric functions. +CLASS GeometryUtility + + // Calculates frustum planes. + CSRAW static public Plane[] CalculateFrustumPlanes (Camera camera) + { + return CalculateFrustumPlanes (camera.projectionMatrix * camera.worldToCameraMatrix); + } + + // Calculates frustum planes. + CSRAW static public Plane[] CalculateFrustumPlanes (Matrix4x4 worldToProjectionMatrix) + { + Plane[] planes = new Plane[6]; + Internal_ExtractPlanes (planes, worldToProjectionMatrix); + return planes; + } + + CUSTOM private static void Internal_ExtractPlanes (Plane[] planes, Matrix4x4 worldToProjectionMatrix) + { + ExtractProjectionPlanes(worldToProjectionMatrix, Scripting::GetScriptingArrayStart<Plane> (planes)); + } + + + // Returns true if bounds are inside the plane array. + CUSTOM static bool TestPlanesAABB (Plane[] planes, Bounds bounds) + { + return TestPlanesAABB(Scripting::GetScriptingArrayStart<Plane> (planes), GetScriptingArraySize(planes), bounds); + } +END + + +// Describes screen orientation. +ENUM ScreenOrientation + //*undocumented* + Unknown = 0, + + // Portrait orientation. + Portrait = 1, + + // Portrait orientation, upside down. + PortraitUpsideDown = 2, + + // Landscape orientation, counter-clockwise from the portrait orientation. + LandscapeLeft = 3, + + // Landscape orientation, clockwise from the portrait orientation. + LandscapeRight = 4, + + // Auto Rotation, will use enabled orientations. + AutoRotation = 5, + + //*undocumented* + Landscape = 3 +END + + +// Access to display information. +CLASS Screen + + // All fullscreen resolutions supported by the monitor (RO). + + CUSTOM_PROP static Resolution[] resolutions + { + ScriptingClassPtr klass = GetScriptingManager ().GetCommonClasses ().resolution; + ScreenManager::Resolutions resolutions = GetScreenManager ().GetResolutions (); + ScriptingArrayPtr array = CreateScriptingArray<ScreenManager::Resolution> (klass, resolutions.size ()); + for (int i=0;i<resolutions.size ();i++) + Scripting::SetScriptingArrayElement (array, i, resolutions[i]); + + return array; + } + + OBSOLETE planned + CSRAW static public Resolution[] GetResolution { get { return resolutions; } } + + // The current screen resolution (RO). + CUSTOM_PROP static Resolution currentResolution { return GetScreenManager().GetCurrentResolution (); } + + // Switches the screen resolution. + CUSTOM static void SetResolution (int width, int height, bool fullscreen, int preferredRefreshRate = 0) + { + #if WEBPLUG + if (fullscreen) + { + if (!GetScreenManager ().GetAllowFullscreenSwitch()) + { + ErrorString("Fullscreen mode can only be enabled in the web player after clicking on the content."); + return; + } + // when going from windowed to fullscreen, show escape warning + if( !GetScreenManager().IsFullScreen() ) + ShowFullscreenEscapeWarning(); + } + #endif + + GetScreenManager ().RequestResolution (width, height, fullscreen, preferredRefreshRate); + } + + // Should the cursor be visible? + CUSTOM_PROP static bool showCursor { return GetScreenManager ().GetShowCursor (); } { GetScreenManager ().SetShowCursor (value); } + + // Should the cursor be locked? + CUSTOM_PROP static bool lockCursor { return GetScreenManager ().GetLockCursor (); } { GetScreenManager ().SetLockCursor (value); } + + + // The current width of the screen window in pixels (RO). + THREAD_SAFE + CUSTOM_PROP static int width { return GetScreenManager ().GetWidth (); } + + // The current height of the screen window in pixels (RO). + THREAD_SAFE + CUSTOM_PROP static int height { return GetScreenManager ().GetHeight (); } + + // The current DPI of the screen / device (RO). + CUSTOM_PROP static float dpi { return GetScreenManager ().GetDPI (); } + + // Is the game running fullscreen? + CUSTOM_PROP static bool fullScreen + { + return GetScreenManager ().IsFullScreen (); + } + { + ScreenManager& screen = GetScreenManager(); + bool goFullscreen = (bool)value; + if (goFullscreen == screen.IsFullScreen ()) + { + return; + } + + #if WEBPLUG + if (goFullscreen) + { + if (!GetScreenManager().GetAllowFullscreenSwitch()) + { + ErrorString("Fullscreen mode can only be enabled in the web player after clicking on the content."); + return; + } + // when going from windowed to fullscreen, show escape warning + if( !screen.IsFullScreen() ) + ShowFullscreenEscapeWarning(); + } + #endif + + screen.RequestSetFullscreen (goFullscreen); + } + + // Allow auto-rotation to portrait? + CUSTOM_PROP static bool autorotateToPortrait { + return GetScreenManager().GetIsOrientationEnabled(kAutorotateToPortrait); + } { + GetScreenManager().SetIsOrientationEnabled(kAutorotateToPortrait, value); + } + + // Allow auto-rotation to portrait, upside down? + CUSTOM_PROP static bool autorotateToPortraitUpsideDown { + return GetScreenManager().GetIsOrientationEnabled(kAutorotateToPortraitUpsideDown); + } { + GetScreenManager().SetIsOrientationEnabled(kAutorotateToPortraitUpsideDown, value); + } + + // Allow auto-rotation to landscape left? + CUSTOM_PROP static bool autorotateToLandscapeLeft { + return GetScreenManager().GetIsOrientationEnabled(kAutorotateToLandscapeLeft); + } { + GetScreenManager().SetIsOrientationEnabled(kAutorotateToLandscapeLeft, value); + } + + // Allow auto-rotation to landscape right? + CUSTOM_PROP static bool autorotateToLandscapeRight { + return GetScreenManager().GetIsOrientationEnabled(kAutorotateToLandscapeRight); + } { + GetScreenManager().SetIsOrientationEnabled(kAutorotateToLandscapeRight, value); + } + + + // Specifies logical orientation of the screen. + CUSTOM_PROP static ScreenOrientation orientation { + return GetScreenManager ().GetScreenOrientation (); + } { + GetScreenManager ().RequestOrientation (value); + } + + // A power saving setting, allowing the screen to dim some time after the + CUSTOM_PROP static int sleepTimeout { + return GetScreenManager ().GetScreenTimeout (); + } { + GetScreenManager ().SetScreenTimeout (value); + } +END + +// Constants for special values of [[Screen.sleepTimeout]]. Use them to +CLASS SleepTimeout + // Prevent screen dimming. + CSRAW public const int NeverSleep = -1; + + // Set the sleep timeout to whatever user has specified in the system + CSRAW public const int SystemSetting = -2; +END + + + +// Low-level graphics library. +CLASS GL + // Submit a vertex. + CUSTOM static void Vertex3 (float x, float y, float z) { GetGfxDevice().ImmediateVertex( x,y,z ); } + // Submit a vertex. + CUSTOM static void Vertex (Vector3 v) { GetGfxDevice().ImmediateVertex( v.x, v.y, v.z ); } + + // Sets current vertex color. + CUSTOM static void Color (Color c) { GetGfxDevice().ImmediateColor(c.r, c.g, c.b, c.a); } + + // Sets current texture coordinate (v.x,v.y,v.z) for all texture units. + CUSTOM static void TexCoord (Vector3 v) { GetGfxDevice().ImmediateTexCoordAll(v.x, v.y, v.z); } + + // Sets current texture coordinate (x,y) for all texture units. + CUSTOM static void TexCoord2 (float x, float y) { GetGfxDevice().ImmediateTexCoordAll(x, y, 0.0f); } + + // Sets current texture coordinate (x,y,z) for all texture units. + CUSTOM static void TexCoord3 (float x, float y, float z) { GetGfxDevice().ImmediateTexCoordAll(x, y, z); } + + // Sets current texture coordinate (x,y) for the actual texture /unit/. + CUSTOM static void MultiTexCoord2 (int unit, float x, float y) + { + GetGfxDevice().ImmediateTexCoord( unit, x, y, 0.0f ); + } + + // Sets current texture coordinate (x,y,z) to the actual texture /unit/. + CUSTOM static void MultiTexCoord3 (int unit, float x, float y, float z) + { + GetGfxDevice().ImmediateTexCoord( unit, x, y, z ); + } + + // Sets current texture coordinate (v.x,v.y,v.z) to the actual texture /unit/. + CUSTOM static void MultiTexCoord (int unit, Vector3 v) + { + GetGfxDevice().ImmediateTexCoord( unit, v.x, v.y, v.z ); + } + + + // Mode for ::ref::Begin: draw triangles. + CSRAW public const int TRIANGLES = 0x0004; + + // Mode for ::ref::Begin: draw triangle strip. + CSRAW public const int TRIANGLE_STRIP = 0x0005; + + // Mode for ::ref::Begin: draw quads. + CSRAW public const int QUADS = 0x0007; + + // Mode for ::ref::Begin: draw lines. + CSRAW public const int LINES = 0x0001; + + + // Begin drawing 3D primitives. + CUSTOM static void Begin (int mode) { + GfxPrimitiveType pt; + if( mode == 0x0004 ) + pt = kPrimitiveTriangles; + else if( mode == 0x0005 ) + pt = kPrimitiveTriangleStripDeprecated; + else if( mode == 0x0007 ) + pt = kPrimitiveQuads; + else if( mode == 0x0001 ) + pt = kPrimitiveLines; + else { + Scripting::RaiseMonoException( "Invalid mode for GL.Begin" ); + return; + } + GetGfxDevice().ImmediateBegin( pt ); + } + + // End drawing 3D primitives. + CUSTOM static void End () { + GetGfxDevice().ImmediateEnd(); + GPU_TIMESTAMP(); + } + + // Helper function to set up an ortho perspective transform. + CUSTOM static void LoadOrtho () + { + LoadFullScreenOrthoMatrix(); + } + + // Setup a matrix for pixel-correct rendering. + CUSTOM static void LoadPixelMatrix () { + // Now the hack: regular code (GUITexts, GUITExtures etc.) needs to add the + // vertical texel offset. However, looks like GUI code needs to subtract the + // vertical texel offset. No idea why; I guess it's because GUI code does + // the y-inversion by itself. So we pass true as the last parameter. + if (GetCurrentCameraPtr() != NULL) + { + LoadPixelMatrix( GetCurrentCamera().GetScreenViewportRect(), GetGfxDevice(), true, true ); + } + } + + // Do this "different name" trick because otherwise the wrapper functions for both + // LoadPixelMatrix overloads will have the same name, making a compile error. + CUSTOM private static void LoadPixelMatrixArgs(float left, float right, float bottom, float top) + { + // Now the hack: regular code (GUITexts, GUITExtures etc.) needs to add the + // vertical texel offset. However, looks like GUI code needs to subtract the + // vertical texel offset. No idea why; I guess it's because GUI code does + // the y-inversion by itself. So we pass true as the last parameter. + Rectf rect( left, bottom, right-left, top-bottom ); + LoadPixelMatrix( rect, GetGfxDevice(), true, true ); + } + + + // Setup a matrix for pixel-correct rendering. + CSRAW public static void LoadPixelMatrix (float left, float right, float bottom, float top) + { + LoadPixelMatrixArgs(left,right,bottom,top); + } + + // Set the rendering viewport. + CUSTOM static void Viewport (Rect pixelRect) { + SetGLViewport(pixelRect); + } + + // Load an arbitrary matrix to the current projection matrix. + CUSTOM static void LoadProjectionMatrix (Matrix4x4 mat) { + GetGfxDevice().SetProjectionMatrix (mat); + } + + // Load the identity matrix to the current modelview matrix. + CUSTOM static void LoadIdentity () { + GetGfxDevice().SetViewMatrix (Matrix4x4f::identity.GetPtr()); // implicitly sets world to identity + } + + // The current modelview matrix. + CUSTOM_PROP static Matrix4x4 modelview + { + Matrix4x4f temp; + GetGfxDevice().GetMatrix( temp.GetPtr() ); + return temp; + } + { + GetGfxDevice().SetViewMatrix( value.GetPtr() ); + } + + // Multiplies the current modelview matrix with the one specified. + CUSTOM static void MultMatrix (Matrix4x4 mat) { + GetGfxDevice().SetWorldMatrix( mat.GetPtr() ); + } + + // Saves both projection and modelview matrices to the matrix stack. + CUSTOM static void PushMatrix() + { + GfxDevice& dev = GetGfxDevice(); + g_ViewMatrixStack.Push(dev.GetViewMatrix()); + g_WorldMatrixStack.Push(dev.GetWorldMatrix()); + g_ProjectionMatrixStack.Push(dev.GetProjectionMatrix()); + } + + // Restores both projection and modelview matrices off the top of the matrix stack. + CUSTOM static void PopMatrix () + { + GfxDevice& dev = GetGfxDevice(); + g_WorldMatrixStack.Pop(); + g_ViewMatrixStack.Pop(); + g_ProjectionMatrixStack.Pop(); + // Setting the view matrix clears the world matrix to be compatible with GL the ways + dev.SetViewMatrix(g_ViewMatrixStack.GetMatrix().GetPtr()); + dev.SetWorldMatrix(g_WorldMatrixStack.GetMatrix().GetPtr()); + dev.SetProjectionMatrix(g_ProjectionMatrixStack.GetMatrix()); + } + + + // Compute GPU projection matrix from camera's projection matrix. + CUSTOM static Matrix4x4 GetGPUProjectionMatrix (Matrix4x4 proj, bool renderIntoTexture) + { + bool openGLStyle = GetGfxDevice().UsesOpenGLTextureCoords(); + Matrix4x4f m = proj; + CalculateDeviceProjectionMatrix (m, openGLStyle, !openGLStyle && renderIntoTexture); + return m; + } + + + // Should rendering be done in wireframe? + CUSTOM_PROP static bool wireframe { return GetGfxDevice().GetWireframe(); } { GetGfxDevice().SetWireframe(value); } + + CUSTOM_PROP static bool sRGBWrite { return GetGfxDevice().GetSRGBWrite(); } { GetGfxDevice().SetSRGBWrite(value); } + + // Select whether to invert the backface culling (true) or not (false). + CUSTOM static void SetRevertBackfacing (bool revertBackFaces) { GetGfxDevice().SetUserBackfaceMode (revertBackFaces); } + + // Clear the current render buffer. + CSRAW static public void Clear (bool clearDepth, bool clearColor, Color backgroundColor, float depth=1.0f) { + Internal_Clear (clearDepth, clearColor, backgroundColor, depth); + } + + CUSTOM static private void Internal_Clear (bool clearDepth, bool clearColor, Color backgroundColor, float depth) { + UInt32 flags = 0; + if (clearColor) flags |= kGfxClearColor; + if (clearDepth) flags |= kGfxClearDepthStencil; + GraphicsHelper::Clear (flags, backgroundColor.GetPtr(), depth, 0); + GPU_TIMESTAMP(); + } + + + // Clear the current render buffer with camera's skybox. + CUSTOM static void ClearWithSkybox (bool clearDepth, Camera camera) { + ClearWithSkybox(clearDepth, camera); + } + + // Invalidate the internally cached renderstates. + CUSTOM static void InvalidateState () { + GL_CUSTOM_PushMatrix(); + GfxDevice& dev = GetGfxDevice(); + dev.InvalidateState(); + GL_CUSTOM_PopMatrix(); + } + + // Send a user-defined event to a native code plugin. + CUSTOM static void IssuePluginEvent (int eventID) + { + GetGfxDevice().InsertCustomMarker (eventID); + } + +END + + +// GUI STUFF +// -------------------------------- + +// Base class for images & text strings displayed in a GUI. +NONSEALED_CLASS GUIElement : Behaviour + + // Is a point on screen inside the element. + CUSTOM bool HitTest (Vector3 screenPosition, Camera camera = null) { + return self->HitTest (Vector2f (screenPosition.x, screenPosition.y), GetCameraOrWindowRect(camera)); + } + + // Returns bounding rectangle of [[GUIElement]] in screen coordinates. + CUSTOM Rect GetScreenRect (Camera camera = null) { return self->GetScreenRect (GetCameraOrWindowRect(camera)); } + +END + +// A texture image used in a 2D GUI. +CLASS GUITexture : GUIElement + // The color of the GUI texture. + AUTO_PROP Color color GetColor SetColor + + // The texture used for drawing. + + AUTO_PTR_PROP Texture texture GetTexture SetTexture + + // Pixel inset used for pixel adjustments for size and position. + CUSTOM_PROP Rect pixelInset { return self->GetPixelInset(); } { self->SetPixelInset(value); } + + + // The border defines the number of pixels from the edge that are not affected by scale. + CUSTOM_PROP RectOffset border + { + RectOffset* rectOffset = new RectOffset (); + + rectOffset->left = self->m_LeftBorder; + rectOffset->right = self->m_RightBorder; + rectOffset->top = self->m_TopBorder; + rectOffset->bottom = self->m_BottomBorder; + + ScriptingObjectWithIntPtrField<RectOffset> monoObject(scripting_object_new (MONO_COMMON.rectOffset)); + monoObject.SetPtr(rectOffset); + return monoObject.object; + } + { + self->m_LeftBorder = value->left; + self->m_RightBorder = value->right; + self->m_TopBorder = value->top; + self->m_BottomBorder = value->bottom; + } +END + + +// How multiline text should be aligned. +ENUM TextAlignment + // Text lines are aligned on the left side. + Left = 0, + // Text lines are centered. + Center = 1, + // Text lines are aligned on the right side. + Right = 2 +END + + +// Where the anchor of the text is placed. +ENUM TextAnchor + + // Text is anchored in upper left corner. + UpperLeft = 0, + + // Text is anchored in upper side, centered horizontally. + UpperCenter = 1, + + // Text is anchored in upper right corner. + UpperRight = 2, + + // Text is anchored in left side, centered vertically. + MiddleLeft = 3, + + // Text is centered both horizontally and vertically. + MiddleCenter = 4, + + // Text is anchored in right side, centered vertically. + MiddleRight = 5, + + // Text is anchored in lower left corner. + LowerLeft = 6, + + // Text is anchored in lower side, centered horizontally. + LowerCenter = 7, + + // Text is anchored in lower right corner. + LowerRight = 8 + +END + + +// A text string displayed in a GUI. +CLASS GUIText : GUIElement + + // The text to display. + CUSTOM_PROP string text { return scripting_string_new (self->GetText ()); } { self->SetText (value); } + + // The [[Material]] to use for rendering. + CUSTOM_PROP Material material + { + Material* material = self->GetMaterial (); + if (material == NULL) + material = GetBuiltinResource<Material> ("Font.mat"); + + Material* instantiated = &Material::GetInstantiatedMaterial (material, *self, false); + if (material != instantiated) + self->SetMaterial (instantiated); + + return Scripting::ScriptingWrapperFor (instantiated); + } + { + self->SetMaterial (value); + } + + // Workaround for gcc/msvc where passing small mono structures by value does not work + CUSTOM private void Internal_GetPixelOffset (out Vector2 output) + { + *output = self->GetPixelOffset(); + } + CUSTOM private void Internal_SetPixelOffset (Vector2 p) { self->SetPixelOffset(p); } + + // The pixel offset of the text. + CSRAW public Vector2 pixelOffset { get { Vector2 p; Internal_GetPixelOffset(out p); return p; } set { Internal_SetPixelOffset(value); } } + + // The font used for the text. + AUTO_PTR_PROP Font font GetFont SetFont + + // The alignment of the text. + AUTO_PROP TextAlignment alignment GetAlignment SetAlignment + + // The anchor of the text. + AUTO_PROP TextAnchor anchor GetAnchor SetAnchor + + // The line spacing multiplier. + AUTO_PROP float lineSpacing GetLineSpacing SetLineSpacing + + // The tab width multiplier. + AUTO_PROP float tabSize GetTabSize SetTabSize + + // The font size to use (for dynamic fonts) + AUTO_PROP int fontSize GetFontSize SetFontSize + + // The font style to use (for dynamic fonts) + AUTO_PROP FontStyle fontStyle GetFontStyle SetFontStyle + + // Enable HTML-style tags for Text Formatting Markup. + AUTO_PROP bool richText GetRichText SetRichText + + // Color used to render the text + AUTO_PROP Color color GetColor SetColor +END +// Info how to render a character from the font texture. See /Font.characterInfo/ +STRUCT CharacterInfo + CSRAW + // Unicode value of the character + public int index; + // UV coordinates for the character in the texture + public Rect uv; + // Screen coordinates for the character in generated text meshes + public Rect vert; + // How for to advance between the beginning of this charcater and the next. + public float width; + // The size of the character or 0 if it is the default font size. + public int size; + // The style of the character. + public FontStyle style; + // Is the character flipped? + public bool flipped; +END + +// Script interface for [[wiki:class-Font|font assets]]. +CLASS Font : Object + + CUSTOM private static void Internal_CreateFont ([Writable]Font _font, string name) + { + Font* font = NEW_OBJECT (Font); + SmartResetObject(*font); + font->SetNameCpp (name); + Scripting::ConnectScriptingWrapperToObject (_font.GetScriptingObject(), font); + } + + // Creates a new font. + CSRAW public Font () { Internal_CreateFont (this,null); } + + // Creates a new font named /name/. + CSRAW public Font (string name){ Internal_CreateFont (this,name); } + + // The material used for the font display. + AUTO_PTR_PROP Material material GetMaterial SetMaterial + + // Does this font have a specific character? + CUSTOM bool HasCharacter (char c) { return self->HasCharacter((int)c);} + + // *undocumented* + CONDITIONAL ENABLE_MONO || UNITY_WINRT + CUSTOM_PROP string[] fontNames + { + ScriptingArrayPtr arr = CreateScriptingArray<ScriptingStringPtr>(MONO_COMMON.string, self->GetFontNames().size()); + int idx = 0; + for (UNITY_VECTOR(kMemFont,UnityStr)::const_iterator i = self->GetFontNames().begin(); i != self->GetFontNames().end(); ++i) + { + Scripting::SetScriptingArrayElement<ScriptingStringPtr>(arr, idx, scripting_string_new(*i)); + idx++; + } + return arr; + } + { + UNITY_VECTOR(kMemFont,UnityStr) names; + for (int i = 0; i < GetScriptingArraySize(value); ++i) + names.push_back(scripting_cpp_string_for(Scripting::GetScriptingArrayElementNoRef<ScriptingStringPtr>(value, i))); + self->SetFontNames(names); + } + + // Access an array of all characters contained in the font texture. + CUSTOM_PROP public CharacterInfo[] characterInfo + { + const Font::CharacterInfos &infos = self->GetCharacterInfos(); + int size = infos.size(); + ScriptingArrayPtr array = CreateScriptingArray<ScriptingCharacterInfo> (GetScriptingManager().GetCommonClasses().characterInfo, size); + #if UNITY_WINRT + for (int i=0; i<size; i++) + { + ScriptingCharacterInfo temp; temp.CopyFrom(infos[i]); + ScriptingObjectPtr data; + MarshallNativeStructIntoManaged(temp, data); + Scripting::SetScriptingArrayElement(array, i, data); + } + #else + ScriptingCharacterInfo *sci = Scripting::GetScriptingArrayStart<ScriptingCharacterInfo>(array); + for (int i=0; i<size; i++) + { + sci[i].CopyFrom(infos[i]); + } + #endif + return array; + } + { + Font::CharacterInfos infos; + int size = GetScriptingArraySize(value); + infos.resize(size); + + #if UNITY_WINRT + for (int i=0; i<size; i++) + { + ScriptingCharacterInfo temp; + MarshallManagedStructIntoNative(Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(value, i), &temp); + temp.CopyTo(infos[i]); + } + #else + ScriptingCharacterInfo *sci = Scripting::GetScriptingArrayStart<ScriptingCharacterInfo>(value); + for (int i=0; i<size; i++) + { + sci[i].CopyTo(infos[i]); + } + #endif + self->SetCharacterInfos (infos); + } + + // Request characters to be added to the font texture (dynamic fonts only). + + CUSTOM void RequestCharactersInTexture (string characters, int size = 0, FontStyle style = FontStyle.Normal) + { + UTF16String str(characters.AsUTF8().c_str()); + self->CacheFontForText (str.text, str.length, size, style); + } + + // Callback delegate for use with ::ref::textureRebuildCallback. + CSRAW public delegate void FontTextureRebuildCallback(); + CSRAW private event FontTextureRebuildCallback m_FontTextureRebuildCallback = null; + + CSRAW private void InvokeFontTextureRebuildCallback_Internal() + { + if (m_FontTextureRebuildCallback != null) + m_FontTextureRebuildCallback(); + } + + // A delegate which gets called when the font texture is rebuilt (dynamic fonts only). + CSRAW public FontTextureRebuildCallback textureRebuildCallback { get { + return m_FontTextureRebuildCallback; } + set { m_FontTextureRebuildCallback = value; } + } + + // Get rendering info for a specific character + CUSTOM bool GetCharacterInfo(char ch, out CharacterInfo info, int size = 0, FontStyle style = FontStyle.Normal) + { + if (self->HasCharacterInTexture (ch, size, style)) + { + info->index = ch; + info->size = size; + info->style = style; + self->GetCharacterRenderInfo( ch, size, style, info->vert, info->uv, info->flipped ); + info->width = self->GetCharacterWidth (ch, size, style); + return true; + } + return false; + } + +END + + +// [[Component]] added to a camera to make it render 2D GUI elements. +CLASS GUILayer : Behaviour + // Get the GUI element at a specific screen position. + CUSTOM GUIElement HitTest (Vector3 screenPosition) { return Scripting::ScriptingWrapperFor (self->HitTest (Vector2f (screenPosition.x, screenPosition.y))); } +END + +// Renders meshes inserted by the [[MeshFilter]] or [[TextMesh]]. +CLASS MeshRenderer : Renderer +END + +// StaticBatchingUtility can prepare your objects to take advantage of Unity's static batching. +CONDITIONAL !UNITY_FLASH +CLASS StaticBatchingUtility + + // Combine will prepare all children of the @@staticBatchRoot@@ for static batching. + CSRAW static public void Combine (GameObject staticBatchRoot) + { + InternalStaticBatchingUtility.Combine(staticBatchRoot); + } + + // Combine will prepare all @@gos@@ for the static batching. @@staticBatchRoot@@ will be treated as their parent. + CSRAW static public void Combine (GameObject[] gos, GameObject staticBatchRoot) + { + InternalStaticBatchingUtility.Combine(gos, staticBatchRoot); + } + + + C++RAW + + struct InternalMonoMeshInstance + { + int meshInstanceID; + Matrix4x4f transform; + Vector4f lightmapTilingOffset; + }; + + CUSTOM static internal Mesh InternalCombineVertices (MeshSubsetCombineUtility.MeshInstance[] meshes, string meshName) + { + const int numMeshes = GetScriptingArraySize( meshes ); + + CombineInstances mi; + + mi.resize ( numMeshes ); + InternalMonoMeshInstance* instances = Scripting::GetScriptingArrayStart<InternalMonoMeshInstance>( meshes ); + for ( int i=0; i!=numMeshes; ++i ) + { + mi[i].mesh = PPtr<Mesh>(instances[i].meshInstanceID); + mi[i].transform = instances[i].transform; + mi[i].lightmapTilingOffset = instances[i].lightmapTilingOffset; + } + + Mesh* outMesh = CreateObjectFromCode<Mesh> (kDefaultAwakeFromLoad); + + CombineMeshVerticesForStaticBatching ( mi, meshName, *outMesh ); + + return Scripting::ScriptingWrapperFor( outMesh ); + } + + C++RAW + + struct InternalMonoSubMeshInstance + { + int meshInstanceID; // public Mesh mesh; + int vertexOffset; // public int vertexOffset; + int goInstanceID; // public GameObject gameObject; + int subMeshIndex; // public int subMeshIndex; + Matrix4x4f transform; + }; + + CUSTOM static internal void InternalCombineIndices(MeshSubsetCombineUtility.SubMeshInstance[] submeshes, [Writable]Mesh combinedMesh) + { + InternalMonoSubMeshInstance* instances = Scripting::GetScriptingArrayStart<InternalMonoSubMeshInstance>( submeshes ); + int numSubMeshes = GetScriptingArraySize( submeshes ); + CombineInstances smi; + smi.resize( numSubMeshes ); + + for( int i=0; i!=numSubMeshes; ++i ) + { + smi[i].mesh = PPtr<Mesh>(instances[i].meshInstanceID); + smi[i].vertexOffset = instances[i].vertexOffset; + smi[i].subMeshIndex = instances[i].subMeshIndex; + smi[i].transform = instances[i].transform; + } + + Mesh* mesh = combinedMesh; + CombineMeshIndicesForStaticBatching (smi, *mesh, false, true); + mesh->SetIsReadable (false); + mesh->SetKeepIndices (true); + // Call awake to create the actual VBO; needed since we did SetIsReadable (false) + mesh->AwakeFromLoad (kDefaultAwakeFromLoad); + } +END + +// When using HDR rendering it can sometime be desirable to switch to LDR rendering during ImageEffect rendering. +CLASS ImageEffectTransformsToLDR : Attribute + +END + +// Any Image Effect with this attribute will be rendered after opaque geometry but before transparent geometry. +CLASS ImageEffectOpaque : Attribute + +END + +CSRAW +} diff --git a/Runtime/Export/GraphicsEnums.cs b/Runtime/Export/GraphicsEnums.cs new file mode 100644 index 0000000..6752dfc --- /dev/null +++ b/Runtime/Export/GraphicsEnums.cs @@ -0,0 +1,185 @@ +using System; + +namespace UnityEngine +{ + public enum FilterMode + { + Point = 0, + Bilinear = 1, + Trilinear = 2, + } + + public enum TextureWrapMode + { + Repeat = 0, + Clamp = 1, + } + + public enum NPOTSupport + { + None = 0, + Restricted = 1, + Full = 2 + } + + public enum TextureFormat + { + Alpha8 = 1, + ARGB4444 = 2, + RGB24 = 3, + RGBA32 = 4, + ARGB32 = 5, + RGB565 = 7, + DXT1 = 10, + DXT5 = 12, + RGBA4444 = 13, + + [System.Obsolete ("Use PVRTC_RGB2")] + PVRTC_2BPP_RGB = 30, + [System.Obsolete ("Use PVRTC_RGBA2")] + PVRTC_2BPP_RGBA = 31, + [System.Obsolete ("Use PVRTC_RGB4")] + PVRTC_4BPP_RGB = 32, + [System.Obsolete ("Use PVRTC_RGBA4")] + PVRTC_4BPP_RGBA = 33, + + PVRTC_RGB2 = 30, + PVRTC_RGBA2 = 31, + PVRTC_RGB4 = 32, + PVRTC_RGBA4 = 33, + ETC_RGB4 = 34, + ATC_RGB4 = 35, + ATC_RGBA8 = 36, + BGRA32 = 37, + ATF_RGB_DXT1 = 38, + ATF_RGBA_JPG = 39, + ATF_RGB_JPG = 40 + } + + public enum CubemapFace + { + PositiveX = 0, + NegativeX = 1, + PositiveY = 2, + NegativeY = 3, + PositiveZ = 4, + NegativeZ = 5 + } + + public enum RenderTextureFormat + { + ARGB32 = 0, + Depth = 1, + ARGBHalf = 2, + RGB565 = 4, + ARGB4444 = 5, + ARGB1555 = 6, + Default = 7, + DefaultHDR = 9, + ARGBFloat = 11, + RGFloat = 12, + RGHalf = 13, + RFloat = 14, + RHalf = 15, + R8 = 16, + ARGBInt = 17, + RGInt = 18, + RInt = 19 + } + + public enum RenderTextureReadWrite + { + Default = 0, + Linear = 1, + sRGB = 2 + } + +} // namespace UnityEngine + + +namespace UnityEngine.Rendering +{ + public enum BlendMode + { + Zero = 0, + One = 1, + DstColor = 2, + SrcColor = 3, + OneMinusDstColor = 4, + SrcAlpha = 5, + OneMinusSrcColor = 6, + DstAlpha = 7, + OneMinusDstAlpha = 8, + SrcAlphaSaturate = 9, + OneMinusSrcAlpha = 10 + } + + public enum BlendOp + { + Add = 0, + Subtract = 1, + ReverseSubtract = 2, + Min = 3, + Max = 4, + LogicalClear = 5, + LogicalSet = 6, + LogicalCopy = 7, + LogicalCopyInverted = 8, + LogicalNoop = 9, + LogicalInvert = 10, + LogicalAnd = 11, + LogicalNand = 12, + LogicalOr = 13, + LogicalNor = 14, + LogicalXor = 15, + LogicalEquivalence = 16, + LogicalAndReverse = 17, + LogicalAndInverted = 18, + LogicalOrReverse = 19, + LogicalOrInverted = 20, + } + + public enum CompareFunction + { + Disabled = 0, + Never = 1, + Less = 2, + Equal = 3, + LessEqual = 4, + Greater = 5, + NotEqual = 6, + GreaterEqual = 7, + Always = 8 + } + + public enum CullMode + { + Off = 0, + Front = 1, + Back = 2 + } + + [Flags] + public enum ColorWriteMask + { + Alpha = 1, + Blue = 2, + Green = 4, + Red = 8, + All = 15 + } + + public enum StencilOp + { + Keep = 0, + Zero = 1, + Replace = 2, + IncrementSaturate = 3, + DecrementSaturate = 4, + Invert = 5, + IncrementWrap = 6, + DecrementWrap = 7 + } + + +} // namespace UnityEngine.Rendering diff --git a/Runtime/Export/Handheld.txt b/Runtime/Export/Handheld.txt new file mode 100644 index 0000000..b1268a8 --- /dev/null +++ b/Runtime/Export/Handheld.txt @@ -0,0 +1,424 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Video/MoviePlayback.h" +#include "Runtime/Graphics/RenderTexture.h" +#include "Runtime/Input/GetInput.h" +#include "Runtime/Input/OnScreenKeyboard.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Misc/PlayerSettings.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Math/Vector2.h" +#include "Runtime/Shaders/Material.h" +#include "PlatformDependent/iPhonePlayer/iPhoneSettings.h" +#include "PlatformDependent/iPhonePlayer/iPhoneMisc.h" +#include "PlatformDependent/AndroidPlayer/AndroidSystemInfo.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + + +#if UNITY_ANDROID +#include "PlatformDependent/AndroidPlayer/EntryPoint.h" +#elif UNITY_IPHONE + void StartActivityIndicator(); + void StopActivityIndicator(); + const char* GetVendorIdentifier(); + const char* GetAdvertisingIdentifier(); + bool IsAdvertisingTrackingEnabled(); +#endif + +using namespace Unity; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// Simple struct that contains all the arguments needed by +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API +STRUCT internal TouchScreenKeyboard_InternalConstructorHelperArguments + CSRAW public uint keyboardType; + CSRAW public uint autocorrection; + CSRAW public uint multiline; + CSRAW public uint secure; + CSRAW public uint alert; +END + +C++RAW +struct MonoTouchScreenKeyboard_InternalConstructorHelperArguments { + unsigned int keyboardType; + unsigned int autocorrection; + unsigned int multiline; + unsigned int secure; + unsigned int alert; +}; + +// Describes options for displaying movie playback controls. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API +ENUM FullScreenMovieControlMode + // Display the standard controls for controlling movie playback. This + Full = 0, + // Display minimal set of controls controlling movie playback. Set of + Minimal = 1, + // Do not display any controls, but cancel movie playback if input occurs. + CancelOnInput = 2, + // Do not display any controls. This mode prevents the user from + Hidden = 3, +END + +// Describes scaling modes for displaying movies. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API +ENUM FullScreenMovieScalingMode + // Do not scale the movie. + None = 0, + // Scale the movie until one dimension fits on the screen exactly. In + AspectFit = 1, + // Scale the movie until the movie fills the entire screen. Content at + AspectFill = 2, + // Scale the movie until both dimensions fit the screen exactly. The + Fill = 3 +END + +CONDITIONAL UNITY_IPHONE_API +/// iOS-specific ActivityIndicator styles. +ENUM iOSActivityIndicatorStyle + /// Do not show ActivityIndicator + DontShow = -1, + /// The large white style of indicator (UIActivityIndicatorViewStyleWhiteLarge). + WhiteLarge = 0, + /// The standard white style of indicator (UIActivityIndicatorViewStyleWhite). + White = 1, + /// The standard gray style of indicator (UIActivityIndicatorViewStyleGray). + Gray = 2, +END + +CONDITIONAL UNITY_ANDROID_API +ENUM AndroidActivityIndicatorStyle + /// Do not show ActivityIndicator + DontShow = -1, + /// Large (android.R.attr.progressBarStyleLarge). + Large = 0, + /// Large Inversed (android.R.attr.progressBarStyleLargeInverse). + InversedLarge = 1, + /// Small (android.R.attr.progressBarStyleSmall). + Small = 2, + /// Small Inversed (android.R.attr.progressBarStyleSmallInverse). + InversedSmall = 3, +END + + +// Interface into functionality unique to handheld devices. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API +CLASS Handheld + // Plays a full-screen movie. + CUSTOM static bool PlayFullScreenMovie (string path, Color bgColor = Color.black, FullScreenMovieControlMode controlMode = FullScreenMovieControlMode.Full, FullScreenMovieScalingMode scalingMode = FullScreenMovieScalingMode.AspectFit) + { + return PlayFullScreenMovie (path, bgColor, controlMode, scalingMode); + } + + // Triggers device vibration. + CUSTOM static void Vibrate () + { + Vibrate (); + } + + CUSTOM_PROP static bool use32BitDisplayBuffer + { + return GetPlayerSettings().GetUse32BitDisplayBuffer(); + } + { + GetPlayerSettings().SetUse32BitDisplayBuffer(value); + } + + CUSTOM internal static void SetActivityIndicatorStyleImpl(int style) + { + #if UNITY_IPHONE + GetPlayerSettings().SetIOSShowActivityIndicatorOnLoading(style); + #elif UNITY_ANDROID + GetPlayerSettings().SetAndroidShowActivityIndicatorOnLoading(style); + #endif + } + + CONDITIONAL UNITY_IPHONE_API + /// Sets ActivityIndicator style. See iOSActivityIndicatorStyle enumeration for possible values. + /// Be warned that it will take effect on next call to StartActivityIndicator. + CSRAW public static void SetActivityIndicatorStyle(iOSActivityIndicatorStyle style) + { + SetActivityIndicatorStyleImpl((int)style); + } + + CONDITIONAL UNITY_ANDROID_API + /// Sets ActivityIndicator style. See AndroidActivityIndicatorStyle enumeration for possible values. + /// Be warned that it will take effect on next call to StartActivityIndicator. + CSRAW public static void SetActivityIndicatorStyle(AndroidActivityIndicatorStyle style) + { + SetActivityIndicatorStyleImpl((int)style); + } + + /// Gets current ActivityIndicator style. + CUSTOM static int GetActivityIndicatorStyle() + { + #if UNITY_IPHONE + return GetPlayerSettings().GetIOSShowActivityIndicatorOnLoading(); + #elif UNITY_ANDROID + return GetPlayerSettings().GetAndroidShowActivityIndicatorOnLoading(); + #else + return -1; + #endif + } + + // Starts os activity indicator + CUSTOM static void StartActivityIndicator() + { + #if UNITY_IPHONE || UNITY_ANDROID + StartActivityIndicator(); + #endif + } + + // Stops os activity indicator + CUSTOM static void StopActivityIndicator() + { + #if UNITY_IPHONE || UNITY_ANDROID + StopActivityIndicator(); + #endif + } + + //*undocumented* + CUSTOM static void ClearShaderCache() + { + #if UNITY_ANDROID + extern void Internal_ClearShaderCache(); + Internal_ClearShaderCache(); + #endif + } +END + +// Describes the type of keyboard. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API +ENUM TouchScreenKeyboardType + // Default keyboard for the current input method. + Default = 0, + // Keyboard displays standard ASCII characters. + ASCIICapable = 1, + // Keyboard with numbers and punctuation. + NumbersAndPunctuation = 2, + // Keyboard optimized for URL entry, features ".", "/", and ".com" + URL = 3, + // Numeric keypad designed for PIN entry, features the numbers 0 through 9 + NumberPad = 4, + // Keypad designed for entering telephone numbers, features the numbers 0 + PhonePad = 5, + // Keypad designed for entering a person's name or phone number. + NamePhonePad = 6, + // Keyboard optimized for specifying email addresses, features the "@", + EmailAddress = 7 +END + +// Interface into the native iPhone and Android on-screen keyboards - it is not available on other platforms. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API +CLASS TouchScreenKeyboard + // We are matching the KeyboardOnScreen class here so we can directly + // access it. + CSRAW + [System.NonSerialized] [NotRenamed] + internal IntPtr m_Ptr; + + THREAD_SAFE + CUSTOM private void Destroy() + { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) + { + delete keyboard; + self.SetPtr(NULL); + } + } + + //*undocumented* + CSRAW ~TouchScreenKeyboard() + { + Destroy(); + } + + //*undocumented* + CSRAW public TouchScreenKeyboard(string text, TouchScreenKeyboardType keyboardType, bool autocorrection, bool multiline, bool secure, bool alert, string textPlaceholder) + { + TouchScreenKeyboard_InternalConstructorHelperArguments arguments = new TouchScreenKeyboard_InternalConstructorHelperArguments (); + arguments.keyboardType = Convert.ToUInt32(keyboardType); + arguments.autocorrection = Convert.ToUInt32(autocorrection); + arguments.multiline = Convert.ToUInt32(multiline); + arguments.secure = Convert.ToUInt32(secure); + arguments.alert = Convert.ToUInt32(alert); + TouchScreenKeyboard_InternalConstructorHelper (ref arguments, text, textPlaceholder); + } + + CUSTOM private void TouchScreenKeyboard_InternalConstructorHelper (ref TouchScreenKeyboard_InternalConstructorHelperArguments arguments, string text, string textPlaceholder) + { + KeyboardOnScreen* keyboard = new KeyboardOnScreen(text, arguments.keyboardType, arguments.autocorrection, arguments.multiline, arguments.secure, arguments.alert, textPlaceholder); + self.SetPtr(keyboard); + } + + // Opens the native keyboard provided by OS on the screen. + CSRAW public static TouchScreenKeyboard Open(string text, TouchScreenKeyboardType keyboardType = TouchScreenKeyboardType.Default, bool autocorrection = true, bool multiline = false, bool secure = false, bool alert = false, string textPlaceholder = "") + { + return new TouchScreenKeyboard(text, keyboardType, autocorrection, multiline, secure, alert, textPlaceholder); + } + + // Returns the text displayed by the input field of the keyboard. This + CUSTOM_PROP public string text { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) return scripting_string_new(keyboard->getText()); + else return scripting_string_new(""); + } + { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) keyboard->setText(value); + } + + // Specifies if text input field above the keyboard will be hidden when + CUSTOM_PROP public static bool hideInput { + return KeyboardOnScreen::isInputHidden(); + } { + KeyboardOnScreen::setInputHidden(value); + } + + // Specifies if the keyboard is visible or is sliding into the position on + CUSTOM_PROP public bool active { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) return (short)keyboard->isActive(); + else return false; + } { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) keyboard->setActive(value); + } + + // Specifies if input process was finished (RO) + CUSTOM_PROP public bool done { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) return (short)keyboard->isDone(); + else return false; + } + + // Specifies if input process was canceled (RO) + CUSTOM_PROP public bool wasCanceled { + KeyboardOnScreen* keyboard = self.GetPtr(); + if (keyboard) return (short)keyboard->wasCanceled(); + else return false; + } + + // Returns portion of the screen which is covered by the keyboard. Returns + CUSTOM_PROP static Rect area { return KeyboardOnScreen::GetRect(); } + + // Returns true whenever any keyboard is completely visible on the screen. + CUSTOM_PROP static bool visible { return KeyboardOnScreen::IsVisible(); } +END + +// iPhone device generation +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +ENUM iPhoneGeneration + //*undocumented* + Unknown = 0, + // First generation device + iPhone = 1, + // Second generation + iPhone3G = 2, + // Third generation + iPhone3GS = 3, + // iPod Touch, first generation + iPodTouch1Gen = 4, + // iPod Touch, second generation + iPodTouch2Gen = 5, + // iPod Touch, third generation + iPodTouch3Gen = 6, + // iPad, first generation + iPad1Gen = 7, + // Fourth generation + iPhone4 = 8, + // iPod Touch, fourth generation + iPodTouch4Gen = 9, + // iPad, second generation + iPad2Gen = 10, + // Fifth generation + iPhone4S = 11, + // iPad, third generation + iPad3Gen = 12, + // iPhone5 + iPhone5 = 13, + // iPod Touch, fifth generation + iPodTouch5Gen = 14, + // iPadMini, first generation + iPadMini1Gen = 15, + // iPad, fourth generation + iPad4Gen = 16, + // iPhone5C + iPhone5C = 17, + // iPhone5S + iPhone5S = 18, + + // Yet unknown iPhone + iPhoneUnknown = 10001, + // Yet unknown iPad + iPadUnknown = 10002, + // Yet unknown iPodTouch + iPodTouchUnknown = 10003, +END + +// Interface into iPhone specific functionality. +CONDITIONAL UNITY_IPHONE_API +CLASS iPhone + // The generation of the device (RO) + CUSTOM_PROP static iPhoneGeneration generation { + return iphone::GetDeviceGeneration (); + } + + // Set file flag to be excluded from iCloud/iTunes backup. + CUSTOM static void SetNoBackupFlag(string path) + { + #if UNITY_IPHONE + iphone::SetNoBackupFlag(path.AsUTF8().c_str()); + #else + (void)path; + #endif + } + + // Reset "no backup" file flag: file will be synced with iCloud/iTunes backup and can be deleted by OS in low storage situations. + CUSTOM static void ResetNoBackupFlag(string path) + { + #if UNITY_IPHONE + iphone::ResetNoBackupFlag(path.AsUTF8().c_str()); + #else + (void)path; + #endif + } + + CUSTOM_PROP static string vendorIdentifier + { + #if UNITY_IPHONE + return scripting_string_new(GetVendorIdentifier()); + #else + return 0; + #endif + } + CUSTOM_PROP static string advertisingIdentifier + { + #if UNITY_IPHONE + return scripting_string_new(GetAdvertisingIdentifier()); + #else + return 0; + #endif + } + CUSTOM_PROP static bool advertisingTrackingEnabled + { + #if UNITY_IPHONE + return IsAdvertisingTrackingEnabled(); + #else + return false; + #endif + } +END + +CSRAW +} diff --git a/Runtime/Export/ImplementedInActionScript.cs b/Runtime/Export/ImplementedInActionScript.cs new file mode 100644 index 0000000..afd0e41 --- /dev/null +++ b/Runtime/Export/ImplementedInActionScript.cs @@ -0,0 +1,20 @@ +using System; + +namespace UnityEngine +{ + [AttributeUsage(AttributeTargets.Method)] + public class ImplementedInActionScriptAttribute : System.Attribute + { +// string actionScriptMethod; + + public ImplementedInActionScriptAttribute() + { + } +/* + public ImplementedInActionScriptAttribute(string actionScriptMethod) + { + this.actionScriptMethod = actionScriptMethod; + } +*/ + } +} diff --git a/Runtime/Export/Internal/DefaultValueAttribute.cs b/Runtime/Export/Internal/DefaultValueAttribute.cs new file mode 100644 index 0000000..a664aa4 --- /dev/null +++ b/Runtime/Export/Internal/DefaultValueAttribute.cs @@ -0,0 +1,43 @@ +using System; + +namespace UnityEngine.Internal +{ + /// <summary> + /// Adds default value information for optional parameters + /// </summary> + [Serializable] + [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.GenericParameter)] + public class DefaultValueAttribute : Attribute + { + private object DefaultValue; + + public DefaultValueAttribute (string value) + { + DefaultValue = value; + } + + public object Value { + get { return DefaultValue; } + } + + public override bool Equals (object obj) + { + DefaultValueAttribute dva = (obj as DefaultValueAttribute); + if (dva == null) + return false; + + if (DefaultValue == null) + return (dva.Value == null); + + return DefaultValue.Equals (dva.Value); + } + + public override int GetHashCode() + { + if (DefaultValue == null) + return base.GetHashCode (); + return DefaultValue.GetHashCode(); + } + + } +} diff --git a/Runtime/Export/Internal/ExcludeFromDocs.cs b/Runtime/Export/Internal/ExcludeFromDocs.cs new file mode 100644 index 0000000..42cfdbb --- /dev/null +++ b/Runtime/Export/Internal/ExcludeFromDocs.cs @@ -0,0 +1,16 @@ +using System; + +namespace UnityEngine.Internal +{ + /// <summary> + /// Adds default value information for optional parameters + /// </summary> + [Serializable] + [AttributeUsage(AttributeTargets.Method)] + public class ExcludeFromDocsAttribute : Attribute + { + public ExcludeFromDocsAttribute() + { + } + } +} diff --git a/Runtime/Export/JPEGMemsrc.c b/Runtime/Export/JPEGMemsrc.c new file mode 100644 index 0000000..fcab486 --- /dev/null +++ b/Runtime/Export/JPEGMemsrc.c @@ -0,0 +1,174 @@ +/* + * ... this file ought really to have been a part of jpeglib to begin with. + * + * memsrc.c + * + * Copyright (C) 1994-1996, Thomas G. Lane. + * This file is part of the Independent JPEG Group's software. + * For conditions of distribution and use, see the accompanying README file. + * + * This file contains decompression data source routines for the case of + * reading JPEG data from a memory buffer that is preloaded with the entire + * JPEG file. This would not seem especially useful at first sight, but + * a number of people have asked for it. + * This is really just a stripped-down version of jdatasrc.c. Comparison + * of this code with jdatasrc.c may be helpful in seeing how to make + * custom source managers for other purposes. + */ + +/* this is not a core library module, so it doesn't define JPEG_INTERNALS */ +#include "External/ProphecySDK/src/extlib/jpglib/jinclude.h" +#include "External/ProphecySDK/src/extlib/jpglib/jpeglib.h" +#include "External/ProphecySDK/src/extlib/jpglib/jerror.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* Expanded data source object for memory input */ + +typedef struct { + struct jpeg_source_mgr pub; /* public fields */ + + JOCTET eoi_buffer[2]; /* a place to put a dummy EOI */ +} my_source_mgr; + +typedef my_source_mgr * my_src_ptr; + + +/* + * Initialize source --- called by jpeg_read_header + * before any data is actually read. + */ + +METHODDEF(void) +init_source (j_decompress_ptr cinfo) +{ + /* No work, since jpeg_memory_src set up the buffer pointer and count. + * Indeed, if we want to read multiple JPEG images from one buffer, + * this *must* not do anything to the pointer. + */ +} + + +/* + * Fill the input buffer --- called whenever buffer is emptied. + * + * In this application, this routine should never be called; if it is called, + * the decompressor has overrun the end of the input buffer, implying we + * supplied an incomplete or corrupt JPEG datastream. A simple error exit + * might be the most appropriate response. + * + * But what we choose to do in this code is to supply dummy EOI markers + * in order to force the decompressor to finish processing and supply + * some sort of output image, no matter how corrupted. + */ + +METHODDEF(int) +fill_input_buffer (j_decompress_ptr cinfo) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + WARNMS(cinfo, JWRN_JPEG_EOF); + + /* Create a fake EOI marker */ + src->eoi_buffer[0] = (JOCTET) 0xFF; + src->eoi_buffer[1] = (JOCTET) JPEG_EOI; + src->pub.next_input_byte = src->eoi_buffer; + src->pub.bytes_in_buffer = 2; + + return TRUE; +} + + +/* + * Skip data --- used to skip over a potentially large amount of + * uninteresting data (such as an APPn marker). + * + * If we overrun the end of the buffer, we let fill_input_buffer deal with + * it. An extremely large skip could cause some time-wasting here, but + * it really isn't supposed to happen ... and the decompressor will never + * skip more than 64K anyway. + */ + +METHODDEF(void) +skip_input_data (j_decompress_ptr cinfo, long num_bytes) +{ + my_src_ptr src = (my_src_ptr) cinfo->src; + + if (num_bytes > 0) { + while (num_bytes > (long) src->pub.bytes_in_buffer) { + num_bytes -= (long) src->pub.bytes_in_buffer; + (void) fill_input_buffer(cinfo); + /* note we assume that fill_input_buffer will never return FALSE, + * so suspension need not be handled. + */ + } + src->pub.next_input_byte += (size_t) num_bytes; + src->pub.bytes_in_buffer -= (size_t) num_bytes; + } +} + + +/* + * An additional method that can be provided by data source modules is the + * resync_to_restart method for error recovery in the presence of RST markers. + * For the moment, this source module just uses the default resync method + * provided by the JPEG library. That method assumes that no backtracking + * is possible. + */ + + +/* + * Terminate source --- called by jpeg_finish_decompress + * after all data has been read. Often a no-op. + * + * NB: *not* called by jpeg_abort or jpeg_destroy; surrounding + * application must deal with any cleanup that should happen even + * for error exit. + */ + +METHODDEF(void) +term_source (j_decompress_ptr cinfo) +{ + /* no work necessary here */ +} + + +/* + * Prepare for input from a memory buffer. + */ +GLOBAL(void) +jpeg_memory_src (j_decompress_ptr cinfo, JOCTET * buffer, size_t bufsize); + +GLOBAL(void) +jpeg_memory_src (j_decompress_ptr cinfo, JOCTET * buffer, size_t bufsize) +{ + my_src_ptr src; + + /* The source object is made permanent so that a series of JPEG images + * can be read from a single buffer by calling jpeg_memory_src + * only before the first one. + * This makes it unsafe to use this manager and a different source + * manager serially with the same JPEG object. Caveat programmer. + */ + if (cinfo->src == NULL) { /* first time for this JPEG object? */ + cinfo->src = (struct jpeg_source_mgr *) + (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_PERMANENT, + SIZEOF(my_source_mgr)); + } + + src = (my_src_ptr) cinfo->src; + src->pub.init_source = init_source; + src->pub.fill_input_buffer = fill_input_buffer; + src->pub.skip_input_data = skip_input_data; + src->pub.resync_to_restart = jpeg_resync_to_restart; /* use default method */ + src->pub.term_source = term_source; + + src->pub.next_input_byte = buffer; + src->pub.bytes_in_buffer = bufsize; +} + +#ifdef __cplusplus +} +#endif diff --git a/Runtime/Export/JPEGMemsrc.h b/Runtime/Export/JPEGMemsrc.h new file mode 100644 index 0000000..3c847ac --- /dev/null +++ b/Runtime/Export/JPEGMemsrc.h @@ -0,0 +1,16 @@ +#ifndef JPEGMEMSRC_H +#define JPEGMEMSRC_H + +#include "External/ProphecySDK/src/extlib/jpglib/jinclude.h" +#include "External/ProphecySDK/src/extlib/jpglib/jpeglib.h" +#include "External/ProphecySDK/src/extlib/jpglib/jerror.h" + +extern "C" +{ + +GLOBAL(void) +jpeg_memory_src (j_decompress_ptr cinfo, JOCTET * buffer, size_t bufsize); + +} + +#endif diff --git a/Runtime/Export/LODBindings.txt b/Runtime/Export/LODBindings.txt new file mode 100644 index 0000000..d6053a3 --- /dev/null +++ b/Runtime/Export/LODBindings.txt @@ -0,0 +1,117 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Camera/LODGroup.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Utilities/LODUtility.h" +#include "Runtime/Camera/LODGroupManager.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ +// Structure for building a LOD for passing to the SetLODs function +CONDITIONAL !UNITY_FLASH +STRUCT LOD + // Construct a LOD + CSRAW public LOD (float screenRelativeTransitionHeight, Renderer[] renderers) + { + this.screenRelativeTransitionHeight = screenRelativeTransitionHeight; + this.renderers = renderers; + } + + // The screen relative height to use for the transition [0-1] + CSRAW public float screenRelativeTransitionHeight; + // List of renderers for this LOD level + CSRAW public Renderer[] renderers; +END + +// LODGroup lets you group multiple Renderers into LOD levels. +CLASS LODGroup : Component + + // The local reference point against which the LOD distance is calculated. + AUTO_PROP Vector3 localReferencePoint GetLocalReferencePoint SetLocalReferencePoint + + // The size of LOD object in local space + AUTO_PROP float size GetSize SetSize + + // The number of LOD levels + CUSTOM_PROP int lodCount { return self->GetLODCount(); } + + // Enable / Disable the LODGroup - Disabling will turn off all renderers. + CUSTOM_PROP bool enabled { return self->GetEnabled (); } { self->SetEnabled (value); } + + // Recalculate the bounding region for the LODGroup (Relatively slow, do not call often) + CUSTOM void RecalculateBounds () + { + CalculateLODGroupBoundingBox (*self); + } + + // Set the LODs for the LOD group. This will remove any existing LODs configured on the LODGroup + CONDITIONAL !UNITY_FLASH + CUSTOM void SetLODS (LOD[] scriptingLODs) + { + //Number of LOD's + int size = GetScriptingArraySize (scriptingLODs); + + if (size > kMaximumLODLevels) + { + WarningString(Format("SetLODs: Attempting to set more then the maximum number of LODS (%i) clamping", kMaximumLODLevels)); + size = kMaximumLODLevels; + } + + LODGroup::LODArray lods; + lods.resize(size); + + for (int i = 0; i < size; i++) + { + #if UNITY_WINRT + // LOD is a structure with managed type inside that's why we need to perform slow Marshalling here. + MonoLOD monoLOD; + MarshallManagedStructIntoNative(Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(scriptingLODs, i), &monoLOD); + #else + MonoLOD& monoLOD = Scripting::GetScriptingArrayElement<MonoLOD> (scriptingLODs, i); + #endif + + lods[i].screenRelativeHeight = monoLOD.screenRelativeTransitionHeight; + + // clamp to 0 - 1 + lods[i].screenRelativeHeight = clamp01 (lods[i].screenRelativeHeight); + + // if our values are broken... + if (i > 0 && (lods[i].screenRelativeHeight >= lods[i-1].screenRelativeHeight)) + { + ErrorString("SetLODs: Attempting to set LOD where the screen relative size is greater then or equal to a higher detail LOD level."); + return; + } + + int renderersSize = GetScriptingArraySize (monoLOD.renderers); + lods[i].renderers.resize_initialized(renderersSize); + for (int r = 0; r < renderersSize; r++) + { + ScriptingObjectPtr o = Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(monoLOD.renderers,r); + lods[i].renderers[r].renderer = ScriptingObjectToObject<Renderer> (o);; + } + } + + self->SetLODArray (lods); + CalculateLODGroupBoundingBox (*self); + } + + // Force a LOD level on this LOD group + // + // @param index The LOD level to use. Passing index < 0 will return to standard LOD processing + CUSTOM void ForceLOD (int index) + { + ForceLODLevel (*self, index); + } +END + +CSRAW +} diff --git a/Runtime/Export/LightProbeBindings.txt b/Runtime/Export/LightProbeBindings.txt new file mode 100644 index 0000000..172ff04 --- /dev/null +++ b/Runtime/Export/LightProbeBindings.txt @@ -0,0 +1,35 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Graphics/LightProbeGroup.h" + +CSRAW +using System; +namespace UnityEngine +{ + +// Light Probe Group +CLASS LightProbeGroup : Component + + // Editor only function to access and modify probe positions. + CONDITIONAL !UNITY_FLASH + CUSTOM_PROP Vector3[] probePositions + { + #if UNITY_EDITOR + return CreateScriptingArray (self->GetPositions(), self->GetPositionsSize (), MONO_COMMON.vector3); + #else + return CreateScriptingArray ((const Vector3f*)NULL, 0, MONO_COMMON.vector3); + #endif + } + { + #if UNITY_EDITOR + self->SetPositions (&GetMonoArrayElement<Vector3f> (value, 0), mono_array_length_safe(value)); + #endif + } +END + +CSRAW } diff --git a/Runtime/Export/LocalService.cs b/Runtime/Export/LocalService.cs new file mode 100644 index 0000000..bbb8ca4 --- /dev/null +++ b/Runtime/Export/LocalService.cs @@ -0,0 +1,655 @@ +using System; +using System.Collections.Generic; + +namespace UnityEngine.SocialPlatforms.Impl +{ + public class LocalUser : UserProfile, ILocalUser + { + private IUserProfile[] m_Friends; + private bool m_Authenticated; + private bool m_Underage; + + public LocalUser() + { + m_Friends = new UserProfile[0]; + m_Authenticated = false; + m_Underage = false; + } + + public void Authenticate (Action<bool> callback) + { + ActivePlatform.Instance.Authenticate((ILocalUser)this, callback); + } + + public void LoadFriends (Action<bool> callback) + { + ActivePlatform.Instance.LoadFriends((ILocalUser)this, callback); + } + + // Setters for implementors + public void SetFriends(IUserProfile[] friends) + { + m_Friends = friends; + } + public void SetAuthenticated(bool value) + { + m_Authenticated = value; + } + public void SetUnderage(bool value) + { + m_Underage = value; + } + + public IUserProfile[] friends { get { return m_Friends; } } + public bool authenticated { get { return m_Authenticated; } } + public bool underage { get { return m_Underage; } } + } + + public class UserProfile : IUserProfile + { + protected string m_UserName; + protected string m_ID; + protected bool m_IsFriend; + protected UserState m_State; + protected Texture2D m_Image; + + public UserProfile() + { + m_UserName = "Uninitialized"; + m_ID = "0"; + m_IsFriend = false; + m_State = UserState.Offline; + m_Image = new Texture2D(32, 32); + } + + public UserProfile(string name, string id, bool friend) : this (name, id, friend, UserState.Offline, new Texture2D(0, 0)) { } + + public UserProfile(string name, string id, bool friend, UserState state, Texture2D image) + { + m_UserName = name; + m_ID = id; + m_IsFriend = friend; + m_State = state; + m_Image = image; + } + + public override string ToString() + { + return id + " - " + + userName + " - " + + isFriend + " - " + + state; + } + + public void SetUserName(string name) + { + m_UserName = name; + } + public void SetUserID(string id) + { + m_ID = id; + } + public void SetImage(Texture2D image) + { + m_Image = image; + } + public void SetIsFriend(bool value) + { + m_IsFriend = value; + } + public void SetState(UserState state) + { + m_State = state; + } + + public string userName { get { return m_UserName; } } + public string id { get { return m_ID; } } + public bool isFriend { get { return m_IsFriend; } } + public UserState state { get { return m_State; } } + public Texture2D image { get { return m_Image; } } + } + + public class Achievement : IAchievement + { + private bool m_Completed; + private bool m_Hidden; + private DateTime m_LastReportedDate; + + public Achievement(string id, + double percentCompleted, + bool completed, + bool hidden, + DateTime lastReportedDate) + { + this.id = id; + this.percentCompleted = percentCompleted; + m_Completed = completed; + m_Hidden = hidden; + m_LastReportedDate = lastReportedDate; + } + + public Achievement(string id, double percent) + { + this.id = id; + percentCompleted = percent; + m_Hidden = false; + m_Completed = false; + m_LastReportedDate = DateTime.MinValue; + } + + public Achievement() : this("unknown", 0.0) { } + + public override string ToString() + { + return id + " - " + + percentCompleted + " - " + + completed + " - " + + hidden + " - " + + lastReportedDate; + } + + public void ReportProgress(Action<bool> callback) + { + ActivePlatform.Instance.ReportProgress(id, percentCompleted, callback); + } + + // Setters for implementors + public void SetCompleted(bool value) + { + m_Completed = value; + } + public void SetHidden(bool value) + { + m_Hidden = value; + } + public void SetLastReportedDate(DateTime date) + { + m_LastReportedDate = date; + } + + public string id { get; set; } + public double percentCompleted { get; set; } + public bool completed { get { return m_Completed; } } + public bool hidden { get { return m_Hidden; } } + public DateTime lastReportedDate { get { return m_LastReportedDate; } } + + // TODO: How to have a static method for resetting all achivements? + //public abstract void ResetAllAchievements(); + } + + public class AchievementDescription : IAchievementDescription + { + private string m_Title; + private Texture2D m_Image; + private string m_AchievedDescription; + private string m_UnachievedDescription; + private bool m_Hidden; + private int m_Points; + + public AchievementDescription(string id, + string title, + Texture2D image, + string achievedDescription, + string unachievedDescription, + bool hidden, + int points) + { + this.id = id; + m_Title = title; + m_Image = image; + m_AchievedDescription = achievedDescription; + m_UnachievedDescription = unachievedDescription; + m_Hidden = hidden; + m_Points = points; + } + + public override string ToString() + { + return id + " - " + + title + " - " + + achievedDescription + " - " + + unachievedDescription + " - " + + points + " - " + + hidden; + } + + public void SetImage(Texture2D image) + { + m_Image = image; + } + + public string id { get; set; } + public string title { get { return m_Title; } } + public Texture2D image { get { return m_Image; } } + public string achievedDescription { get { return m_AchievedDescription; } } + public string unachievedDescription { get { return m_UnachievedDescription; } } + public bool hidden { get { return m_Hidden; } } + public int points { get { return m_Points; } } + } + + public class Score : IScore + { + private DateTime m_Date; + private string m_FormattedValue; + private string m_UserID; + private int m_Rank; + + public Score() : this("unkown", -1) { } + + public Score(string leaderboardID, Int64 value) + : this(leaderboardID, value, "0", DateTime.Now, "", -1) + { } + + public Score(string leaderboardID, Int64 value, string userID, DateTime date, string formattedValue, int rank) + { + this.leaderboardID = leaderboardID; + this.value = value; + m_UserID = userID; + m_Date = date; + m_FormattedValue = formattedValue; + m_Rank = rank; + } + + public override string ToString() + { + return "Rank: '" + m_Rank + "' Value: '" + value + "' Category: '" + leaderboardID + "' PlayerID: '" + + m_UserID + "' Date: '" + m_Date; + } + + public void ReportScore(Action<bool> callback) + { + ActivePlatform.Instance.ReportScore(value, leaderboardID, callback); + } + + public void SetDate(DateTime date) + { + m_Date = date; + } + public void SetFormattedValue(string value) + { + m_FormattedValue = value; + } + public void SetUserID(string userID) + { + m_UserID = userID; + } + public void SetRank(int rank) + { + m_Rank = rank; + } + + public string leaderboardID { get; set; } + // TODO: This is just an int64 here, but should be able to represent all supported formats, except for float type scores ... + public Int64 value { get; set; } + public DateTime date { get { return m_Date; } } + public string formattedValue { get { return m_FormattedValue; } } + public string userID { get { return m_UserID; } } + public int rank { get { return m_Rank; } } + } + + public class Leaderboard : ILeaderboard + { + private bool m_Loading; + private IScore m_LocalUserScore; + private uint m_MaxRange; + private IScore[] m_Scores; + private string m_Title; + private string[] m_UserIDs; + + public Leaderboard() + { + id = "Invalid"; + range = new Range(1, 10); + userScope = UserScope.Global; + timeScope = TimeScope.AllTime; + m_Loading = false; + m_LocalUserScore = new Score("Invalid", 0); + m_MaxRange = 0; + m_Scores = new Score[0]; + m_Title = "Invalid"; + m_UserIDs = new string[0]; + } + + // TODO: Implement different behaviour when this is populated + /*public Leaderboard(string[] userIDs): this() + { + m_UserIDs = userIDs; + }*/ + + public void SetUserFilter(string[] userIDs) + { + m_UserIDs = userIDs; + } + + public override string ToString() + { + return "ID: '" + id + "' Title: '" + m_Title + "' Loading: '" + m_Loading + "' Range: [" + + range.from + "," + range.count + "] MaxRange: '" + m_MaxRange + "' Scores: '" + + m_Scores.Length + "' UserScope: '" + userScope + "' TimeScope: '" + timeScope + "' UserFilter: '" + + m_UserIDs.Length; + } + + public void LoadScores(Action<bool> callback) + { + ActivePlatform.Instance.LoadScores(this, callback); + } + + public bool loading + { + get { return ActivePlatform.Instance.GetLoading(this); } + } + + // Setters for implementors + public void SetLocalUserScore(IScore score) + { + m_LocalUserScore = score; + } + public void SetMaxRange(uint maxRange) + { + m_MaxRange = maxRange; + } + public void SetScores(IScore[] scores) + { + m_Scores = scores; + } + public void SetTitle(string title) + { + m_Title = title; + } + public string[] GetUserFilter() + { + return m_UserIDs; + } + + public string id { get; set; } + public UserScope userScope { get; set; } + public Range range { get; set; } + public TimeScope timeScope { get; set; } + public IScore localUserScore { get { return m_LocalUserScore; } } + public uint maxRange { get { return m_MaxRange; } } + public IScore[] scores { get { return m_Scores; } } + public string title { get { return m_Title; } } + } +} + +namespace UnityEngine.SocialPlatforms +{ + using UnityEngine.SocialPlatforms.Impl; + + public class Local : ISocialPlatform + { + static LocalUser m_LocalUser = null; + List<UserProfile> m_Friends = new List<UserProfile>(); + List<UserProfile> m_Users = new List<UserProfile>(); + List<AchievementDescription> m_AchievementDescriptions = new List<AchievementDescription>(); + List<Achievement> m_Achievements = new List<Achievement>(); + List<Leaderboard> m_Leaderboards = new List<Leaderboard>(); + Texture2D m_DefaultTexture; + + public ILocalUser localUser + { + get + { + if (m_LocalUser == null) + m_LocalUser = new LocalUser(); + return m_LocalUser; + } + } + + void ISocialPlatform.Authenticate(ILocalUser user, System.Action<bool> callback) + { + LocalUser thisUser = (LocalUser)user; + m_DefaultTexture = CreateDummyTexture(32, 32); + PopulateStaticData(); + thisUser.SetAuthenticated(true); + thisUser.SetUnderage(false); + thisUser.SetUserID("1000"); + thisUser.SetUserName("Lerpz"); + thisUser.SetImage(m_DefaultTexture); + if (callback != null) + callback(true); + } + + void ISocialPlatform.LoadFriends(ILocalUser user, System.Action<bool> callback) + { + if (!VerifyUser()) return; + ((LocalUser)user).SetFriends(m_Friends.ToArray()); + if (callback != null) + callback(true); + } + + public void LoadUsers(string[] userIDs, Action<IUserProfile[]> callback) + { + List<UserProfile> matches = new List<UserProfile>(); + if (!VerifyUser()) return; + foreach (string userId in userIDs) + { + foreach(UserProfile user in m_Users) + if (user.id == userId) + matches.Add(user); + foreach(UserProfile user in m_Friends) + if (user.id == userId) + matches.Add(user); + } + callback(matches.ToArray()); + } + + public void ReportProgress(string id, double progress, System.Action<bool> callback) + { + if (!VerifyUser()) return; + // Update achievement if it's already been reported + foreach (Achievement achoo in m_Achievements) + { + // TODO: Only allow increase in progress, figure out if xbox/gc report errors when lower progress is reported + if (achoo.id == id && achoo.percentCompleted <= progress) + { + if (progress >= 100.0) + achoo.SetCompleted(true); + achoo.SetHidden(false); + achoo.SetLastReportedDate(DateTime.Now); + achoo.percentCompleted = progress; + if (callback != null) + callback(true); + // No need to process this report any more + return; + } + } + + // If it's not been reported already check if it's a valid achievement description ID and add it, else it's an error + foreach (AchievementDescription achoo in m_AchievementDescriptions) + { + // TODO: Only allow increase in progress, figure out if xbox/gc report errors when lower progress is reported + if (achoo.id == id) + { + bool completed = (progress >= 100.0 ? true : false); + Achievement newAchievement = new Achievement(id, progress, completed, false, DateTime.Now); + m_Achievements.Add(newAchievement); + if (callback != null) + callback(true); + return; + } + } + + Debug.LogError("Achievement ID not found"); + if (callback != null) + callback(false); + } + + public void LoadAchievementDescriptions(System.Action<IAchievementDescription[]> callback) + { + if (!VerifyUser()) return; + if (callback != null) + callback(m_AchievementDescriptions.ToArray()); + } + + public void LoadAchievements(System.Action<IAchievement[]> callback) + { + if (!VerifyUser()) return; + if (callback != null) + callback(m_Achievements.ToArray()); + } + + public void ReportScore(Int64 score, string board, System.Action<bool> callback) + { + if (!VerifyUser()) return; + foreach (Leaderboard current in m_Leaderboards) + { + if (current.id == board) + { + // TODO: IIRC GameCenter only adds scores if they are higher than the users previous score, maybe mirror this here. + List<Score> scores = new List<Score>((Score[])current.scores); + scores.Add(new Score(board, score, localUser.id, DateTime.Now, score + " points", 0)); + current.SetScores(scores.ToArray()); + if (callback != null) + callback(true); + return; + } + } + Debug.LogError("Leaderboard not found"); + if (callback != null) + callback(false); + } + + public void LoadScores(string leaderboardID, Action<IScore[]> callback) + { + if (!VerifyUser()) return; + foreach (Leaderboard current in m_Leaderboards) + { + if (current.id == leaderboardID) + { + SortScores(current); + if (callback != null) + callback(current.scores); + return; + } + } + Debug.LogError("Leaderboard not found"); + if (callback != null) + callback(new Score[0]); + } + + void ISocialPlatform.LoadScores(ILeaderboard board, System.Action<bool> callback) + { + if (!VerifyUser()) return; + // Fill in fake server side data on leaderboard + Leaderboard thisBoard = (Leaderboard)board; + foreach (Leaderboard lb in m_Leaderboards) + { + // TODO: In the real world the board might have thousands of scores but only 100 + // are returned, for now we can assume they are less than 100 here + // TODO: Apply the filters which the leaderboard has, right now it always returns everything found + if (lb.id == thisBoard.id) + { + thisBoard.SetTitle(lb.title); + thisBoard.SetScores(lb.scores); + thisBoard.SetMaxRange((uint)lb.scores.Length); + } + } + SortScores(thisBoard); + SetLocalPlayerScore(thisBoard); + if (callback != null) + callback(true); + } + + bool ISocialPlatform.GetLoading(ILeaderboard board) + { + if (!VerifyUser()) return false; + return ((Leaderboard)board).loading; + } + + // TODO: Sorting seems to be broken... + private void SortScores(Leaderboard board) + { + List<Score> scores = new List<Score>((Score[])board.scores); + scores.Sort(delegate(Score s1, Score s2) + { + return s2.value.CompareTo(s1.value); + }); + for (int i = 0; i < scores.Count; i++) + scores[i].SetRank(i+1); + } + + private void SetLocalPlayerScore(Leaderboard board) + { + foreach (Score score in board.scores) + { + if (score.userID == localUser.id) + { + board.SetLocalUserScore(score); + break; + } + } + } + + + public void ShowAchievementsUI() + { + Debug.Log("ShowAchievementsUI not implemented"); + } + + public void ShowLeaderboardUI() + { + Debug.Log("ShowLeaderboardUI not implemented"); + } + + public ILeaderboard CreateLeaderboard() + { + Leaderboard lb = new Leaderboard(); + return (ILeaderboard)lb; + } + + public IAchievement CreateAchievement() + { + Achievement achoo = new Achievement(); + return (IAchievement)achoo; + } + + private bool VerifyUser() + { + if (!localUser.authenticated) + { + Debug.LogError("Must authenticate first"); + return false; + } + return true; + } + + private void PopulateStaticData() + { + m_Friends.Add(new UserProfile("Fred", "1001", true, UserState.Online, m_DefaultTexture)); + m_Friends.Add(new UserProfile("Julia", "1002", true, UserState.Online, m_DefaultTexture)); + m_Friends.Add(new UserProfile("Jeff", "1003", true, UserState.Online, m_DefaultTexture)); + m_Users.Add(new UserProfile("Sam", "1004", false, UserState.Offline, m_DefaultTexture)); + m_Users.Add(new UserProfile("Max", "1005", false, UserState.Offline, m_DefaultTexture)); + m_AchievementDescriptions.Add (new AchievementDescription("Achievement01", "First achievement", m_DefaultTexture, "Get first achievement", "Received first achievement", false, 10)); + m_AchievementDescriptions.Add (new AchievementDescription("Achievement02", "Second achievement", m_DefaultTexture, "Get second achievement", "Received second achievement", false, 20)); + m_AchievementDescriptions.Add (new AchievementDescription("Achievement03", "Third achievement", m_DefaultTexture, "Get third achievement", "Received third achievement", false, 15)); + Leaderboard board = new Leaderboard(); + board.SetTitle("High Scores"); + board.id = "Leaderboard01"; + List<Score> scores = new List<Score>(); + scores.Add(new Score("Leaderboard01", 300, "1001", DateTime.Now.AddDays(-1), "300 points", 1)); + scores.Add(new Score("Leaderboard01", 255, "1002", DateTime.Now.AddDays(-1), "255 points", 2)); + scores.Add(new Score("Leaderboard01", 55, "1003", DateTime.Now.AddDays(-1), "55 points", 3)); + scores.Add(new Score("Leaderboard01", 10, "1004", DateTime.Now.AddDays(-1), "10 points", 4)); + board.SetScores(scores.ToArray()); + m_Leaderboards.Add(board); + } + + private Texture2D CreateDummyTexture(int width, int height) + { + Texture2D texture = new Texture2D(width, height); + for (int y = 0; y < height; ++y) + { + for (int x = 0; x < width; ++x) + { + Color color = (x&y) > 0 ? Color.white : Color.gray; + texture.SetPixel (x, y, color); + } + } + texture.Apply(); + return texture; + } + } +} + diff --git a/Runtime/Export/Math.txt b/Runtime/Export/Math.txt new file mode 100644 index 0000000..6dbd21f --- /dev/null +++ b/Runtime/Export/Math.txt @@ -0,0 +1,2391 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Math/Quaternion.h" +#include "Runtime/Utilities/Utility.h" +#include "Runtime/Geometry/AABB.h" +#include "Runtime/Geometry/Ray.h" +#include "Runtime/Geometry/Ray2D.h" +#include "Runtime/Geometry/Intersection.h" +#include <vector> +#include "Runtime/Utilities/BitUtility.h" +#include "Runtime/Terrain/PerlinNoise.h" +#include "Runtime/Camera/CameraUtil.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Math/ColorSpaceConversion.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UnityEngine +{ + +// Representation of 2D vectors and points. +THREAD_SAFE +STRUCT Vector2 + // X component of the vector. + CSRAW public float x; + // Y component of the vector. + CSRAW public float y; + + // Access the /x/ or /y/ component using [0] or [1] respectively. + CSRAW public float this [int index] + { + get + { + switch(index) + { + case 0: return x; + case 1: return y; + default: + throw new IndexOutOfRangeException("Invalid Vector2 index!"); + } + } + + set + { + switch(index) + { + case 0: x = value; break; + case 1: y = value; break; + default: + throw new IndexOutOfRangeException("Invalid Vector2 index!"); + } + } + } + + // Constructs a new vector with given x, y components. + public Vector2 (float x, float y) { this.x = x; this.y = y; } + + // Set x and y components of an existing Vector2. + CSRAW public void Set (float new_x, float new_y) { x = new_x; y = new_y; } + + // Linearly interpolates between two vectors. + CSRAW public static Vector2 Lerp (Vector2 from, Vector2 to, float t) + { + t = Mathf.Clamp01 (t); + return new Vector2( + from.x + (to.x - from.x)*t, + from.y + (to.y - from.y)*t + ); + } + + // Moves a point /current/ towards /target/. + CSRAW static public Vector2 MoveTowards (Vector2 current, Vector2 target, float maxDistanceDelta) + { + Vector2 toVector = target - current; + float dist = toVector.magnitude; + if (dist <= maxDistanceDelta || dist == 0) + return target; + return current + toVector / dist * maxDistanceDelta; + } + + // Multiplies two vectors component-wise. + CSRAW public static Vector2 Scale (Vector2 a, Vector2 b) { return new Vector2 (a.x*b.x, a.y*b.y); } + + // Multiplies every component of this vector by the same component of /scale/. + CSRAW public void Scale (Vector2 scale) { x *= scale.x; y *= scale.y; } + + // Makes this vector have a ::ref::magnitude of 1. + CSRAW public void Normalize () + { + float mag = this.magnitude; + if (mag > kEpsilon) + this = this / mag; + else + this = zero; + } + + // Returns this vector with a ::ref::magnitude of 1 (RO). + CSRAW public Vector2 normalized { get { + Vector2 v = new Vector2(x, y); + v.Normalize(); + return v; + } } + + /// *listonly* + CSRAW override public string ToString() { return UnityString.Format("({0:F1}, {1:F1})", x, y); } + // Returns a nicely formatted string for this vector. + CSRAW public string ToString(string format) { + return UnityString.Format("({0}, {1})", x.ToString(format), y.ToString(format)); + } + + // used to allow Vector2s to be used as keys in hash tables + public override int GetHashCode() { + return x.GetHashCode() ^ (y.GetHashCode()<<2); + } + + // also required for being able to use Vector2s as keys in hash tables + public override bool Equals(object other) { + if(!(other is Vector2)) return false; + + Vector2 rhs=(Vector2)other; + return x.Equals(rhs.x) && y.Equals(rhs.y); + } + + // Dot Product of two vectors. + public static float Dot (Vector2 lhs, Vector2 rhs) { return lhs.x*rhs.x + lhs.y*rhs.y; } + + // Returns the length of this vector (RO). + CSRAW public float magnitude { get { return Mathf.Sqrt (x*x + y*y); } } + // Returns the squared length of this vector (RO). + CSRAW public float sqrMagnitude { get { return x*x + y*y; } } + + // Returns the angle in degrees between /from/ and /to/. + CSRAW public static float Angle(Vector2 from, Vector2 to) { return Mathf.Acos(Mathf.Clamp (Vector2.Dot (from.normalized, to.normalized), -1F, 1F)) * Mathf.Rad2Deg; } + + // Returns the distance between /a/ and /b/. + CSRAW public static float Distance (Vector2 a, Vector2 b) { return (a-b).magnitude; } + + // Returns a copy of /vector/ with its magnitude clamped to /maxLength/. + CSRAW public static Vector2 ClampMagnitude (Vector2 vector, float maxLength) + { + if (vector.sqrMagnitude > maxLength * maxLength) + return vector.normalized * maxLength; + return vector; + } + + OBSOLETE planned Use Vector2.sqrMagnitude + CSRAW public static float SqrMagnitude (Vector2 a) { return a.x*a.x + a.y*a.y; } + OBSOLETE planned Use .sqrMagnitude + CSRAW public float SqrMagnitude () { return x*x + y*y; } + + // Returns a vector that is made from the smallest components of two vectors. + CSRAW public static Vector2 Min (Vector2 lhs, Vector2 rhs) { return new Vector2 (Mathf.Min(lhs.x,rhs.x), Mathf.Min(lhs.y,rhs.y)); } + + // Returns a vector that is made from the largest components of two vectors. + CSRAW public static Vector2 Max (Vector2 lhs, Vector2 rhs) { return new Vector2 (Mathf.Max(lhs.x,rhs.x), Mathf.Max(lhs.y,rhs.y)); } + + // Adds two vectors. + CSRAW public static Vector2 operator + (Vector2 a, Vector2 b) { return new Vector2 (a.x+b.x, a.y+b.y); } + // Subtracts one vector from another. + CSRAW public static Vector2 operator - (Vector2 a, Vector2 b) { return new Vector2 (a.x-b.x, a.y-b.y); } + // Negates a vector. + CSRAW public static Vector2 operator - (Vector2 a) { return new Vector2 (-a.x, -a.y); } + // Multiplies a vector by a number. + CSRAW public static Vector2 operator * (Vector2 a, float d) { return new Vector2 (a.x*d, a.y*d); } + // Multiplies a vector by a number. + CSRAW public static Vector2 operator * (float d, Vector2 a) { return new Vector2 (a.x*d, a.y*d); } + // Divides a vector by a number. + CSRAW public static Vector2 operator / (Vector2 a, float d) { return new Vector2 (a.x/d, a.y/d); } + // Returns true if the vectors are equal. + CSRAW public static bool operator == (Vector2 lhs, Vector2 rhs) { + return SqrMagnitude (lhs - rhs) < kEpsilon * kEpsilon; + } + // Returns true if vectors different. + CSRAW public static bool operator != (Vector2 lhs, Vector2 rhs) + { + return SqrMagnitude (lhs - rhs) >= kEpsilon * kEpsilon; + } + + // Converts a [[Vector3]] to a Vector2. + CSRAW public static implicit operator Vector2(Vector3 v) { + return new Vector2(v.x, v.y); + } + // Converts a Vector2 to a [[Vector3]]. + CSRAW public static implicit operator Vector3(Vector2 v) { + return new Vector3(v.x, v.y, 0); + } + + // Shorthand for writing @@Vector2(0, 0)@@ + CSRAW public static Vector2 zero { get { return new Vector2 (0.0F, 0.0F); } } + // Shorthand for writing @@Vector2(1, 1)@@ + CSRAW public static Vector2 one { get { return new Vector2 (1.0F, 1.0F); } } + // Shorthand for writing @@Vector2(0, 1)@@ + CSRAW public static Vector2 up { get { return new Vector2 (0.0F, 1.0F); } } + // Shorthand for writing @@Vector2(1, 0)@@ + CSRAW public static Vector2 right { get { return new Vector2 (1.0F, 0.0F); } } + + // *Undocumented* + CSRAW public const float kEpsilon = 0.00001F; +END + + +// Representation of 3D vectors and points. +CSRAW +THREAD_SAFE +STRUCT Vector3 + + // *undocumented* + CSRAW public const float kEpsilon = 0.00001F; + + // X component of the vector. + CSRAW public float x; + // Y component of the vector. + CSRAW public float y; + // Z component of the vector. + CSRAW public float z; + + + // Linearly interpolates between two vectors. + CSRAW public static Vector3 Lerp (Vector3 from, Vector3 to, float t) + { + t = Mathf.Clamp01 (t); + return new Vector3( + from.x + (to.x - from.x)*t, + from.y + (to.y - from.y)*t, + from.z + (to.z - from.z)*t + ); + } + + + // Spherically interpolates between two vectors. + CUSTOM static Vector3 Slerp (Vector3 from, Vector3 to, float t) { return Slerp (from, to, clamp01 (t)); } + + + CUSTOM private static void Internal_OrthoNormalize2 (ref Vector3 a, ref Vector3 b) { OrthoNormalize (&a, &b); } + CUSTOM private static void Internal_OrthoNormalize3 (ref Vector3 a, ref Vector3 b, ref Vector3 c) { OrthoNormalize (&a, &b, &c); } + + // Makes vectors normalized and orthogonal to each other. + CSRAW static public void OrthoNormalize (ref Vector3 normal, ref Vector3 tangent) { Internal_OrthoNormalize2 (ref normal, ref tangent); } + // Makes vectors normalized and orthogonal to each other. + CSRAW static public void OrthoNormalize (ref Vector3 normal, ref Vector3 tangent, ref Vector3 binormal) { Internal_OrthoNormalize3 (ref normal, ref tangent, ref binormal); } + + + // Moves a point /current/ in a straight line towards a /target/ point. + CSRAW static public Vector3 MoveTowards (Vector3 current, Vector3 target, float maxDistanceDelta) + { + Vector3 toVector = target - current; + float dist = toVector.magnitude; + if (dist <= maxDistanceDelta || dist == 0) + return target; + return current + toVector / dist * maxDistanceDelta; + } + + // Rotates a vector /current/ towards /target/. + CUSTOM static Vector3 RotateTowards (Vector3 current, Vector3 target, float maxRadiansDelta, float maxMagnitudeDelta) { return RotateTowards (current, target, maxRadiansDelta, maxMagnitudeDelta); } + + // Gradually changes a vector towards a desired goal over time. + CSRAW public static Vector3 SmoothDamp (Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime) + { + // Based on Game Programming Gems 4 Chapter 1.10 + smoothTime = Mathf.Max(0.0001F, smoothTime); + float omega = 2F / smoothTime; + + float x = omega * deltaTime; + float exp = 1F / (1F + x + 0.48F*x*x + 0.235F*x*x*x); + Vector3 change = current - target; + Vector3 originalTo = target; + + // Clamp maximum speed + float maxChange = maxSpeed * smoothTime; + change = Vector3.ClampMagnitude(change, maxChange); + target = current - change; + + Vector3 temp = (currentVelocity + omega * change) * deltaTime; + currentVelocity = (currentVelocity - omega * temp) * exp; + Vector3 output = target + (change + temp) * exp; + + // Prevent overshooting + if (Vector3.Dot(originalTo - current, output - originalTo) > 0) + { + output = originalTo; + currentVelocity = (output - originalTo) / deltaTime; + } + + return output; + } + + // Access the x, y, z components using [0], [1], [2] respectively. + CSRAW public float this [int index] + { + get + { + switch(index) + { + case 0: return x; + case 1: return y; + case 2: return z; + default: + throw new IndexOutOfRangeException("Invalid Vector3 index!"); + } + } + + set + { + switch(index) + { + case 0: x = value; break; + case 1: y = value; break; + case 2: z = value; break; + default: + throw new IndexOutOfRangeException("Invalid Vector3 index!"); + } + } + } + + // Creates a new vector with given x, y, z components. + public Vector3 (float x, float y, float z) { this.x = x; this.y = y; this.z = z; } + // Creates a new vector with given x, y components and sets /z/ to zero. + public Vector3 (float x, float y) { this.x = x; this.y = y; z = 0F; } + + // Set x, y and z components of an existing Vector3. + CSRAW public void Set (float new_x, float new_y, float new_z) { x = new_x; y = new_y; z = new_z; } + + // Multiplies two vectors component-wise. + CSRAW public static Vector3 Scale (Vector3 a, Vector3 b) { return new Vector3 (a.x*b.x, a.y*b.y, a.z*b.z); } + + // Multiplies every component of this vector by the same component of /scale/. + CSRAW public void Scale (Vector3 scale) { x *= scale.x; y *= scale.y; z *= scale.z; } + + // Cross Product of two vectors. + CSRAW public static Vector3 Cross (Vector3 lhs, Vector3 rhs) + { + return new Vector3 ( + lhs.y * rhs.z - lhs.z * rhs.y, + lhs.z * rhs.x - lhs.x * rhs.z, + lhs.x * rhs.y - lhs.y * rhs.x); + } + + // used to allow Vector3s to be used as keys in hash tables + public override int GetHashCode() { + return x.GetHashCode() ^ (y.GetHashCode()<<2) ^ (z.GetHashCode()>>2); + } + + // also required for being able to use Vector3s as keys in hash tables + public override bool Equals(object other) { + if(!(other is Vector3)) return false; + + Vector3 rhs=(Vector3)other; + return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z); + } + + // Reflects a vector off the plane defined by a normal. + CSRAW public static Vector3 Reflect (Vector3 inDirection, Vector3 inNormal) + { + return -2F * Dot (inNormal, inDirection) * inNormal + inDirection; + } + + // *undoc* --- we have normalized property now + CSRAW public static Vector3 Normalize (Vector3 value) + { + float mag = Magnitude (value); + if (mag > kEpsilon) + return value / mag; + else + return zero; + } + + // Makes this vector have a ::ref::magnitude of 1. + CSRAW public void Normalize () + { + float mag = Magnitude (this); + if (mag > kEpsilon) + this = this / mag; + else + this = zero; + } + + // Returns this vector with a ::ref::magnitude of 1 (RO). + CSRAW public Vector3 normalized { get { return Vector3.Normalize (this); } } + + /// *listonly* + CSRAW override public string ToString() { return UnityString.Format("({0:F1}, {1:F1}, {2:F1})", x, y, z); } + // Returns a nicely formatted string for this vector. + CSRAW public string ToString(string format) { + return UnityString.Format("({0}, {1}, {2})", x.ToString(format), y.ToString(format), z.ToString(format)); + } + + // Dot Product of two vectors. + public static float Dot (Vector3 lhs, Vector3 rhs) { return lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z; } + + // Projects a vector onto another vector. + public static Vector3 Project (Vector3 vector, Vector3 onNormal) { + float sqrMag = Dot(onNormal,onNormal); + if (sqrMag < Mathf.Epsilon) + return zero; + else + return onNormal * Dot (vector, onNormal) / sqrMag; + } + + //*undocumented* --------------------------- TODO is this generally useful? What is the intention? I know i understood it once upon a time but it evaded my mind. + CSRAW public static Vector3 Exclude (Vector3 excludeThis, Vector3 fromThat) { + return fromThat - Project (fromThat, excludeThis); + } + + // Returns the angle in degrees between /from/ and /to/. This is always the smallest + CSRAW public static float Angle(Vector3 from, Vector3 to) { return Mathf.Acos(Mathf.Clamp (Vector3.Dot (from.normalized, to.normalized), -1F, 1F)) * Mathf.Rad2Deg; } + + // Returns the distance between /a/ and /b/. + public static float Distance (Vector3 a, Vector3 b) { Vector3 vec = new Vector3 (a.x - b.x, a.y - b.y, a.z - b.z); return Mathf.Sqrt (vec.x * vec.x + vec.y * vec.y + vec.z * vec.z); } + + // Returns a copy of /vector/ with its magnitude clamped to /maxLength/. + CSRAW public static Vector3 ClampMagnitude (Vector3 vector, float maxLength) + { + if (vector.sqrMagnitude > maxLength * maxLength) + return vector.normalized * maxLength; + return vector; + } + + // *undoc* --- there's a property now + CSRAW public static float Magnitude (Vector3 a) { return Mathf.Sqrt (a.x*a.x + a.y*a.y + a.z*a.z); } + + // Returns the length of this vector (RO). + CSRAW public float magnitude { get { return Mathf.Sqrt (x*x + y*y + z*z); } } + + // *undoc* --- there's a property now + CSRAW public static float SqrMagnitude (Vector3 a) { return a.x*a.x + a.y*a.y + a.z*a.z; } + + // Returns the squared length of this vector (RO). + CSRAW public float sqrMagnitude { get { return x * x + y * y + z * z; } } + + + // Returns a vector that is made from the smallest components of two vectors. + CSRAW public static Vector3 Min (Vector3 lhs, Vector3 rhs) { return new Vector3 (Mathf.Min(lhs.x,rhs.x), Mathf.Min(lhs.y,rhs.y), Mathf.Min(lhs.z,rhs.z)); } + + // Returns a vector that is made from the largest components of two vectors. + CSRAW public static Vector3 Max (Vector3 lhs, Vector3 rhs) { return new Vector3 (Mathf.Max(lhs.x,rhs.x), Mathf.Max(lhs.y,rhs.y), Mathf.Max(lhs.z,rhs.z)); } + + // Shorthand for writing @@Vector3(0, 0, 0)@@ + CSRAW public static Vector3 zero { get { return new Vector3 (0F, 0F, 0F); } } + // Shorthand for writing @@Vector3(1, 1, 1)@@ + CSRAW public static Vector3 one { get { return new Vector3 (1F, 1F, 1F); } } + // Shorthand for writing @@Vector3(0, 0, 1)@@ + CSRAW public static Vector3 forward { get { return new Vector3 (0F, 0F, 1F); } } + OBSOLETE planned Use -Vector3.forward + CSRAW public static Vector3 back { get { return new Vector3 (0F, 0F, -1F); } } + // Shorthand for writing @@Vector3(0, 1, 0)@@ + CSRAW public static Vector3 up { get { return new Vector3 (0F, 1F, 0F); } } + OBSOLETE planned Use -Vector3.up + CSRAW public static Vector3 down { get { return new Vector3 (0F, -1F, 0F); } } + OBSOLETE planned Use -Vector3.right + CSRAW public static Vector3 left { get { return new Vector3 (-1F, 0F, 0F); } } + // Shorthand for writing @@Vector3(1, 0, 0)@@ + CSRAW public static Vector3 right { get { return new Vector3 (1F, 0F, 0F); } } + + + // Adds two vectors. + CSRAW public static Vector3 operator + (Vector3 a, Vector3 b) { return new Vector3 (a.x+b.x, a.y+b.y, a.z+b.z); } + // Subtracts one vector from another. + CSRAW public static Vector3 operator - (Vector3 a, Vector3 b) { return new Vector3 (a.x-b.x, a.y-b.y, a.z-b.z); } + // Negates a vector. + CSRAW public static Vector3 operator - (Vector3 a) { return new Vector3 (-a.x, -a.y, -a.z); } + // Multiplies a vector by a number. + CSRAW public static Vector3 operator * (Vector3 a, float d) { return new Vector3 (a.x*d, a.y*d, a.z*d); } + // Multiplies a vector by a number. + CSRAW public static Vector3 operator * (float d, Vector3 a) { return new Vector3 (a.x*d, a.y*d, a.z*d); } + // Divides a vector by a number. + CSRAW public static Vector3 operator / (Vector3 a, float d) { return new Vector3 (a.x/d, a.y/d, a.z/d); } + + // Returns true if the vectors are equal. + CSRAW public static bool operator == (Vector3 lhs, Vector3 rhs) + { + return SqrMagnitude (lhs - rhs) < kEpsilon * kEpsilon; + } + + // Returns true if vectors different. + CSRAW public static bool operator != (Vector3 lhs, Vector3 rhs) + { + return SqrMagnitude (lhs - rhs) >= kEpsilon * kEpsilon; + } + + OBSOLETE warning Use Vector3.forward instead. + CSRAW public static Vector3 fwd { get { return new Vector3 (0F, 0F, 1F); } } + + OBSOLETE warning Use Vector3.Angle instead. AngleBetween uses radians instead of degrees and was deprecated for this reason + CSRAW public static float AngleBetween(Vector3 from, Vector3 to) { return Mathf.Acos(Mathf.Clamp (Vector3.Dot (from.normalized, to.normalized), -1F, 1F)); } +END + + +// Representation of RGBA colors. + +THREAD_SAFE +STRUCT Color + // Red component of the color. + CSRAW public float r; + + // Green component of the color. + CSRAW public float g; + + // Blue component of the color. + CSRAW public float b; + + // Alpha component of the color. + CSRAW public float a; + + + // Constructs a new Color with given r,g,b,a components. + CSRAW public Color (float r, float g, float b, float a) + { + this.r = r; this.g = g; this.b = b; this.a = a; + } + + // Constructs a new Color with given r,g,b components and sets /a/ to 1. + CSRAW public Color (float r, float g, float b) + { + this.r = r; this.g = g; this.b = b; this.a = 1.0F; + } + + /// *listonly* + CSRAW override public string ToString() { + return UnityString.Format("RGBA({0:F3}, {1:F3}, {2:F3}, {3:F3})", r, g, b, a); + } + // Returns a nicely formatted string of this color. + CSRAW public string ToString(string format) { + return UnityString.Format("RGBA({0}, {1}, {2}, {3})", r.ToString(format), g.ToString(format), b.ToString(format), a.ToString(format)); + } + + // used to allow Colors to be used as keys in hash tables + public override int GetHashCode() { + return ((Vector4)this).GetHashCode(); + } + + // also required for being able to use Colors as keys in hash tables + public override bool Equals(object other) { + if (!(other is Color)) return false; + Color rhs = (Color)other; + return r.Equals(rhs.r) && g.Equals(rhs.g) && b.Equals(rhs.b) && a.Equals(rhs.a); + } + + // Adds two colors together. Each component is added separately. + CSRAW public static Color operator + (Color a, Color b) { return new Color (a.r+b.r, a.g+b.g, a.b+b.b, a.a+b.a); } + + // Subtracts color /b/ from color /a/. Each component is subtracted separately. + CSRAW public static Color operator - (Color a, Color b) { return new Color (a.r-b.r, a.g-b.g, a.b-b.b, a.a-b.a); } + + // Multiplies two colors together. Each component is multiplied separately. + CSRAW public static Color operator * (Color a, Color b) { return new Color (a.r*b.r, a.g*b.g, a.b*b.b, a.a*b.a); } + + // Multiplies color /a/ by the float /b/. Each color component is scaled separately. + CSRAW public static Color operator * (Color a, float b) { return new Color (a.r*b, a.g*b, a.b*b, a.a*b); } + + // Multiplies color /a/ by the float /b/. Each color component is scaled separately. + CSRAW public static Color operator * (float b, Color a) { return new Color (a.r*b, a.g*b, a.b*b, a.a*b); } + + // Divides color /a/ by the float /b/. Each color component is scaled separately. + CSRAW public static Color operator / (Color a, float b) { return new Color (a.r/b, a.g/b, a.b/b, a.a/b); } + + //*undoc* + CSRAW public static bool operator == (Color lhs, Color rhs) + { + return ((Vector4)lhs == (Vector4)rhs); + } + //*undoc* + CSRAW public static bool operator != (Color lhs, Color rhs) + { + return ((Vector4)lhs != (Vector4)rhs); + } + + // Interpolates between colors /a/ and /b/ by /t/. + CSRAW public static Color Lerp (Color a, Color b, float t) + { + t = Mathf.Clamp01 (t); + return new Color( + a.r + (b.r - a.r)*t, + a.g + (b.g - a.g)*t, + a.b + (b.b - a.b)*t, + a.a + (b.a - a.a)*t + ); + } + + // Returns new color that has RGB components multiplied, but leaving alpha untouched. + CSRAW internal Color RGBMultiplied (float multiplier) { return new Color (r * multiplier, g * multiplier, b * multiplier, a); } + // Returns new color that has RGB components multiplied, but leaving alpha untouched. + CSRAW internal Color AlphaMultiplied (float multiplier) { return new Color (r,g,b,a * multiplier); } + // Returns new color that has RGB components multiplied, but leaving alpha untouched. + CSRAW internal Color RGBMultiplied (Color multiplier) { return new Color (r * multiplier.r, g * multiplier.g, b * multiplier.b, a); } + + // Solid red. RGBA is (1, 0, 0, 1). + CSRAW public static Color red { get { return new Color (1F, 0F, 0F, 1F); } } + // Solid green. RGBA is (0, 1, 0, 1). + CSRAW public static Color green { get { return new Color (0F, 1F, 0F, 1F); } } + // Solid blue. RGBA is (0, 0, 1, 1). + CSRAW public static Color blue { get { return new Color (0F, 0F, 1F, 1F); } } + // Solid white. RGBA is (1, 1, 1, 1). + CSRAW public static Color white { get { return new Color (1F, 1F, 1F, 1F); } } + // Solid black. RGBA is (0, 0, 0, 1). + CSRAW public static Color black { get { return new Color (0F, 0F, 0F, 1F); } } + // Yellow. RGBA is (1, 0.92, 0.016, 1), but the color is nice to look at! + CSRAW public static Color yellow { get { return new Color (1F, 235F / 255F, 4F / 255F, 1F); } } + // Cyan. RGBA is (0, 1, 1, 1). + CSRAW public static Color cyan { get { return new Color (0F, 1F, 1F, 1F); } } + // Magenta. RGBA is (1, 0, 1, 1). + CSRAW public static Color magenta { get { return new Color (1F, 0F, 1F, 1F); } } + // Gray. RGBA is (0.5, 0.5, 0.5, 1). + CSRAW public static Color gray { get { return new Color (.5F, .5F, .5F, 1F); } } + // English spelling for ::ref::gray. RGBA is the same (0.5, 0.5, 0.5, 1). + CSRAW public static Color grey { get { return new Color (.5F, .5F, .5F, 1F); } } + // Completely transparent. RGBA is (0, 0, 0, 0). + CSRAW public static Color clear { get { return new Color (0F, 0F, 0F, 0F); } } + + // The grayscale value of the color (RO) + CSRAW public float grayscale { get { return 0.299F * r + 0.587F * g + 0.114F * b; } } + + // A version of the color that has had the inverse gamma curve applied + CSRAW public Color linear + { + get { + return new Color (Mathf.GammaToLinearSpace(r), Mathf.GammaToLinearSpace(g), Mathf.GammaToLinearSpace(b), a); + } + } + + // A version of the color that has had the gamma curve applied + CSRAW public Color gamma + { + get { + return new Color (Mathf.LinearToGammaSpace(r), Mathf.LinearToGammaSpace(g), Mathf.LinearToGammaSpace(b), a); + } + } + + // Colors can be implicitly converted to and from [[Vector4]]. + CSRAW public static implicit operator Vector4(Color c) { + return new Vector4(c.r, c.g, c.b, c.a); + } + // Colors can be implicitly converted to and from [[Vector4]]. + CSRAW public static implicit operator Color(Vector4 v) { + return new Color(v.x, v.y, v.z, v.w); + } + + // Access the r, g, b,a components using [0], [1], [2], [3] respectively. + CSRAW public float this [int index] + { + get + { + switch(index) + { + case 0: return r; + case 1: return g; + case 2: return b; + case 3: return a; + default: + throw new IndexOutOfRangeException("Invalid Vector3 index!"); + } + } + + set + { + switch(index) + { + case 0: r = value; break; + case 1: g = value; break; + case 2: b = value; break; + case 3: a = value; break; + default: + throw new IndexOutOfRangeException("Invalid Vector3 index!"); + } + } + } + + +END + + +// Representation of RGBA colors in 32 bit format +THREAD_SAFE +STRUCT Color32 + // Red component of the color. + CSRAW public byte r; + + // Green component of the color. + CSRAW public byte g; + + // Blue component of the color. + CSRAW public byte b; + + // Alpha component of the color. + CSRAW public byte a; + + // Constructs a new Color with given r, g, b, a components. + CSRAW public Color32(byte r, byte g, byte b, byte a) { + this.r = r; this.g = g; this.b = b; this.a = a; + } + + // Color32 can be implicitly converted to and from [[Color]]. + CSRAW public static implicit operator Color32(Color c) { + return new Color32((byte)(Mathf.Clamp01(c.r) * 255), (byte)(Mathf.Clamp01(c.g) * 255), (byte)(Mathf.Clamp01(c.b) * 255), (byte)(Mathf.Clamp01(c.a) * 255)); + } + + // Color32 can be implicitly converted to and from [[Color]]. + CSRAW public static implicit operator Color (Color32 c) { + return new Color(c.r / 255f, c.g / 255f, c.b / 255f, c.a / 255f); + } + + /// *listonly* + CSRAW override public string ToString() { + return UnityString.Format("RGBA({0}, {1}, {2}, {3})", r, g, b, a); + } + // Returns a nicely formatted string of this color. + CSRAW public string ToString(string format) { + return UnityString.Format("RGBA({0}, {1}, {2}, {3})", r.ToString(format), g.ToString(format), b.ToString(format), a.ToString(format)); + } + + // Interpolates between colors /a/ and /b/ by /t/. + CSRAW public static Color32 Lerp (Color32 a, Color32 b, float t) + { + t = Mathf.Clamp01 (t); + return new Color32( + (byte)(a.r + (b.r - a.r)*t), + (byte)(a.g + (b.g - a.g)*t), + (byte)(a.b + (b.b - a.b)*t), + (byte)(a.a + (b.a - a.a)*t) + ); + } +END + + +// Quaternions are used to represent rotations. + +CSRAW +THREAD_SAFE +STRUCT Quaternion + + // X component of the Quaternion. Don't modify this directly unless you know quaternions inside out. + CSRAW public float x; + // Y component of the Quaternion. Don't modify this directly unless you know quaternions inside out. + CSRAW public float y; + // Z component of the Quaternion. Don't modify this directly unless you know quaternions inside out. + CSRAW public float z; + // W component of the Quaternion. Don't modify this directly unless you know quaternions inside out. + CSRAW public float w; + + // Access the x, y, z, w components using [0], [1], [2], [3] respectively. + CSRAW public float this [int index] + { + get + { + switch(index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: + throw new IndexOutOfRangeException("Invalid Quaternion index!"); + } + } + + set + { + switch(index) + { + case 0: x = value; break; + case 1: y = value; break; + case 2: z = value; break; + case 3: w = value; break; + default: + throw new IndexOutOfRangeException("Invalid Quaternion index!"); + } + } + } + + + // Constructs new Quaternion with given x,y,z,w components. + CSRAW public Quaternion (float x, float y, float z, float w) { this.x = x; this.y = y; this.z = z; this.w = w; } + + // Set x, y, z and w components of an existing Quaternion. + CSRAW public void Set (float new_x, float new_y, float new_z, float new_w) { x = new_x; y = new_y; z = new_z; w = new_w; } + + // The identity rotation (RO). This quaternion corresponds to "no rotation": the object + CSRAW public static Quaternion identity { get { return new Quaternion (0F, 0F, 0F, 1F); } } + + // Combines rotations /lhs/ and /rhs/. + CSRAW public static Quaternion operator * (Quaternion lhs, Quaternion rhs) + { + return new Quaternion ( + lhs.w*rhs.x + lhs.x*rhs.w + lhs.y*rhs.z - lhs.z*rhs.y, + lhs.w*rhs.y + lhs.y*rhs.w + lhs.z*rhs.x - lhs.x*rhs.z, + lhs.w*rhs.z + lhs.z*rhs.w + lhs.x*rhs.y - lhs.y*rhs.x, + lhs.w*rhs.w - lhs.x*rhs.x - lhs.y*rhs.y - lhs.z*rhs.z); + } + + // Rotates the point /point/ with /rotation/. + CSRAW public static Vector3 operator * (Quaternion rotation, Vector3 point) + { + float x = rotation.x * 2F; + float y = rotation.y * 2F; + float z = rotation.z * 2F; + float xx = rotation.x * x; + float yy = rotation.y * y; + float zz = rotation.z * z; + float xy = rotation.x * y; + float xz = rotation.x * z; + float yz = rotation.y * z; + float wx = rotation.w * x; + float wy = rotation.w * y; + float wz = rotation.w * z; + + Vector3 res; + res.x = (1F - (yy + zz)) * point.x + (xy - wz) * point.y + (xz + wy) * point.z; + res.y = (xy + wz) * point.x + (1F - (xx + zz)) * point.y + (yz - wx) * point.z; + res.z = (xz - wy) * point.x + (yz + wx) * point.y + (1F - (xx + yy)) * point.z; + return res; + } + + // *undocumented* + CSRAW public const float kEpsilon = 0.000001F; + + // Are two quaternions equal to each other? + CSRAW public static bool operator == (Quaternion lhs, Quaternion rhs) + { + return Dot (lhs, rhs) > 1.0f-kEpsilon; + } + + // Are two quaternions different from each other? + CSRAW public static bool operator != (Quaternion lhs, Quaternion rhs) + { + return Dot (lhs, rhs) <= 1.0f-kEpsilon; + } + + // The dot product between two rotations. + CSRAW public static float Dot (Quaternion a, Quaternion b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; } + + // Creates a rotation which rotates /angle/ degrees around /axis/. + CUSTOM static Quaternion AngleAxis (float angle, Vector3 axis) { return AxisAngleToQuaternionSafe (axis, Deg2Rad(angle)); } + + // Converts a rotation to angle-axis representation. + CSRAW public void ToAngleAxis (out float angle, out Vector3 axis) { Internal_ToAxisAngleRad (this, out axis, out angle); angle *= Mathf.Rad2Deg; } + + // Creates a rotation which rotates from /fromDirection/ to /toDirection/. + CUSTOM static Quaternion FromToRotation (Vector3 fromDirection, Vector3 toDirection) { return FromToQuaternionSafe (fromDirection, toDirection); } + + // Creates a rotation which rotates from /fromDirection/ to /toDirection/. + CSRAW public void SetFromToRotation (Vector3 fromDirection, Vector3 toDirection) { this = FromToRotation (fromDirection, toDirection); } + + // Creates a rotation with the specified /forward/ and /upwards/ directions. + CUSTOM static Quaternion LookRotation (Vector3 forward, Vector3 upwards = Vector3.up) + { + Quaternionf q = Quaternionf::identity (); + if (!LookRotationToQuaternion (forward, upwards, &q)) + { + float mag = Magnitude (forward); + if (mag > Vector3f::epsilon) + { + Matrix3x3f m; + m.SetFromToRotation (Vector3f::zAxis, forward / mag); + MatrixToQuaternion (m, q); + } + else + { + LogString ("Look rotation viewing vector is zero"); + } + } + return q; + } + + // Creates a rotation with the specified /forward/ and /upwards/ directions. + CSRAW public void SetLookRotation (Vector3 view, Vector3 up = Vector3.up) { this = LookRotation (view, up); } + + // Spherically interpolates between /from/ and /to/ by t. + CUSTOM static Quaternion Slerp (Quaternion from, Quaternion to, float t) { return Slerp (from, to, clamp01 (t)); } + + // Interpolates between /from/ and /to/ by /t/ and normalizes the result afterwards. + CUSTOM static Quaternion Lerp (Quaternion from, Quaternion to, float t) { return Lerp (from, to, clamp01 (t)); } + + // Rotates a rotation /from/ towards /to/. + CSRAW public static Quaternion RotateTowards (Quaternion from, Quaternion to, float maxDegreesDelta) + { + float angle = Quaternion.Angle(from, to); + if (angle == 0.0f) + return to; + float slerpValue = Mathf.Min(1.0f, maxDegreesDelta / angle); + return UnclampedSlerp(from, to, slerpValue); + } + + CUSTOM private static Quaternion UnclampedSlerp (Quaternion from, Quaternion to, float t) { return Slerp (from, to, t); } + + // Returns the Inverse of /rotation/. + CUSTOM static Quaternion Inverse (Quaternion rotation) { return Inverse (rotation); } + + + /// *listonly* + CSRAW override public string ToString() { + return UnityString.Format("({0:F1}, {1:F1}, {2:F1}, {3:F1})", x, y, z, w); + } + // Returns a nicely formatted string of the Quaternion + CSRAW public string ToString(string format) { + return UnityString.Format("({0}, {1}, {2}, {3})", x.ToString(format), y.ToString(format), z.ToString(format), w.ToString(format)); + } + + // Returns the angle in degrees between two rotations /a/ and /b/. + CSRAW static public float Angle (Quaternion a, Quaternion b) + { + float dot = Dot(a, b); + return Mathf.Acos(Mathf.Min(Mathf.Abs(dot), 1.0F)) * 2.0F * Mathf.Rad2Deg; + } + + // Returns the euler angle representation of the rotation. + CSRAW public Vector3 eulerAngles { get { return Internal_ToEulerRad(this) * Mathf.Rad2Deg; } set { this=Internal_FromEulerRad(value * Mathf.Deg2Rad); } } + + // Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order). + CSRAW static public Quaternion Euler (float x, float y, float z) { return Internal_FromEulerRad (new Vector3 (x, y, z) * Mathf.Deg2Rad); } + + // Returns a rotation that rotates z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order). + CSRAW static public Quaternion Euler (Vector3 euler) { return Internal_FromEulerRad (euler * Mathf.Deg2Rad); } + + + // Internal implementation. Note Rad suffix that indicates that this method works in radians. + CUSTOM static private Vector3 Internal_ToEulerRad (Quaternion rotation) + { + Quaternionf outRotation = NormalizeSafe (rotation); + return QuaternionToEuler (outRotation); + } + + // Internal implementation. Note Rad suffix that indicates that this method works in radians. + CUSTOM static private Quaternion Internal_FromEulerRad (Vector3 euler) { + return EulerToQuaternion (euler); + } + + // Internal implementation. Note Rad suffix that indicates that this method works in radians. + CUSTOM private static void Internal_ToAxisAngleRad (Quaternion q, out Vector3 axis, out float angle) { + QuaternionToAxisAngle (NormalizeSafe (q), axis, angle); + } + + + // Old obsolete radians-based Euler functions: + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW static public Quaternion EulerRotation (float x, float y, float z) { return Internal_FromEulerRad (new Vector3 (x, y, z)); } + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW public static Quaternion EulerRotation (Vector3 euler) { return Internal_FromEulerRad (euler); } + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW public void SetEulerRotation (float x, float y, float z) { this = Internal_FromEulerRad (new Vector3 (x, y, z)); } + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW public void SetEulerRotation (Vector3 euler) { this = Internal_FromEulerRad (euler); } + OBSOLETE warning Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees + CSRAW public Vector3 ToEuler () { return Internal_ToEulerRad (this); } + + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW static public Quaternion EulerAngles (float x, float y, float z) { return Internal_FromEulerRad (new Vector3 (x, y, z)); } + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW public static Quaternion EulerAngles (Vector3 euler) { return Internal_FromEulerRad (euler); } + + OBSOLETE warning Use Quaternion.ToAngleAxis instead. This function was deprecated because it uses radians instead of degrees + CSRAW public void ToAxisAngle (out Vector3 axis, out float angle) { Internal_ToAxisAngleRad (this, out axis, out angle); } + + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW public void SetEulerAngles (float x, float y, float z) { SetEulerRotation (new Vector3 (x, y, z)); } + OBSOLETE warning Use Quaternion.Euler instead. This function was deprecated because it uses radians instead of degrees + CSRAW public void SetEulerAngles (Vector3 euler) { this = EulerRotation (euler); } + OBSOLETE warning Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees + CSRAW public static Vector3 ToEulerAngles (Quaternion rotation) { return Quaternion.Internal_ToEulerRad (rotation); } + OBSOLETE warning Use Quaternion.eulerAngles instead. This function was deprecated because it uses radians instead of degrees + CSRAW public Vector3 ToEulerAngles () { return Quaternion.Internal_ToEulerRad (this); } + + OBSOLETE warning Use Quaternion.AngleAxis instead. This function was deprecated because it uses radians instead of degrees + CUSTOM static Quaternion AxisAngle (Vector3 axis, float angle) { return AxisAngleToQuaternionSafe (axis, angle); } + + OBSOLETE warning Use Quaternion.AngleAxis instead. This function was deprecated because it uses radians instead of degrees + CSRAW public void SetAxisAngle (Vector3 axis, float angle) { this = AxisAngle (axis, angle); } + + // used to allow Quaternions to be used as keys in hash tables + CSRAW public override int GetHashCode() { + return x.GetHashCode() ^ (y.GetHashCode()<<2) ^ (z.GetHashCode()>>2) ^ (w.GetHashCode()>>1); + } + + // also required for being able to use Quaternions as keys in hash tables + public override bool Equals(object other) { + if(!(other is Quaternion)) return false; + + Quaternion rhs=(Quaternion)other; + return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z) && w.Equals(rhs.w); + } + +END + + +// A 2D Rectangle defined by x, y position and width, height +THREAD_SAFE +STRUCT Rect + CSRAW private float m_XMin, m_YMin, m_Width, m_Height; + + // Creates a new rectangle. + CSRAW public Rect (float left, float top, float width, float height) { + m_XMin = left; + m_YMin = top; + m_Width = width; + m_Height = height; + } + + //*undocumented* + CSRAW public Rect (Rect source) { + m_XMin = source.m_XMin; + m_YMin = source.m_YMin; + m_Width = source.m_Width; + m_Height= source.m_Height; + } + + // Creates a rectangle from min/max coordinate values. + static public Rect MinMaxRect (float left, float top, float right, float bottom) + { + return new Rect (left, top, right - left, bottom - top); + } + + // Set components of an existing Rect. + CSRAW public void Set (float left, float top, float width, float height) { + m_XMin = left; + m_YMin = top; + m_Width = width; + m_Height = height; + } + + // Left coordinate of the rectangle. + CSRAW public float x { get { return m_XMin; } set { m_XMin = value; } } + + // Top coordinate of the rectangle. + CSRAW public float y { get { return m_YMin; } set { m_YMin = value; } } + + // Center coordinate of the rectangle. + CSRAW public Vector2 center { get { return new Vector2 (x + m_Width / 2f, y + m_Height / 2f); } set { m_XMin = value.x - m_Width / 2f; m_YMin = value.y - m_Height / 2f; } } + + // Width of the rectangle. + CSRAW public float width { get { return m_Width; } set { m_Width = value; } } + + // Height of the rectangle. + CSRAW public float height { get { return m_Height; } set { m_Height = value; } } + + OBSOLETE warning use xMin + CSRAW public float left { get { return m_XMin; } } + OBSOLETE warning use xMax + CSRAW public float right { get { return m_XMin + m_Width; } } + OBSOLETE warning use yMin + CSRAW public float top { get { return m_YMin; } } + OBSOLETE warning use yMax + CSRAW public float bottom { get { return m_YMin + m_Height; } } + + // Left coordinate of the rectangle. + CSRAW public float xMin { get { return m_XMin; } set { float oldxmax = xMax; m_XMin = value; m_Width = oldxmax - m_XMin; } } + // Top coordinate of the rectangle. + CSRAW public float yMin { get { return m_YMin; } set { float oldymax = yMax; m_YMin = value; m_Height = oldymax - m_YMin; } } + // Right coordinate of the rectangle. + CSRAW public float xMax { get { return m_Width + m_XMin; } set { m_Width = value - m_XMin; } } + // Bottom coordinate of the rectangle. + CSRAW public float yMax { get { return m_Height + m_YMin; } set { m_Height = value - m_YMin; } } + + /// *listonly* + CSRAW override public string ToString() { return UnityString.Format("(x:{0:F2}, y:{1:F2}, width:{2:F2}, height:{3:F2})", x, y, width, height); } + // Returns a nicely formatted string for this Rect. + CSRAW public string ToString(string format) { + return UnityString.Format("(x:{0}, y:{1}, width:{2}, height:{3})", x.ToString(format), y.ToString(format), width.ToString(format), height.ToString(format)); + } + + /// *listonly* + CSRAW public bool Contains (Vector2 point) + { + return (point.x >= xMin) && (point.x < xMax) && (point.y >= yMin) && (point.y < yMax); + } + // Returns true if the /x/ and /y/ components of /point/ is a point inside this rectangle. + public bool Contains (Vector3 point) + { + return (point.x >= xMin) && (point.x < xMax) && (point.y >= yMin) && (point.y < yMax); + } + public bool Contains(Vector3 point, bool allowInverse) + { + if (!allowInverse) + { + return Contains(point); + } + bool xAxis = false; + if (width < 0f && (point.x <= xMin) && (point.x > xMax) || width >= 0f && (point.x >= xMin) && (point.x < xMax)) + xAxis = true; + if (xAxis && (height < 0f && (point.y <= yMin) && (point.y > yMax) || height >= 0f && (point.y >= yMin) && (point.y < yMax))) + return true; + return false; + } + // removed for 2.0 + // Clamp a point to be within a rectangle. +// CSRAW public Vector2 Clamp (Vector2 point) { +// return new Vector2 (Mathf.Clamp (point.x, left, xMax-1), Mathf.Clamp (point.y, yMin, yMax-1)); +// } + + // Swaps min and max if min was greater than max. + private static Rect OrderMinMax (Rect rect) + { + if (rect.xMin > rect.xMax) + { + float temp = rect.xMin; + rect.xMin = rect.xMax; + rect.xMax = temp; + } + if (rect.yMin > rect.yMax) + { + float temp = rect.yMin; + rect.yMin = rect.yMax; + rect.yMax = temp; + } + return rect; + } + + CSRAW public bool Overlaps (Rect other) + { + return (other.xMax > xMin && + other.xMin < xMax && + other.yMax > yMin && + other.yMin < yMax); + } + + CSRAW public bool Overlaps (Rect other, bool allowInverse) + { + Rect self = this; + if (allowInverse) + { + self = OrderMinMax (self); + other = OrderMinMax (other); + } + return self.Overlaps (other); + } + + // Returns true if the rectangles are different. + CSRAW public static bool operator != (Rect lhs, Rect rhs) + { + return lhs.x != rhs.x || lhs.y != rhs.y || lhs.width != rhs.width || lhs.height != rhs.height; + } + + // Returns true if the rectangles are the same. + CSRAW public static bool operator == (Rect lhs, Rect rhs) { + return lhs.x == rhs.x && lhs.y == rhs.y && lhs.width == rhs.width && lhs.height == rhs.height; + } + + public override int GetHashCode() { + return x.GetHashCode() ^ (width.GetHashCode()<<2) ^ (y.GetHashCode()>>2) ^ (height.GetHashCode()>>1); + } + + public override bool Equals(object other) { + if(!(other is Rect)) return false; + + Rect rhs=(Rect)other; + return x.Equals(rhs.x) && y.Equals(rhs.y) && width.Equals(rhs.width) && height.Equals(rhs.height); + } +END + + +// A standard 4x4 transformation matrix. +THREAD_SAFE +STRUCT Matrix4x4 + CSRAW + ///*undocumented* + public float m00; + ///*undocumented* + public float m10; + ///*undocumented* + public float m20; + ///*undocumented* + public float m30; + + ///*undocumented* + public float m01; + ///*undocumented* + public float m11; + ///*undocumented* + public float m21; + ///*undocumented* + public float m31; + + ///*undocumented* + public float m02; + ///*undocumented* + public float m12; + ///*undocumented* + public float m22; + ///*undocumented* + public float m32; + + ///*undocumented* + public float m03; + ///*undocumented* + public float m13; + ///*undocumented* + public float m23; + ///*undocumented* + public float m33; + + + CSRAW + // Access element at [row, column]. + public float this [int row, int column] + { + get + { + return this [ row + column*4 ]; + } + + set + { + this [ row + column*4 ] = value; + } + } + + // Access element at sequential index (0..15 inclusive). + CSRAW public float this [int index] + { + get + { + switch(index) + { + case 0: return m00; + case 1: return m10; + case 2: return m20; + case 3: return m30; + case 4: return m01; + case 5: return m11; + case 6: return m21; + case 7: return m31; + case 8: return m02; + case 9: return m12; + case 10:return m22; + case 11:return m32; + case 12:return m03; + case 13:return m13; + case 14:return m23; + case 15:return m33; + default: + throw new IndexOutOfRangeException("Invalid matrix index!"); + } + } + + set + { + switch(index) + { + case 0: m00 = value; break; + case 1: m10 = value; break; + case 2: m20 = value; break; + case 3: m30 = value; break; + case 4: m01 = value; break; + case 5: m11 = value; break; + case 6: m21 = value; break; + case 7: m31 = value; break; + case 8: m02 = value; break; + case 9: m12 = value; break; + case 10:m22 = value; break; + case 11:m32 = value; break; + case 12:m03 = value; break; + case 13:m13 = value; break; + case 14:m23 = value; break; + case 15:m33 = value; break; + + default: + throw new IndexOutOfRangeException("Invalid matrix index!"); + } + } + } + + // used to allow Matrix4x4s to be used as keys in hash tables + public override int GetHashCode() { + return GetColumn( 0 ).GetHashCode() ^ (GetColumn( 1 ).GetHashCode()<<2) ^ (GetColumn( 2 ).GetHashCode()>>2) ^ (GetColumn( 3 ).GetHashCode()>>1); + } + + // also required for being able to use Matrix4x4s as keys in hash tables + public override bool Equals(object other) { + if(!(other is Matrix4x4)) return false; + + Matrix4x4 rhs=(Matrix4x4)other; + return GetColumn( 0 ).Equals(rhs.GetColumn( 0 )) + && GetColumn( 1 ).Equals(rhs.GetColumn( 1 )) + && GetColumn( 2 ).Equals(rhs.GetColumn( 2 )) + && GetColumn( 3 ).Equals(rhs.GetColumn( 3 )); + } + + // Multiplies two matrices. + CSRAW static public Matrix4x4 operator * (Matrix4x4 lhs, Matrix4x4 rhs) + { + Matrix4x4 res = new Matrix4x4(); + res.m00 = lhs.m00 * rhs.m00 + lhs.m01 * rhs.m10 + lhs.m02 * rhs.m20 + lhs.m03 * rhs.m30; + res.m01 = lhs.m00 * rhs.m01 + lhs.m01 * rhs.m11 + lhs.m02 * rhs.m21 + lhs.m03 * rhs.m31; + res.m02 = lhs.m00 * rhs.m02 + lhs.m01 * rhs.m12 + lhs.m02 * rhs.m22 + lhs.m03 * rhs.m32; + res.m03 = lhs.m00 * rhs.m03 + lhs.m01 * rhs.m13 + lhs.m02 * rhs.m23 + lhs.m03 * rhs.m33; + + res.m10 = lhs.m10 * rhs.m00 + lhs.m11 * rhs.m10 + lhs.m12 * rhs.m20 + lhs.m13 * rhs.m30; + res.m11 = lhs.m10 * rhs.m01 + lhs.m11 * rhs.m11 + lhs.m12 * rhs.m21 + lhs.m13 * rhs.m31; + res.m12 = lhs.m10 * rhs.m02 + lhs.m11 * rhs.m12 + lhs.m12 * rhs.m22 + lhs.m13 * rhs.m32; + res.m13 = lhs.m10 * rhs.m03 + lhs.m11 * rhs.m13 + lhs.m12 * rhs.m23 + lhs.m13 * rhs.m33; + + res.m20 = lhs.m20 * rhs.m00 + lhs.m21 * rhs.m10 + lhs.m22 * rhs.m20 + lhs.m23 * rhs.m30; + res.m21 = lhs.m20 * rhs.m01 + lhs.m21 * rhs.m11 + lhs.m22 * rhs.m21 + lhs.m23 * rhs.m31; + res.m22 = lhs.m20 * rhs.m02 + lhs.m21 * rhs.m12 + lhs.m22 * rhs.m22 + lhs.m23 * rhs.m32; + res.m23 = lhs.m20 * rhs.m03 + lhs.m21 * rhs.m13 + lhs.m22 * rhs.m23 + lhs.m23 * rhs.m33; + + res.m30 = lhs.m30 * rhs.m00 + lhs.m31 * rhs.m10 + lhs.m32 * rhs.m20 + lhs.m33 * rhs.m30; + res.m31 = lhs.m30 * rhs.m01 + lhs.m31 * rhs.m11 + lhs.m32 * rhs.m21 + lhs.m33 * rhs.m31; + res.m32 = lhs.m30 * rhs.m02 + lhs.m31 * rhs.m12 + lhs.m32 * rhs.m22 + lhs.m33 * rhs.m32; + res.m33 = lhs.m30 * rhs.m03 + lhs.m31 * rhs.m13 + lhs.m32 * rhs.m23 + lhs.m33 * rhs.m33; + + return res; + } + + // Transforms a [[Vector4]] by a matrix. + CSRAW static public Vector4 operator * (Matrix4x4 lhs, Vector4 v) + { + Vector4 res; + res.x = lhs.m00 * v.x + lhs.m01 * v.y + lhs.m02 * v.z + lhs.m03 * v.w; + res.y = lhs.m10 * v.x + lhs.m11 * v.y + lhs.m12 * v.z + lhs.m13 * v.w; + res.z = lhs.m20 * v.x + lhs.m21 * v.y + lhs.m22 * v.z + lhs.m23 * v.w; + res.w = lhs.m30 * v.x + lhs.m31 * v.y + lhs.m32 * v.z + lhs.m33 * v.w; + return res; + } + + //*undoc* + CSRAW public static bool operator == (Matrix4x4 lhs, Matrix4x4 rhs) + { + return lhs.GetColumn( 0 ) == rhs.GetColumn( 0 ) + && lhs.GetColumn( 1 ) == rhs.GetColumn( 1 ) + && lhs.GetColumn( 2 ) == rhs.GetColumn( 2 ) + && lhs.GetColumn( 3 ) == rhs.GetColumn( 3 ); + } + //*undoc* + CSRAW public static bool operator != (Matrix4x4 lhs, Matrix4x4 rhs) + { + return !(lhs == rhs); + } + + //*undocumented* --- have a property now + CUSTOM static Matrix4x4 Inverse (Matrix4x4 m) { Matrix4x4f output (m); output.Invert_Full(); return output; } + //*undocumented* --- have a property now + CUSTOM static Matrix4x4 Transpose (Matrix4x4 m) { Matrix4x4f output (m); output.Transpose(); return output; } + + // Invert a matrix and return the success code. + CUSTOM internal static bool Invert (Matrix4x4 inMatrix, out Matrix4x4 dest) { return Matrix4x4f::Invert_Full(inMatrix, *dest); } + + // The inverse of this matrix (RO). + CSRAW public Matrix4x4 inverse { get { return Matrix4x4.Inverse (this); } } + + // Returns the transpose of this matrix (RO). + CSRAW public Matrix4x4 transpose { get { return Matrix4x4.Transpose (this); } } + + // Is this the identity matrix? + CUSTOM_PROP bool isIdentity { return self.IsIdentity(); } + + // Get a column of the matrix. + CSRAW public Vector4 GetColumn (int i) { return new Vector4 (this[0, i], this[1, i], this[2, i], this[3, i]); } + // Returns a row of the matrix. + CSRAW public Vector4 GetRow (int i) { return new Vector4 (this[i, 0], this[i, 1], this[i, 2], this[i, 3]); } + // Sets a column of the matrix. + CSRAW public void SetColumn (int i, Vector4 v) { this[0, i] = v.x; this[1, i] = v.y; this[2, i] = v.z; this[3, i] = v.w; } + // Sets a row of the matrix. + CSRAW public void SetRow (int i, Vector4 v){ this[i, 0] = v.x; this[i, 1] = v.y; this[i, 2] = v.z; this[i, 3] = v.w; } + + + // Transforms a position by this matrix (generic). + CSRAW public Vector3 MultiplyPoint (Vector3 v) + { + Vector3 res; + float w; + res.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03; + res.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13; + res.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23; + w = this.m30 * v.x + this.m31 * v.y + this.m32 * v.z + this.m33; + + w = 1F / w; + res.x *= w; + res.y *= w; + res.z *= w; + return res; + } + + // Transforms a position by this matrix (fast). + CSRAW public Vector3 MultiplyPoint3x4 (Vector3 v) + { + Vector3 res; + res.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z + this.m03; + res.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z + this.m13; + res.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z + this.m23; + return res; + } + + // Transforms a direction by this matrix. + CSRAW public Vector3 MultiplyVector (Vector3 v) + { + Vector3 res; + res.x = this.m00 * v.x + this.m01 * v.y + this.m02 * v.z; + res.y = this.m10 * v.x + this.m11 * v.y + this.m12 * v.z; + res.z = this.m20 * v.x + this.m21 * v.y + this.m22 * v.z; + return res; + } + + // Creates a scaling matrix. + CSRAW static public Matrix4x4 Scale (Vector3 v) + { + Matrix4x4 m = new Matrix4x4(); + m.m00 = v.x; m.m01 = 0F; m.m02 = 0F; m.m03 = 0F; + m.m10 = 0F; m.m11 = v.y; m.m12 = 0F; m.m13 = 0F; + m.m20 = 0F; m.m21 = 0F; m.m22 = v.z; m.m23 = 0F; + m.m30 = 0F; m.m31 = 0F; m.m32 = 0F; m.m33 = 1F; + return m; + } + + // Returns a matrix with all elements set to zero (RO). + CSRAW public static Matrix4x4 zero { + get + { + Matrix4x4 m = new Matrix4x4(); + m.m00 = 0F; m.m01 = 0F; m.m02 = 0F; m.m03 = 0F; + m.m10 = 0F; m.m11 = 0F; m.m12 = 0F; m.m13 = 0F; + m.m20 = 0F; m.m21 = 0F; m.m22 = 0F; m.m23 = 0F; + m.m30 = 0F; m.m31 = 0F; m.m32 = 0F; m.m33 = 0F; + return m; + } + } + + // Returns the identity matrix (RO). + CSRAW public static Matrix4x4 identity { + get + { + Matrix4x4 m = new Matrix4x4(); + m.m00 = 1F; m.m01 = 0F; m.m02 = 0F; m.m03 = 0F; + m.m10 = 0F; m.m11 = 1F; m.m12 = 0F; m.m13 = 0F; + m.m20 = 0F; m.m21 = 0F; m.m22 = 1F; m.m23 = 0F; + m.m30 = 0F; m.m31 = 0F; m.m32 = 0F; m.m33 = 1F; + return m; + } + } + + // Sets this matrix to a translation, rotation and scaling matrix. + CSRAW public void SetTRS(Vector3 pos, Quaternion q, Vector3 s) + { + this = Matrix4x4.TRS(pos, q, s); + } + + // Creates a translation, rotation and scaling matrix. + CUSTOM static Matrix4x4 TRS(Vector3 pos, Quaternion q, Vector3 s) + { + Matrix4x4f temp; + temp.SetTRS(pos,q,s); + return temp; + } + + /// *listonly* + CSRAW override public string ToString() { + return UnityString.Format("{0:F5}\t{1:F5}\t{2:F5}\t{3:F5}\n{4:F5}\t{5:F5}\t{6:F5}\t{7:F5}\n{8:F5}\t{9:F5}\t{10:F5}\t{11:F5}\n{12:F5}\t{13:F5}\t{14:F5}\t{15:F5}\n", m00, m01, m02, m03, m10, m11, m12, m13, m20, m21, m22, m23, m30, m31, m32, m33); + } + // Returns a nicely formatted string for this matrix. + CSRAW public string ToString(string format) { + return UnityString.Format("{0}\t{1}\t{2}\t{3}\n{4}\t{5}\t{6}\t{7}\n{8}\t{9}\t{10}\t{11}\n{12}\t{13}\t{14}\t{15}\n", + m00.ToString(format), m01.ToString(format), m02.ToString(format), m03.ToString(format), + m10.ToString(format), m11.ToString(format), m12.ToString(format), m13.ToString(format), + m20.ToString(format), m21.ToString(format), m22.ToString(format), m23.ToString(format), + m30.ToString(format), m31.ToString(format), m32.ToString(format), m33.ToString(format)); + } + + // Creates an orthogonal projection matrix. + CUSTOM static public Matrix4x4 Ortho (float left, float right, float bottom, float top, float zNear, float zFar) { + Matrix4x4f m; + m.SetOrtho(left, right, bottom, top, zNear, zFar); + return m; + } + + // Creates a perspective projection matrix. + CUSTOM static public Matrix4x4 Perspective (float fov, float aspect, float zNear, float zFar) { + Matrix4x4f m; + m.SetPerspective( fov, aspect, zNear, zFar ); + return m; + } +END + + +// Represents an axis aligned bounding box. +THREAD_SAFE +STRUCT Bounds + + CSRAW private Vector3 m_Center; + CSRAW private Vector3 m_Extents; + + // Creates new Bounds with a given /center/ and total /size/. Bound ::ref::extents will be half the given size. + CSRAW public Bounds (Vector3 center, Vector3 size) + { + m_Center = center; + m_Extents = size * 0.5F; + } + + // used to allow Bounds to be used as keys in hash tables + public override int GetHashCode() { + return center.GetHashCode() ^ (extents.GetHashCode()<<2); + } + + // also required for being able to use Vector4s as keys in hash tables + public override bool Equals(object other) { + if(!(other is Bounds)) return false; + + Bounds rhs=(Bounds)other; + return center.Equals(rhs.center) && extents.Equals(rhs.extents); + } + + // The center of the bounding box. + CSRAW public Vector3 center { get { return m_Center; } set { m_Center = value; } } + + // The total size of the box. This is always twice as large as the ::ref::extents. + CSRAW public Vector3 size { get { return m_Extents * 2.0F; } set { m_Extents = value * 0.5F; } } + + // The extents of the box. This is always half of the ::ref::size. + CSRAW public Vector3 extents { get { return m_Extents; } set { m_Extents = value; } } + + // The minimal point of the box. This is always equal to ''center-extents''. + CSRAW public Vector3 min { get { return center - extents; } set { SetMinMax (value, max); } } + // The maximal point of the box. This is always equal to ''center+extents''. + CSRAW public Vector3 max { get { return center + extents; } set { SetMinMax (min, value); } } + + //*undoc* + CSRAW public static bool operator == (Bounds lhs, Bounds rhs) + { + return (lhs.center == rhs.center && lhs.extents == rhs.extents); + } + //*undoc* + CSRAW public static bool operator != (Bounds lhs, Bounds rhs) + { + return !(lhs == rhs); + } + + // Sets the bounds to the /min/ and /max/ value of the box. + CSRAW public void SetMinMax (Vector3 min, Vector3 max) + { + extents = (max - min) * 0.5F; + center = min + extents; + } + + // Grows the Bounds to include the /point/. + CSRAW public void Encapsulate (Vector3 point) + { + SetMinMax(Vector3.Min (min, point), Vector3.Max (max, point)); + } + + // Grow the bounds to encapsulate the bounds. + CSRAW public void Encapsulate (Bounds bounds) { + Encapsulate (bounds.center - bounds.extents); + Encapsulate (bounds.center + bounds.extents); + } + + // Expand the bounds by increasing its /size/ by /amount/ along each side. + CSRAW public void Expand (float amount) { + amount *= .5f; + extents += new Vector3 (amount, amount, amount); + } + + // Expand the bounds by increasing its /size/ by /amount/ along each side. + CSRAW public void Expand (Vector3 amount) { + extents += amount * .5f; + } + + // Does another bounding box intersect with this bounding box? + CSRAW public bool Intersects (Bounds bounds) { + return (min.x <= bounds.max.x) && (max.x >= bounds.min.x) && + (min.y <= bounds.max.y) && (max.y >= bounds.min.y) && + (min.z <= bounds.max.z) && (max.z >= bounds.min.z); + } + + CUSTOM private static bool Internal_Contains (Bounds m, Vector3 point) { return m.IsInside (point); } + // Is /point/ contained in the bounding box? + CSRAW public bool Contains (Vector3 point) { return Internal_Contains (this, point); } + + CUSTOM private static float Internal_SqrDistance (Bounds m, Vector3 point) { return CalculateSqrDistance(point, m); } + + // The smallest squared distance between the point and this bounding box. + CSRAW public float SqrDistance (Vector3 point) { return Internal_SqrDistance(this, point); } + + CUSTOM private static bool Internal_IntersectRay (ref Ray ray, ref Bounds bounds, out float distance) { return IntersectRayAABB(ray, bounds, distance); } + + // Does /ray/ intersect this bounding box? + CSRAW public bool IntersectRay (Ray ray) { float dist; return Internal_IntersectRay (ref ray, ref this, out dist); } + + // Does /ray/ intersect this bounding box? + CSRAW public bool IntersectRay (Ray ray, out float distance) { return Internal_IntersectRay (ref ray, ref this, out distance); } + + /// *listonly* + CSRAW override public string ToString() { + return UnityString.Format("Center: {0}, Extents: {1}", m_Center, m_Extents); + } + // Returns a nicely formatted string for the bounds. + CSRAW public string ToString(string format) { + return UnityString.Format("Center: {0}, Extents: {1}", m_Center.ToString(format), m_Extents.ToString(format)); + } + + +END + + + +// Representation of four-dimensional vectors. +THREAD_SAFE +STRUCT Vector4 + + // *undocumented* + CSRAW public const float kEpsilon = 0.00001F; + + // X component of the vector. + CSRAW public float x; + // Y component of the vector. + CSRAW public float y; + // Z component of the vector. + CSRAW public float z; + // W component of the vector. + CSRAW public float w; + + // Access the x, y, z, w components using [0], [1], [2], [3] respectively. + CSRAW public float this [int index] + { + get + { + switch(index) + { + case 0: return x; + case 1: return y; + case 2: return z; + case 3: return w; + default: + throw new IndexOutOfRangeException("Invalid Vector4 index!"); + } + } + + set + { + switch(index) + { + case 0: x = value; break; + case 1: y = value; break; + case 2: z = value; break; + case 3: w = value; break; + default: + throw new IndexOutOfRangeException("Invalid Vector4 index!"); + } + } + } + + // Creates a new vector with given x, y, z, w components. + CSRAW public Vector4 (float x, float y, float z, float w) { this.x = x; this.y = y; this.z = z; this.w = w; } + // Creates a new vector with given x, y, z components and sets /w/ to zero. + CSRAW public Vector4 (float x, float y, float z) { this.x = x; this.y = y; this.z = z; this.w = 0F; } + // Creates a new vector with given x, y components and sets /z/ and /w/ to zero. + CSRAW public Vector4 (float x, float y) { this.x = x; this.y = y; this.z = 0F; this.w = 0F; } + + // Set x, y, z and w components of an existing Vector4. + CSRAW public void Set (float new_x, float new_y, float new_z, float new_w) { x = new_x; y = new_y; z = new_z; w = new_w; } + + // Linearly interpolates between two vectors. + CSRAW public static Vector4 Lerp (Vector4 from, Vector4 to, float t) + { + t = Mathf.Clamp01 (t); + return new Vector4( + from.x + (to.x - from.x)*t, + from.y + (to.y - from.y)*t, + from.z + (to.z - from.z)*t, + from.w + (to.w - from.w)*t + ); + } + + // Moves a point /current/ towards /target/. + CSRAW static public Vector4 MoveTowards (Vector4 current, Vector4 target, float maxDistanceDelta) + { + Vector4 toVector = target - current; + float dist = toVector.magnitude; + if (dist <= maxDistanceDelta || dist == 0) + return target; + return current + toVector / dist * maxDistanceDelta; + } + + // Multiplies two vectors component-wise. + CSRAW public static Vector4 Scale (Vector4 a, Vector4 b) { return new Vector4 (a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w); } + // Multiplies every component of this vector by the same component of /scale/. + CSRAW public void Scale (Vector4 scale) { x *= scale.x; y *= scale.y; z *= scale.z; w *= scale.w; } + + + // used to allow Vector4s to be used as keys in hash tables + public override int GetHashCode() { + return x.GetHashCode() ^ (y.GetHashCode()<<2) ^ (z.GetHashCode()>>2) ^ (w.GetHashCode()>>1); + } + + // also required for being able to use Vector4s as keys in hash tables + public override bool Equals(object other) { + if(!(other is Vector4)) return false; + + Vector4 rhs=(Vector4)other; + return x.Equals(rhs.x) && y.Equals(rhs.y) && z.Equals(rhs.z) && w.Equals(rhs.w); + } + + // *undoc* --- we have normalized property now + CSRAW public static Vector4 Normalize (Vector4 a) + { + float mag = Magnitude (a); + if (mag > kEpsilon) + return a / mag; + else + return zero; + } + + // Makes this vector have a ::ref::magnitude of 1. + CSRAW public void Normalize () + { + float mag = Magnitude (this); + if (mag > kEpsilon) + this = this / mag; + else + this = zero; + } + + // Returns this vector with a ::ref::magnitude of 1 (RO). + CSRAW public Vector4 normalized { get { return Vector4.Normalize(this); } } + + + /// *listonly* + CSRAW override public string ToString() { + return UnityString.Format("({0:F1}, {1:F1}, {2:F1}, {3:F1})", x, y, z, w); + } + // Returns a nicely formatted string for this vector. + CSRAW public string ToString(string format) { + return UnityString.Format("({0}, {1}, {2}, {3})", x.ToString(format), y.ToString(format), z.ToString(format), w.ToString(format)); + } + + + // Dot Product of two vectors. + CSRAW public static float Dot (Vector4 a, Vector4 b) { return a.x*b.x + a.y*b.y + a.z*b.z + a.w*b.w; } + + // Projects a vector onto another vector. + CSRAW public static Vector4 Project (Vector4 a, Vector4 b) { return b * Dot (a, b) / Dot (b, b); } + + // Returns the distance between /a/ and /b/. + CSRAW public static float Distance (Vector4 a, Vector4 b) { return Magnitude (a-b); } + + // *undoc* --- there's a property now + CSRAW public static float Magnitude (Vector4 a) { return Mathf.Sqrt (Dot (a, a)); } + + // Returns the length of this vector (RO). + CSRAW public float magnitude { get { return Mathf.Sqrt (Dot (this, this)); } } + + // *undoc* --- there's a property now + CSRAW public static float SqrMagnitude (Vector4 a) { return Vector4.Dot (a, a); } + // *undoc* --- there's a property now + CSRAW public float SqrMagnitude () { return Dot (this, this); } + + // Returns the squared length of this vector (RO). + CSRAW public float sqrMagnitude { get { return Dot (this, this); } } + + + // Returns a vector that is made from the smallest components of two vectors. + CSRAW public static Vector4 Min (Vector4 lhs, Vector4 rhs) { return new Vector4 (Mathf.Min(lhs.x,rhs.x), Mathf.Min(lhs.y,rhs.y), Mathf.Min(lhs.z,rhs.z), Mathf.Min(lhs.w,rhs.w)); } + + // Returns a vector that is made from the largest components of two vectors. + CSRAW public static Vector4 Max (Vector4 lhs, Vector4 rhs) { return new Vector4 (Mathf.Max(lhs.x,rhs.x), Mathf.Max(lhs.y,rhs.y), Mathf.Max(lhs.z,rhs.z), Mathf.Max(lhs.w,rhs.w)); } + + // Shorthand for writing @@Vector4(0,0,0,0)@@ + CSRAW public static Vector4 zero { get { return new Vector4 (0F, 0F, 0F, 0F); } } + // Shorthand for writing @@Vector4(1,1,1,1)@@ + CSRAW public static Vector4 one { get { return new Vector4 (1F, 1F, 1F, 1F); } } + + + // Adds two vectors. + CSRAW public static Vector4 operator + (Vector4 a, Vector4 b) { return new Vector4 (a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w); } + // Subtracts one vector from another. + CSRAW public static Vector4 operator - (Vector4 a, Vector4 b) { return new Vector4 (a.x-b.x, a.y-b.y, a.z-b.z, a.w-b.w); } + // Negates a vector. + CSRAW public static Vector4 operator - (Vector4 a) { return new Vector4 (-a.x, -a.y, -a.z, -a.w); } + // Multiplies a vector by a number. + CSRAW public static Vector4 operator * (Vector4 a, float d) { return new Vector4 (a.x*d, a.y*d, a.z*d, a.w*d); } + // Multiplies a vector by a number. + CSRAW public static Vector4 operator * (float d, Vector4 a) { return new Vector4 (a.x*d, a.y*d, a.z*d, a.w*d); } + // Divides a vector by a number. + CSRAW public static Vector4 operator / (Vector4 a, float d) { return new Vector4 (a.x/d, a.y/d, a.z/d, a.w/d); } + + // Returns true if the vectors are equal. + CSRAW public static bool operator == (Vector4 lhs, Vector4 rhs) + { + return SqrMagnitude (lhs - rhs) < kEpsilon * kEpsilon; + } + // Returns true if vectors different. + CSRAW public static bool operator != (Vector4 lhs, Vector4 rhs) + { + return SqrMagnitude (lhs - rhs) >= kEpsilon * kEpsilon; + } + + // Converts a [[Vector3]] to a Vector4. + CSRAW public static implicit operator Vector4(Vector3 v) { + return new Vector4(v.x, v.y, v.z, 0.0F); + } + + // Converts a Vector4 to a [[Vector3]]. + CSRAW public static implicit operator Vector3(Vector4 v) { + return new Vector3(v.x, v.y, v.z); + } + + // Converts a [[Vector2]] to a Vector4. + CSRAW public static implicit operator Vector4(Vector2 v) { + return new Vector4(v.x, v.y, 0.0F, 0.0F); + } + + // Converts a Vector4 to a [[Vector2]]. + CSRAW public static implicit operator Vector2(Vector4 v) { + return new Vector2(v.x, v.y); + } + +END + + +// Representation of rays. +THREAD_SAFE +STRUCT Ray + CSRAW private Vector3 m_Origin; + CSRAW private Vector3 m_Direction; + + // Creates a ray starting at /origin/ along /direction/. + CSRAW public Ray (Vector3 origin, Vector3 direction) { m_Origin = origin; m_Direction = direction.normalized; } + + // The origin point of the ray. + CSRAW public Vector3 origin { get { return m_Origin; } set { m_Origin = value; } } + // The direction of the ray. + CSRAW public Vector3 direction { get { return m_Direction; } set { m_Direction = value.normalized; } } + + // Returns a point at /distance/ units along the ray. + CSRAW public Vector3 GetPoint (float distance) { return m_Origin + m_Direction * distance; } + + /// *listonly* + CSRAW override public string ToString() { return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin, m_Direction); } + // Returns a nicely formatted string for this ray. + CSRAW public string ToString(string format) { + return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin.ToString(format), m_Direction.ToString(format)); + } + +END + +// Representation of 2D rays. +THREAD_SAFE +STRUCT Ray2D + CSRAW private Vector2 m_Origin; + CSRAW private Vector2 m_Direction; + + // Creates a ray starting at /origin/ along /direction/. + CSRAW public Ray2D (Vector2 origin, Vector2 direction) { m_Origin = origin; m_Direction = direction.normalized; } + + // The origin point of the ray. + CSRAW public Vector2 origin { get { return m_Origin; } set { m_Origin = value; } } + + // The direction of the ray. + CSRAW public Vector2 direction { get { return m_Direction; } set { m_Direction = value.normalized; } } + + // Returns a point at /distance/ units along the ray. + CSRAW public Vector2 GetPoint (float distance) { return m_Origin + m_Direction * distance; } + + /// *listonly* + CSRAW override public string ToString() { return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin, m_Direction); } + + // Returns a nicely formatted string for this ray. + CSRAW public string ToString(string format) { + return UnityString.Format("Origin: {0}, Dir: {1}", m_Origin.ToString(format), m_Direction.ToString(format)); + } + +END + +// Representation of planes. +THREAD_SAFE +STRUCT Plane + CSRAW Vector3 m_Normal; + CSRAW float m_Distance; + + // Normal vector of the plane. + CSRAW public Vector3 normal { get { return m_Normal; } set { m_Normal = value; } } + // Distance from the origin to the plane. + CSRAW public float distance { get { return m_Distance; } set { m_Distance = value; } } + + // Creates a plane. + public Plane (Vector3 inNormal, Vector3 inPoint) { + m_Normal = Vector3.Normalize (inNormal); + m_Distance = -Vector3.Dot (inNormal, inPoint); + } + + // Creates a plane. + public Plane (Vector3 inNormal, float d) { + m_Normal = Vector3.Normalize (inNormal); + m_Distance = d; + } + + // Creates a plane. + public Plane (Vector3 a, Vector3 b, Vector3 c) { + m_Normal = Vector3.Normalize (Vector3.Cross (b - a, c - a)); + m_Distance = -Vector3.Dot (m_Normal, a); + } + + // Sets a plane using a point that lies within it plus a normal to orient it (note that the normal must be a normalised vector). + public void SetNormalAndPosition (Vector3 inNormal, Vector3 inPoint) { + normal = Vector3.Normalize (inNormal); + distance = -Vector3.Dot (inNormal, inPoint); + } + + // Sets a plane using three points that lie within it. The points go around clockwise as you look down on the top surface of the plane. + public void Set3Points (Vector3 a, Vector3 b, Vector3 c) { + normal = Vector3.Normalize (Vector3.Cross (b - a, c - a)); + distance = -Vector3.Dot (normal, a); + } + + // Returns a signed distance from plane to point. + public float GetDistanceToPoint (Vector3 inPt) { return Vector3.Dot (normal, inPt) + distance; } + + // Is a point on the positive side of the plane? + public bool GetSide (Vector3 inPt) { return Vector3.Dot (normal, inPt) + distance > 0.0F; } + + // Are two points on the same side of the plane? + public bool SameSide (Vector3 inPt0, Vector3 inPt1) { + float d0 = GetDistanceToPoint(inPt0); + float d1 = GetDistanceToPoint(inPt1); + if (d0 > 0.0f && d1 > 0.0f) + return true; + else if (d0 <= 0.0f && d1 <= 0.0f) + return true; + else + return false; + } + + // Intersects a ray with the plane. + public bool Raycast (Ray ray, out float enter) { + float vdot = Vector3.Dot (ray.direction, normal); + float ndot = -Vector3.Dot (ray.origin, normal) - distance; + + // is line parallel to the plane? if so, even if the line is + // at the plane it is not considered as intersection because + // it would be impossible to determine the point of intersection + if ( Mathf.Approximately (vdot, 0.0f) ) { + enter = 0.0F; + return false; + } + + // the resulting intersection is behind the origin of the ray + // if the result is negative ( enter < 0 ) + enter = ndot / vdot; + + return enter > 0.0F; + } + +END + + +// A collection of common math functions. +THREAD_SAFE +STRUCT Mathf + CSRAW + + // Returns the sine of angle /f/ in radians. + CSRAW public static float Sin (float f) { return (float)Math.Sin (f); } + + // Returns the cosine of angle /f/ in radians. + CSRAW public static float Cos (float f) { return (float)Math.Cos (f); } + + // Returns the tangent of angle /f/ in radians. + CSRAW public static float Tan (float f) { return (float)Math.Tan (f); } + + // Returns the arc-sine of /f/ - the angle in radians whose sine is /f/. + CSRAW public static float Asin (float f) { return (float)Math.Asin (f); } + + // Returns the arc-cosine of /f/ - the angle in radians whose cosine is /f/. + CSRAW public static float Acos (float f) { return (float)Math.Acos (f); } + + // Returns the arc-tangent of /f/ - the angle in radians whose tangent is /f/. + CSRAW public static float Atan (float f) { return (float)Math.Atan (f); } + + // Returns the angle in radians whose ::ref::Tan is @@y/x@@. + CSRAW public static float Atan2 (float y, float x) { return (float)Math.Atan2 (y,x); } + + // Returns square root of /f/. + CSRAW public static float Sqrt (float f) { return (float)Math.Sqrt (f); } + + // Returns the absolute value of /f/. + CSRAW public static float Abs (float f) { return (float)Math.Abs (f); } + + // Returns the absolute value of /value/. + CSRAW public static int Abs (int value) { return Math.Abs (value); } + + /// *listonly* + CSRAW public static float Min (float a, float b) { return a < b ? a : b; } + // Returns the smallest of two or more values. + CSRAW public static float Min (params float[] values) + { + int len = values.Length; // cache the length + if (len == 0) + return 0; + float m = values[0]; + for (int i=1; i<len; i++) + { + if (values[i] < m) + m = values[i]; + } + return m; + } + + /// *listonly* + CSRAW public static int Min (int a, int b) { return a < b ? a : b; } + // Returns the smallest of two or more values. + CSRAW public static int Min (params int[] values) + { + int len = values.Length; // cache the length + if (len == 0) + return 0; + int m = values[0]; + for (int i=1; i<len; i++) + { + if (values[i] < m) + m = values[i]; + } + return m; + } + + /// *listonly* + CSRAW public static float Max (float a, float b) { return a > b ? a : b; } + // Returns largest of two or more values. + CSRAW public static float Max (params float[] values) + { + int len = values.Length; // cache the length + if (len == 0) + return 0; + float m = values[0]; + for (int i=1; i<len; i++) + { + if (values[i] > m) + m = values[i]; + } + return m; + } + + /// *listonly* + CSRAW public static int Max (int a, int b) { return a > b ? a : b; } + // Returns the largest of two or more values. + CSRAW public static int Max (params int[] values) + { + int len = values.Length; // cache the length + if (len == 0) + return 0; + int m = values[0]; + for (int i=1; i<len; i++) + { + if (values[i] > m) + m = values[i]; + } + return m; + } + + // Returns /f/ raised to power /p/. + CSRAW public static float Pow (float f, float p) { return (float)Math.Pow (f, p); } + + // Returns e raised to the specified power. + CSRAW public static float Exp (float power) { return (float)Math.Exp (power); } + + // Returns the logarithm of a specified number in a specified base. + CSRAW public static float Log (float f, float p) { return (float)Math.Log (f, p); } + + // Returns the natural (base e) logarithm of a specified number. + CSRAW public static float Log (float f) { return (float)Math.Log (f); } + + // Returns the base 10 logarithm of a specified number. + CSRAW public static float Log10 (float f) { return (float)Math.Log10 (f); } + + // Returns the smallest integer greater to or equal to /f/. + CSRAW public static float Ceil (float f) { return (float)Math.Ceiling (f); } + + // Returns the largest integer smaller to or equal to /f/. + CSRAW public static float Floor (float f) { return (float)Math.Floor (f); } + + // Returns /f/ rounded to the nearest integer. + CSRAW public static float Round (float f) { return (float)Math.Round (f); } + + // Returns the smallest integer greater to or equal to /f/. + CSRAW public static int CeilToInt (float f) { return (int)Math.Ceiling (f); } + + // Returns the largest integer smaller to or equal to /f/. + CSRAW public static int FloorToInt (float f) { return (int)Math.Floor (f); } + + // Returns /f/ rounded to the nearest integer. + CSRAW public static int RoundToInt (float f) { return (int)Math.Round (f); } + + // Returns the sign of /f/. + CSRAW public static float Sign (float f) { return f >= 0F ? 1F : -1F; } + + // The infamous ''3.14159265358979...'' value (RO). + CSRAW public const float PI = (float)Math.PI; + + + // A representation of positive infinity (RO). + CSRAW public const float Infinity = Single.PositiveInfinity; + + + // A representation of negative infinity (RO). + CSRAW public const float NegativeInfinity = Single.NegativeInfinity; + + + // Degrees-to-radians conversion constant (RO). + CSRAW public const float Deg2Rad = PI * 2F / 360F; + + // Radians-to-degrees conversion constant (RO). + CSRAW public const float Rad2Deg = 1F / Deg2Rad; + + // A tiny floating point value (RO). + #if UNITY_IPHONE || UNITY_BB10 || UNITY_TIZEN + CSRAW public const float Epsilon = 1.17549435E-38f; // VFP rounds de-normlized values to 0, unfortunatelly Single.Epsilon is de-normalized value! + #else + CSRAW public const float Epsilon = Single.Epsilon; + #endif + + + // Clamps a value between a minimum float and maximum float value. + CSRAW public static float Clamp (float value, float min, float max) + { + if (value < min) + value = min; + else if (value > max) + value = max; + return value; + } + + // Clamps value between min and max and returns value. + // Set the position of the transform to be that of the time + // but never less than 1 or more than 3 + // + CSRAW public static int Clamp (int value, int min, int max) + { + if (value < min) + value = min; + else if (value > max) + value = max; + return value; + } + + // Clamps value between 0 and 1 and returns value + CSRAW public static float Clamp01 (float value) + { + if (value < 0F) + return 0F; + else if (value > 1F) + return 1F; + else + return value; + } + + // Interpolates between /a/ and /b/ by /t/. /t/ is clamped between 0 and 1. + CSRAW public static float Lerp (float from, float to, float t) + { + return from + (to - from) * Clamp01 (t); + } + + // Same as ::ref::Lerp but makes sure the values interpolate correctly when they wrap around 360 degrees. + CSRAW public static float LerpAngle (float a, float b, float t) + { + float delta = Repeat ((b - a), 360); + if (delta > 180) + delta -= 360; + return a + delta * Clamp01 (t); + } + + // Moves a value /current/ towards /target/. + CSRAW static public float MoveTowards (float current, float target, float maxDelta) + { + if (Mathf.Abs(target - current) <= maxDelta) + return target; + return current + Mathf.Sign(target - current) * maxDelta; + } + + // Same as ::ref::MoveTowards but makes sure the values interpolate correctly when they wrap around 360 degrees. + CSRAW static public float MoveTowardsAngle (float current, float target, float maxDelta) + { + target = current + DeltaAngle(current, target); + return MoveTowards(current, target, maxDelta); + } + + // Interpolates between /min/ and /max/ with smoothing at the limits. + CSRAW public static float SmoothStep (float from, float to, float t) + { + t = Mathf.Clamp01(t); + t = -2.0F * t*t*t + 3.0F * t*t; + return to * t + from * (1F - t); + } + + //*undocumented + CSRAW public static float Gamma (float value, float absmax, float gamma) + { + bool negative = false; + if (value < 0F) + negative = true; + float absval = Abs(value); + if (absval > absmax) + return negative ? -absval : absval; + + float result = Pow(absval / absmax, gamma) * absmax; + return negative ? -result : result; + } + + // Compares two floating point values if they are similar. + CSRAW public static bool Approximately (float a, float b) + { + // If a or b is zero, compare that the other is less or equal to epsilon. + // If neither a or b are 0, then find an epsilon that is good for + // comparing numbers at the maximum magnitude of a and b. + // Floating points have about 7 significant digits, so + // 1.000001f can be represented while 1.0000001f is rounded to zero, + // thus we could use an epsilon of 0.000001f for comparing values close to 1. + // We multiply this epsilon by the biggest magnitude of a and b. + return Abs(b - a) < Max( 0.000001f * Max(Abs(a), Abs(b)), Epsilon*8); + } + + // Gradually changes a value towards a desired goal over time. + CSRAW public static float SmoothDamp (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime) + { + // Based on Game Programming Gems 4 Chapter 1.10 + smoothTime = Mathf.Max(0.0001F, smoothTime); + float omega = 2F / smoothTime; + + float x = omega * deltaTime; + float exp = 1F / (1F + x + 0.48F*x*x + 0.235F*x*x*x); + float change = current - target; + float originalTo = target; + + // Clamp maximum speed + float maxChange = maxSpeed * smoothTime; + change = Mathf.Clamp(change, -maxChange, maxChange); + target = current - change; + + float temp = (currentVelocity + omega * change) * deltaTime; + currentVelocity = (currentVelocity - omega * temp) * exp; + float output = target + (change + temp) * exp; + + // Prevent overshooting + if (originalTo - current > 0.0F == output > originalTo) + { + output = originalTo; + currentVelocity = (output - originalTo) / deltaTime; + } + + return output; + } + + + // Gradually changes an angle given in degrees towards a desired goal angle over time. + CSRAW public static float SmoothDampAngle (float current, float target, ref float currentVelocity, float smoothTime, float maxSpeed = Mathf.Infinity, float deltaTime = Time.deltaTime) + { + // Normalize angles + target = current + DeltaAngle(current, target); + return SmoothDamp(current, target, ref currentVelocity, smoothTime, maxSpeed, deltaTime); + } + + // Loops the value t, so that it is never larger than length and never smaller than 0. + CSRAW public static float Repeat (float t, float length) + { + return t - Mathf.Floor (t / length) * length; + } + + // PingPongs the value t, so that it is never larger than length and never smaller than 0. + CSRAW public static float PingPong (float t, float length) + { + t = Repeat (t, length * 2F); + return length - Mathf.Abs (t - length); + } + + // Calculates the ::ref::Lerp parameter between of two values. + CSRAW public static float InverseLerp (float from, float to, float value) + { + if (from < to) + { + if (value < from) + return 0.0F; + else if (value > to) + return 1.0F; + else + { + value -= from; + value /= (to - from); + return value; + } + } + else if (from > to) + { + if (value < to) + return 1.0F; + else if (value > from) + return 0.0F; + else + { + return 1.0F - ((value - to) / (from - to)); + } + } + else + { + return 0.0F; + } + } + + // Returns the closest power of two value. + CUSTOM static int ClosestPowerOfTwo (int value) + { + return ClosestPowerOfTwo(value); + } + + // Converts the given value from gamma to linear color space. + CUSTOM static float GammaToLinearSpace (float value) + { + return GammaToLinearSpace (value); + } + + // Converts the given value from linear to gamma color space. + CUSTOM static float LinearToGammaSpace (float value) + { + return LinearToGammaSpace (value); + } + + // Returns true if the value is power of two. + CUSTOM static bool IsPowerOfTwo (int value) + { + return IsPowerOfTwo(value); + } + + // Returns the next power of two value + CUSTOM static int NextPowerOfTwo (int value) + { + return NextPowerOfTwo(value); + } + + // Calculates the shortest difference between two given angles. + CSRAW public static float DeltaAngle (float current, float target) + { + float delta = Mathf.Repeat ((target - current), 360.0F); + if (delta > 180.0F) + delta -= 360.0F; + return delta; + } + + // Generate 2D Perlin noise. + CUSTOM static float PerlinNoise (float x, float y) + { + return PerlinNoise::NoiseNormalized (x,y); + } + + + // Infinite Line Intersection (line1 is p1-p2 and line2 is p3-p4) + CSRAW internal static bool LineIntersection (Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result) + { + float bx = p2.x - p1.x; + float by = p2.y - p1.y; + float dx = p4.x - p3.x; + float dy = p4.y - p3.y; + float bDotDPerp = bx * dy - by * dx; + if (bDotDPerp == 0) + { + return false; + } + float cx = p3.x - p1.x; + float cy = p3.y - p1.y; + float t = (cx * dy - cy * dx) / bDotDPerp; + + result = new Vector2 (p1.x + t * bx, p1.y + t * by); + return true; + } + + // Line Segment Intersection (line1 is p1-p2 and line2 is p3-p4) + CSRAW internal static bool LineSegmentIntersection(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, ref Vector2 result) + { + float bx = p2.x - p1.x; + float by = p2.y - p1.y; + float dx = p4.x - p3.x; + float dy = p4.y - p3.y; + float bDotDPerp = bx * dy - by * dx; + if (bDotDPerp == 0) + { + return false; + } + float cx = p3.x - p1.x; + float cy = p3.y - p1.y; + float t = (cx * dy - cy * dx) / bDotDPerp; + if (t < 0 || t > 1) + { + return false; + } + float u = (cx * by - cy * bx) / bDotDPerp; + if (u < 0 || u > 1) + { + return false; + } + result = new Vector2(p1.x + t * bx, p1.y + t * by); + return true; + } +END +CSRAW +} diff --git a/Runtime/Export/MonoICallRegistration.cpp b/Runtime/Export/MonoICallRegistration.cpp new file mode 100644 index 0000000..435cb28 --- /dev/null +++ b/Runtime/Export/MonoICallRegistration.cpp @@ -0,0 +1,343 @@ +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "MonoICallRegistration.h" +#include "Runtime/Modules/ModuleRegistration.h" + +#if ENABLE_SCRIPTING && (ENABLE_MONO || UNITY_WINRT) + +// Generated by BuildPlayer for AOT platforms when we want +// to take advantage of dead code stripping of C++ code +void RegisterAllStrippedInternalCalls (); + +#if INTERNAL_CALL_STRIPPING + +void RegisterAllInternalCalls () +{ + RegisterAllStrippedInternalCalls(); + RegisterAllAvailableModuleICalls (); +} + +#else + +void ExportCrashReporter(); +void ExportAssetBundleBindings(); +void ExportCrashReporter(); +void ExportBaseClass(); +void ExportGradientBindings(); +void ExportGraphics(); +void ExportTextureBindings(); +void ExportGUI(); +void ExportEventBindings (); +void ExportGUIUtility(); +void ExportHandheld(); +void ExportGUILayoutUtility(); +void ExportGUISkinBindings(); +void ExportGUIStyleBindings(); +void ExportGizmoBindings(); +void ExportMath(); +void ExportNetworking(); +void ExportScriptAssets(); +void ExportUtility (); +void ExportAnimationRecorderBindings(); +void ExportUtils(); + +void ExportWiiDrive(); +void ExportiPhoneInput(); +void ExportiAD(); +void ExportAssetServer(); +void ExportEditorHandles(); +void ExportEditorHandlesUtility(); +void ExportEditorGUIUtility(); +void ExportSavedGUIState(); +void ExportEditorResourcesUtility(); +void ExportInternalUtility(); +void ExportShaderUtilBindings(); +void ExportMeshUtilityBindings(); +void ExportPrefabs(); +void ExportEditorApplication(); +void ExportBuildPipeline(); +void ExportSerializedObject(); +void ExportSerializedPropertyBindings(); +void ExportAssetDatabase(); +void ExportUtility_WIP(); +void ExportAnimationUtilityBindings(); +void ExportStateMachineBindings(); +void ExportAvatarAnimation(); +void ExportAnimatorControllerBindings(); +void ExportAvatarMaskBindings(); +void ExportBlendTreeBindings(); +void ExportMotionBindings(); +void ExportEditorWindow(); +void ExportWebView(); +void ExportAvatarUtility(); +void ExportAnimatorUtilityBindings(); +void ExportAvatar(); +void ExportAvatarBuilderBindings(); +void ExportAssetStoreUtils(); +void ExportAssetStoreToolUtilsBindings(); +void ExportProfilerAPI(); +void ExportPlayerSettings(); +void ExportXboxServices() {} +void ExportXboxKinect() {} +void ExportXboxAvatar() {} +void ExportXboxKeyboard(); +void ExportXboxVideoMode(); +void ExportPS3() {} +void ExportInternalEditorUtility(); +void ExportEditorMaterialUtility(); +void ExportInternalGraphUtility(); +void ExportFileUtil(); +void ExportEditorSettings (); +void ExportEditorUserSettings (); +void ExportAndroidInput(); +void ExportAndroidJNI(); +void ExportNavMeshBuilding(); +void ExportAnnotationUtility (); +void ExportUploadingBuildsUtility (); +void ExportShaderBindings (); +void ExportSubstanceEditorUtility(); +void ExportSubstanceUtility(); +void ExportGradientBindings(); +void ExportParticleSystemEditorBindings (); +void ExportParticleSystemBindings (); +void ExportUnityEngineAsyncOperation (); +void ExportUnityEngineApplication (); +void ExportUnityEngineObject (); +void ExportUnityEngineCamera (); +void ExportUnityEngineComponent (); +void ExportUnityEngineComputeShader (); +void ExportUnityEngineDisplay (); +void ExportUnityEngineTransform (); +void ExportUnityEngineGameObject (); +void ExportUnityEngineMetro(); +void ExportLODBindings (); +void ExportUnityEngineTime (); +void ExportUnityEngineBehaviour (); +void ExportUnityEngineMonoBehaviour (); +void ExportUnityEngineDebug (); +void ExportUnityEngineLight (); +void ExportUnityEngineRandom (); +void ExportUnityEngineInput (); +void ExportSpritesBindings (); +void ExportLODUtilityBindings (); +void ExportGameObjectUtilityBindings (); +void ExportComponentUtilityBindings (); +void ExportLightProbeBindings (); +void ExportVCAssetBindings (); +void ExportVCChangeSetBindings (); +void ExportVCProviderBindings (); +void ExportVCCustomCommandBindings (); +void ExportVCTaskBindings (); +void ExportVCMessageBindings (); +void ExportVCPluginBindings (); +void ExportAsyncHTTPClientBindings (); +void ExportAssetStoreContextBindings (); +void ExportUndoBindings (); +void ExportCursorBindings (); +void ExportAssetImporterBindings (); +void ExportAssetPreviewBindings (); +void ExportLicenseManagementWindow (); +void ExportEditorBindings (); +void ExportTerrainDataBindings (); +void ExportWindZoneBindings (); +void ExportSpritePackerBindings (); +void ExportSpritesBindingsEditor (); +void ExportPolygonEditorBindings(); +void ExportGameCenterServices(); +void ExportSerializedStateReader(); +void ExportSerializedStateWriter(); +void ExportPPtrRemapper(); +void ExportManagedLivenessAnalysis(); +void ExportSecurityPublic (); +void ExportPlayerPrefsBindings (); +void ExportHighlighterBindings (); + +void ExportAppTrial(); +void ExportWindowsFile(); +void ExportWindowsDirectory(); +void ExportWindowsCrypto(); +void ExportWSAApplication(); +void ExportWSATiles(); + +typedef void InternallCallMethod (); +static InternallCallMethod* sMonoBindingsRegistration[] = +{ + &ExportBaseClass, + &ExportCrashReporter, + &ExportAssetBundleBindings, + &ExportCrashReporter, + &ExportGradientBindings, + &ExportGraphics, + &ExportTextureBindings, + &ExportGUI, + &ExportGUIUtility, + &ExportGUILayoutUtility, + &ExportGUISkinBindings, + &ExportGUIStyleBindings, + &ExportEventBindings, + &ExportGizmoBindings, + &ExportMath, + &ExportParticleSystemBindings, + &ExportUnityEngineAsyncOperation, + &ExportUnityEngineObject, + &ExportUnityEngineCamera, + &ExportUnityEngineComponent, + &ExportUnityEngineComputeShader, + &ExportUnityEngineGameObject, + &ExportUnityEngineMonoBehaviour, + &ExportUnityEngineTransform, + &ExportLODBindings, + &ExportShaderBindings, + &ExportUnityEngineTime, + &ExportUnityEngineBehaviour, + &ExportUnityEngineDebug, + &ExportUnityEngineDisplay, + &ExportUnityEngineLight, + &ExportUnityEngineRandom, + &ExportUnityEngineInput, + &ExportUnityEngineApplication, + &ExportSpritesBindings, + &ExportLightProbeBindings, + &ExportCursorBindings, + &ExportPlayerPrefsBindings, +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + &ExportSerializedStateReader, + &ExportSerializedStateWriter, + &ExportPPtrRemapper, + &ExportManagedLivenessAnalysis, +#endif + +#if UNITY_XENON_API ///@TODO: Remove all #ifdefs. We are doing everything via defines in the generated cpp files. + &ExportXboxServices, + &ExportXboxKinect, + &ExportXboxAvatar, + &ExportXboxKeyboard, + &ExportXboxVideoMode, +#endif +#if UNITY_WINRT + &ExportUnityEngineMetro, +#endif +#if UNITY_PS3_API + &ExportPS3, +#endif +#if ENABLE_NETWORK + &ExportNetworking, +#endif + &ExportScriptAssets, +#if ENABLE_WWW + &ExportUtils, +#endif + + &ExportSubstanceUtility, + +#if UNITY_IPHONE_API || UNITY_ANDROID_API + &ExportiPhoneInput, +#endif + +#if UNITY_IPHONE_API + &ExportiAD, +#endif + +#if UNITY_IPHONE_API || UNITY_ANDROID_API || UNITY_BB10_API || UNITY_WP8 || UNITY_TIZEN_API + &ExportHandheld, +#endif + +#if ENABLE_GAMECENTER + &ExportGameCenterServices, +#endif + +#if UNITY_ANDROID_API + &ExportAndroidInput, + &ExportAndroidJNI, +#endif + +#if UNITY_WEBPLAYER + &ExportSecurityPublic, +#endif +#if UNITY_WINRT_API + &ExportAppTrial, + &ExportWindowsFile, + &ExportWindowsDirectory, + &ExportWindowsCrypto, +#endif +#if UNITY_METRO_API + &ExportWSAApplication, + &ExportWSATiles, +#endif +#if UNITY_EDITOR + &ExportUtility, + &ExportEditorHandles, + &ExportEditorHandlesUtility, + &ExportEditorGUIUtility, + &ExportSavedGUIState, + &ExportInternalUtility, + &ExportShaderUtilBindings, + &ExportMeshUtilityBindings, + &ExportPrefabs, + &ExportEditorApplication, + &ExportEditorResourcesUtility, + &ExportBuildPipeline, + &ExportSerializedPropertyBindings, + &ExportAssetDatabase, + &ExportInternalEditorUtility, + &ExportEditorMaterialUtility, + &ExportInternalGraphUtility, + &ExportFileUtil, + &ExportNavMeshBuilding, + &ExportAnimationUtilityBindings, + &ExportStateMachineBindings, + &ExportAvatarAnimation, + &ExportAnimatorControllerBindings, + &ExportAvatarMaskBindings, + &ExportBlendTreeBindings, + &ExportAvatarUtility, + &ExportAnimatorUtilityBindings, + &ExportMotionBindings, + &ExportAssetServer, + &ExportEditorWindow, + &ExportWebView, + &ExportAssetStoreUtils, + &ExportAssetStoreToolUtilsBindings, + &ExportProfilerAPI, + &ExportEditorSettings, + &ExportEditorUserSettings, + &ExportPlayerSettings, + &ExportAnnotationUtility, + &ExportUploadingBuildsUtility, + &ExportSubstanceEditorUtility, + &ExportLODUtilityBindings, + &ExportGameObjectUtilityBindings, + &ExportComponentUtilityBindings, + &ExportAsyncHTTPClientBindings, + &ExportParticleSystemEditorBindings, + &ExportVCAssetBindings, + &ExportVCChangeSetBindings, + &ExportVCProviderBindings, + &ExportVCCustomCommandBindings, + &ExportVCTaskBindings, + &ExportVCMessageBindings, + &ExportVCPluginBindings, + &ExportAssetStoreContextBindings, + &ExportUndoBindings, + &ExportAssetImporterBindings, + &ExportAssetPreviewBindings, + &ExportLicenseManagementWindow, + &ExportEditorBindings, + &ExportSpritePackerBindings, + &ExportSpritesBindingsEditor, + &ExportPolygonEditorBindings, + &ExportHighlighterBindings +#endif +}; + +void RegisterAllInternalCalls () +{ + for( int i=0; i<sizeof(sMonoBindingsRegistration)/sizeof(sMonoBindingsRegistration[0]); ++i ) + sMonoBindingsRegistration[i](); + + RegisterAllAvailableModuleICalls (); +} + +#endif + +#endif diff --git a/Runtime/Export/MonoICallRegistration.h b/Runtime/Export/MonoICallRegistration.h new file mode 100644 index 0000000..14d6730 --- /dev/null +++ b/Runtime/Export/MonoICallRegistration.h @@ -0,0 +1,2 @@ + +void RegisterAllInternalCalls (); diff --git a/Runtime/Export/MotionBindings.txt b/Runtime/Export/MotionBindings.txt new file mode 100644 index 0000000..46aef06 --- /dev/null +++ b/Runtime/Export/MotionBindings.txt @@ -0,0 +1,43 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Mono/MonoScript.h" +#include "Runtime/Animation/Motion.h" + +CSRAW +using System; +using Object=UnityEngine.Object; + +namespace UnityEngine +{ + +//*undocumented* leave undocumented until BlendTree are in public API +NONSEALED_CLASS public Motion : Object + + CONDITIONAL UNITY_EDITOR + CUSTOM bool ValidateIfRetargetable(bool showWarning) {return self->ValidateIfRetargetable(showWarning);} + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP float averageDuration { return self->GetAverageDuration(); } + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP float averageAngularSpeed { return self->GetAverageAngularSpeed(); } + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP Vector3 averageSpeed { return self->GetAverageSpeed(); } + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP float apparentSpeed { return self->GetApparentSpeed(); } + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP bool isLooping {return self->IsLooping();} + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP bool isAnimatorMotion {return self->IsAnimatorMotion();} + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP bool isHumanMotion {return self->IsHumanMotion();} + +END + + +CSRAW } diff --git a/Runtime/Export/MouseEvents.cs b/Runtime/Export/MouseEvents.cs new file mode 100644 index 0000000..bd87008 --- /dev/null +++ b/Runtime/Export/MouseEvents.cs @@ -0,0 +1,187 @@ +using System; +using System.Collections; +using System.Reflection; + +namespace UnityEngine +{ + +internal class SendMouseEvents +{ + struct HitInfo + { + public GameObject target; + public Camera camera; + + public void SendMessage (string name) + { + target.SendMessage (name, null, SendMessageOptions.DontRequireReceiver); + } + + public static implicit operator bool (HitInfo exists) + { + return exists.target != null && exists.camera != null; + } + + public static bool Compare (HitInfo lhs, HitInfo rhs) + { + return lhs.target == rhs.target && lhs.camera == rhs.camera; + } + } + + static HitInfo[] m_LastHit = { new HitInfo (), new HitInfo () }; + static HitInfo[] m_MouseDownHit = { new HitInfo (), new HitInfo () }; + static RaycastHit2D[] m_MouseRayHits2D = {new RaycastHit2D()}; + + [NotRenamed] + static void DoSendMouseEvents (int mouseUsed, int skipRTCameras) + { + HitInfo[] currentHit = { new HitInfo (), new HitInfo () }; + Vector3 mousePosition = Input.mousePosition; + Camera[] cameras = Camera.allCameras; + + // If UnityGUI has the mouse over, we simply don't do any mouse hit detection. + // That way, it will appear as if the mouse has missed everything. + if (mouseUsed == 0) + { + foreach (Camera camera in cameras) + { + // we do not want to check cameras that are rendering to textures, starting with 4.0 + if (skipRTCameras != 0 && camera.targetTexture != null) + continue; + + // Is the mouse inside the cameras viewport? + Rect rect = camera.pixelRect; + if (!rect.Contains (mousePosition)) + continue; + + // Did we hit any gui elements? + GUILayer layer = (GUILayer)camera.GetComponent (typeof (GUILayer)); + if (layer) + { + GUIElement element = layer.HitTest (mousePosition); + if (element) + { + currentHit[0].target = element.gameObject; + currentHit[0].camera = camera; + } + } +#if ENABLE_PHYSICS || ENABLE_2D_PHYSICS + // There is no need to continue if the camera shouldn't be sending out events + if ((int)camera.eventMask == 0) + continue; + +#if ENABLE_PHYSICS + // Did we hit any colliders? + RaycastHit hit; + if (camera.farClipPlane > 0.0f && Physics.Raycast (camera.ScreenPointToRay (mousePosition), + out hit, camera.farClipPlane, camera.cullingMask & camera.eventMask & Physics.DefaultRaycastLayers + )) + { + if (hit.rigidbody) + { + currentHit[1].target = hit.rigidbody.gameObject; + currentHit[1].camera = camera; + } + else + { + currentHit[1].target = hit.collider.gameObject; + currentHit[1].camera = camera; + } + } +#endif +#if ENABLE_2D_PHYSICS + // Did we hit any 2D colliders? + else if (camera.farClipPlane > 0.0f) + { + // Did we hit any 2D colliders? + if (Physics2D.GetRayIntersectionNonAlloc (camera.ScreenPointToRay (mousePosition), + m_MouseRayHits2D, camera.farClipPlane, camera.cullingMask & camera.eventMask & Physics2D.DefaultRaycastLayers) == 1) + { + currentHit[1].camera = camera; + if (m_MouseRayHits2D[0].rigidbody) + currentHit[1].target = m_MouseRayHits2D[0].rigidbody.gameObject; + else + currentHit[1].target = m_MouseRayHits2D[0].collider.gameObject; + } + } +#endif + else + { + // We did not hit anything with a raycast from this camera. But our camera + // clears the screen and renders on top of whatever was below, thus making things + // rendered before invisible. So clear any previous hit we have found. + if (camera.clearFlags == CameraClearFlags.Skybox || camera.clearFlags == CameraClearFlags.Color) + { + currentHit[1].target = null; + currentHit[1].camera = null; + } + } +#endif + } + } + + // i=0: CameraGUILayer, i=1: 3D Objects + for (int i=0;i<2;i++) + SendEvents(i, currentHit[i]); + } + + /// <summary> + /// Old-style mouse events used prior to the new event system of 4.2. + /// </summary> + + static void SendEvents (int i, HitInfo hit) + { + // Handle MouseDown, MouseDrag, MouseUp + bool mouseDownThisFrame = Input.GetMouseButtonDown(0); + bool mousePressed = Input.GetMouseButton(0); + + if (mouseDownThisFrame) + { + if (hit) + { + m_MouseDownHit[i] = hit; + m_MouseDownHit[i].SendMessage("OnMouseDown"); + } + } + else if (!mousePressed) + { + if (m_MouseDownHit[i]) + { + // For button like behavior only fire this event if same as on MouseDown + if (HitInfo.Compare(hit, m_MouseDownHit[i])) + m_MouseDownHit[i].SendMessage("OnMouseUpAsButton"); + + // For backwards compatibility we keep the event name OnMouseUp + m_MouseDownHit[i].SendMessage("OnMouseUp"); + m_MouseDownHit[i] = new HitInfo(); + } + } + else if (m_MouseDownHit[i]) + { + m_MouseDownHit[i].SendMessage("OnMouseDrag"); + } + + + // Handle MouseOver, MouseEnter, MouseExit + if (HitInfo.Compare(hit, m_LastHit[i])) + { + if (hit) + hit.SendMessage("OnMouseOver"); + } + else + { + if (m_LastHit[i]) + { + m_LastHit[i].SendMessage("OnMouseExit"); + } + + if (hit) + { + hit.SendMessage("OnMouseEnter"); + hit.SendMessage("OnMouseOver"); + } + } + m_LastHit[i] = hit; + } +} +} diff --git a/Runtime/Export/NetworkServices.cs b/Runtime/Export/NetworkServices.cs new file mode 100644 index 0000000..0e1f1cd --- /dev/null +++ b/Runtime/Export/NetworkServices.cs @@ -0,0 +1,231 @@ +using System; + +namespace UnityEngine +{ + using UnityEngine.SocialPlatforms; + + // A facade for the social API namespace, no state, only helper functions which delegate into others + public static class Social + { + public static ISocialPlatform Active + { + get { return ActivePlatform.Instance; } + set { ActivePlatform.Instance = value; } + } + + public static ILocalUser localUser { get { return Active.localUser; } } + + public static void LoadUsers(string[] userIDs, Action<IUserProfile[]> callback) + { + Active.LoadUsers(userIDs, callback); + } + + public static void ReportProgress(string achievementID, double progress, Action<bool> callback) + { + Active.ReportProgress(achievementID, progress, callback); + } + + public static void LoadAchievementDescriptions(Action<IAchievementDescription[]> callback) + { + Active.LoadAchievementDescriptions(callback); + } + + public static void LoadAchievements(Action<IAchievement[]> callback) + { + Active.LoadAchievements(callback); + } + + public static void ReportScore(Int64 score, string board, Action<bool> callback) + { + Active.ReportScore(score, board, callback); + } + + public static void LoadScores(string leaderboardID, Action<IScore[]> callback) + { + Active.LoadScores(leaderboardID, callback); + } + + public static ILeaderboard CreateLeaderboard() + { + return Active.CreateLeaderboard(); + } + + public static IAchievement CreateAchievement() + { + return Active.CreateAchievement(); + } + + public static void ShowAchievementsUI() + { + Active.ShowAchievementsUI(); + } + + public static void ShowLeaderboardUI() + { + Active.ShowLeaderboardUI(); + } + } +} + +namespace UnityEngine.SocialPlatforms +{ + // The state of the current active social implementation + internal static class ActivePlatform + { + private static ISocialPlatform _active; + + internal static ISocialPlatform Instance + { + get + { + if (_active == null) + _active = SelectSocialPlatform(); + return _active; + } + set + { + _active = value; + } + } + + private static ISocialPlatform SelectSocialPlatform() { + // statically selecting community + #if ENABLE_GAMECENTER + return new UnityEngine.SocialPlatforms.GameCenter.GameCenterPlatform(); + #elif UNITY_XENON_API && ENABLE_XENON_SOCIALAPI + return new XboxLive(); + #else + return new UnityEngine.SocialPlatforms.Local(); + #endif + } + } + + public interface ISocialPlatform + { + ILocalUser localUser { get; } + + void LoadUsers(string[] userIDs, Action<IUserProfile[]> callback); + + void ReportProgress(string achievementID, double progress, Action<bool> callback); + void LoadAchievementDescriptions(Action<IAchievementDescription[]> callback); + void LoadAchievements(Action<IAchievement[]> callback); + IAchievement CreateAchievement(); + + void ReportScore(Int64 score, string board, Action<bool> callback); + void LoadScores(string leaderboardID, Action<IScore[]> callback); + ILeaderboard CreateLeaderboard(); + + void ShowAchievementsUI(); + void ShowLeaderboardUI(); + + // ===> These should be explicitly implemented <=== + void Authenticate(ILocalUser user, Action<bool> callback); + void LoadFriends(ILocalUser user, Action<bool> callback); + void LoadScores(ILeaderboard board, Action<bool> callback); + bool GetLoading(ILeaderboard board); + } + + public interface ILocalUser : IUserProfile + { + void Authenticate (Action<bool> callback); + void LoadFriends (Action<bool> callback); + + IUserProfile[] friends { get; } + bool authenticated { get; } + bool underage { get; } + } + + public enum UserState + { + Online, + OnlineAndAway, + OnlineAndBusy, + Offline, + Playing + } + + public interface IUserProfile + { + string userName { get; } + string id { get; } + bool isFriend { get; } + UserState state { get; } + Texture2D image { get; } + } + + public interface IAchievement + { + void ReportProgress(Action<bool> callback); + + string id { get; set; } + double percentCompleted { get; set; } + bool completed { get; } + bool hidden { get; } + DateTime lastReportedDate { get; } + } + + public interface IAchievementDescription + { + string id { get; set; } + string title { get; } + Texture2D image { get; } + string achievedDescription { get; } + string unachievedDescription { get; } + bool hidden { get; } + int points { get; } + } + + public interface IScore + { + void ReportScore(Action<bool> callback); + + string leaderboardID { get; set; } + // TODO: This is just an int64 here, but should be able to represent all supported formats, except for float type scores ... + Int64 value { get; set; } + DateTime date { get; } + string formattedValue { get; } + string userID { get; } + int rank { get; } + } + + public enum UserScope + { + Global = 0, + FriendsOnly + } + + public enum TimeScope + { + Today = 0, + Week, + AllTime + } + + public struct Range + { + public int from; + public int count; + + public Range(int fromValue, int valueCount) + { + from = fromValue; + count = valueCount; + } + } + + public interface ILeaderboard + { + void SetUserFilter(string[] userIDs); + void LoadScores(Action<bool> callback); + bool loading { get; } + + string id { get; set; } + UserScope userScope { get; set; } + Range range { get; set; } + TimeScope timeScope { get; set; } + IScore localUserScore { get; } + uint maxRange { get; } + IScore[] scores { get; } + string title { get; } + } +} diff --git a/Runtime/Export/Networking.txt b/Runtime/Export/Networking.txt new file mode 100644 index 0000000..8779122 --- /dev/null +++ b/Runtime/Export/Networking.txt @@ -0,0 +1,921 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Math/Quaternion.h" +#include "Runtime/Utilities/Utility.h" +#include "Runtime/Network/NetworkManager.h" +#include "Runtime/Network/NetworkUtility.h" +#include "Runtime/Network/BitStreamPacker.h" +#include "Runtime/Network/MasterServerInterface.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/Scripting.h" + +CSRAW + +#if ENABLE_NETWORK + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// Option for who will receive an [[RPC]], used by NetworkView.RPC. +CONDITIONAL ENABLE_NETWORK +ENUM RPCMode + // Sends to the server only + Server = 0, + + // Sends to everyone except the sender + Others = 1, + + // Sends to everyone except the sender and adds to the buffer + OthersBuffered = 5, + + // Sends to everyone + All = 2, + + // Sends to everyone and adds to the buffer + AllBuffered = 6 +END + +// The various test results the connection tester may return with. +CONDITIONAL ENABLE_NETWORK +ENUM ConnectionTesterStatus + // Some unknown error occurred. + Error = -2, + // Test result undetermined, still in progress. + Undetermined = -1, + OBSOLETE warning No longer returned, use newer connection tester enums instead. + PrivateIPNoNATPunchthrough = 0, + OBSOLETE warning No longer returned, use newer connection tester enums instead. + PrivateIPHasNATPunchThrough = 1, + // Public IP address detected and game listen port is accessible to the internet. + PublicIPIsConnectable = 2, + // Public IP address detected but the port is not connectable from the internet. + PublicIPPortBlocked = 3, + // Public IP address detected but server is not initialized and no port is listening. + PublicIPNoServerStarted = 4, + // Port-restricted NAT type, can do NAT punchthrough to everyone except symmetric. + LimitedNATPunchthroughPortRestricted = 5, + // Symmetric NAT type, cannot do NAT punchthrough to other symmetric types nor port restricted type. + LimitedNATPunchthroughSymmetric = 6, + // Full cone type, NAT punchthrough fully supported. + NATpunchthroughFullCone = 7, + // Address-restricted cone type, NAT punchthrough fully supported. + NATpunchthroughAddressRestrictedCone = 8 +END + +// Possible status messages returned by Network.Connect and in [[MonoBehaviour.OnFailedToConnect|OnFailedToConnect]] +CONDITIONAL ENABLE_NETWORK +ENUM NetworkConnectionError + // No error occurred. + NoError = 0, + + // We presented an RSA public key which does not match what the system we connected to is using. + RSAPublicKeyMismatch = 21, + + // The server is using a password and has refused our connection because we did not set the correct password. + InvalidPassword = 23, + + // Connection attempt failed, possibly because of internal connectivity problems. + ConnectionFailed = 15, + + // The server is at full capacity, failed to connect. + TooManyConnectedPlayers = 18, + + // We are banned from the system we attempted to connect to (likely temporarily). + ConnectionBanned = 22, + + // We are already connected to this particular server (can happen after fast disconnect/reconnect). + AlreadyConnectedToServer = 16, + + // Cannot connect to two servers at once. Close the connection before connecting again. + AlreadyConnectedToAnotherServer = -1, + + // Internal error while attempting to initialize network interface. Socket possibly already in use. + CreateSocketOrThreadFailure = -2, + + // Incorrect parameters given to Connect function. + IncorrectParameters = -3, + + // No host target given in Connect. + EmptyConnectTarget = -4, + + // Client could not connect internally to same network NAT enabled server. + InternalDirectConnectFailed = -5, + + // The NAT target we are trying to connect to is not connected to the facilitator server. + NATTargetNotConnected = 69, + + // Connection lost while attempting to connect to NAT target. + NATTargetConnectionLost = 71, + + // NAT punchthrough attempt has failed. The cause could be a too restrictive NAT implementation on either endpoints. + NATPunchthroughFailed = 73 +END + +// The reason a disconnect event occured, like in [[MonoBehaviour.OnDisconnectedFromServer|OnDisconnectedFromServer]]. +CONDITIONAL ENABLE_NETWORK +ENUM NetworkDisconnection + // The connection to the system has been lost, no reliable packets could be delivered. + LostConnection = 20, + + // The connection to the system has been closed. + Disconnected = 19 +END + +// Describes status messages from the master server as returned in [[MonoBehaviour.OnMasterServerEvent|OnMasterServerEvent]]. +CONDITIONAL ENABLE_NETWORK +ENUM MasterServerEvent + // Registration failed because an empty game name was given. + RegistrationFailedGameName = 0, + + // Registration failed because an empty game type was given. + RegistrationFailedGameType = 1, + + // Registration failed because no server is running. + RegistrationFailedNoServer = 2, + + // Registration to master server succeeded, received confirmation. + RegistrationSucceeded = 3, + + // Received a host list from the master server. + HostListReceived = 4 +END + +// Different types of synchronization for the [[NetworkView]] component. +CONDITIONAL ENABLE_NETWORK +ENUM NetworkStateSynchronization + + // No state data will be synchronized + Off = 0, + + // All packets are sent reliable and ordered. + ReliableDeltaCompressed = 1, + + // Brute force unreliable state sending + Unreliable = 2 +END + +// Describes the status of the network interface peer type as returned by Network.peerType. +CONDITIONAL ENABLE_NETWORK +ENUM NetworkPeerType + // No client connection running. Server not initialized. + Disconnected = 0, + // Running as server. + Server = 1, + // Running as client. + Client = 2, + // Attempting to connect to a server. + Connecting = 3 +END + +// Describes different levels of log information the network layer supports. +CONDITIONAL ENABLE_NETWORK +ENUM NetworkLogLevel + // Only report errors, otherwise silent. + Off = 0, + // Report informational messages like connectivity events. + Informational = 1, + // Full debug level logging down to each individual message being reported. + Full = 3 +END + + +// The NetworkPlayer is a data structure with which you can locate another player over the network. +CONDITIONAL ENABLE_NETWORK +STRUCT NetworkPlayer + CSRAW internal int index; + + CUSTOM private static string Internal_GetIPAddress(int index) { return scripting_string_new(GetNetworkManager().GetIPAddress(index)); } + CUSTOM private static int Internal_GetPort(int index) { return GetNetworkManager().GetPort(index); } + CUSTOM private static string Internal_GetExternalIP() { return scripting_string_new(GetNetworkManager().GetExternalIP()); } + CUSTOM private static int Internal_GetExternalPort() { return GetNetworkManager().GetExternalPort(); } + CUSTOM private static string Internal_GetLocalIP() { return scripting_string_new(GetLocalIP()); } + CUSTOM private static int Internal_GetLocalPort() { return GetNetworkManager().GetPort(); } + CUSTOM private static int Internal_GetPlayerIndex () { return GetNetworkManager().GetPlayerID(); } + CUSTOM private static string Internal_GetGUID(int index) { return scripting_string_new(GetNetworkManager().GetGUID(index)); } + CUSTOM private static string Internal_GetLocalGUID () { return scripting_string_new(GetNetworkManager().GetGUID()); } + + // *undocumented* + CSRAW public NetworkPlayer (string ip, int port) + { + Debug.LogError("Not yet implemented"); + index = 0; + } + + // Returns true if two NetworkPlayers are the same player. + CSRAW public static bool operator == (NetworkPlayer lhs, NetworkPlayer rhs) + { + return lhs.index == rhs.index; + } + + // Returns true if two NetworkPlayers are not the same player. + CSRAW public static bool operator != (NetworkPlayer lhs, NetworkPlayer rhs) + { + return lhs.index != rhs.index; + } + + // *undocumented* Used to allow NetworkPlayer to be used as keys in hash tables. Also triggers warning for == and != operators if not present + CSRAW public override int GetHashCode() { + return index.GetHashCode(); + } + + // *undocumented* Required for being able to use NetworkPlayer as keys in hash tables + CSRAW public override bool Equals(object other) { + if(!(other is NetworkPlayer)) return false; + + NetworkPlayer rhs=(NetworkPlayer)other; + return rhs.index == index; + } + + // The IP address of this player. + CSRAW public string ipAddress { get { if (index == Internal_GetPlayerIndex()) return Internal_GetLocalIP(); else return Internal_GetIPAddress(index); } } + + // The port of this player. + CSRAW public int port { get { if (index == Internal_GetPlayerIndex()) return Internal_GetLocalPort(); else return Internal_GetPort(index); } } + + // The GUID for this player, used when connecting with NAT punchthrough. + CSRAW public string guid { get { if (index == Internal_GetPlayerIndex()) return Internal_GetLocalGUID(); else return Internal_GetGUID(index); } } + + // Returns the index number for this network player. + CSRAW override public string ToString() { return index.ToString(); } + + // Returns the external IP address of the network interface. + CSRAW public string externalIP { get { return Internal_GetExternalIP(); } } + + // Returns the external port of the network interface. + CSRAW public int externalPort { get { return Internal_GetExternalPort(); } } + + CSRAW static internal NetworkPlayer unassigned { get { NetworkPlayer val; val.index = -1; return val; } } + +END + +// The NetworkViewID is a unique identifier for a network view instance in a multiplayer game. +CONDITIONAL ENABLE_NETWORK +STRUCT NetworkViewID + CSRAW int a; + CSRAW int b; + CSRAW int c; + + // Represents an invalid network view ID. + CUSTOM_PROP static NetworkViewID unassigned { return NetworkViewID::GetUnassignedViewID(); } + + CUSTOM static internal bool Internal_IsMine(NetworkViewID value) { return GetNetworkManager().WasViewIdAllocatedByMe(value); } + CUSTOM static internal void Internal_GetOwner(NetworkViewID value, out NetworkPlayer player) { *player = GetNetworkManager().GetNetworkViewIDOwner(value); } + CUSTOM static internal string Internal_GetString(NetworkViewID value) { return scripting_string_new(value.ToString()); } + CUSTOM static internal bool Internal_Compare(NetworkViewID lhs, NetworkViewID rhs) { return rhs == lhs; } + + // Returns true if two NetworkViewIDs are identical + CSRAW public static bool operator == (NetworkViewID lhs, NetworkViewID rhs) + { + return Internal_Compare(lhs, rhs); + } + + // Returns true if two NetworkViewIDs are not identical + CSRAW public static bool operator != (NetworkViewID lhs, NetworkViewID rhs) + { + return !Internal_Compare(lhs, rhs); + } + + // *undocumented* Used to allow NetworkViewIDs to be used as keys in hash tables. Also triggers warning for == and != operators if not present + CSRAW public override int GetHashCode() { + return a ^ b ^ c; + } + + // *undocumented* Required for being able to use NetworkViewIDs as keys in hash tables + CSRAW public override bool Equals(object other) { + if(!(other is NetworkViewID)) return false; + + NetworkViewID rhs=(NetworkViewID)other; + return Internal_Compare(this, rhs); + } + + // True if instantiated by me + CSRAW public bool isMine { get + { return Internal_IsMine(this); } } + + // The [[NetworkPlayer]] who owns the [[NetworkView]]. Could be the server. + CSRAW public NetworkPlayer owner { get { NetworkPlayer p; Internal_GetOwner(this, out p); return p;} } + + // Returns a formatted string with details on this NetworkViewID. + CSRAW override public string ToString() { return Internal_GetString(this); } + +END + + +// Ping any given IP address (given in dot notation). +CONDITIONAL ENABLE_NETWORK +CLASS Ping + + // We are matching the Ping class here so we can directly access it. + CSRAW private IntPtr pingWrapper; + + // this is needed only for batched android build due to bug in txt parser + // screwing up iphone_input.txt to have cpp line emited in wrong place + C++RAW #undef GET + C++RAW #define GET ExtractMonoObjectData<Ping*> (self) + + // Perform a ping to the supplied target IP address. + CUSTOM Ping(string address) + { + GET = new Ping(address); + GetNetworkManager().PingWrapper(GET); + } + + //*undocumented* + THREAD_SAFE + CUSTOM void DestroyPing() + { + if (GET) + { + GET->Release(); + GET = 0; + } + } + + CSRAW ~Ping() + { + DestroyPing(); + } + + // Has the ping function completed? + CUSTOM_PROP public bool isDone + { + if (GET) return (short)GET->GetIsDone(); + else return false; + } + + // This property contains the ping time result after isDone returns true. + CUSTOM_PROP public int time + { + return GET->GetTime(); + } + + // The IP target of the ping. + CUSTOM_PROP public string ip + { + return scripting_string_new(GET->GetIP()); + } + + C++RAW + #undef GET + +END + + +// The network view is the binding material of multiplayer games. +CONDITIONAL ENABLE_NETWORK +CLASS NetworkView : Behaviour + + CUSTOM private static void Internal_RPC (NetworkView view, string name, RPCMode mode, object[] args) + { + view->RPCCall(name, mode, args); + } + + CUSTOM private static void Internal_RPC_Target (NetworkView view, string name, NetworkPlayer target, object[] args) + { + view->RPCCallSpecificTarget(name, target, args); + } + + // Call a [[RPC]] function on all connected peers. + CSRAW public void RPC (string name, RPCMode mode, params object[] args) { Internal_RPC(this, name, mode, args); } + + // Call a RPC function on a specific player + CSRAW public void RPC (string name, NetworkPlayer target, params object[] args) { Internal_RPC_Target(this, name, target, args); } + + // The component the network view is observing. + AUTO_PTR_PROP Component observed GetObserved SetObserved + + // The type of [[NetworkStateSynchronization]] set for this network view. + CUSTOM_PROP NetworkStateSynchronization stateSynchronization { return self->GetStateSynchronization(); } { self->SetStateSynchronization(value); } + + CUSTOM private void Internal_GetViewID (out NetworkViewID viewID) + { + *viewID = self->GetViewID(); + } + CUSTOM private void Internal_SetViewID (NetworkViewID viewID) { self->SetViewID(viewID); } + + // The ViewID of this network view. + CSRAW public NetworkViewID viewID { get { NetworkViewID val; Internal_GetViewID(out val); return val; } set { Internal_SetViewID(value); } } + + // The network group number of this network view. + AUTO_PROP int group GetGroup SetGroup + + // Is the network view controlled by this object? + CSRAW public bool isMine { get { return viewID.isMine; } } + + // The [[NetworkPlayer]] who owns this network view. + CSRAW public NetworkPlayer owner { get { return viewID.owner; } } + + // Set the scope of the network view in relation to a specific network player. + CUSTOM bool SetScope(NetworkPlayer player, bool relevancy) + { + return self->SetPlayerScope(player, relevancy); + } + + // Find a network view based on a [[NetworkViewID]]. + CUSTOM static NetworkView Find (NetworkViewID viewID) { return Scripting::ScriptingWrapperFor(GetNetworkManager().ViewIDToNetworkView (viewID)); } + +END + +// The network class is at the heart of the network implementation and provides the core functions. +CONDITIONAL ENABLE_NETWORK +CLASS Network + + // Initialize the server. + CUSTOM static NetworkConnectionError InitializeServer (int connections, int listenPort, bool useNat) { return GetNetworkManager().InitializeServer(connections, listenPort, useNat); } + + CUSTOM private static NetworkConnectionError Internal_InitializeServerDeprecated (int connections, int listenPort) { return GetNetworkManager().InitializeServer(connections, listenPort, false); } + + OBSOLETE warning Use the IntializeServer(connections, listenPort, useNat) function instead + CSRAW public static NetworkConnectionError InitializeServer (int connections, int listenPort) { return Internal_InitializeServerDeprecated(connections, listenPort); } + + // Set the password for the server (for incoming connections). + CUSTOM_PROP static string incomingPassword { return scripting_string_new(GetNetworkManager().GetIncomingPassword());} { GetNetworkManager().SetIncomingPassword(value);} + + // Set the log level for network messages (default is Off). + CUSTOM_PROP static NetworkLogLevel logLevel { return GetNetworkManager().GetDebugLevel(); } { GetNetworkManager().SetDebugLevel(value); } + + // Initializes security layer. + CUSTOM static void InitializeSecurity() { GetNetworkManager().InitializeSecurity(); } + + CUSTOM private static NetworkConnectionError Internal_ConnectToSingleIP (string IP, int remotePort, int localPort, string password = "") + { + return GetNetworkManager().Connect(IP, remotePort, localPort, password); + } + + CUSTOM private static NetworkConnectionError Internal_ConnectToGuid (string guid, string password) + { + RakNetGUID remoteGuid; + remoteGuid.FromString(guid.AsUTF8().c_str()); + return GetNetworkManager().Connect(remoteGuid, 0, password); + } + + CUSTOM private static NetworkConnectionError Internal_ConnectToIPs (string[] IP, int remotePort, int localPort, string password = "") + { + std::vector<string> ipvector; + for (int i=0; i < mono_array_length_safe(IP); i++) + { + ipvector.push_back(scripting_cpp_string_for(GetMonoArrayElement<MonoString*> (IP, i))); + } + return GetNetworkManager().Connect(ipvector, remotePort, localPort, password); + } + + // Connect to the specified host (ip or domain name) and server port. + CSRAW public static NetworkConnectionError Connect (string IP, int remotePort, string password = "") { return Internal_ConnectToSingleIP(IP, remotePort, 0, password); } + + // This function is exactly like Network.Connect but can accept an array of IP addresses. + CSRAW public static NetworkConnectionError Connect (string[] IPs, int remotePort, string password = ""){ + return Internal_ConnectToIPs(IPs, remotePort, 0, password); } + + // Connect to a server GUID. NAT punchthrough can only be performed this way. + CSRAW public static NetworkConnectionError Connect (string GUID, string password = "") { + return Internal_ConnectToGuid(GUID, password); + } + + // Connect to the host represented by a [[HostData]] structure returned by the Master Server. + CSRAW public static NetworkConnectionError Connect (HostData hostData, string password = "") { + if(hostData == null) + throw new NullReferenceException(); + if (hostData.guid.Length > 0 && hostData.useNat) + return Connect(hostData.guid, password); + else + return Connect(hostData.ip, hostData.port, password); + } + + // Close all open connections and shuts down the network interface. + CUSTOM static void Disconnect(int timeout = 200) { GetNetworkManager().Disconnect(timeout); } + + // Close the connection to another system. + CUSTOM static void CloseConnection (NetworkPlayer target, bool sendDisconnectionNotification) { GetNetworkManager().CloseConnection(target, sendDisconnectionNotification); } + + // All connected players. + CUSTOM_PROP static NetworkPlayer[] connections { + MonoArray* array = mono_array_new (mono_domain_get (), MONO_COMMON.networkPlayer, GetNetworkManager().GetConnectionCount()); + GetNetworkManager().GetConnections(&GetMonoArrayElement<int> (array,0)); + return array; + } + + CUSTOM private static int Internal_GetPlayer () { return GetNetworkManager().GetPlayerID(); } + + // Get the local [[NetworkPlayer]] instance + CSRAW public static NetworkPlayer player { get { NetworkPlayer np; np.index = Internal_GetPlayer(); return np; } } + + CUSTOM private static void Internal_AllocateViewID(out NetworkViewID viewID) + { *viewID = GetNetworkManager().AllocateViewID(); } + + // Query for the next available network view ID number and allocate it (reserve). + CSRAW public static NetworkViewID AllocateViewID() { NetworkViewID val; Internal_AllocateViewID (out val); return val; } + + // Network instantiate a prefab. + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeOfFirstArgument)] + CUSTOM public static Object Instantiate (Object prefab, Vector3 position, Quaternion rotation, int group) { return Scripting::ScriptingWrapperFor(GetNetworkManager().Instantiate (*prefab, position, rotation, group)); } + + // Destroy the object associated with this view ID across the network. + CUSTOM static void Destroy (NetworkViewID viewID) { GetNetworkManager().DestroyDelayed(viewID); } + + // Destroy the object across the network. + CSRAW public static void Destroy (GameObject gameObject) { + if (gameObject != null) + { + NetworkView view = gameObject.networkView; + if (view != null) + Destroy(view.viewID); + else + Debug.LogError("Couldn't destroy game object because no network view is attached to it.", gameObject); + } + } + + // Destroy all the objects based on view IDs belonging to this player. + CUSTOM static void DestroyPlayerObjects(NetworkPlayer playerID) { GetNetworkManager().DestroyPlayerObjects(playerID); } + + CUSTOM private static void Internal_RemoveRPCs(NetworkPlayer playerID, NetworkViewID viewID, uint channelMask) { GetNetworkManager().RemoveRPCs(playerID, viewID, channelMask); } + + // Remove all [[RPC]] functions which belong to this player ID. + CSRAW public static void RemoveRPCs(NetworkPlayer playerID) { Internal_RemoveRPCs(playerID, NetworkViewID.unassigned, 0xFFFFFFFF); } + // Remove all [[RPC]] functions which belong to this player ID and were sent based on the given group. + CSRAW public static void RemoveRPCs(NetworkPlayer playerID, int group) { Internal_RemoveRPCs(playerID, NetworkViewID.unassigned, (uint)(1 << group)); } + // Remove the [[RPC]] function calls accociated with this view ID number. + CSRAW public static void RemoveRPCs(NetworkViewID viewID) { Internal_RemoveRPCs(NetworkPlayer.unassigned, viewID, 0xFFFFFFFF); } + // Remove all [[RPC]] functions which belong to given group number. + CSRAW public static void RemoveRPCsInGroup (int group) { Internal_RemoveRPCs(NetworkPlayer.unassigned, NetworkViewID.unassigned, (uint)(1 << group)); } + + // Returns true if your peer type is client. + CUSTOM_PROP static bool isClient { return GetNetworkManager().IsClient(); } + + // Returns true if your peer type is server. + CUSTOM_PROP static bool isServer { return GetNetworkManager().IsServer(); } + + // The status of the peer type, i.e. if it is disconnected, connecting, server or client. + CUSTOM_PROP static NetworkPeerType peerType { return GetNetworkManager().GetPeerType(); } + + // Set the level prefix which will then be prefixed to all network ViewID numbers. + CUSTOM static void SetLevelPrefix (int prefix) { return GetNetworkManager().SetLevelPrefix(prefix); } + + + // The last ping time to the given /player/ in milliseconds. + CUSTOM static int GetLastPing (NetworkPlayer player) { return GetNetworkManager().GetLastPing(player); } + + // The last average ping time to the given /player/ in milliseconds. + CUSTOM static int GetAveragePing (NetworkPlayer player) { return GetNetworkManager().GetAveragePing(player); } + + // The default send rate of network updates for all Network Views. + CUSTOM_PROP static float sendRate { return GetNetworkManager().GetSendRate(); } { GetNetworkManager().SetSendRate(value); } + + // Enable or disable the processing of network messages. + CUSTOM_PROP static bool isMessageQueueRunning { return GetNetworkManager().GetMessageQueueRunning(); } { GetNetworkManager().SetMessageQueueRunning(value); } + + // Enable or disables the reception of messages in a specific group number from a specific player. + CUSTOM static void SetReceivingEnabled (NetworkPlayer player, int group, bool enabled) { GetNetworkManager().SetReceivingGroupEnabled(player, group, enabled); } + + CUSTOM private static void Internal_SetSendingGlobal(int group, bool enabled) { GetNetworkManager().SetSendingGroupEnabled(group, enabled); } + + CUSTOM private static void Internal_SetSendingSpecific (NetworkPlayer player, int group, bool enabled) { GetNetworkManager().SetSendingGroupEnabled(player, group, enabled); } + + // Enables or disables transmission of messages and [[RPC]] calls on a specific network group number. + CSRAW public static void SetSendingEnabled (int group, bool enabled) { Internal_SetSendingGlobal(group, enabled); } + + // Enable or disable transmission of messages and [[RPC]] calls based on target network player as well as the network group. + CSRAW public static void SetSendingEnabled (NetworkPlayer player, int group, bool enabled) { Internal_SetSendingSpecific(player, group, enabled); } + + CUSTOM private static void Internal_GetTime(out double t) { *t = GetNetworkManager().GetTime();} + + // Get the current network time (seconds). + CSRAW public static double time { get { double t; Internal_GetTime(out t); return t; } } + + // Called on the server whenever a new player has successfully connected. + CSNONE void OnPlayerConnected (NetworkPlayer player); + + // Called on the server whenever a Network.InitializeServer was invoked and has completed. + CSNONE void OnServerInitialized (); + + // Called on the client when you have successfully connected to a server + CSNONE void OnConnectedToServer (); + + // Called on the server whenever a player is disconnected from the server + CSNONE void OnPlayerDisconnected (NetworkPlayer player); + + // Called on client during disconnection from server, but also on the server when the connection has disconnected. + CSNONE void OnDisconnectedFromServer (NetworkDisconnection mode); + + // Called on the client when a connection attempt fails for some reason. + CSNONE void OnFailedToConnect (NetworkConnectionError error); + + // Called on objects which have been network instantiated with Network.Instantiate + CSNONE void OnNetworkInstantiate (NetworkMessageInfo info); + + // Used to customize synchronization of variables in a script watched by a network view. + CSNONE void OnSerializeNetworkView (BitStream stream, NetworkMessageInfo info); + + // Get or set the minimum number of ViewID numbers in the ViewID pool given to clients by the server. + CUSTOM_PROP static int minimumAllocatableViewIDs { return GetNetworkManager().GetMinimumAllocatableViewIDs(); } { GetNetworkManager().SetMinimumAllocatableViewIDs(value); } + + OBSOLETE warning No longer needed. This is now explicitly set in the InitializeServer function call. It is implicitly set when calling Connect depending on if an IP/port combination is used (useNat=false) or a GUID is used(useNat=true). + CUSTOM_PROP static bool useNat { return GetNetworkManager().GetUseNat(); } { GetNetworkManager().SetUseNat(value); } + + // The IP address of the NAT punchthrough facilitator. + CUSTOM_PROP static string natFacilitatorIP { return scripting_string_new(GetNetworkManager().GetFacilitatorAddress().ToString());} { GetNetworkManager().GetFacilitatorAddress(false).SetBinaryAddress(value.AsUTF8().c_str());} + // The port of the NAT punchthrough facilitator. + CUSTOM_PROP static int natFacilitatorPort { return GetNetworkManager().GetFacilitatorAddress().port;} { + #ifdef _XBOX // mircea@XBOX: for some reason, the xbox compiler chokes on the "simple" assign + SystemAddress& sa = GetNetworkManager().GetFacilitatorAddress(false); sa.port = value; + #else + GetNetworkManager().GetFacilitatorAddress(false).port = value; + #endif +} + + // Test this machines network connection. + CUSTOM static ConnectionTesterStatus TestConnection(bool forceTest = false) { return GetNetworkManager().TestConnection(false, forceTest); } + + // Test the connecction specifically for NAT punchthrough connectivity. + CUSTOM static ConnectionTesterStatus TestConnectionNAT(bool forceTest = false) { return GetNetworkManager().TestConnection(true, forceTest); } + + // The IP address of the connection tester used in Network.TestConnection. + CUSTOM_PROP static string connectionTesterIP { return scripting_string_new(GetNetworkManager().GetConnTesterAddress().ToString(false));} { SystemAddress address = GetNetworkManager().GetConnTesterAddress(); address.SetBinaryAddress(value.AsUTF8().c_str()); GetNetworkManager().SetConnTesterAddress(address);} + // The port of the connection tester used in Network.TestConnection. + CUSTOM_PROP static int connectionTesterPort { return GetNetworkManager().GetConnTesterAddress().port;} { SystemAddress address = GetNetworkManager().GetConnTesterAddress(); address.port = value; GetNetworkManager().SetConnTesterAddress(address);} + + // Check if this machine has a public IP address. + CUSTOM static bool HavePublicAddress() { return CheckForPublicAddress(); } + + // Set the maximum amount of connections/players allowed. + CUSTOM_PROP static int maxConnections {return GetNetworkManager().GetMaxConnections(); } { GetNetworkManager().SetMaxConnections(value); } + + // The IP address of the proxy server. + CUSTOM_PROP static string proxyIP { return scripting_string_new(GetNetworkManager().GetProxyIP());} { GetNetworkManager().SetProxyIP(value);} + + // The port of the proxy server. + CUSTOM_PROP static int proxyPort { return GetNetworkManager().GetProxyPort();} { GetNetworkManager().SetProxyPort(value);} + + // Indicate if proxy support is needed, in which case traffic is relayed through the proxy server. + CUSTOM_PROP static bool useProxy { return GetNetworkManager().GetUseProxy(); } { GetNetworkManager().SetUseProxy(value); } + + // Set the proxy server password. + CUSTOM_PROP static string proxyPassword + { + return scripting_string_new(GetNetworkManager().GetProxyPassword()); + } + { + GetNetworkManager().SetProxyPassword(value); + } +END + +// The BitStream class represents seralized variables, packed into a stream. +CONDITIONAL ENABLE_NETWORK +CLASS BitStream + CSRAW internal IntPtr m_Ptr; + + + C++RAW + #define GET ExtractMonoObjectData<BitstreamPacker*> (self) + + C++RAW + #define CHECK_PTR if (ExtractMonoObjectData<BitstreamPacker*> (self) == NULL) Scripting::RaiseNullException(""); + + CUSTOM private void Serializeb (ref int value) { CHECK_PTR bool temp = value; GET->Serialize(temp); value = temp; } + CUSTOM private void Serializec (ref char value) { + // pre-Unity 2.5 serialized .NET chars as single bytes. Let's keep it backwards compatible for now. + // on big endian the lower order bits of the 2 byte .NET Char value contains the actual bits we need to send + #if UNITY_BIG_ENDIAN + char* hack = reinterpret_cast<char*>(&value)+1; + #else + char* hack = reinterpret_cast<char*>(&value); + #endif + CHECK_PTR GET->Serialize(*hack); + } + CUSTOM private void Serializes (ref short value) { CHECK_PTR GET->Serialize(value); } + CUSTOM private void Serializei (ref int value) { CHECK_PTR GET->Serialize(reinterpret_cast<SInt32&>(value)); } + CUSTOM private void Serializef (ref float value, float maximumDelta) { CHECK_PTR GET->Serialize(value, maximumDelta); } + CUSTOM private void Serializeq (ref Quaternion value, float maximumDelta) { CHECK_PTR GET->Serialize(value, maximumDelta); } + CUSTOM private void Serializev (ref Vector3 value, float maximumDelta) { CHECK_PTR GET->Serialize(value, maximumDelta); } + CUSTOM private void Serializen (ref NetworkViewID viewID) { CHECK_PTR GET->Serialize(viewID); } + + ///*listonly* + CSRAW public void Serialize(ref bool value) { int cross = value ? 1 : 0; Serializeb( ref cross ); value = cross == 0 ? false : true; } + ///*listonly* + CSRAW public void Serialize(ref char value) { Serializec( ref value ); } + ///*listonly* + CSRAW public void Serialize(ref short value) { Serializes( ref value); } + ///*listonly* + CSRAW public void Serialize(ref int value) { Serializei( ref value); } + ///*listonly* + CSRAW public void Serialize(ref float value, float maxDelta = 0.00001F) { Serializef( ref value, maxDelta); } + ///*listonly* + CSRAW public void Serialize(ref Quaternion value, float maxDelta = 0.00001F) { Serializeq( ref value, maxDelta); } + ///*listonly* + CSRAW public void Serialize(ref Vector3 value, float maxDelta = 0.00001F) { Serializev( ref value, maxDelta); } + ///*listonly* + CSRAW public void Serialize(ref NetworkPlayer value) { int index = value.index; Serializei( ref index ); value.index = index;} + // Serializes different types of variables. + CSRAW public void Serialize(ref NetworkViewID viewID) { Serializen(ref viewID); } + + // Is the BitStream currently being read? (RO) + CUSTOM_PROP bool isReading { CHECK_PTR return GET->IsReading(); } + // Is the BitStream currently being written? (RO) + CUSTOM_PROP bool isWriting { CHECK_PTR return GET->IsWriting(); } + + CUSTOM private void Serialize (ref string value) + { + CHECK_PTR + std::string cppValue; + if (GET->IsWriting()) + cppValue = value; + + GET->Serialize(cppValue); + + if (GET->IsReading()) + value.str = scripting_string_new(cppValue); + } + + C++RAW + #undef GET + + C++RAW + #undef CHECK + +END + + +// Attribute for setting up RPC functions. +CONDITIONAL ENABLE_NETWORK +CSRAW [AttributeUsage(AttributeTargets.Method, AllowMultiple=true)] +CLASS RPC : Attribute +END + +// This is the data structure for holding individual host information. +CONDITIONAL ENABLE_NETWORK +CSRAW [StructLayout (LayoutKind.Sequential)] +CLASS HostData + CSRAW private int m_Nat; + CSRAW private string m_GameType; + CSRAW private string m_GameName; + CSRAW private int m_ConnectedPlayers; + CSRAW private int m_PlayerLimit; + CSRAW private string[] m_IP; + CSRAW private int m_Port; + CSRAW private int m_PasswordProtected; + CSRAW private string m_Comment; + CSRAW private string m_GUID; + + // Does this server require NAT punchthrough? + + CSRAW public bool useNat { get { return m_Nat != 0; } set { m_Nat = value ? 1 : 0; } } + // The type of the game (like "MyUniqueGameType") + CSRAW public string gameType { get { return m_GameType; } set { m_GameType = value; } } + + // The name of the game (like John Doe's Game) + CSRAW public string gameName { get { return m_GameName; } set { m_GameName = value; } } + + // Currently connected players + CSRAW public int connectedPlayers { get { return m_ConnectedPlayers; } set { m_ConnectedPlayers = value; } } + + // Maximum players limit + CSRAW public int playerLimit { get { return m_PlayerLimit; } set { m_PlayerLimit = value; } } + // Server IP address + CSRAW public string[] ip { get { return m_IP; } set { m_IP = value; } } + + // Server port + CSRAW public int port { get { return m_Port; } set { m_Port = value; } } + + // Does the server require a password? + CSRAW public bool passwordProtected { get { return m_PasswordProtected != 0; } set { m_PasswordProtected = value ? 1 : 0; } } + + // A miscellaneous comment (can hold data) + CSRAW public string comment { get { return m_Comment; } set { m_Comment = value; } } + + // The GUID of the host, needed when connecting with NAT punchthrough. + CSRAW public string guid { get { return m_GUID; } set { m_GUID = value; } } +END + +C++RAW + +struct HostDataCpp +{ + int useNat; + MonoString* gameType; + MonoString* gameName; + int connectedPlayers; + int playerLimit; + MonoArray* IP; + int port; + int passwordProtected; + MonoString* comment; + MonoString* guid; +}; + + +// The Master Server is used to make matchmaking between servers and clients easy. +CONDITIONAL ENABLE_NETWORK +CLASS MasterServer + + // Called on clients or servers when there is a problem connecting to the master server. + CSNONE void OnFailedToConnectToMasterServer (NetworkConnectionError error); + + // Called on clients or servers when reporting events from the MasterServer. + CSNONE void OnMasterServerEvent (MasterServerEvent msEvent); + + // The IP address of the master server. + CUSTOM_PROP static string ipAddress { return scripting_string_new(GetMasterServerInterface().GetIPAddress());} { GetMasterServerInterface().SetIPAddress(value);} + + // The connection port of the master server. + CUSTOM_PROP static int port { return GetMasterServerInterface().GetPort();} { GetMasterServerInterface().SetPort(value);} + + // Request a host list from the master server. + CUSTOM static void RequestHostList(string gameTypeName) { GetMasterServerInterface().QueryHostList(gameTypeName); } + + // Check for the latest host list received by using MasterServer.RequestHostList. + CUSTOM static HostData[] PollHostList() + { + const std::vector<HostData>& data = GetMasterServerInterface().PollHostList(); + MonoClass* hostType = GetMonoManager ().GetCommonClasses ().hostData; + + //if (data == NULL) return NULL; + + //count = 0; + + MonoArray* array = mono_array_new (mono_domain_get (), hostType, data.size()); + for (int i = 0; i < data.size(); i++) + { + MonoObject* element = mono_object_new(mono_domain_get(), hostType); + GetMonoArrayElement<MonoObject*> (array, i) = element; + HostDataCpp& dst = ExtractMonoObjectData<HostDataCpp> (element); + HostData src = data[i]; + + dst.useNat = src.useNat; + dst.gameType = scripting_string_new(src.gameType); + dst.gameName = scripting_string_new(src.gameName); + dst.connectedPlayers = src.connectedPlayers; + dst.playerLimit = src.playerLimit; + MonoArray* ips = mono_array_new (mono_domain_get (), mono_get_string_class(), src.IP.size()); + for (int i = 0; i < src.IP.size(); i++) + { + GetMonoArrayElement<MonoString*> (ips, i) = scripting_string_new(src.IP[i]); + } + dst.IP = ips; + dst.port = src.port; + dst.passwordProtected = src.passwordProtected; + dst.comment = scripting_string_new(src.comment); + dst.guid = scripting_string_new(src.guid); + } + + return array; + } + + // Register this server on the master server. + CUSTOM static void RegisterHost(string gameTypeName, string gameName, string comment = "") { GetMasterServerInterface().RegisterHost(gameTypeName, gameName, comment); } + + // Unregister this server from the master server. + CUSTOM static void UnregisterHost() { GetMasterServerInterface().UnregisterHost(); } + + // Clear the host list which was received by MasterServer.PollHostList. + CUSTOM static void ClearHostList() { GetMasterServerInterface().ClearHostList(); } + + // Set the minimum update rate for master server host information update. + CUSTOM_PROP static int updateRate { return GetMasterServerInterface().GetUpdateRate();} { GetMasterServerInterface().SetUpdateRate(value);} + + // Report this machine as a dedicated server. + CUSTOM_PROP static bool dedicatedServer { return GetMasterServerInterface().GetDedicatedServer(); } { GetMasterServerInterface().SetDedicatedServer(value); } +END + +// This data structure contains information on a message just received from the network. +CONDITIONAL ENABLE_NETWORK +STRUCT NetworkMessageInfo + CSRAW + double m_TimeStamp; + NetworkPlayer m_Sender; + NetworkViewID m_ViewID; + + // The time stamp when the Message was sent in seconds. + CSRAW public double timestamp { get { return m_TimeStamp; } } + + // The player who sent this network message (owner) + CSRAW public NetworkPlayer sender { get { return m_Sender; } } + + // The [[NetworkView]] who sent this message + CSRAW public NetworkView networkView + { + get + { + if (m_ViewID == NetworkViewID.unassigned) + { + Debug.LogError("No NetworkView is assigned to this NetworkMessageInfo object. Note that this is expected in OnNetworkInstantiate()."); + return NullNetworkView(); + } + return NetworkView.Find(m_ViewID); + } + } + + CUSTOM internal NetworkView NullNetworkView() { return Scripting::ScriptingObjectNULL (ScriptingClassFor (NetworkView)); } + +END + + +CSRAW } +#endif + diff --git a/Runtime/Export/ParticleSystemBindings.txt b/Runtime/Export/ParticleSystemBindings.txt new file mode 100644 index 0000000..f3d3a07 --- /dev/null +++ b/Runtime/Export/ParticleSystemBindings.txt @@ -0,0 +1,413 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +//#include "Runtime/Graphics/ParticleSystem/ParticleCollisionEvents.h" +#include "Runtime/Graphics/ParticleSystem/ParticleSystem.h" +#include "Runtime/Graphics/ParticleSystem/ParticleSystemRenderer.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Filters/Mesh/LodMesh.h" +#include "Runtime/Scripting/Scripting.h" +#if ENABLE_PHYSICS +#include "Runtime/Dynamics/Collider.h" +#endif + +#if UNITY_EDITOR +#include "Editor/Src/ParticleSystem/ParticleSystemEditor.h" +#endif + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Collections.Generic; + +namespace UnityEngine +{ + +C++RAW + +// The rendering mode for particle systems (Shuriken). +ENUM ParticleSystemRenderMode + // Render particles as billboards facing the player. (Default) + Billboard = 0, + // Stretch particles in the direction of motion. + Stretch = 1, + // Render particles as billboards always facing up along the y-Axis. + HorizontalBillboard = 2, + // Render particles as billboards always facing the player, but not pitching along the x-Axis. + VerticalBillboard = 3, + + // Render particles as meshes. + Mesh = 4 +END + +// The simulation space for particle systems (Shuriken). +ENUM ParticleSystemSimulationSpace + // Use local simulation space. (Default) + Local = 0, + // Use world simulation space. + World = 1 +END + +// Script interface for particle systems (Shuriken). + +CLASS ParticleSystem : Component + +// Script interface for a Particle +STRUCT Particle + CSRAW + private Vector3 m_Position; + private Vector3 m_Velocity; + private Vector3 m_AnimatedVelocity; + private Vector3 m_AxisOfRotation; + private float m_Rotation; + private float m_AngularVelocity; + private float m_Size; + private Color32 m_Color; + private UInt32 m_RandomSeed; + private float m_Lifetime; + private float m_StartLifetime; + private float m_EmitAccumulator0; + private float m_EmitAccumulator1; + + // The position of the particle. + CSRAW public Vector3 position { get { return m_Position; } set { m_Position = value; } } + + // The velocity of the particle. + CSRAW public Vector3 velocity { get { return m_Velocity; } set { m_Velocity = value; } } + + // The lifetime of the particle. + CSRAW public float lifetime { get { return m_Lifetime; } set { m_Lifetime = value; } } + + // The starting lifetime of the particle. + CSRAW public float startLifetime { get { return m_StartLifetime; } set { m_StartLifetime = value; } } + + // The size of the particle. + CSRAW public float size { get { return m_Size; } set { m_Size = value; } } + + // The rotation axis of the particle. + CSRAW public Vector3 axisOfRotation { get { return m_AxisOfRotation; } set { m_AxisOfRotation = value; } } + + // The rotation of the particle. + CSRAW public float rotation { get { return m_Rotation * Mathf.Rad2Deg; } set { m_Rotation = value * Mathf.Deg2Rad; } } + + // The angular velocity of the particle. + CSRAW public float angularVelocity { get { return m_AngularVelocity * Mathf.Rad2Deg; } set { m_AngularVelocity = value * Mathf.Deg2Rad; } } + + // The color of the particle. + CSRAW public Color32 color { get { return m_Color; } set { m_Color = value; } } + + // The random value of the particle. + CONDITIONAL !UNITY_FLASH + OBSOLETE warning randomValue property is deprecated. Use randomSeed instead to control random behavior of particles. + CSRAW public float randomValue { get { return BitConverter.ToSingle(BitConverter.GetBytes(m_RandomSeed), 0); } set { m_RandomSeed = BitConverter.ToUInt32(BitConverter.GetBytes(value), 0); } } + + // The random seed of the particle. + CSRAW public UInt32 randomSeed { get { return m_RandomSeed; } set { m_RandomSeed = value; } } +END + +CONDITIONAL ENABLE_PHYSICS +CUSTOM static internal Collider InstanceIDToCollider(int instanceID) + { + return instanceID != 0 ? Scripting::ScriptingWrapperFor (PPtr<Collider> (instanceID)) : SCRIPTING_NULL; + } + +// Script interface for a Particle collision event +STRUCT CollisionEvent + CSRAW + private Vector3 m_Intersection; + private Vector3 m_Normal; + private Vector3 m_Velocity; + private int m_ColliderInstanceID; + + CSRAW public Vector3 intersection { get { return m_Intersection; } } + CSRAW public Vector3 normal { get { return m_Normal; } } + CSRAW public Vector3 velocity { get { return m_Velocity; } } + CONDITIONAL ENABLE_PHYSICS + CSRAW public Collider collider { get { return InstanceIDToCollider(m_ColliderInstanceID); } } +END + + // Start delay in seconds. + SYNC_JOBS AUTO_PROP float startDelay GetStartDelay SetStartDelay + + // Is the particle system playing right now ? + SYNC_JOBS AUTO_PROP bool isPlaying IsPlaying + + // Is the particle system stopped right now ? + SYNC_JOBS AUTO_PROP bool isStopped IsStopped + + // Is the particle system paused right now ? + SYNC_JOBS AUTO_PROP bool isPaused IsPaused + + // Is the particle system looping? + SYNC_JOBS AUTO_PROP bool loop GetLoop SetLoop + + // If set to true, the particle system will automatically start playing on startup. + SYNC_JOBS AUTO_PROP bool playOnAwake GetPlayOnAwake SetPlayOnAwake + + // Playback position in seconds. + SYNC_JOBS AUTO_PROP float time GetSecPosition SetSecPosition + + // The duration of the particle system in seconds (Read Only) + SYNC_JOBS AUTO_PROP float duration GetLengthInSec + + // The playback speed of the particle system. 1 is normal playback speed. + SYNC_JOBS AUTO_PROP float playbackSpeed GetPlaybackSpeed SetPlaybackSpeed + + // The current number of particles (Read Only). + SYNC_JOBS AUTO_PROP int particleCount GetParticleCount + + // Safe array size for the collision event array used with GetCollisionEvents (Read Only). + AUTO_PROP int safeCollisionEventSize GetSafeCollisionEventSize + + // When set to false, the particle system will not emit particles + SYNC_JOBS AUTO_PROP bool enableEmission GetEnableEmission SetEnableEmission + + // The rate of emission + SYNC_JOBS AUTO_PROP float emissionRate GetEmissionRate SetEmissionRate + + // The initial speed of particles when emitted. When using curves, this values acts as a scale on the curve. + SYNC_JOBS AUTO_PROP float startSpeed GetStartSpeed SetStartSpeed + + // The initial size of particles when emitted. When using curves, this values acts as a scale on the curve. + SYNC_JOBS AUTO_PROP float startSize GetStartSize SetStartSize + + // The initial color of particles when emitted. + SYNC_JOBS AUTO_PROP Color startColor GetStartColor SetStartColor + + // The initial rotation of particles when emitted. When using curves, this values acts as a scale on the curve. + SYNC_JOBS AUTO_PROP float startRotation GetStartRotation SetStartRotation + + // The total lifetime in seconds that particles will have when emitted. When using curves, this values acts as a scale on the curve. This value is set in the particle when it is create by the particle system. + SYNC_JOBS AUTO_PROP float startLifetime GetStartLifeTime SetStartLifeTime + + // Scale being applied to the gravity defined by [[Physics.gravity]]. + SYNC_JOBS AUTO_PROP float gravityModifier GetGravityModifier SetGravityModifier + + // Maximum number of particles. + SYNC_JOBS AUTO_PROP int maxParticles GetMaxNumParticles SetMaxNumParticles + + // Selects the space in which to simulate particles; can be local (default) or world. + SYNC_JOBS AUTO_PROP ParticleSystemSimulationSpace simulationSpace GetSimulationSpace SetSimulationSpace + + // Random seed used for the particle system emission. If set to 0, it will be assigned a random value on awake. + SYNC_JOBS AUTO_PROP UInt32 randomSeed GetRandomSeed SetRandomSeed + + // Set the particles of this particle system. /size/ is the number of particles that is set. + SYNC_JOBS CUSTOM void SetParticles (ParticleSystem.Particle[] particles, int size) + { + unsigned int actualSize = GetScriptingArraySize(particles); + if (size < 0 || actualSize < size) + size = actualSize; + + self->SetParticlesExternal (Scripting::GetScriptingArrayStart<ParticleSystemParticle>(particles), size); + } + + // Get the particles of this particle system. Returns the number of particles written to the input particle array. + SYNC_JOBS CUSTOM int GetParticles (ParticleSystem.Particle[] particles) + { + int size = std::min<unsigned int>(self->GetParticleCount(), GetScriptingArraySize(particles)); + self->GetParticlesExternal (Scripting::GetScriptingArrayStart<ParticleSystemParticle>(particles), size); + return size; + } + + // Get the particle collision events recorded for this particle system. Returns the number of particles written to the input collision event array. + CUSTOM int GetCollisionEvents (GameObject go, ParticleSystem.CollisionEvent[] collisionEvents) + { + return self->GetCollisionEventsExternal (go->GetInstanceID (), Scripting::GetScriptingArrayStart<MonoParticleCollisionEvent>(collisionEvents), GetScriptingArraySize(collisionEvents)); + } + + SYNC_JOBS CUSTOM private void Internal_Simulate (float t, bool restart) { self->Simulate (t, restart); } + SYNC_JOBS CUSTOM private void Internal_Play () { self->Play (); } + SYNC_JOBS CUSTOM private void Internal_Stop () { self->Stop (); } + SYNC_JOBS CUSTOM private void Internal_Pause () { self->Pause (); } + SYNC_JOBS CUSTOM private void Internal_Clear () { self->Clear (); } + SYNC_JOBS CUSTOM private bool Internal_IsAlive () { return self->IsAlive(); } + + // Fastforwards the particle system by simulating particles over given period of time, then pauses it. + CSRAW public void Simulate (float t, bool withChildren = true, bool restart = true) + { + if (withChildren) + { + ParticleSystem[] emitters = GetParticleSystems (this); + foreach (var emitter in emitters) + emitter.Internal_Simulate (t, restart); + } + else + { + Internal_Simulate (t, restart); + } + } + + // Plays the particle system. + CSRAW public void Play (bool withChildren = true) + { + if (withChildren) + { + ParticleSystem[] emitters = GetParticleSystems (this); + foreach (var emitter in emitters) + emitter.Internal_Play (); + } + else + { + Internal_Play (); + } + } + + // Stops playing the particle system. + CSRAW public void Stop (bool withChildren = true) + { + if (withChildren) + { + ParticleSystem[] emitters = GetParticleSystems (this); + foreach (var emitter in emitters) + emitter.Internal_Stop (); + } + else + { + Internal_Stop (); + } + } + + // Pauses playing the particle system. + CSRAW public void Pause (bool withChildren = true) + { + if (withChildren) + { + ParticleSystem[] emitters = GetParticleSystems (this); + foreach (var emitter in emitters) + emitter.Internal_Pause (); + } + else + { + Internal_Pause (); + } + + } + + // Remove all particles in the particle system + CSRAW public void Clear (bool withChildren = true) + { + if (withChildren) + { + ParticleSystem[] emitters = GetParticleSystems (this); + foreach (var emitter in emitters) + emitter.Internal_Clear (); + } + else + { + Internal_Clear (); + } + } + + // Is the particle system done emitting particles and are all particles dead? + CSRAW public bool IsAlive (bool withChildren = true) + { + if (withChildren) + { + ParticleSystem[] emitters = GetParticleSystems (this); + foreach (var emitter in emitters) + if(emitter.Internal_IsAlive()) + return true; + return false; + } + + return this.Internal_IsAlive (); + } + + // Emit /count/ particles immediately. + SYNC_JOBS AUTO void Emit (int count); + + // Emit a single particle with given parameters. + CSRAW public void Emit(Vector3 position, Vector3 velocity, float size, float lifetime, Color32 color) + { + ParticleSystem.Particle particle = new ParticleSystem.Particle(); + particle.position = position; + particle.velocity = velocity; + particle.lifetime = lifetime; + particle.startLifetime = lifetime; + particle.size = size; + particle.rotation = 0.0f; + particle.angularVelocity = 0.0f; + particle.color = color; + particle.randomSeed = 5; + Internal_Emit(ref particle); + } + + // Emit a single particle. + CSRAW public void Emit(ParticleSystem.Particle particle) + { + Internal_Emit(ref particle); + } + + SYNC_JOBS CUSTOM private void Internal_Emit (ref ParticleSystem.Particle particle) + { + self->EmitParticleExternal (&particle); + } + + + // Returns a list with 'root' and all its direct children. + CSRAW static internal ParticleSystem[] GetParticleSystems (ParticleSystem root) + { + if (!root) + return null; + + List<ParticleSystem> particleSystems = new List<ParticleSystem>(); + particleSystems.Add(root); + GetDirectParticleSystemChildrenRecursive(root.transform, particleSystems); + return particleSystems.ToArray(); + } + + // Adds only active Particle Systems + CSRAW static private void GetDirectParticleSystemChildrenRecursive(Transform transform, List<ParticleSystem> particleSystems) + { + foreach (Transform childTransform in transform) + { + ParticleSystem ps = childTransform.gameObject.GetComponent<ParticleSystem>(); + if (ps != null) + { + // Note: we do not check for if the gameobject is active (we want inactive particle systems as well due prefabs) + particleSystems.Add (ps); + GetDirectParticleSystemChildrenRecursive(childTransform, particleSystems); + } + } + } + + CONDITIONAL UNITY_EDITOR + //*undocumented + CUSTOM internal void SetupDefaultType (int type) + { + ParticleSystemEditor::SetupDefaultParticleSystemType(*self, (ParticleSystemSubType)type); + } +END + +// Renders particles on to the screen (Shuriken). +CLASS ParticleSystemRenderer : Renderer + + // How particles are drawn. + AUTO_PROP ParticleSystemRenderMode renderMode GetRenderMode SetRenderMode + + // How much are the particles stretched in their direction of motion. + AUTO_PROP float lengthScale GetLengthScale SetLengthScale + + // How much are the particles strectched depending on "how fast they move" + AUTO_PROP float velocityScale GetVelocityScale SetVelocityScale + + // How much are the particles strected depending on the [[Camera]]'s speed. + AUTO_PROP float cameraVelocityScale GetCameraVelocityScale SetCameraVelocityScale + + // Clamp the maximum particle size. + AUTO_PROP float maxParticleSize GetMaxParticleSize SetMaxParticleSize + + // Mesh used as particle instead of billboarded texture + AUTO_PTR_PROP Mesh mesh GetMesh SetMesh + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP internal bool editorEnabled { return self->GetEditorEnabled();} {self->SetEditorEnabled(value);} +END + +CSRAW +} diff --git a/Runtime/Export/PlayerPrefsBindings.txt b/Runtime/Export/PlayerPrefsBindings.txt new file mode 100644 index 0000000..331886e --- /dev/null +++ b/Runtime/Export/PlayerPrefsBindings.txt @@ -0,0 +1,115 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Utilities/PathNameUtility.h" +#include "Runtime/Profiler/ProfilerHistory.h" +#include "Runtime/Allocator/MemoryManager.h" +#include "Runtime/Animation/Animation.h" +#include "Runtime/Utilities/PlayerPrefs.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/GetComponent.h" +#include "Runtime/Scripting/Backend/ScriptingBackendApi.h" +#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h" + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; +using UnityEngineInternal; + +namespace UnityEngine +{ + + +// This exception is thrown by the [[PlayerPrefs]] class in the Web player if the preference file would exceed the allotted storage space when setting a value. +CLASS PlayerPrefsException : Exception + + //*undocumented* + CSRAW public PlayerPrefsException(string error) : base(error) {} +END + +// Stores and accesses player preferences between game sessions. +CLASS PlayerPrefs + CUSTOM private static bool TrySetInt (string key, int value) { return (int)PlayerPrefs::SetInt (key, value); } + CUSTOM private static bool TrySetFloat (string key, float value) { return (int)PlayerPrefs::SetFloat (key, value); } + CUSTOM private static bool TrySetSetString (string key, string value) { return (int)PlayerPrefs::SetString (key, value); } + + // Sets the value of the preference identified by /key/. + CSRAW public static void SetInt (string key, int value) { if( ! TrySetInt(key, value) ) throw new PlayerPrefsException("Could not store preference value"); } + + + // Returns the value corresponding to /key/ in the preference file if it exists. + CUSTOM static int GetInt (string key, int defaultValue = 0) { return PlayerPrefs::GetInt (key, defaultValue); } + + // Sets the value of the preference identified by /key/. + CSRAW public static void SetFloat (string key, float value) { if( ! TrySetFloat(key, value) ) throw new PlayerPrefsException("Could not store preference value"); } + + // Returns the value corresponding to /key/ in the preference file if it exists. + CUSTOM static float GetFloat (string key, float defaultValue = 0.0F) { return PlayerPrefs::GetFloat (key, defaultValue); } + + // Sets the value of the preference identified by /key/. + CSRAW public static void SetString (string key, string value) { if( ! TrySetSetString(key, value) ) throw new PlayerPrefsException("Could not store preference value"); } + + + // Returns the value corresponding to /key/ in the preference file if it exists. + CUSTOM static string GetString (string key, string defaultValue = "") { return scripting_string_new (PlayerPrefs::GetString (key, defaultValue)); } + + // Returns true if /key/ exists in the preferences. + CUSTOM static bool HasKey(string key) { return (int)PlayerPrefs::HasKey(key); } + + // Removes /key/ and its corresponding value from the preferences. + CUSTOM static void DeleteKey(string key) { PlayerPrefs::DeleteKey(key); } + + // Removes all keys and values from the preferences. Use with caution. + CUSTOM static void DeleteAll() { PlayerPrefs::DeleteAll(); } + + // Writes all modified preferences to disk. + CUSTOM static void Save() { PlayerPrefs::Sync(); } + + + // Transfers PlayerPrefs content to and from an array of bytes. Can be useful to implement save/load game functionality. + CONDITIONAL UNITY_WII_API + CUSTOM_PROP static byte[] rawData + { + PlayerPrefs::RawData data; + #if (UNITY_WIN || UNITY_WII) + if (PlayerPrefs::GetRawData(data)) + { + return CreateScriptingArray(&data[0], data.size(), GetMonoManager().GetCommonClasses().byte); + } + else + { + return CreateEmptyStructArray(GetMonoManager().GetCommonClasses().byte); + } + #else + return CreateEmptyStructArray(GetMonoManager().GetCommonClasses().byte); + #endif + } + { + size_t size = GetScriptingArraySize(value); + UInt8 const* begin = Scripting::GetScriptingArrayStart<UInt8>(value); + UInt8 const* end = begin + size; + PlayerPrefs::RawData data (begin, end); + #if (UNITY_WIN || UNITY_WII) + if (!PlayerPrefs::SetRawData(data)) + printf_console ("Failed to load PlayerPrefs from rawData (size:%d)\n", size); + #endif + } + +END + +CSRAW } + diff --git a/Runtime/Export/PropertyAttribute.cs b/Runtime/Export/PropertyAttribute.cs new file mode 100644 index 0000000..f008483 --- /dev/null +++ b/Runtime/Export/PropertyAttribute.cs @@ -0,0 +1,46 @@ +using System; + +namespace UnityEngine +{ + +// Base class to derive custom property attributes from. Use this to create custom attributes for script variables. +[System.AttributeUsage (AttributeTargets.Field, Inherited = true, AllowMultiple = false)] +public abstract class PropertyAttribute : Attribute +{ +} + +// Attribute used to make a float or int variable in a script be restricted to a specific range. +[System.AttributeUsage (AttributeTargets.Field, Inherited = true, AllowMultiple = false)] +public sealed class RangeAttribute : PropertyAttribute +{ + public readonly float min; + public readonly float max; + + // Attribute used to make a float or int variable in a script be restricted to a specific range. + public RangeAttribute (float min, float max) + { + this.min = min; + this.max = max; + } +} + + +// Attribute to make a string be edited with a multi-line textfield +[System.AttributeUsage (AttributeTargets.Field, Inherited = true, AllowMultiple = false)] +public sealed class MultilineAttribute : PropertyAttribute +{ + public readonly int lines; + + public MultilineAttribute () + { + this.lines = 3; + } + // Attribute used to make a string value be shown in a multiline textarea. + public MultilineAttribute (int lines) + { + this.lines = lines; + } + +} + +} diff --git a/Runtime/Export/ScriptAssets.txt b/Runtime/Export/ScriptAssets.txt new file mode 100644 index 0000000..6002497 --- /dev/null +++ b/Runtime/Export/ScriptAssets.txt @@ -0,0 +1,33 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/TextAsset.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + + +namespace UnityEngine +{ + +// Text file assets. +NONSEALED_CLASS TextAsset : Object + // The text contents of the .txt file as a string. (RO) + CUSTOM_PROP string text { return scripting_string_new(self->GetScript().c_str()); } + + // The raw bytes of the text asset. (RO) + + CUSTOM_PROP byte[] bytes { return CreateScriptingArray( self->GetScript().c_str(), self->GetScript().size(), GetScriptingManager().GetCommonClasses().byte ); } + + CSRAW public override string ToString() { return text; } +END + + +CSRAW +} diff --git a/Runtime/Export/ScriptRefImages/AlignPosition.png b/Runtime/Export/ScriptRefImages/AlignPosition.png Binary files differnew file mode 100644 index 0000000..e352bb4 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/AlignPosition.png diff --git a/Runtime/Export/ScriptRefImages/Aligner.png b/Runtime/Export/ScriptRefImages/Aligner.png Binary files differnew file mode 100644 index 0000000..fe7de69 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/Aligner.png diff --git a/Runtime/Export/ScriptRefImages/ArrowCap.png b/Runtime/Export/ScriptRefImages/ArrowCap.png Binary files differnew file mode 100644 index 0000000..887b1ab --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ArrowCap.png diff --git a/Runtime/Export/ScriptRefImages/BeginEndGUI.png b/Runtime/Export/ScriptRefImages/BeginEndGUI.png Binary files differnew file mode 100644 index 0000000..b74a062 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/BeginEndGUI.png diff --git a/Runtime/Export/ScriptRefImages/BeginEndHorizontalExample.png b/Runtime/Export/ScriptRefImages/BeginEndHorizontalExample.png Binary files differnew file mode 100644 index 0000000..f586c17 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/BeginEndHorizontalExample.png diff --git a/Runtime/Export/ScriptRefImages/BeginEndScrollView.png b/Runtime/Export/ScriptRefImages/BeginEndScrollView.png Binary files differnew file mode 100644 index 0000000..1cf1ac5 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/BeginEndScrollView.png diff --git a/Runtime/Export/ScriptRefImages/BeginEndVerticalExample.png b/Runtime/Export/ScriptRefImages/BeginEndVerticalExample.png Binary files differnew file mode 100644 index 0000000..91fcc44 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/BeginEndVerticalExample.png diff --git a/Runtime/Export/ScriptRefImages/ButtonHandle.png b/Runtime/Export/ScriptRefImages/ButtonHandle.png Binary files differnew file mode 100644 index 0000000..d1a7f84 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ButtonHandle.png diff --git a/Runtime/Export/ScriptRefImages/CameraViewer.png b/Runtime/Export/ScriptRefImages/CameraViewer.png Binary files differnew file mode 100644 index 0000000..a2cef2c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CameraViewer.png diff --git a/Runtime/Export/ScriptRefImages/CircleCap.png b/Runtime/Export/ScriptRefImages/CircleCap.png Binary files differnew file mode 100644 index 0000000..c33631e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CircleCap.png diff --git a/Runtime/Export/ScriptRefImages/ClearEditorPrefs.png b/Runtime/Export/ScriptRefImages/ClearEditorPrefs.png Binary files differnew file mode 100644 index 0000000..7783168 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ClearEditorPrefs.png diff --git a/Runtime/Export/ScriptRefImages/CloneObjects.png b/Runtime/Export/ScriptRefImages/CloneObjects.png Binary files differnew file mode 100644 index 0000000..7b244e2 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CloneObjects.png diff --git a/Runtime/Export/ScriptRefImages/ConeCap.png b/Runtime/Export/ScriptRefImages/ConeCap.png Binary files differnew file mode 100644 index 0000000..15be1ab --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ConeCap.png diff --git a/Runtime/Export/ScriptRefImages/CubeCap.png b/Runtime/Export/ScriptRefImages/CubeCap.png Binary files differnew file mode 100644 index 0000000..ac1c82e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CubeCap.png diff --git a/Runtime/Export/ScriptRefImages/CustomEditor.png b/Runtime/Export/ScriptRefImages/CustomEditor.png Binary files differnew file mode 100644 index 0000000..dff5638 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CustomEditor.png diff --git a/Runtime/Export/ScriptRefImages/CustomPropertyDrawer_Class.png b/Runtime/Export/ScriptRefImages/CustomPropertyDrawer_Class.png Binary files differnew file mode 100644 index 0000000..c158ada --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CustomPropertyDrawer_Class.png diff --git a/Runtime/Export/ScriptRefImages/CylinderCap.png b/Runtime/Export/ScriptRefImages/CylinderCap.png Binary files differnew file mode 100644 index 0000000..9feebe9 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/CylinderCap.png diff --git a/Runtime/Export/ScriptRefImages/DiscHandle.png b/Runtime/Export/ScriptRefImages/DiscHandle.png Binary files differnew file mode 100644 index 0000000..ece5ce0 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DiscHandle.png diff --git a/Runtime/Export/ScriptRefImages/DotCap.png b/Runtime/Export/ScriptRefImages/DotCap.png Binary files differnew file mode 100644 index 0000000..2e7c968 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DotCap.png diff --git a/Runtime/Export/ScriptRefImages/DrawAAPolyLine.png b/Runtime/Export/ScriptRefImages/DrawAAPolyLine.png Binary files differnew file mode 100644 index 0000000..bfdd9da --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawAAPolyLine.png diff --git a/Runtime/Export/ScriptRefImages/DrawBezier.png b/Runtime/Export/ScriptRefImages/DrawBezier.png Binary files differnew file mode 100644 index 0000000..e3c1434 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawBezier.png diff --git a/Runtime/Export/ScriptRefImages/DrawLine.png b/Runtime/Export/ScriptRefImages/DrawLine.png Binary files differnew file mode 100644 index 0000000..7a0b378 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawLine.png diff --git a/Runtime/Export/ScriptRefImages/DrawPolyLine.png b/Runtime/Export/ScriptRefImages/DrawPolyLine.png Binary files differnew file mode 100644 index 0000000..bfdd9da --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawPolyLine.png diff --git a/Runtime/Export/ScriptRefImages/DrawSolidArc.png b/Runtime/Export/ScriptRefImages/DrawSolidArc.png Binary files differnew file mode 100644 index 0000000..df308aa --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawSolidArc.png diff --git a/Runtime/Export/ScriptRefImages/DrawSolidDisc.png b/Runtime/Export/ScriptRefImages/DrawSolidDisc.png Binary files differnew file mode 100644 index 0000000..07bd01d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawSolidDisc.png diff --git a/Runtime/Export/ScriptRefImages/DrawSolidRectangle.png b/Runtime/Export/ScriptRefImages/DrawSolidRectangle.png Binary files differnew file mode 100644 index 0000000..281b215 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawSolidRectangle.png diff --git a/Runtime/Export/ScriptRefImages/DrawWireArc.png b/Runtime/Export/ScriptRefImages/DrawWireArc.png Binary files differnew file mode 100644 index 0000000..bfbdf95 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawWireArc.png diff --git a/Runtime/Export/ScriptRefImages/DrawWireDisc.png b/Runtime/Export/ScriptRefImages/DrawWireDisc.png Binary files differnew file mode 100644 index 0000000..0831fdd --- /dev/null +++ b/Runtime/Export/ScriptRefImages/DrawWireDisc.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIActionKey.png b/Runtime/Export/ScriptRefImages/EditorGUIActionKey.png Binary files differnew file mode 100644 index 0000000..ff01d91 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIActionKey.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIBoundsField.png b/Runtime/Export/ScriptRefImages/EditorGUIBoundsField.png Binary files differnew file mode 100644 index 0000000..a7a94b3 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIBoundsField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIColorField.png b/Runtime/Export/ScriptRefImages/EditorGUIColorField.png Binary files differnew file mode 100644 index 0000000..a085068 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIColorField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUICurveField.png b/Runtime/Export/ScriptRefImages/EditorGUICurveField.png Binary files differnew file mode 100644 index 0000000..7241e18 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUICurveField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIDrawPreviewTexture.png b/Runtime/Export/ScriptRefImages/EditorGUIDrawPreviewTexture.png Binary files differnew file mode 100644 index 0000000..898f742 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIDrawPreviewTexture.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIDrawTextureAlpha.png b/Runtime/Export/ScriptRefImages/EditorGUIDrawTextureAlpha.png Binary files differnew file mode 100644 index 0000000..b9fc13f --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIDrawTextureAlpha.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIDropShadowLabel.png b/Runtime/Export/ScriptRefImages/EditorGUIDropShadowLabel.png Binary files differnew file mode 100644 index 0000000..d597b62 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIDropShadowLabel.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIEnumPopup.png b/Runtime/Export/ScriptRefImages/EditorGUIEnumPopup.png Binary files differnew file mode 100644 index 0000000..36e79e0 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIEnumPopup.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIFloatField.png b/Runtime/Export/ScriptRefImages/EditorGUIFloatField.png Binary files differnew file mode 100644 index 0000000..2583c6c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIFloatField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIFoldout.png b/Runtime/Export/ScriptRefImages/EditorGUIFoldout.png Binary files differnew file mode 100644 index 0000000..b9b6690 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIFoldout.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIIndent.png b/Runtime/Export/ScriptRefImages/EditorGUIIndent.png Binary files differnew file mode 100644 index 0000000..fa467fc --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIIndent.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIInspectorTitlebar.png b/Runtime/Export/ScriptRefImages/EditorGUIInspectorTitlebar.png Binary files differnew file mode 100644 index 0000000..2641790 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIInspectorTitlebar.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIIntField.png b/Runtime/Export/ScriptRefImages/EditorGUIIntField.png Binary files differnew file mode 100644 index 0000000..29017e1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIIntField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIIntPopup.png b/Runtime/Export/ScriptRefImages/EditorGUIIntPopup.png Binary files differnew file mode 100644 index 0000000..964f1ec --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIIntPopup.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIIntSlider.png b/Runtime/Export/ScriptRefImages/EditorGUIIntSlider.png Binary files differnew file mode 100644 index 0000000..2ecd884 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIIntSlider.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILabelField.png b/Runtime/Export/ScriptRefImages/EditorGUILabelField.png Binary files differnew file mode 100644 index 0000000..87f09bd --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILabelField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayerField.png b/Runtime/Export/ScriptRefImages/EditorGUILayerField.png Binary files differnew file mode 100644 index 0000000..e31e8e7 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayerField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutEnumPopup.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutEnumPopup.png Binary files differnew file mode 100644 index 0000000..ad932e6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutEnumPopup.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutFloatField.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutFloatField.png Binary files differnew file mode 100644 index 0000000..c5f93de --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutFloatField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutIntField.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutIntField.png Binary files differnew file mode 100644 index 0000000..6ce1c56 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutIntField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutIntPopup.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutIntPopup.png Binary files differnew file mode 100644 index 0000000..b4d04ea --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutIntPopup.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutIntSlider.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutIntSlider.png Binary files differnew file mode 100644 index 0000000..68c2c25 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutIntSlider.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutLabel.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutLabel.png Binary files differnew file mode 100644 index 0000000..a481b45 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutLabel.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutLayerField.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutLayerField.png Binary files differnew file mode 100644 index 0000000..2cef88e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutLayerField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutMinMaxSlider.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutMinMaxSlider.png Binary files differnew file mode 100644 index 0000000..325b0f1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutMinMaxSlider.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutPasswordField.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutPasswordField.png Binary files differnew file mode 100644 index 0000000..38060d0 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutPasswordField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutPopup.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutPopup.png Binary files differnew file mode 100644 index 0000000..46a1739 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutPopup.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutSlider.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutSlider.png Binary files differnew file mode 100644 index 0000000..8917254 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutSlider.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutTagField.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutTagField.png Binary files differnew file mode 100644 index 0000000..2f25d3f --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutTagField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutTextArea.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutTextArea.png Binary files differnew file mode 100644 index 0000000..0603b89 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutTextArea.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutTextField.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutTextField.png Binary files differnew file mode 100644 index 0000000..37eba3a --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutTextField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutToggle.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutToggle.png Binary files differnew file mode 100644 index 0000000..39758e0 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutToggle.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutVector2Field.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutVector2Field.png Binary files differnew file mode 100644 index 0000000..b310776 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutVector2Field.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUILayoutVector3Field.png b/Runtime/Export/ScriptRefImages/EditorGUILayoutVector3Field.png Binary files differnew file mode 100644 index 0000000..378f004 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUILayoutVector3Field.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIMinMaxSlider.png b/Runtime/Export/ScriptRefImages/EditorGUIMinMaxSlider.png Binary files differnew file mode 100644 index 0000000..06f604c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIMinMaxSlider.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIObjectField.png b/Runtime/Export/ScriptRefImages/EditorGUIObjectField.png Binary files differnew file mode 100644 index 0000000..82f8f00 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIObjectField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIPasswordField.png b/Runtime/Export/ScriptRefImages/EditorGUIPasswordField.png Binary files differnew file mode 100644 index 0000000..3d360e1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIPasswordField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIPopup.png b/Runtime/Export/ScriptRefImages/EditorGUIPopup.png Binary files differnew file mode 100644 index 0000000..d9eebc2 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIPopup.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIPrefixLabel.png b/Runtime/Export/ScriptRefImages/EditorGUIPrefixLabel.png Binary files differnew file mode 100644 index 0000000..ff91c97 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIPrefixLabel.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIProgressBar.png b/Runtime/Export/ScriptRefImages/EditorGUIProgressBar.png Binary files differnew file mode 100644 index 0000000..0c42458 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIProgressBar.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIRectField.png b/Runtime/Export/ScriptRefImages/EditorGUIRectField.png Binary files differnew file mode 100644 index 0000000..1abc7dd --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIRectField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUISlider.png b/Runtime/Export/ScriptRefImages/EditorGUISlider.png Binary files differnew file mode 100644 index 0000000..c0c9c04 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUISlider.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUITagField.png b/Runtime/Export/ScriptRefImages/EditorGUITagField.png Binary files differnew file mode 100644 index 0000000..15c5de0 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUITagField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUITextArea.png b/Runtime/Export/ScriptRefImages/EditorGUITextArea.png Binary files differnew file mode 100644 index 0000000..9c4459d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUITextArea.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUITextField.png b/Runtime/Export/ScriptRefImages/EditorGUITextField.png Binary files differnew file mode 100644 index 0000000..36b3f26 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUITextField.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIToggle.png b/Runtime/Export/ScriptRefImages/EditorGUIToggle.png Binary files differnew file mode 100644 index 0000000..f486dfc --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIToggle.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIUtilityFindTexture.png b/Runtime/Export/ScriptRefImages/EditorGUIUtilityFindTexture.png Binary files differnew file mode 100644 index 0000000..db6b86b --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIUtilityFindTexture.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIUtilityLookLikeControls.png b/Runtime/Export/ScriptRefImages/EditorGUIUtilityLookLikeControls.png Binary files differnew file mode 100644 index 0000000..7a5abe3 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIUtilityLookLikeControls.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIUtilityLookLikeInspector.png b/Runtime/Export/ScriptRefImages/EditorGUIUtilityLookLikeInspector.png Binary files differnew file mode 100644 index 0000000..8622855 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIUtilityLookLikeInspector.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIUtilityObjectContent.png b/Runtime/Export/ScriptRefImages/EditorGUIUtilityObjectContent.png Binary files differnew file mode 100644 index 0000000..cf48295 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIUtilityObjectContent.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIUtilitySystemCopyBuffer.png b/Runtime/Export/ScriptRefImages/EditorGUIUtilitySystemCopyBuffer.png Binary files differnew file mode 100644 index 0000000..0c4b362 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIUtilitySystemCopyBuffer.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIUtilityWhiteTexture.png b/Runtime/Export/ScriptRefImages/EditorGUIUtilityWhiteTexture.png Binary files differnew file mode 100644 index 0000000..bac47f5 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIUtilityWhiteTexture.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIVector2Field.png b/Runtime/Export/ScriptRefImages/EditorGUIVector2Field.png Binary files differnew file mode 100644 index 0000000..588b6ef --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIVector2Field.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIVector3Field.png b/Runtime/Export/ScriptRefImages/EditorGUIVector3Field.png Binary files differnew file mode 100644 index 0000000..959bde6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIVector3Field.png diff --git a/Runtime/Export/ScriptRefImages/EditorGUIVector4Field.png b/Runtime/Export/ScriptRefImages/EditorGUIVector4Field.png Binary files differnew file mode 100644 index 0000000..463f740 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorGUIVector4Field.png diff --git a/Runtime/Export/ScriptRefImages/EditorPrefsBool.png b/Runtime/Export/ScriptRefImages/EditorPrefsBool.png Binary files differnew file mode 100644 index 0000000..a7289ef --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorPrefsBool.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtility CreateGameObjectWithHideFlags.png b/Runtime/Export/ScriptRefImages/EditorUtility CreateGameObjectWithHideFlags.png Binary files differnew file mode 100644 index 0000000..365ef91 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtility CreateGameObjectWithHideFlags.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityCollectDependencies.png b/Runtime/Export/ScriptRefImages/EditorUtilityCollectDependencies.png Binary files differnew file mode 100644 index 0000000..134f1b6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityCollectDependencies.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityDisplayCancelableProgressBar.png b/Runtime/Export/ScriptRefImages/EditorUtilityDisplayCancelableProgressBar.png Binary files differnew file mode 100644 index 0000000..6cef1ad --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityDisplayCancelableProgressBar.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityDisplayDialogComplex.png b/Runtime/Export/ScriptRefImages/EditorUtilityDisplayDialogComplex.png Binary files differnew file mode 100644 index 0000000..18d0524 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityDisplayDialogComplex.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityDisplayProgressBar.png b/Runtime/Export/ScriptRefImages/EditorUtilityDisplayProgressBar.png Binary files differnew file mode 100644 index 0000000..4b7d9a6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityDisplayProgressBar.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityFocusProjectWindow.png b/Runtime/Export/ScriptRefImages/EditorUtilityFocusProjectWindow.png Binary files differnew file mode 100644 index 0000000..ae80250 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityFocusProjectWindow.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityInstanceIDToObject.png b/Runtime/Export/ScriptRefImages/EditorUtilityInstanceIDToObject.png Binary files differnew file mode 100644 index 0000000..1a9fea6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityInstanceIDToObject.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityOpenFilePanel.png b/Runtime/Export/ScriptRefImages/EditorUtilityOpenFilePanel.png Binary files differnew file mode 100644 index 0000000..a3f641c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityOpenFilePanel.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilityOpenFolderPanel.png b/Runtime/Export/ScriptRefImages/EditorUtilityOpenFolderPanel.png Binary files differnew file mode 100644 index 0000000..6fe12de --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilityOpenFolderPanel.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilitySaveFilePanel.png b/Runtime/Export/ScriptRefImages/EditorUtilitySaveFilePanel.png Binary files differnew file mode 100644 index 0000000..c785d80 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilitySaveFilePanel.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilitySaveFilePanelInProject.png b/Runtime/Export/ScriptRefImages/EditorUtilitySaveFilePanelInProject.png Binary files differnew file mode 100644 index 0000000..131301f --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilitySaveFilePanelInProject.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilitySaveFolderPanel.png b/Runtime/Export/ScriptRefImages/EditorUtilitySaveFolderPanel.png Binary files differnew file mode 100644 index 0000000..2deba38 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilitySaveFolderPanel.png diff --git a/Runtime/Export/ScriptRefImages/EditorUtilitySetSelectedWireframeHidden.png b/Runtime/Export/ScriptRefImages/EditorUtilitySetSelectedWireframeHidden.png Binary files differnew file mode 100644 index 0000000..65866b6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorUtilitySetSelectedWireframeHidden.png diff --git a/Runtime/Export/ScriptRefImages/EditorWindowPosition.png b/Runtime/Export/ScriptRefImages/EditorWindowPosition.png Binary files differnew file mode 100644 index 0000000..d819e69 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/EditorWindowPosition.png diff --git a/Runtime/Export/ScriptRefImages/ErrorString.png b/Runtime/Export/ScriptRefImages/ErrorString.png Binary files differnew file mode 100644 index 0000000..ddd5831 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ErrorString.png diff --git a/Runtime/Export/ScriptRefImages/FinishCompiling.png b/Runtime/Export/ScriptRefImages/FinishCompiling.png Binary files differnew file mode 100644 index 0000000..7e92eaf --- /dev/null +++ b/Runtime/Export/ScriptRefImages/FinishCompiling.png diff --git a/Runtime/Export/ScriptRefImages/FoldoutUsage.png b/Runtime/Export/ScriptRefImages/FoldoutUsage.png Binary files differnew file mode 100644 index 0000000..07baa98 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/FoldoutUsage.png diff --git a/Runtime/Export/ScriptRefImages/FollowCurve.png b/Runtime/Export/ScriptRefImages/FollowCurve.png Binary files differnew file mode 100644 index 0000000..b89cf3b --- /dev/null +++ b/Runtime/Export/ScriptRefImages/FollowCurve.png diff --git a/Runtime/Export/ScriptRefImages/ForceSync.png b/Runtime/Export/ScriptRefImages/ForceSync.png Binary files differnew file mode 100644 index 0000000..0bc50f5 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ForceSync.png diff --git a/Runtime/Export/ScriptRefImages/FreeMoveHandle.png b/Runtime/Export/ScriptRefImages/FreeMoveHandle.png Binary files differnew file mode 100644 index 0000000..1dcf0cc --- /dev/null +++ b/Runtime/Export/ScriptRefImages/FreeMoveHandle.png diff --git a/Runtime/Export/ScriptRefImages/FreeRotateHandle.png b/Runtime/Export/ScriptRefImages/FreeRotateHandle.png Binary files differnew file mode 100644 index 0000000..7ca4c73 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/FreeRotateHandle.png diff --git a/Runtime/Export/ScriptRefImages/GUIBackgroundColor.png b/Runtime/Export/ScriptRefImages/GUIBackgroundColor.png Binary files differnew file mode 100644 index 0000000..35dda9a --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIBackgroundColor.png diff --git a/Runtime/Export/ScriptRefImages/GUIColor.png b/Runtime/Export/ScriptRefImages/GUIColor.png Binary files differnew file mode 100644 index 0000000..332d4c2 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIColor.png diff --git a/Runtime/Export/ScriptRefImages/GUIContentColor.png b/Runtime/Export/ScriptRefImages/GUIContentColor.png Binary files differnew file mode 100644 index 0000000..1dcdbf1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIContentColor.png diff --git a/Runtime/Export/ScriptRefImages/GUIDepth.png b/Runtime/Export/ScriptRefImages/GUIDepth.png Binary files differnew file mode 100644 index 0000000..3c6f128 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIDepth.png diff --git a/Runtime/Export/ScriptRefImages/GUIEnabled.png b/Runtime/Export/ScriptRefImages/GUIEnabled.png Binary files differnew file mode 100644 index 0000000..3629528 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIEnabled.png diff --git a/Runtime/Export/ScriptRefImages/GUILabel.png b/Runtime/Export/ScriptRefImages/GUILabel.png Binary files differnew file mode 100644 index 0000000..f8a3dfe --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILabel.png diff --git a/Runtime/Export/ScriptRefImages/GUILabelTexture.png b/Runtime/Export/ScriptRefImages/GUILabelTexture.png Binary files differnew file mode 100644 index 0000000..3e08dae --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILabelTexture.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutArea.png b/Runtime/Export/ScriptRefImages/GUILayoutArea.png Binary files differnew file mode 100644 index 0000000..6974460 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutArea.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutBox.png b/Runtime/Export/ScriptRefImages/GUILayoutBox.png Binary files differnew file mode 100644 index 0000000..ff5b9d1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutBox.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutButton.png b/Runtime/Export/ScriptRefImages/GUILayoutButton.png Binary files differnew file mode 100644 index 0000000..1f3b634 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutButton.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutFlexibleSpace.png b/Runtime/Export/ScriptRefImages/GUILayoutFlexibleSpace.png Binary files differnew file mode 100644 index 0000000..0ab248d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutFlexibleSpace.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutHeight.png b/Runtime/Export/ScriptRefImages/GUILayoutHeight.png Binary files differnew file mode 100644 index 0000000..c345eed --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutHeight.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutHorizontal.png b/Runtime/Export/ScriptRefImages/GUILayoutHorizontal.png Binary files differnew file mode 100644 index 0000000..9679169 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutHorizontal.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutHorizontalScrollBar.png b/Runtime/Export/ScriptRefImages/GUILayoutHorizontalScrollBar.png Binary files differnew file mode 100644 index 0000000..e65b69f --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutHorizontalScrollBar.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutHorizontalSlider.png b/Runtime/Export/ScriptRefImages/GUILayoutHorizontalSlider.png Binary files differnew file mode 100644 index 0000000..21c4e97 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutHorizontalSlider.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutLabel.png b/Runtime/Export/ScriptRefImages/GUILayoutLabel.png Binary files differnew file mode 100644 index 0000000..33c7072 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutLabel.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutMaxHeight.png b/Runtime/Export/ScriptRefImages/GUILayoutMaxHeight.png Binary files differnew file mode 100644 index 0000000..37f7d97 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutMaxHeight.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutMaxWidth.png b/Runtime/Export/ScriptRefImages/GUILayoutMaxWidth.png Binary files differnew file mode 100644 index 0000000..45f05c9 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutMaxWidth.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutMinHeight.png b/Runtime/Export/ScriptRefImages/GUILayoutMinHeight.png Binary files differnew file mode 100644 index 0000000..534f5d1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutMinHeight.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutMinWidth.png b/Runtime/Export/ScriptRefImages/GUILayoutMinWidth.png Binary files differnew file mode 100644 index 0000000..4703b2c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutMinWidth.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutPasswordField.png b/Runtime/Export/ScriptRefImages/GUILayoutPasswordField.png Binary files differnew file mode 100644 index 0000000..b6649c3 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutPasswordField.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutScrollView.png b/Runtime/Export/ScriptRefImages/GUILayoutScrollView.png Binary files differnew file mode 100644 index 0000000..4e96b52 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutScrollView.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutSelectionGrid.png b/Runtime/Export/ScriptRefImages/GUILayoutSelectionGrid.png Binary files differnew file mode 100644 index 0000000..33d05c8 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutSelectionGrid.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutSpace.png b/Runtime/Export/ScriptRefImages/GUILayoutSpace.png Binary files differnew file mode 100644 index 0000000..732dd86 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutSpace.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutTextArea.png b/Runtime/Export/ScriptRefImages/GUILayoutTextArea.png Binary files differnew file mode 100644 index 0000000..9eb86ca --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutTextArea.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutTextField.png b/Runtime/Export/ScriptRefImages/GUILayoutTextField.png Binary files differnew file mode 100644 index 0000000..cb53789 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutTextField.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutToggle.png b/Runtime/Export/ScriptRefImages/GUILayoutToggle.png Binary files differnew file mode 100644 index 0000000..e93960b --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutToggle.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutToolbar.png b/Runtime/Export/ScriptRefImages/GUILayoutToolbar.png Binary files differnew file mode 100644 index 0000000..3036479 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutToolbar.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutVertical.png b/Runtime/Export/ScriptRefImages/GUILayoutVertical.png Binary files differnew file mode 100644 index 0000000..7f4a854 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutVertical.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutVerticalScrollBar.png b/Runtime/Export/ScriptRefImages/GUILayoutVerticalScrollBar.png Binary files differnew file mode 100644 index 0000000..9a9db32 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutVerticalScrollBar.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutVerticalSlider.png b/Runtime/Export/ScriptRefImages/GUILayoutVerticalSlider.png Binary files differnew file mode 100644 index 0000000..fd3f5bf --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutVerticalSlider.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutWidth.png b/Runtime/Export/ScriptRefImages/GUILayoutWidth.png Binary files differnew file mode 100644 index 0000000..62ebc6d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutWidth.png diff --git a/Runtime/Export/ScriptRefImages/GUILayoutWindow.png b/Runtime/Export/ScriptRefImages/GUILayoutWindow.png Binary files differnew file mode 100644 index 0000000..840bb6d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUILayoutWindow.png diff --git a/Runtime/Export/ScriptRefImages/GUITooltip.png b/Runtime/Export/ScriptRefImages/GUITooltip.png Binary files differnew file mode 100644 index 0000000..57c49a2 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUITooltip.png diff --git a/Runtime/Export/ScriptRefImages/GUIWindowDemo.png b/Runtime/Export/ScriptRefImages/GUIWindowDemo.png Binary files differnew file mode 100644 index 0000000..525138b --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIWindowDemo.png diff --git a/Runtime/Export/ScriptRefImages/GUIWindowDemo2.png b/Runtime/Export/ScriptRefImages/GUIWindowDemo2.png Binary files differnew file mode 100644 index 0000000..4ae6853 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GUIWindowDemo2.png diff --git a/Runtime/Export/ScriptRefImages/GetWindowEx.png b/Runtime/Export/ScriptRefImages/GetWindowEx.png Binary files differnew file mode 100644 index 0000000..c1e4272 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GetWindowEx.png diff --git a/Runtime/Export/ScriptRefImages/GetWindowRectEx.png b/Runtime/Export/ScriptRefImages/GetWindowRectEx.png Binary files differnew file mode 100644 index 0000000..4d1ea3a --- /dev/null +++ b/Runtime/Export/ScriptRefImages/GetWindowRectEx.png diff --git a/Runtime/Export/ScriptRefImages/HandlesLabel.png b/Runtime/Export/ScriptRefImages/HandlesLabel.png Binary files differnew file mode 100644 index 0000000..6043ac1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/HandlesLabel.png diff --git a/Runtime/Export/ScriptRefImages/HelpString.png b/Runtime/Export/ScriptRefImages/HelpString.png Binary files differnew file mode 100644 index 0000000..d019af4 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/HelpString.png diff --git a/Runtime/Export/ScriptRefImages/InspectorTitlebarUsage.png b/Runtime/Export/ScriptRefImages/InspectorTitlebarUsage.png Binary files differnew file mode 100644 index 0000000..7d4c285 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/InspectorTitlebarUsage.png diff --git a/Runtime/Export/ScriptRefImages/InspectorTitlebarUsageSpace.png b/Runtime/Export/ScriptRefImages/InspectorTitlebarUsageSpace.png Binary files differnew file mode 100644 index 0000000..9432184 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/InspectorTitlebarUsageSpace.png diff --git a/Runtime/Export/ScriptRefImages/LeftHandRuleDiagram.png b/Runtime/Export/ScriptRefImages/LeftHandRuleDiagram.png Binary files differnew file mode 100644 index 0000000..3d83a39 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/LeftHandRuleDiagram.png diff --git a/Runtime/Export/ScriptRefImages/MaskField.png b/Runtime/Export/ScriptRefImages/MaskField.png Binary files differnew file mode 100644 index 0000000..e9248f4 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/MaskField.png diff --git a/Runtime/Export/ScriptRefImages/MassiveColorChange.png b/Runtime/Export/ScriptRefImages/MassiveColorChange.png Binary files differnew file mode 100644 index 0000000..d5616e3 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/MassiveColorChange.png diff --git a/Runtime/Export/ScriptRefImages/MaterialPropertyDrawer_UI.png b/Runtime/Export/ScriptRefImages/MaterialPropertyDrawer_UI.png Binary files differnew file mode 100644 index 0000000..0fd4ea9 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/MaterialPropertyDrawer_UI.png diff --git a/Runtime/Export/ScriptRefImages/ModifyQuaternionDirectly.png b/Runtime/Export/ScriptRefImages/ModifyQuaternionDirectly.png Binary files differnew file mode 100644 index 0000000..2ed8489 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ModifyQuaternionDirectly.png diff --git a/Runtime/Export/ScriptRefImages/MoveResizeSelectedWindow.png b/Runtime/Export/ScriptRefImages/MoveResizeSelectedWindow.png Binary files differnew file mode 100644 index 0000000..d5ed0ee --- /dev/null +++ b/Runtime/Export/ScriptRefImages/MoveResizeSelectedWindow.png diff --git a/Runtime/Export/ScriptRefImages/OrthographicPreviewer.png b/Runtime/Export/ScriptRefImages/OrthographicPreviewer.png Binary files differnew file mode 100644 index 0000000..a613faf --- /dev/null +++ b/Runtime/Export/ScriptRefImages/OrthographicPreviewer.png diff --git a/Runtime/Export/ScriptRefImages/PerformVariousRedo.png b/Runtime/Export/ScriptRefImages/PerformVariousRedo.png Binary files differnew file mode 100644 index 0000000..c5a130e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PerformVariousRedo.png diff --git a/Runtime/Export/ScriptRefImages/PerformVariousUndo.png b/Runtime/Export/ScriptRefImages/PerformVariousUndo.png Binary files differnew file mode 100644 index 0000000..0073f04 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PerformVariousUndo.png diff --git a/Runtime/Export/ScriptRefImages/PerlinExample.png b/Runtime/Export/ScriptRefImages/PerlinExample.png Binary files differnew file mode 100644 index 0000000..142978e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PerlinExample.png diff --git a/Runtime/Export/ScriptRefImages/PlaceSelectionOnSurface.png b/Runtime/Export/ScriptRefImages/PlaceSelectionOnSurface.png Binary files differnew file mode 100644 index 0000000..605c30e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PlaceSelectionOnSurface.png diff --git a/Runtime/Export/ScriptRefImages/Plane3Points.png b/Runtime/Export/ScriptRefImages/Plane3Points.png Binary files differnew file mode 100644 index 0000000..e2b9dbb --- /dev/null +++ b/Runtime/Export/ScriptRefImages/Plane3Points.png diff --git a/Runtime/Export/ScriptRefImages/PlaneNormalOffset.png b/Runtime/Export/ScriptRefImages/PlaneNormalOffset.png Binary files differnew file mode 100644 index 0000000..85af155 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PlaneNormalOffset.png diff --git a/Runtime/Export/ScriptRefImages/PlaneNormalOrigin.png b/Runtime/Export/ScriptRefImages/PlaneNormalOrigin.png Binary files differnew file mode 100644 index 0000000..a29a657 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PlaneNormalOrigin.png diff --git a/Runtime/Export/ScriptRefImages/PlayerSettingsCustomSettings.png b/Runtime/Export/ScriptRefImages/PlayerSettingsCustomSettings.png Binary files differnew file mode 100644 index 0000000..69df5f5 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PlayerSettingsCustomSettings.png diff --git a/Runtime/Export/ScriptRefImages/PositionHandle.png b/Runtime/Export/ScriptRefImages/PositionHandle.png Binary files differnew file mode 100644 index 0000000..f24c2cd --- /dev/null +++ b/Runtime/Export/ScriptRefImages/PositionHandle.png diff --git a/Runtime/Export/ScriptRefImages/QuickHelper.png b/Runtime/Export/ScriptRefImages/QuickHelper.png Binary files differnew file mode 100644 index 0000000..393bd9c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/QuickHelper.png diff --git a/Runtime/Export/ScriptRefImages/QuickHelperObjectField.png b/Runtime/Export/ScriptRefImages/QuickHelperObjectField.png Binary files differnew file mode 100644 index 0000000..9259aeb --- /dev/null +++ b/Runtime/Export/ScriptRefImages/QuickHelperObjectField.png diff --git a/Runtime/Export/ScriptRefImages/QuickNotes.png b/Runtime/Export/ScriptRefImages/QuickNotes.png Binary files differnew file mode 100644 index 0000000..e6b5841 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/QuickNotes.png diff --git a/Runtime/Export/ScriptRefImages/RadiusHandle.png b/Runtime/Export/ScriptRefImages/RadiusHandle.png Binary files differnew file mode 100644 index 0000000..ded8669 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RadiusHandle.png diff --git a/Runtime/Export/ScriptRefImages/RandomizeInSelection.png b/Runtime/Export/ScriptRefImages/RandomizeInSelection.png Binary files differnew file mode 100644 index 0000000..55b3e0d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RandomizeInSelection.png diff --git a/Runtime/Export/ScriptRefImages/RectXMinYMin.png b/Runtime/Export/ScriptRefImages/RectXMinYMin.png Binary files differnew file mode 100644 index 0000000..c024477 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RectXMinYMin.png diff --git a/Runtime/Export/ScriptRefImages/RectXY.png b/Runtime/Export/ScriptRefImages/RectXY.png Binary files differnew file mode 100644 index 0000000..e6ba87b --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RectXY.png diff --git a/Runtime/Export/ScriptRefImages/RectangleCap.png b/Runtime/Export/ScriptRefImages/RectangleCap.png Binary files differnew file mode 100644 index 0000000..2c95a87 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RectangleCap.png diff --git a/Runtime/Export/ScriptRefImages/RemoveSpecificEditorPrefs.png b/Runtime/Export/ScriptRefImages/RemoveSpecificEditorPrefs.png Binary files differnew file mode 100644 index 0000000..a69be5f --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RemoveSpecificEditorPrefs.png diff --git a/Runtime/Export/ScriptRefImages/RotationHandle.png b/Runtime/Export/ScriptRefImages/RotationHandle.png Binary files differnew file mode 100644 index 0000000..e582d09 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/RotationHandle.png diff --git a/Runtime/Export/ScriptRefImages/ScaleHandle.png b/Runtime/Export/ScriptRefImages/ScaleHandle.png Binary files differnew file mode 100644 index 0000000..5053026 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScaleHandle.png diff --git a/Runtime/Export/ScriptRefImages/ScaleSliderHandle.png b/Runtime/Export/ScriptRefImages/ScaleSliderHandle.png Binary files differnew file mode 100644 index 0000000..dfbcbc5 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScaleSliderHandle.png diff --git a/Runtime/Export/ScriptRefImages/ScaleValueHandle.png b/Runtime/Export/ScriptRefImages/ScaleValueHandle.png Binary files differnew file mode 100644 index 0000000..3b48719 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScaleValueHandle.png diff --git a/Runtime/Export/ScriptRefImages/ScriptAdder.png b/Runtime/Export/ScriptRefImages/ScriptAdder.png Binary files differnew file mode 100644 index 0000000..7109eab --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScriptAdder.png diff --git a/Runtime/Export/ScriptRefImages/ScriptableWizardDisplayWizard.png b/Runtime/Export/ScriptRefImages/ScriptableWizardDisplayWizard.png Binary files differnew file mode 100644 index 0000000..0e4e4b9 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScriptableWizardDisplayWizard.png diff --git a/Runtime/Export/ScriptRefImages/ScriptableWizardOnDrawGizmos.png b/Runtime/Export/ScriptRefImages/ScriptableWizardOnDrawGizmos.png Binary files differnew file mode 100644 index 0000000..ae0113b --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScriptableWizardOnDrawGizmos.png diff --git a/Runtime/Export/ScriptRefImages/ScriptableWizardOnWizardCreate.png b/Runtime/Export/ScriptRefImages/ScriptableWizardOnWizardCreate.png Binary files differnew file mode 100644 index 0000000..608baae --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScriptableWizardOnWizardCreate.png diff --git a/Runtime/Export/ScriptRefImages/ScriptableWizardOnWizardOtherButton.png b/Runtime/Export/ScriptRefImages/ScriptableWizardOnWizardOtherButton.png Binary files differnew file mode 100644 index 0000000..7a53bc1 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ScriptableWizardOnWizardOtherButton.png diff --git a/Runtime/Export/ScriptRefImages/SelectAllOfTag.png b/Runtime/Export/ScriptRefImages/SelectAllOfTag.png Binary files differnew file mode 100644 index 0000000..e555343 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SelectAllOfTag.png diff --git a/Runtime/Export/ScriptRefImages/SelectionChange.png b/Runtime/Export/ScriptRefImages/SelectionChange.png Binary files differnew file mode 100644 index 0000000..93cbbd9 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SelectionChange.png diff --git a/Runtime/Export/ScriptRefImages/ShowPopupEx.png b/Runtime/Export/ScriptRefImages/ShowPopupEx.png Binary files differnew file mode 100644 index 0000000..0697fe6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ShowPopupEx.png diff --git a/Runtime/Export/ScriptRefImages/ShowRemoveNotification.png b/Runtime/Export/ScriptRefImages/ShowRemoveNotification.png Binary files differnew file mode 100644 index 0000000..0f08f52 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/ShowRemoveNotification.png diff --git a/Runtime/Export/ScriptRefImages/SimpleAutoSave.png b/Runtime/Export/ScriptRefImages/SimpleAutoSave.png Binary files differnew file mode 100644 index 0000000..7b35c28 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SimpleAutoSave.png diff --git a/Runtime/Export/ScriptRefImages/SimplePrefixLabelUsage.png b/Runtime/Export/ScriptRefImages/SimplePrefixLabelUsage.png Binary files differnew file mode 100644 index 0000000..fe741ef --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SimplePrefixLabelUsage.png diff --git a/Runtime/Export/ScriptRefImages/SimpleRecorder.png b/Runtime/Export/ScriptRefImages/SimpleRecorder.png Binary files differnew file mode 100644 index 0000000..45e9d0f --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SimpleRecorder.png diff --git a/Runtime/Export/ScriptRefImages/SliderHandle.png b/Runtime/Export/ScriptRefImages/SliderHandle.png Binary files differnew file mode 100644 index 0000000..9cb7e6e --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SliderHandle.png diff --git a/Runtime/Export/ScriptRefImages/SphereCap.png b/Runtime/Export/ScriptRefImages/SphereCap.png Binary files differnew file mode 100644 index 0000000..27ec6ac --- /dev/null +++ b/Runtime/Export/ScriptRefImages/SphereCap.png diff --git a/Runtime/Export/ScriptRefImages/TearMeshApart.png b/Runtime/Export/ScriptRefImages/TearMeshApart.png Binary files differnew file mode 100644 index 0000000..fbf8afe --- /dev/null +++ b/Runtime/Export/ScriptRefImages/TearMeshApart.png diff --git a/Runtime/Export/ScriptRefImages/Vec3ProjectDiagram.png b/Runtime/Export/ScriptRefImages/Vec3ProjectDiagram.png Binary files differnew file mode 100644 index 0000000..260980c --- /dev/null +++ b/Runtime/Export/ScriptRefImages/Vec3ProjectDiagram.png diff --git a/Runtime/Export/ScriptRefImages/Vec3ReflectDiagram.png b/Runtime/Export/ScriptRefImages/Vec3ReflectDiagram.png Binary files differnew file mode 100644 index 0000000..4f40c73 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/Vec3ReflectDiagram.png diff --git a/Runtime/Export/ScriptRefImages/WantsMouseMoveEx.png b/Runtime/Export/ScriptRefImages/WantsMouseMoveEx.png Binary files differnew file mode 100644 index 0000000..7b5ab71 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/WantsMouseMoveEx.png diff --git a/Runtime/Export/ScriptRefImages/WheelFrictionCurve.png b/Runtime/Export/ScriptRefImages/WheelFrictionCurve.png Binary files differnew file mode 100644 index 0000000..4535fb6 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/WheelFrictionCurve.png diff --git a/Runtime/Export/ScriptRefImages/Window1.png b/Runtime/Export/ScriptRefImages/Window1.png Binary files differnew file mode 100644 index 0000000..d21ef02 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/Window1.png diff --git a/Runtime/Export/ScriptRefImages/focusedWindowEx.png b/Runtime/Export/ScriptRefImages/focusedWindowEx.png Binary files differnew file mode 100644 index 0000000..17859ed --- /dev/null +++ b/Runtime/Export/ScriptRefImages/focusedWindowEx.png diff --git a/Runtime/Export/ScriptRefImages/isValidScriptableWizard.png b/Runtime/Export/ScriptRefImages/isValidScriptableWizard.png Binary files differnew file mode 100644 index 0000000..6c4a9c5 --- /dev/null +++ b/Runtime/Export/ScriptRefImages/isValidScriptableWizard.png diff --git a/Runtime/Export/ScriptRefImages/mouseFocusedWindowEx.png b/Runtime/Export/ScriptRefImages/mouseFocusedWindowEx.png Binary files differnew file mode 100644 index 0000000..eb04a7d --- /dev/null +++ b/Runtime/Export/ScriptRefImages/mouseFocusedWindowEx.png diff --git a/Runtime/Export/ScrollWaitDefinitions.cs b/Runtime/Export/ScrollWaitDefinitions.cs new file mode 100644 index 0000000..babafd1 --- /dev/null +++ b/Runtime/Export/ScrollWaitDefinitions.cs @@ -0,0 +1,8 @@ +namespace UnityEngine +{ + internal static class ScrollWaitDefinitions + { + public const int firstWait = 250; // ms + public const int regularWait = 30; // ms + } +} diff --git a/Runtime/Export/Security.cs b/Runtime/Export/Security.cs new file mode 100644 index 0000000..8d0dbad --- /dev/null +++ b/Runtime/Export/Security.cs @@ -0,0 +1,122 @@ +#if !UNITY_WINRT +using System; +using System.IO; +using System.Security; +using System.Security.Cryptography; +using System.Reflection; +using System.Collections.Generic; +using Mono.Security; +using Mono.Security.Cryptography; + +namespace UnityEngine +{ + public sealed partial class Security + { + #if UNITY_EDITOR || UNITY_WEBPLAYER + static List<Assembly> _verifiedAssemblies = new List<Assembly>(); + #endif + + static MethodInfo GetUnityCrossDomainHelperMethod(string methodname) + { + //todo: enter strong name with public key here + Type type = Types.GetType ("UnityEngine.UnityCrossDomainHelper", "CrossDomainPolicyParser, Version=1.0.0.0, Culture=neutral"); + if (type == null) + throw new SecurityException("Cant find type UnityCrossDomainHelper"); + var result = type.GetMethod (methodname); + if (result == null) + throw new SecurityException("Cant find "+methodname); + return result; + } + + internal static string TokenToHex (byte[] token) + { + if (null == token || 8 > token.Length) + return string.Empty; + + return string.Format ("{0:x2}{1:x2}{2:x2}{3:x2}{4:x2}{5:x2}{6:x2}{7:x2}", + token[0], + token[1], + token[2], + token[3], + token[4], + token[5], + token[6], + token[7] + ); + } + + #if UNITY_EDITOR + internal static void ClearVerifiedAssemblies () + { + _verifiedAssemblies.Clear (); + } + #endif + + [SecuritySafeCritical] + public static Assembly LoadAndVerifyAssembly (byte[] assemblyData) + { + #if UNITY_EDITOR || UNITY_WEBPLAYER + var assembly = Assembly.Load (assemblyData); + byte[] publicKey = assembly.GetName ().GetPublicKey (); + if (null == publicKey || 0 == publicKey.Length) + return null; + + var rsa = new RSACryptoServiceProvider (); + rsa.ImportCspBlob (publicKey); + var strongName = new StrongName (rsa); + using (var stream = new MemoryStream (assemblyData)) + { + if (strongName.Verify (stream)) + { + _verifiedAssemblies.Add(assembly); + return assembly; + } else + { + return null; + } + } + #else + return null; + #endif + } + +#if UNITY_EDITOR + static readonly string kSignatureExtension = ".signature"; + + internal static bool VerifySignature (string file, byte[] publicKey) + { + try { + string signature = file + kSignatureExtension; + if (!File.Exists (signature)) + return false; + + using (var provider = new RSACryptoServiceProvider ()) + { + provider.ImportCspBlob (publicKey); + using (var sha1 = new SHA1CryptoServiceProvider ()) + return provider.VerifyData (File.ReadAllBytes (file), sha1, File.ReadAllBytes (signature)); + } + } catch (Exception e) { + Debug.LogException (e); + } + return false; + } +#endif + } + + public static class Types + { + public static Type GetType(string typeName, string assemblyName) + { + try + { + return Assembly.Load(assemblyName).GetType(typeName); + } + catch (Exception) + { + return null; + } + } + } +} +#endif
\ No newline at end of file diff --git a/Runtime/Export/SecurityPublic.txt b/Runtime/Export/SecurityPublic.txt new file mode 100644 index 0000000..a130ca4 --- /dev/null +++ b/Runtime/Export/SecurityPublic.txt @@ -0,0 +1,61 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" + +#if UNITY_WEBPLAYER +#include "PlatformDependent/CommonWebPlayer/ChainOfTrust.h" +#endif + +CSRAW +using System; +using System.Security; + +namespace UnityEngine +{ +CSRAW #if !UNITY_WINRT + // Webplayer security related class. + CLASS Security + + // Prefetch the webplayer socket security policy from a non-default port number. + CSRAW static public bool PrefetchSocketPolicy(string ip, int atPort, int timeout=3000) + { + #if UNITY_EDITOR || UNITY_WEBPLAYER + var method = GetUnityCrossDomainHelperMethod("PrefetchSocketPolicy"); + var result = method.Invoke(null, new object[] { ip, atPort, timeout}); + return (bool)result; + #else + return true; + #endif + } + + CONDITIONAL UNITY_WEBPLAYER || UNITY_EDITOR + CSRAW + [System.Security.SecuritySafeCritical] + public static string GetChainOfTrustValue (string name) + { + var callingAssembly = System.Reflection.Assembly.GetCallingAssembly (); + if (!_verifiedAssemblies.Contains(callingAssembly)) + throw new ArgumentException("Calling assembly needs to be verified by Security.LoadAndVerifyAssembly"); + + var token = callingAssembly.GetName ().GetPublicKeyToken (); + + return GetChainOfTrustValueInternal (name, UnityEngine.Security.TokenToHex (token)); + } + + CONDITIONAL UNITY_WEBPLAYER || UNITY_EDITOR + CUSTOM private static string GetChainOfTrustValueInternal (string name, string publicKeyToken) + { + #if UNITY_WEBPLAYER + std::string token = publicKeyToken.AsUTF8 (); + std::string result = ChainOfTrust::GetValue(name,token); + return scripting_string_new(result); + #else + return scripting_string_new(string()); + #endif + } + END +CSRAW #endif +} diff --git a/Runtime/Export/Serialization/IManagedLivenessAnalysis.cs b/Runtime/Export/Serialization/IManagedLivenessAnalysis.cs new file mode 100644 index 0000000..e9d8f00 --- /dev/null +++ b/Runtime/Export/Serialization/IManagedLivenessAnalysis.cs @@ -0,0 +1,11 @@ +namespace UnityEngine +{ +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + public interface IManagedLivenessAnalysis + { + void Reset(); + bool HasBeenProcessed(object value); + object GetNewInstanceToReplaceOldInstance(object value); + } +#endif +}
\ No newline at end of file diff --git a/Runtime/Export/Serialization/IPPtrRemapper.cs b/Runtime/Export/Serialization/IPPtrRemapper.cs new file mode 100644 index 0000000..047615c --- /dev/null +++ b/Runtime/Export/Serialization/IPPtrRemapper.cs @@ -0,0 +1,9 @@ +namespace UnityEngine +{ +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + public interface IPPtrRemapper + { + object GetNewInstanceToReplaceOldInstance(object value); + } +#endif +}
\ No newline at end of file diff --git a/Runtime/Export/Serialization/ISerializedStateReader.cs b/Runtime/Export/Serialization/ISerializedStateReader.cs new file mode 100644 index 0000000..cc96a7b --- /dev/null +++ b/Runtime/Export/Serialization/ISerializedStateReader.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace UnityEngine +{ +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + public interface ISerializedStateReader + { + void Align(); + byte ReadByte(); + int ReadInt32(); + float ReadSingle(); + double ReadDouble(); + bool ReadBoolean(); + string ReadString(); + object ReadUnityEngineObject(); + object ReadAnimationCurve(); + object ReadGradient(); + object ReadGUIStyle(); + object ReadRectOffset(); + + byte[] ReadArrayOfByte(); + List<byte> ReadListOfByte(); + } +#endif +} diff --git a/Runtime/Export/Serialization/ISerializedStateWriter.cs b/Runtime/Export/Serialization/ISerializedStateWriter.cs new file mode 100644 index 0000000..2bcea66 --- /dev/null +++ b/Runtime/Export/Serialization/ISerializedStateWriter.cs @@ -0,0 +1,25 @@ +using System.Collections.Generic; + +namespace UnityEngine +{ +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + public interface ISerializedStateWriter + { + void Align(); + void WriteByte(byte value); + void WriteInt32(int value); + void WriteSingle(float value); + void WriteDouble(double value); + void WriteBoolean(bool value); + void WriteString(string value); + void WriteUnityEngineObject(object value); + void WriteAnimationCurve(object value); + void WriteGradient(object value); + void WriteGUIStyle(object value); + void WriteRectOffset(object value); + + void WriteArrayOfByte(byte[] value); + void WriteListOfByte(List<byte> value); + } +#endif +} diff --git a/Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs b/Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs new file mode 100644 index 0000000..64fff2d --- /dev/null +++ b/Runtime/Export/Serialization/IUnityAssetsReferenceHolder.cs @@ -0,0 +1,9 @@ +namespace UnityEngine +{ +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + public interface IUnityAssetsReferenceHolder + { + void Unity_LivenessCheck(); + } +#endif +}
\ No newline at end of file diff --git a/Runtime/Export/Serialization/IUnitySerializable.cs b/Runtime/Export/Serialization/IUnitySerializable.cs new file mode 100644 index 0000000..2abeb4f --- /dev/null +++ b/Runtime/Export/Serialization/IUnitySerializable.cs @@ -0,0 +1,11 @@ +namespace UnityEngine +{ +#if ENABLE_SERIALIZATION_BY_CODEGENERATION + public interface IUnitySerializable + { + void Unity_Serialize(); + void Unity_Deserialize(); + void Unity_RemapPPtrs(); + } +#endif +}
\ No newline at end of file diff --git a/Runtime/Export/Serialization/ManagedLivenessAnalysis.txt b/Runtime/Export/Serialization/ManagedLivenessAnalysis.txt new file mode 100644 index 0000000..4f9800e --- /dev/null +++ b/Runtime/Export/Serialization/ManagedLivenessAnalysis.txt @@ -0,0 +1,67 @@ +C++RAW +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#if ENABLE_SERIALIZATION_BY_CODEGENERATION +#include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h" +#endif + +CSRAW +using System; +using System.Collections.Generic; +using UnityEngine; +using Object=UnityEngine.Object; +using System.Runtime.CompilerServices; + +namespace UnityEngine.Serialization +{ + +CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION +CLASS public ManagedLivenessAnalysis : IManagedLivenessAnalysis + + CSRAW public static IManagedLivenessAnalysis Instance = null; + CSRAW public readonly HashSet<int> _state = new HashSet<int>(); + + CSRAW public static void Init() + { + if(Instance == null) + Instance = new ManagedLivenessAnalysis(); + } + CSRAW public static void ResetState() + { + Instance.Reset(); + } + CSRAW public static void SetInstance(IManagedLivenessAnalysis analysis) + { + Instance = analysis; + } + CSRAW public void Reset() + { + ((ManagedLivenessAnalysis)Instance)._state.Clear(); + } + CSRAW public bool HasBeenProcessed(object value) + { + return !_state.Add(RuntimeHelpers.GetHashCode(value)); + } + CSRAW public object GetNewInstanceToReplaceOldInstance(object value) + { + return INTERNAL_GetNewInstanceToReplaceOldInstance(((UnityEngine.Object)value).GetInstanceID()); + } + + THREAD_SAFE + CUSTOM private static object INTERNAL_GetNewInstanceToReplaceOldInstance(int instance_id) + { + return NativeExt_MonoBehaviourSerialization_GetNewInstanceToReplaceOldInstance(instance_id); + } + +END + +CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_WINRT +CLASS public ManagedLivenessAnalysis + CSRAW public static void SetInstance(IManagedLivenessAnalysis analysis) + { + } +END + +CSRAW +} diff --git a/Runtime/Export/Serialization/PPtrRemapper.txt b/Runtime/Export/Serialization/PPtrRemapper.txt new file mode 100644 index 0000000..e1fd2a7 --- /dev/null +++ b/Runtime/Export/Serialization/PPtrRemapper.txt @@ -0,0 +1,53 @@ +C++RAW +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#if ENABLE_SERIALIZATION_BY_CODEGENERATION +#include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h" +#endif + +CSRAW +using System; +using System.Collections.Generic; +using UnityEngine; +using Object=UnityEngine.Object; + +namespace UnityEngine.Serialization +{ + +CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION +CLASS public PPtrRemapper : IPPtrRemapper + + CSRAW public static IPPtrRemapper Instance = null; + + CSRAW public static void Init() + { + if(Instance == null) + Instance = new PPtrRemapper(); + } + CSRAW public static void SetInstance(IPPtrRemapper remapper) + { + Instance = remapper; + } + CSRAW public object GetNewInstanceToReplaceOldInstance(object value) + { + return INTERNAL_GetNewInstanceToReplaceOldInstance(((UnityEngine.Object)value).GetInstanceID()); + } + + THREAD_SAFE + CUSTOM private static object INTERNAL_GetNewInstanceToReplaceOldInstance(int instance_id) + { + return NativeExt_MonoBehaviourSerialization_GetNewInstanceToReplaceOldInstance(instance_id); + } + +END + +CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_METRO +CLASS public PPtrRemapper + CSRAW public static void SetInstance(IPPtrRemapper reader) + { + } +END + +CSRAW +} diff --git a/Runtime/Export/Serialization/SerializedStateReader.txt b/Runtime/Export/Serialization/SerializedStateReader.txt new file mode 100644 index 0000000..35f6f0c --- /dev/null +++ b/Runtime/Export/Serialization/SerializedStateReader.txt @@ -0,0 +1,214 @@ +C++RAW + +#include "UnityPrefix.h" + +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +#if ENABLE_SERIALIZATION_BY_CODEGENERATION +# include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h" +#endif + +CSRAW +using System; +using System.Collections.Generic; +using UnityEngine; +using Object=UnityEngine.Object; + +namespace UnityEngine.Serialization +{ + +CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION +CLASS public SerializedStateReader : ISerializedStateReader + + CSRAW public static ISerializedStateReader Instance = null; + + CSRAW public static void Init() + { + if(Instance == null) + Instance = new SerializedStateReader(); + } + CSRAW public static void SetInstance(ISerializedStateReader reader) + { + Instance = reader; + } + CSRAW public void Align() + { + INTERNAL_Align(); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_Align() + { + NativeExt_MonoBehaviourSerialization_ReaderAlign(); + } + + CSRAW public byte ReadByte() + { + return INTERNAL_ReadByte(); + } + + THREAD_SAFE + CUSTOM private static byte INTERNAL_ReadByte() + { + return NativeExt_MonoBehaviourSerialization_ReadByte(); + } + + CSRAW public int ReadInt32() + { + return INTERNAL_ReadInt32(); + } + + THREAD_SAFE + CUSTOM private static int INTERNAL_ReadInt32() + { + return NativeExt_MonoBehaviourSerialization_ReadInt(); + } + + CSRAW public float ReadSingle() + { + return INTERNAL_ReadSingle(); + } + + THREAD_SAFE + CUSTOM private static float INTERNAL_ReadSingle() + { + return NativeExt_MonoBehaviourSerialization_ReadFloat(); + } + + CSRAW public double ReadDouble() + { + return INTERNAL_ReadDouble(); + } + + THREAD_SAFE + CUSTOM private static double INTERNAL_ReadDouble() + { + return NativeExt_MonoBehaviourSerialization_ReadDouble(); + } + + CSRAW public bool ReadBoolean() + { + return INTERNAL_ReadBoolean(); + } + + THREAD_SAFE + CUSTOM private static bool INTERNAL_ReadBoolean() + { + return NativeExt_MonoBehaviourSerialization_ReadBool() == 1; + } + + CSRAW public string ReadString() + { + return INTERNAL_ReadString(); + } + + THREAD_SAFE + CUSTOM private static string INTERNAL_ReadString() + { + return NativeExt_MonoBehaviourSerialization_ReadString(); + } + + CSRAW public object ReadUnityEngineObject() + { + return INTERNAL_ReadUnityEngineObject(); + } + + THREAD_SAFE + CUSTOM private static object INTERNAL_ReadUnityEngineObject() + { + return NativeExt_MonoBehaviourSerialization_ReadUnityEngineObject(); + } + + CSRAW public object ReadAnimationCurve() + { + var animation_curve = new AnimationCurve(); + INTERNAL_ReadAnimationCurve(animation_curve); + return animation_curve; + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_ReadAnimationCurve(AnimationCurve animation_curve) + { + NativeExt_MonoBehaviourSerialization_ReadAnimationCurve(animation_curve); + } + + CSRAW public object ReadGradient() + { + var gradient = new Gradient(); + INTERNAL_ReadGradient(gradient); + return gradient; + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_ReadGradient(Gradient gradient) + { + NativeExt_MonoBehaviourSerialization_ReadGradient(gradient); + } + + CSRAW public object ReadGUIStyle() + { + var style = new GUIStyle(); + INTERNAL_ReadGUIStyle(style); + return style; + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_ReadGUIStyle(GUIStyle style) + { + NativeExt_MonoBehaviourSerialization_ReadGUIStyle(style); + } + + CSRAW public object ReadRectOffset() + { + var rect_offset = new RectOffset(); + INTERNAL_RectOffset(rect_offset); + return rect_offset; + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_RectOffset(RectOffset rect_offset) + { + NativeExt_MonoBehaviourSerialization_ReadRectOffset(rect_offset); + } + + CSRAW public byte[] ReadArrayOfByte() + { + return ReadArrayInternal<byte>(ReadByte); + } + + CSRAW public List<byte> ReadListOfByte() + { + return ReadListInternal<byte>(ReadByte); + } + + CSRAW private T[] ReadArrayInternal<T>(Func<T> reader) + { + var length = ReadInt32(); + var result = new T[length]; + for(var i = 0; i < length; ++i) + result[i] = reader(); + return result; + } + + CSRAW private List<T> ReadListInternal<T>(Func<T> reader) + { + var length = ReadInt32(); + var result = new List<T>(length); + for(var i = 0; i < length; ++i) + result.Add(reader()); + return result; + } + +END + +CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_METRO +CLASS public SerializedStateReader + CSRAW public static void SetInstance(ISerializedStateReader reader) + { + } +END + +CSRAW +} diff --git a/Runtime/Export/Serialization/SerializedStateWriter.txt b/Runtime/Export/Serialization/SerializedStateWriter.txt new file mode 100644 index 0000000..fb3a07c --- /dev/null +++ b/Runtime/Export/Serialization/SerializedStateWriter.txt @@ -0,0 +1,220 @@ +C++RAW + +#include "UnityPrefix.h" + +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +#if ENABLE_SERIALIZATION_BY_CODEGENERATION +# include "Runtime/Mono/MonoBehaviourSerialization_ByCodeGeneration.h" +#endif + +CSRAW +using System; +using System.Collections.Generic; +using UnityEngine; +using Object=UnityEngine.Object; + +namespace UnityEngine.Serialization +{ + +CONDITIONAL ENABLE_SERIALIZATION_BY_CODEGENERATION +CLASS public SerializedStateWriter : ISerializedStateWriter + + CSRAW public static ISerializedStateWriter Instance = null; + + CSRAW public static void Init() + { + if(Instance == null) + Instance = new SerializedStateWriter(); + } + + CSRAW public static void SetInstance(ISerializedStateWriter writer) + { + Instance = writer; + } + + CSRAW public void Align() + { + INTERNAL_Align(); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_Align() + { + NativeExt_MonoBehaviourSerialization_WriterAlign(); + } + + CSRAW public void WriteByte(byte value) + { + INTERNAL_WriteByte(value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteByte(byte value) + { + NativeExt_MonoBehaviourSerialization_WriteByte(value); + } + + CSRAW public void WriteInt32(int value) + { + INTERNAL_WriteInt32(value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteInt32(int value) + { + NativeExt_MonoBehaviourSerialization_WriteInt(value); + } + + CSRAW public void WriteSingle(float value) + { + INTERNAL_WriteSingle(value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteSingle(float value) + { + NativeExt_MonoBehaviourSerialization_WriteFloat(value); + } + + CSRAW public void WriteDouble(double value) + { + INTERNAL_WriteDouble(value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteDouble(double value) + { + NativeExt_MonoBehaviourSerialization_WriteDouble(value); + } + + CSRAW public void WriteBoolean(bool value) + { + INTERNAL_WriteBoolean(value ? 1 : 0); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteBoolean(int value) + { + NativeExt_MonoBehaviourSerialization_WriteBool(value); + } + + CSRAW public void WriteString(string value) + { + INTERNAL_WriteString(value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteString(string value) + { + NativeExt_MonoBehaviourSerialization_WriteString(const_cast<char*>(value.AsUTF8().c_str()), value.Length()); + } + + CSRAW public void WriteUnityEngineObject(object value) + { + if(typeof(UnityEngine.Object).IsAssignableFrom(value.GetType())) + INTERNAL_WriteUnityEngineObject(((UnityEngine.Object)value).GetInstanceID()); + else + throw new NotImplementedException("WriteUnityEngineObject on " + value.GetType().Name + " is not supported"); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteUnityEngineObject(int value) + { + NativeExt_MonoBehaviourSerialization_WriteUnityEngineObject(value); + } + + CSRAW public void WriteIDeserializable(object value, Type type) + { + throw new NotImplementedException("WriteIDeserializable"); + } + + CSRAW public void WriteAnimationCurve(object value) + { + INTERNAL_WriteAnimationCurve((UnityEngine.AnimationCurve)value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteAnimationCurve(AnimationCurve value) + { + NativeExt_MonoBehaviourSerialization_WriteAnimationCurve(value); + } + + CSRAW public void WriteGradient(object value) + { + INTERNAL_WriteGradient((UnityEngine.Gradient)value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteGradient(Gradient value) + { + NativeExt_MonoBehaviourSerialization_WriteGradient(value); + } + + CSRAW public void WriteGUIStyle(object value) + { + INTERNAL_WriteGUIStyle((UnityEngine.GUIStyle)value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteGUIStyle(GUIStyle value) + { + NativeExt_MonoBehaviourSerialization_WriteGUIStyle(value); + } + + CSRAW public void WriteRectOffset(object value) + { + INTERNAL_WriteRectOffset((UnityEngine.RectOffset)value); + } + + THREAD_SAFE + CUSTOM private static void INTERNAL_WriteRectOffset(RectOffset value) + { + NativeExt_MonoBehaviourSerialization_WriteRectOffset(value); + } + + CSRAW public void WriteArrayOfByte(byte[] value) + { + WriteArrayInternal(value, WriteByte); + } + + CSRAW public void WriteListOfByte(List<byte> value) + { + WriteListInternal(value, WriteByte); + } + + CSRAW private void WriteArrayInternal<T>(T[] value, Action<T> writer) + { + if(value != null) + { + WriteInt32(value.Length); + foreach(var item in value) + writer(item); + } else + WriteInt32(0); + } + + CSRAW private void WriteListInternal<T>(List<T> value, Action<T> writer) + { + if(value != null) + { + WriteInt32(value.Count); + foreach(var item in value) + writer(item); + } else + WriteInt32(0); + } + +END + +CONDITIONAL !ENABLE_SERIALIZATION_BY_CODEGENERATION && UNITY_METRO +CLASS public SerializedStateWriter + CSRAW public static void SetInstance(ISerializedStateWriter reader) + { + } +END + +CSRAW +} diff --git a/Runtime/Export/Serialization/UnitySurrogateSelector.cs b/Runtime/Export/Serialization/UnitySurrogateSelector.cs new file mode 100644 index 0000000..17f09e4 --- /dev/null +++ b/Runtime/Export/Serialization/UnitySurrogateSelector.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace UnityEngine.Serialization +{ +#if !UNITY_WINRT + /// <summary> + /// Serialization support for <see cref="List{T}" /> and <see cref="Dictionary{TKey,TValue}" /> that doesn't rely on reflection + /// of private members in order to be useable under the CoreCLR security model (WebPlayer). + /// </summary> + public class UnitySurrogateSelector : ISurrogateSelector + { + public ISerializationSurrogate GetSurrogate(Type type, StreamingContext context, out ISurrogateSelector selector) + { + if (type.IsGenericType) + { + var genericTypeDefinition = type.GetGenericTypeDefinition(); + if (genericTypeDefinition == typeof(List<>)) + { + selector = this; + return ListSerializationSurrogate.Default; + } + if (genericTypeDefinition == typeof(Dictionary<,>)) + { + selector = this; + var dictSurrogateType = typeof(DictionarySerializationSurrogate<,>).MakeGenericType(type.GetGenericArguments()); + return (ISerializationSurrogate) Activator.CreateInstance(dictSurrogateType); + } + } + + selector = null; + return null; + } + + public void ChainSelector(ISurrogateSelector selector) + { + throw new NotImplementedException(); + } + + public ISurrogateSelector GetNextSelector() + { + throw new NotImplementedException(); + } + } + + /// <summary> + /// Serialization support for <see cref="List{T}" /> that doesn't rely on reflection of private members. + /// </summary> + class ListSerializationSurrogate : ISerializationSurrogate + { + public static readonly ISerializationSurrogate Default = new ListSerializationSurrogate(); + + public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) + { + var list = (IList)obj; + info.AddValue("_size", list.Count); + info.AddValue("_items", ArrayFromGenericList(list)); + info.AddValue("_version", 0); // required for compatibility with platform deserialization + } + + public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) + { + var list = (IList)Activator.CreateInstance(obj.GetType()); + var size = info.GetInt32("_size"); + if (size == 0) + return list; + + var items = ((IEnumerable)info.GetValue("_items", typeof(IEnumerable))).GetEnumerator(); + for (var i = 0; i < size; ++i) + { + if (!items.MoveNext()) + throw new InvalidOperationException(); + list.Add(items.Current); + } + return list; + } + + private static Array ArrayFromGenericList(IList list) + { + var items = Array.CreateInstance(list.GetType().GetGenericArguments()[0], list.Count); + list.CopyTo(items, 0); + return items; + } + } + + /// <summary> + /// Serialization support for <see cref="Dictionary{TKey,TValue}" /> that doesn't rely on non public members. + /// </summary> + class DictionarySerializationSurrogate<TKey, TValue> : ISerializationSurrogate + { + public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) + { + var dictionary = ((Dictionary<TKey, TValue>)obj); + dictionary.GetObjectData(info, context); + } + + public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) + { + var comparer = (IEqualityComparer<TKey>)info.GetValue("Comparer", typeof(IEqualityComparer<TKey>)); + var dictionary = new Dictionary<TKey, TValue>(comparer); + if (info.MemberCount > 3) // KeyValuePairs might not be present if the dictionary was empty + { + var keyValuePairs = + (KeyValuePair<TKey, TValue>[]) info.GetValue("KeyValuePairs", typeof(KeyValuePair<TKey, TValue>[])); + if (keyValuePairs != null) + foreach (var kvp in keyValuePairs) + dictionary.Add(kvp.Key, kvp.Value); + } + return dictionary; + } + } +#endif +} diff --git a/Runtime/Export/ShaderBindings.txt b/Runtime/Export/ShaderBindings.txt new file mode 100644 index 0000000..30a64bd --- /dev/null +++ b/Runtime/Export/ShaderBindings.txt @@ -0,0 +1,415 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoExportUtility.h" +#include "Runtime/Shaders/Material.h" +#include "Runtime/Shaders/Shader.h" +#include "External/shaderlab/Library/intshader.h" +#include "Runtime/Camera/Renderqueue.h" +#include "External/shaderlab/Library/properties.h" +#include "Runtime/Misc/ResourceManager.h" +#include "Runtime/Shaders/ShaderNameRegistry.h" +#include "Runtime/Shaders/ShaderKeywords.h" +#include "Runtime/Shaders/ComputeShader.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/Backend/ScriptingBackendApi.h" +#include "Runtime/Misc/GraphicsScriptingUtility.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + + + +C++RAW + +PPtr<Shader> s_ScriptingCurrentShader; +const ChannelAssigns* s_ScriptingCurrentChannels; + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +CLASS Shader : Object + + CUSTOM static Shader Find (string name) + { + return Scripting::ScriptingWrapperFor(GetScriptMapper().FindShader(name)); + } + CUSTOM internal static Shader FindBuiltin (string name) + { + return Scripting::ScriptingWrapperFor(GetBuiltinResource<Shader> (name)); + } + + AUTO_PROP bool isSupported IsSupported + + CONDITIONAL UNITY_EDITOR + CUSTOM_PROP internal string customEditor { return scripting_string_new (self->GetCustomEditorName()); } + + CUSTOM static void EnableKeyword (string keyword) { + g_ShaderKeywords.Enable( keywords::Create( keyword ) ); + } + CUSTOM static void DisableKeyword (string keyword) { + g_ShaderKeywords.Disable( keywords::Create( keyword ) ); + } + + AUTO_PROP int maximumLOD GetMaximumShaderLOD SetMaximumShaderLOD + CUSTOM_PROP static int globalMaximumLOD { return Shader::GetGlobalMaximumShaderLOD(); } { Shader::SetGLobalMaximumShaderLOD (value); } + + CUSTOM_PROP int renderQueue { return self->GetShaderLabShader()->GetRenderQueue(); } + + CSRAW public static void SetGlobalColor (string propertyName, Color color) { + SetGlobalColor(Shader.PropertyToID(propertyName), color); + } + CUSTOM static void SetGlobalColor (int nameID, Color color) { + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + ShaderLab::FastPropertyName propName; propName.index = nameID; + props->SetVector (propName, color.GetPtr ()); + } + CSRAW public static void SetGlobalVector (string propertyName, Vector4 vec) { + SetGlobalColor (propertyName, vec); + } + CSRAW public static void SetGlobalVector (int nameID, Vector4 vec) { + SetGlobalColor (nameID, vec); + } + + CSRAW public static void SetGlobalFloat (string propertyName, float value) { + SetGlobalFloat(Shader.PropertyToID(propertyName), value); + } + CUSTOM static void SetGlobalFloat (int nameID, float value) { + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + ShaderLab::FastPropertyName propName; propName.index = nameID; + props->SetFloat (propName, value); + } + + CSRAW public static void SetGlobalInt (string propertyName, int value) { SetGlobalFloat(propertyName, (float)value); } + CSRAW public static void SetGlobalInt (int nameID, int value) { SetGlobalFloat(nameID, (float)value); } + + CSRAW public static void SetGlobalTexture (string propertyName, Texture tex) { + SetGlobalTexture (Shader.PropertyToID(propertyName), tex); + } + CUSTOM static void SetGlobalTexture (int nameID, Texture tex) { + Texture& texture = *tex; + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + ShaderLab::FastPropertyName propName; propName.index = nameID; + props->SetTexture (propName, &texture); + } + + CSRAW public static void SetGlobalMatrix (string propertyName, Matrix4x4 mat) { + SetGlobalMatrix (Shader.PropertyToID(propertyName), mat); + } + CUSTOM static void SetGlobalMatrix (int nameID, Matrix4x4 mat) { + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + ShaderLab::FastPropertyName propName; propName.index = nameID; + props->SetValueProp (propName, 16, mat.GetPtr()); + } + + CUSTOM static void SetGlobalTexGenMode (string propertyName, TexGenMode mode) { + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + props->GetTexEnv(ScriptingStringToProperty (propertyName))->SetTexGen ((TexGenMode)mode); + } + CUSTOM static void SetGlobalTextureMatrixName (string propertyName, string matrixName) { + if(propertyName.Length() == 0) + { + ErrorString ("SetGlobalTextureMatrixName: Invalid empty propertyName"); + return; + } + if(matrixName.Length() == 0) + { + ErrorString ("SetGlobalTextureMatrixName: Invalid empty matrixName"); + return; + } + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + props->GetTexEnv(ScriptingStringToProperty (propertyName))->SetMatrixName (ScriptingStringToProperty (matrixName)); + } + + CONDITIONAL !UNITY_FLASH + CUSTOM static void SetGlobalBuffer (string propertyName, ComputeBuffer buffer) { + ShaderLab::PropertySheet *props = ShaderLab::g_GlobalProperties; + props->SetComputeBuffer (ScriptingStringToProperty (propertyName), buffer ? buffer->GetBufferHandle() : ComputeBufferID()); + } + + CUSTOM static int PropertyToID (string name) { + return ScriptingStringToProperty (name).index; + } + + CUSTOM static void WarmupAllShaders () { + WarmupAllShaders (); + } + +END + + + +NONSEALED_CLASS Material : Object + + CSRAW public Material (string contents) { Internal_CreateWithString (this, contents); } + + CSRAW public Material (Shader shader) { Internal_CreateWithShader (this, shader); } + + CSRAW public Material (Material source) : base () { Internal_CreateWithMaterial (this, source); } + + + AUTO_PTR_PROP Shader shader GetShader SetShader + + + CSRAW public Color color { get { return GetColor ("_Color"); } set { SetColor ("_Color", value); } } + CSRAW public Texture mainTexture { get { return GetTexture ("_MainTex"); } set { SetTexture ("_MainTex", value); } } + CSRAW public Vector2 mainTextureOffset { get { return GetTextureOffset("_MainTex"); } set { SetTextureOffset("_MainTex", value); } } + CSRAW public Vector2 mainTextureScale { get { return GetTextureScale("_MainTex"); } set { SetTextureScale("_MainTex", value); } } + + CSRAW public void SetColor (string propertyName, Color color) + { + SetColor (Shader.PropertyToID(propertyName), color); + } + CUSTOM void SetColor (int nameID, Color color) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + self->SetColor (propName, color); + } + CSRAW public Color GetColor (string propertyName) + { + return GetColor (Shader.PropertyToID(propertyName)); + } + CUSTOM Color GetColor (int nameID) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + return self->GetColor (propName); + } + + CSRAW public void SetVector (string propertyName, Vector4 vector) + { + SetColor (propertyName, new Color (vector.x, vector.y, vector.z, vector.w)); + } + CSRAW public void SetVector (int nameID, Vector4 vector) + { + SetColor (nameID, new Color (vector.x, vector.y, vector.z, vector.w)); + } + CSRAW public Vector4 GetVector (string propertyName) + { + Color temp = GetColor (propertyName); + return new Vector4 (temp.r, temp.g, temp.b, temp.a); + } + CSRAW public Vector4 GetVector (int nameID) + { + Color temp = GetColor (nameID); + return new Vector4 (temp.r, temp.g, temp.b, temp.a); + } + + CSRAW public void SetTexture (string propertyName, Texture texture) + { + SetTexture (Shader.PropertyToID(propertyName), texture); + } + CUSTOM void SetTexture (int nameID, Texture texture) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + self->SetTexture (propName, texture); + } + CSRAW public Texture GetTexture (string propertyName) + { + return GetTexture (Shader.PropertyToID(propertyName)); + } + CUSTOM Texture GetTexture (int nameID) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + return Scripting::ScriptingWrapperFor (self->GetTexture (propName)); + } + + + // Workaround for gcc/msvc where passing small mono structures by value does not work + CUSTOM private static void Internal_GetTextureOffset (Material mat, string name, out Vector2 output) + { + *output = mat->GetTextureOffset( ScriptingStringToProperty(name) ); + } + CUSTOM private static void Internal_GetTextureScale (Material mat, string name, out Vector2 output) + { + *output = mat->GetTextureScale( ScriptingStringToProperty(name) ); + } + + CUSTOM void SetTextureOffset (string propertyName, Vector2 offset) + { + self->SetTextureOffset( ScriptingStringToProperty(propertyName), offset ); + } + CSRAW public Vector2 GetTextureOffset (string propertyName) + { + Vector2 r; + Internal_GetTextureOffset(this, propertyName, out r); + return r; + } + + CUSTOM void SetTextureScale (string propertyName, Vector2 scale) + { + self->SetTextureScale( ScriptingStringToProperty(propertyName), scale ); + } + CSRAW public Vector2 GetTextureScale (string propertyName) + { + Vector2 r; + Internal_GetTextureScale(this, propertyName, out r); + return r; + } + + CSRAW public void SetMatrix (string propertyName, Matrix4x4 matrix) + { + SetMatrix (Shader.PropertyToID(propertyName), matrix); + } + CUSTOM void SetMatrix (int nameID, Matrix4x4 matrix) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + self->SetMatrix (propName, matrix); + } + CSRAW public Matrix4x4 GetMatrix (string propertyName) + { + return GetMatrix (Shader.PropertyToID(propertyName)); + } + CUSTOM Matrix4x4 GetMatrix (int nameID) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + return self->GetMatrix (propName); + } + + CSRAW public void SetFloat (string propertyName, float value) + { + SetFloat (Shader.PropertyToID(propertyName), value); + } + CUSTOM void SetFloat (int nameID, float value) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + self->SetFloat (propName, value); + } + CSRAW public float GetFloat (string propertyName) + { + return GetFloat (Shader.PropertyToID(propertyName)); + } + CUSTOM float GetFloat (int nameID) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + return self->GetFloat (propName); + } + + CSRAW public void SetInt (string propertyName, int value) { SetFloat(propertyName, (float)value); } + CSRAW public void SetInt (int nameID, int value) { SetFloat(nameID, (float)value); } + CSRAW public int GetInt (string propertyName) { return (int)GetFloat(propertyName); } + CSRAW public int GetInt (int nameID) { return (int)GetFloat(nameID); } + + CONDITIONAL !UNITY_FLASH + CUSTOM void SetBuffer (string propertyName, ComputeBuffer buffer) { + FastPropertyName fpName = ScriptingStringToProperty(propertyName); + self->SetComputeBuffer (fpName, buffer ? buffer->GetBufferHandle() : ComputeBufferID()); + } + + CSRAW public bool HasProperty (string propertyName) + { + return HasProperty (Shader.PropertyToID(propertyName)); + } + CUSTOM bool HasProperty (int nameID) + { + ShaderLab::FastPropertyName propName; propName.index = nameID; + return self->HasProperty (propName); + } + + CUSTOM string GetTag (string tag, bool searchFallbacks, string defaultValue = "") { + return scripting_string_new (self->GetTag (tag, !searchFallbacks, defaultValue)); + } + + CUSTOM void Lerp (Material start, Material end, float t) + { + const ShaderLab::PropertySheet &s1 = start->GetProperties(); + const ShaderLab::PropertySheet &s2 = end->GetProperties(); + self->GetWritableProperties().LerpProperties( s1, s2, clamp01(t) ); + } + + AUTO_PROP int passCount GetPassCount + + + CUSTOM bool SetPass (int pass) { + Material& mat = *self; + if (pass >= mat.GetPassCount()) + { + ErrorStringMsg("Trying to access pass %d, but material '%s' subshader (0) has only %d valid passes.", + pass, + mat.GetName(), + mat.GetPassCount()); + return false; + } + + if (!CheckShouldRenderPass (pass, mat)) + return false; + s_ScriptingCurrentShader = mat.GetShaderPPtr(); + s_ScriptingCurrentChannels = mat.SetPass(pass); + return s_ScriptingCurrentChannels != NULL; + } + + AUTO_PROP int renderQueue GetActualRenderQueue SetCustomRenderQueue + + OBSOLETE warning Use the Material constructor instead. + CSRAW static public Material Create (string scriptContents) + { + return new Material (scriptContents); + } + + CUSTOM private static void Internal_CreateWithString ([Writable]Material mono, string contents) + { + Material *mat = Material::CreateMaterial (contents.AsUTF8().c_str(), 0, true); + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), mat); + mat->ApplyMaterialPropertyDrawers(); + } + + CUSTOM private static void Internal_CreateWithShader ([Writable]Material mono, Shader shader) + { + Material *mat = Material::CreateMaterial (*shader, 0, true); + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), mat); + mat->ApplyMaterialPropertyDrawers(); + } + + CUSTOM private static void Internal_CreateWithMaterial ([Writable]Material mono, Material source) + { + Material *mat = Material::CreateMaterial (*source, 0, true); + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), mat); + mat->ApplyMaterialPropertyDrawers(); + } + + CUSTOM void CopyPropertiesFromMaterial (Material mat) { + if (mat != NULL) + self->CopyPropertiesFromMaterial(*mat); + else + ErrorString ("Trying to copy properties from null material."); + } + + CUSTOM void EnableKeyword (string keyword) { + self->EnableKeyword (keyword); + } + CUSTOM void DisableKeyword (string keyword) { + self->DisableKeyword (keyword); + } + + CONDITIONAL ENABLE_MONO || UNITY_WINRT + CUSTOM_PROP String[] shaderKeywords { + const size_t count = self->GetShaderKeywords ().size (); + + ScriptingArrayPtr array = CreateScriptingArray<ScriptingStringPtr> (GetScriptingManager().GetCommonClasses().string, count); + for (int i=0;i<count;i++) + { + Scripting::SetScriptingArrayElement<ScriptingStringPtr>(array,i,scripting_string_new(self->GetShaderKeywords ()[i])); + } + return array; + } + { + Material::ShaderKeywordsT names; + for (int i=0;i<GetScriptingArraySize (value);i++) + names.push_back (scripting_cpp_string_for (Scripting::GetScriptingArrayElementNoRef<ScriptingStringPtr> (value, i))); + self->SetShaderKeywords (names); + } + +END + + + +CSRAW +} diff --git a/Runtime/Export/SliderHandler.cs b/Runtime/Export/SliderHandler.cs new file mode 100644 index 0000000..057ef70 --- /dev/null +++ b/Runtime/Export/SliderHandler.cs @@ -0,0 +1,330 @@ +using System; + +namespace UnityEngine +{ + // State for when we're dragging a slider. + internal class SliderState + { + public float dragStartPos; + public float dragStartValue; + public bool isDragging; + } + + // TODO: Make the thumb positioning / sizing be right + internal struct SliderHandler + { + readonly Rect position; + readonly float currentValue; + readonly float size; + readonly float start; + readonly float end; + readonly GUIStyle slider; + readonly GUIStyle thumb; + readonly bool horiz; + readonly int id; + + public SliderHandler(Rect position, float currentValue, float size, float start, float end, GUIStyle slider, GUIStyle thumb, bool horiz, int id) + { + this.position = position; + this.currentValue = currentValue; + this.size = size; + this.start = start; + this.end = end; + this.slider = slider; + this.thumb = thumb; + this.horiz = horiz; + this.id = id; + } + + public float Handle() + { + if (slider == null || thumb == null) + return currentValue; + + switch (CurrentEventType()) + { + case EventType.MouseDown: + return OnMouseDown(); + + case EventType.MouseDrag: + return OnMouseDrag(); + + case EventType.MouseUp: + return OnMouseUp(); + + case EventType.Repaint: + return OnRepaint(); + } + return currentValue; + } + + private float OnMouseDown() + { + // if the click is outside this control, just bail out... + if (!position.Contains(CurrentEvent().mousePosition) || IsEmptySlider()) + return currentValue; + + GUI.scrollTroughSide = 0; + GUIUtility.hotControl = id; + CurrentEvent().Use(); + + if (ThumbSelectionRect().Contains(CurrentEvent().mousePosition)) + { + // We have a mousedown on the thumb + // Record where we're draging from, so the user can get back. + StartDraggingWithValue(ClampedCurrentValue()); + return currentValue; + } + + GUI.changed = true; + + // We're outside the thumb, but inside the trough. + // If we have a scrollSize, we do pgup/pgdn style movements + // if not, we just snap to the current position and begin tracking + if (SupportsPageMovements()) + { + SliderState().isDragging = false; + GUI.nextScrollStepTime = SystemClock.now.AddMilliseconds(ScrollWaitDefinitions.firstWait); + GUI.scrollTroughSide = CurrentScrollTroughSide(); + return PageMovementValue(); + } + + float newValue = ValueForCurrentMousePosition(); + StartDraggingWithValue(newValue); + return Clamp(newValue); + } + + private float OnMouseDrag() + { + if (GUIUtility.hotControl != id) + return currentValue; + + var sliderState = SliderState(); + if (!sliderState.isDragging) + return currentValue; + + GUI.changed = true; + CurrentEvent().Use(); + + // Recalculate the value from the mouse position. this has the side effect that values are relative to the + // click point - no matter where inside the trough the original value was. Also means user can get back original value + // if he drags back to start position. + float deltaPos = MousePosition() - sliderState.dragStartPos; + var newValue = sliderState.dragStartValue + deltaPos / ValuesPerPixel(); + return Clamp(newValue); + } + + private float OnMouseUp() + { + if (GUIUtility.hotControl == id) + { + CurrentEvent().Use(); + GUIUtility.hotControl = 0; + } + return currentValue; + } + + private float OnRepaint() + { + slider.Draw(position, GUIContent.none, id); + thumb.Draw(ThumbRect(), GUIContent.none, id); + + if (GUIUtility.hotControl != id || !position.Contains(CurrentEvent().mousePosition) || IsEmptySlider()) + return currentValue; + + if (ThumbRect().Contains(CurrentEvent().mousePosition)) + { + if (GUI.scrollTroughSide != 0) // if was scrolling with "trough" and the thumb reached mouse - sliding action over + { + GUIUtility.hotControl = 0; + } + + return currentValue; + } + + GUI.InternalRepaintEditorWindow(); + + if (SystemClock.now < GUI.nextScrollStepTime) + return currentValue; + + if (CurrentScrollTroughSide() != GUI.scrollTroughSide) + return currentValue; + + GUI.nextScrollStepTime = SystemClock.now.AddMilliseconds(ScrollWaitDefinitions.regularWait); + + if (SupportsPageMovements()) + { + SliderState().isDragging = false; + GUI.changed = true; + return PageMovementValue(); + } + return ClampedCurrentValue(); + } + + private EventType CurrentEventType() + { + return CurrentEvent().GetTypeForControl(id); + } + + private int CurrentScrollTroughSide() + { + float mousePos = horiz ? CurrentEvent().mousePosition.x : CurrentEvent().mousePosition.y; + float thumbPos = horiz ? ThumbRect().x : ThumbRect().y; + + return mousePos > thumbPos ? 1 : -1; + } + + private bool IsEmptySlider() + { + return start == end; + } + + private bool SupportsPageMovements() + { + return size != 0 && GUI.usePageScrollbars; + } + + private float PageMovementValue() + { + var newValue = currentValue; + var sign = start > end ? -1 : 1; + if (MousePosition() > PageUpMovementBound()) + newValue += size * sign * .9f; + else + newValue -= size * sign * .9f; + return Clamp(newValue); + } + + private float PageUpMovementBound() + { + if (horiz) + return ThumbRect().xMax - position.x; + return ThumbRect().yMax - position.y; + } + + private Event CurrentEvent() + { + return Event.current; + } + + private float ValueForCurrentMousePosition() + { + if (horiz) + return (MousePosition() - ThumbRect().width * .5f) / ValuesPerPixel() + start - size * .5f; + return (MousePosition() - ThumbRect().height * .5f) / ValuesPerPixel() + start - size * .5f; + } + + private float Clamp(float value) + { + return Mathf.Clamp(value, MinValue(), MaxValue()); + } + + private Rect ThumbSelectionRect() + { + var selectionRect = ThumbRect(); +#if UNITY_IPHONE + int minSize = 12; + if (selectionRect.width < minSize) + { + selectionRect.x -= (minSize - selectionRect.width) / 2; + selectionRect.width = minSize; + } + if (selectionRect.height < minSize) + { + selectionRect.y -= (minSize - selectionRect.height) / 2; + selectionRect.height = minSize; + } + +#endif + return selectionRect; + } + + private void StartDraggingWithValue(float dragStartValue) + { + var state = SliderState(); + state.dragStartPos = MousePosition(); + state.dragStartValue = dragStartValue; + state.isDragging = true; + } + + private SliderState SliderState() + { + return (SliderState)GUIUtility.GetStateObject(typeof(SliderState), id); + } + + private Rect ThumbRect() + { + return horiz ? HorizontalThumbRect() : VerticalThumbRect(); + } + + private Rect VerticalThumbRect() + { + var valuesPerPixel = ValuesPerPixel(); + if (start < end) + return new Rect( + position.x + slider.padding.left, + (ClampedCurrentValue() - start) * valuesPerPixel + position.y + slider.padding.top, + position.width - slider.padding.horizontal, + size * valuesPerPixel + ThumbSize()); + + return new Rect( + position.x + slider.padding.left, + (ClampedCurrentValue() + size - start) * valuesPerPixel + position.y + slider.padding.top, + position.width - slider.padding.horizontal, + size * -valuesPerPixel + ThumbSize()); + } + + private Rect HorizontalThumbRect() + { + var valuesPerPixel = ValuesPerPixel(); + if (start < end) + return new Rect( + (ClampedCurrentValue() - start) * valuesPerPixel + position.x + slider.padding.left, + position.y + slider.padding.top, + size * valuesPerPixel + ThumbSize(), + position.height - slider.padding.vertical); + + return new Rect( + (ClampedCurrentValue() + size - start) * valuesPerPixel + position.x + slider.padding.left, + position.y, + size * -valuesPerPixel + ThumbSize(), + position.height); + } + + private float ClampedCurrentValue() + { + return Clamp(currentValue); + } + + private float MousePosition() + { + if (horiz) + return CurrentEvent().mousePosition.x - position.x; + return CurrentEvent().mousePosition.y - position.y; + } + + private float ValuesPerPixel() + { + if (horiz) + return (position.width - slider.padding.horizontal - ThumbSize()) / (end - start); + return (position.height - slider.padding.vertical - ThumbSize()) / (end - start); + } + + private float ThumbSize() + { + if (horiz) + return thumb.fixedWidth != 0 ? thumb.fixedWidth : thumb.padding.horizontal; + return thumb.fixedHeight != 0 ? thumb.fixedHeight : thumb.padding.vertical; + } + + private float MaxValue() + { + return Mathf.Max(start, end) - size; + } + + private float MinValue() + { + return Mathf.Min(start, end); + } + } +} diff --git a/Runtime/Export/SpritesBindings.txt b/Runtime/Export/SpritesBindings.txt new file mode 100644 index 0000000..3f9dc97 --- /dev/null +++ b/Runtime/Export/SpritesBindings.txt @@ -0,0 +1,191 @@ +C++RAW +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/Scripting.h" +#if ENABLE_SPRITES +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Filters/Mesh/SpriteRenderer.h" +#include "Runtime/Graphics/SpriteFrame.h" +#include "Runtime/Graphics/Texture2D.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#endif //ENABLE_SPRITES + +CSRAW +using UnityEngine; +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +#if ENABLE_SPRITES +namespace UnityEngine +{ +CSRAW + ENUM public SpriteAlignment + Center = 0, + TopLeft = 1, + TopCenter = 2, + TopRight = 3, + LeftCenter = 4, + RightCenter = 5, + BottomLeft = 6, + BottomCenter = 7, + BottomRight = 8, + Custom = 9, + END + +CONDITIONAL ENABLE_SPRITES +ENUM SpritePackingMode + Tight = 0, + Rectangle +END + +CONDITIONAL ENABLE_SPRITES +ENUM SpritePackingRotation + None = 0, + // Reserved + Any = 15 +END + +CONDITIONAL ENABLE_SPRITES +ENUM SpriteMeshType + FullRect = 0, + Tight = 1 +END + +CONDITIONAL ENABLE_SPRITES +/// Describes one sprite frame. +CLASS Sprite : Object + + CUSTOM public static Sprite Create(Texture2D texture, Rect rect, Vector2 pivot, float pixelsToUnits = 100.0f, uint extrude = 0, SpriteMeshType meshType = SpriteMeshType.Tight) + { + if (texture.IsNull()) + return NULL; + + Sprite* sprite = CreateObjectFromCode<Sprite>(); + sprite->Initialize(texture, rect, pivot, pixelsToUnits, extrude, meshType); + return Scripting::ScriptingWrapperFor(sprite); + } + + CUSTOM_PROP Bounds bounds + { + return self->GetBounds(); + } + + // Sprite definition rectangle on source texture (in texels). + CUSTOM_PROP Rect rect + { + return self->GetRect(); + } + + CUSTOM_PROP Texture2D texture + { + return Scripting::ScriptingWrapperFor(self->GetRenderDataForPlayMode().texture); + } + + // Sprite rectangle on texture (in texels). + CUSTOM_PROP Rect textureRect + { + const SpriteRenderData& rd = self->GetRenderDataForPlayMode(); // RenderData must match <texture> accessor's behavior. + if (rd.settings.packed && rd.settings.packingMode != kSPMRectangle) + Scripting::RaiseMonoException("Sprite is not rectangle-packed. TextureRect is invalid."); + return rd.textureRect; + } + + // Sprite rectangle offset in sprite definition rectangle space (in texels). + CSRAW public Vector2 textureRectOffset + { + get + { + Vector2 v; + Internal_GetTextureRectOffset(this, out v); + return v; + } + } + + CUSTOM_PROP bool packed + { + return self->GetIsPacked(); + } + + CUSTOM_PROP SpritePackingMode packingMode + { + const SpriteRenderData& rd = self->GetRenderData(true); // RenderData must always come from atlasing. + if (!rd.settings.packed) + Scripting::RaiseMonoException("Sprite is not packed."); + return (SpritePackingMode)rd.settings.packingMode; + } + + CUSTOM_PROP SpritePackingRotation packingRotation + { + const SpriteRenderData& rd = self->GetRenderData(true); // RenderData must always come from atlasing. + if (!rd.settings.packed) + Scripting::RaiseMonoException("Sprite is not packed."); + return (SpritePackingRotation)rd.settings.packingRotation; + } + + CUSTOM private static void Internal_GetTextureRectOffset(Sprite sprite, out Vector2 output) + { + const SpriteRenderData& rd = sprite->GetRenderDataForPlayMode(); // RenderData must match <texture> accessor's behavior. + if (rd.settings.packed && rd.settings.packingMode != kSPMRectangle) + Scripting::RaiseMonoException("Sprite is not rectangle-packed. TextureRectOffset is invalid."); + output->x = rd.textureRectOffset.x; + output->y = rd.textureRectOffset.y; + } + + CONDITIONAL ENABLE_SPRITECOLLIDER + CUSTOM_PROP int colliderPathCount + { + return self->GetPoly().GetPathCount(); + } + + CONDITIONAL ENABLE_SPRITECOLLIDER + CUSTOM public Vector2[] GetColliderPath(int index) + { + if (index >= self->GetPoly().GetPathCount()) + { + Scripting::RaiseOutOfRangeException("Path %d does not exist.", index); + return SCRIPTING_NULL; + } + + const Polygon2D::TPath& path = self->GetPoly().GetPath(index); + return CreateScriptingArrayStride<Vector2f>(path.data(), path.size(), MONO_COMMON.vector2, sizeof(*path.data())); + } + +END + +CONDITIONAL ENABLE_SPRITES +/// Renders a Sprite. +CLASS SpriteRenderer : Renderer + + CSRAW + public Sprite sprite + { + get + { + return GetSprite_INTERNAL(); + } + set + { + SetSprite_INTERNAL(value); + } + } + + CUSTOM private Sprite GetSprite_INTERNAL() + { + return Scripting::ScriptingWrapperFor(self->GetSprite()); + } + + CUSTOM private void SetSprite_INTERNAL(Sprite sprite) + { + self->SetSprite(sprite); + } + + AUTO_PROP Color color GetColor SetColor + +END + +} + +#endif //ENABLE_SPRITES diff --git a/Runtime/Export/StackTrace.cs b/Runtime/Export/StackTrace.cs new file mode 100644 index 0000000..6e61bd5 --- /dev/null +++ b/Runtime/Export/StackTrace.cs @@ -0,0 +1,368 @@ +using System; +using System.Diagnostics; +using System.Text; +using System.Reflection.Emit; +using System.Reflection; +using System.Runtime.Serialization; +using System.Collections; + +#if UNITY_WINRT +using SystemException = System.Exception; +#endif + +namespace UnityEngine +{ +#if !UNITY_WINRT +public class StackTraceUtility +{ + static string projectFolder = ""; + + static internal void SetProjectFolder (string folder) + { + projectFolder = folder; + } + + static public string ExtractStackTrace () + { + StackTrace trace = new StackTrace (1, true); + string traceString = ExtractFormattedStackTrace (trace).ToString (); + return traceString; + } + + static bool IsSystemStacktraceType (object name) + { + string casted = (string)name; + return casted.StartsWith ("UnityEditor.") || casted.StartsWith ("UnityEngine.") || casted.StartsWith ("System.") || casted.StartsWith ("UnityScript.Lang.") || casted.StartsWith ("Boo.Lang.") || casted.StartsWith ("UnityEngine.SetupCoroutine"); + } + + static public string ExtractStringFromException(System.Object exception) + { + string message = "", stackTrace = ""; + ExtractStringFromExceptionInternal(exception, out message, out stackTrace); + return message + "\n" + stackTrace; + } + + static internal void ExtractStringFromExceptionInternal(System.Object exceptiono, out string message, out string stackTrace) + { + if (exceptiono == null) throw new ArgumentException("ExtractStringFromExceptionInternal called with null exception"); + var exception = exceptiono as System.Exception; + if (exception == null) throw new ArgumentException("ExtractStringFromExceptionInternal called with an exceptoin that was not of type System.Exception"); + + // StackTrace might not be available + StringBuilder sb = new StringBuilder(exception.StackTrace == null ? 512 : exception.StackTrace.Length*2); + message = ""; + string traceString = ""; + while (exception != null) + { + if (traceString.Length == 0) + traceString = exception.StackTrace; + else + traceString = exception.StackTrace + "\n" + traceString; + + string thisMessage = exception.GetType ().Name; + string exceptionMessage = ""; + if (exception.Message!=null) exceptionMessage = exception.Message; + if (exceptionMessage.Trim().Length != 0) + { + thisMessage += ": "; + thisMessage += exceptionMessage; + } + message = thisMessage; + if (exception.InnerException != null) + { + traceString = "Rethrow as " + thisMessage + "\n" + traceString; + } + exception = exception.InnerException; + } + + sb.Append (traceString + "\n"); + + StackTrace trace = new StackTrace (1, true); + sb.Append (ExtractFormattedStackTrace (trace)); + + stackTrace = sb.ToString(); + } + + static internal string PostprocessStacktrace (string oldString, bool stripEngineInternalInformation) + { + if (oldString==null) return String.Empty; + string [] split = oldString.Split ('\n'); + StringBuilder sb = new StringBuilder(oldString.Length); + for (int i=0; i<split.Length; i++) + split[i] = split[i].Trim(); + + for (int i=0; i<split.Length; i++) + { + string newLine = split[i]; + + // Ignore empty lines + if (newLine.Length == 0 || newLine[0] == '\n') + continue; + + // Ignore unmanaged + if (newLine.StartsWith ("in (unmanaged)")) + continue; + // Make GameView GUI stack traces skip editor GUI part + if (stripEngineInternalInformation && newLine.StartsWith("UnityEditor.EditorGUIUtility:RenderGameViewCameras")) break; + // Ignore deep system stacktraces + if (stripEngineInternalInformation && i<split.Length-1 && IsSystemStacktraceType(newLine)) + { + if (IsSystemStacktraceType(split[i+1])) + continue; + int lineInfo = newLine.IndexOf(" (at"); + if (lineInfo != -1) + newLine = newLine.Substring (0, lineInfo); + } + // Ignore wrapper managed to native + if (newLine.IndexOf ("(wrapper managed-to-native)") != -1) + continue; + if (newLine.IndexOf ("(wrapper delegate-invoke)") != -1) + continue; + // Ignore unknown method + if (newLine.IndexOf ("at <0x00000> <unknown method>") != -1) + continue; + // Ignore C++ line information + if (stripEngineInternalInformation && newLine.StartsWith ("[") && newLine.EndsWith("]")) + continue; + // Ignore starting at + if (newLine.StartsWith ("at ")) + { + newLine = newLine.Remove (0, 3); + } + + // Remove square brace [0x00001] + int brace = newLine.IndexOf("[0x"); + int braceClose = -1; + if (brace != -1) + braceClose = newLine.IndexOf("]", brace); + if (brace != -1 && braceClose > brace) + { + newLine = newLine.Remove (brace, braceClose - brace + 1); + } + + newLine = newLine.Replace(" in <filename unknown>:0", ""); + + newLine = newLine.Replace(projectFolder, ""); + + // Unify path names to unix style + newLine = newLine.Replace('\\','/'); + + int inStart = newLine.LastIndexOf (" in "); + if (inStart != -1) + { + newLine = newLine.Remove(inStart, 5); + newLine = newLine.Insert(inStart, " (at "); + newLine = newLine.Insert(newLine.Length, ")"); + } + + sb.Append (newLine+"\n"); + } + + return sb.ToString (); + } + + static internal string ExtractFormattedStackTrace (StackTrace stackTrace) + { + StringBuilder sb = new StringBuilder(255); + int iIndex; + + // need to skip over "n" frames which represent the + // System.Diagnostics package frames + for (iIndex=0; iIndex < stackTrace.FrameCount; iIndex++) + { + StackFrame frame = stackTrace.GetFrame (iIndex); + + MethodBase mb = frame.GetMethod (); + if (mb == null) + continue; + + Type classType = mb.DeclaringType; + if (classType == null) + continue; + + // Add namespace.classname:MethodName + String ns = classType.Namespace; + if (ns != null && ns.Length != 0) + { + sb.Append (ns); + sb.Append ("."); + } + + sb.Append (classType.Name); + sb.Append (":"); + sb.Append (mb.Name); + sb.Append ("("); + + // Add parameters + int j=0; + ParameterInfo[] pi = mb.GetParameters(); + bool fFirstParam = true; + while (j < pi.Length) + { + if (fFirstParam == false) + sb.Append (", "); + else + fFirstParam = false; + + sb.Append (pi[j].ParameterType.Name); + j++; + } + sb.Append (")"); + + // Add path name and line number - unless it is a Debug.Log call, then we are only interested + // in the calling frame. + string path = frame.GetFileName (); + if (path != null && !(classType.Name == "Debug" && classType.Namespace == "UnityEngine")) + { + sb.Append (" (at "); + + if (path.StartsWith (projectFolder)) + { + path = path.Substring (projectFolder.Length, path.Length - projectFolder.Length); + } + sb.Append (path); + sb.Append (":"); + sb.Append (frame.GetFileLineNumber ().ToString ()); + sb.Append (")"); + } + + sb.Append ("\n"); + } + + return sb.ToString(); + } +} +#endif + +[Serializable] +public class UnityException : SystemException +{ + const int Result = unchecked ((int)0x80004003); + string unityStackTrace; + + // Constructors + public UnityException () + : base ("A Unity Runtime error occurred!") + { + HResult = Result; + } + + public UnityException (string message) + : base (message) + { + HResult = Result; + } + + public UnityException (string message, Exception innerException) + : base (message, innerException) + { + HResult = Result; + } +#if !UNITY_WINRT + protected UnityException (SerializationInfo info, StreamingContext context) + : base (info, context) + { + } +#endif +} + +[Serializable] +public class MissingComponentException : SystemException +{ + const int Result = unchecked ((int)0x80004003); + string unityStackTrace; + + // Constructors + public MissingComponentException () + : base ("A Unity Runtime error occurred!") + { + HResult = Result; + } + + public MissingComponentException (string message) + : base (message) + { + HResult = Result; + } + + public MissingComponentException (string message, Exception innerException) + : base (message, innerException) + { + HResult = Result; + } +#if !UNITY_WINRT + protected MissingComponentException (SerializationInfo info, StreamingContext context) + : base (info, context) + { + } +#endif +} + + +[Serializable] +public class UnassignedReferenceException : SystemException +{ + const int Result = unchecked ((int)0x80004003); + string unityStackTrace; + + // Constructors + public UnassignedReferenceException () + : base ("A Unity Runtime error occurred!") + { + HResult = Result; + } + + public UnassignedReferenceException (string message) + : base (message) + { + HResult = Result; + } + + public UnassignedReferenceException (string message, Exception innerException) + : base (message, innerException) + { + HResult = Result; + } +#if !UNITY_WINRT + protected UnassignedReferenceException (SerializationInfo info, StreamingContext context) + : base (info, context) + { + } +#endif +} + + +[Serializable] +public class MissingReferenceException : SystemException +{ + const int Result = unchecked ((int)0x80004003); + string unityStackTrace; + + // Constructors + public MissingReferenceException () + : base ("A Unity Runtime error occurred!") + { + HResult = Result; + } + + public MissingReferenceException (string message) + : base (message) + { + HResult = Result; + } + + public MissingReferenceException (string message, Exception innerException) + : base (message, innerException) + { + HResult = Result; + } +#if !UNITY_WINRT + protected MissingReferenceException (SerializationInfo info, StreamingContext context) + : base (info, context) + { + } +#endif +} + + +} diff --git a/Runtime/Export/StaticBatching/CombineForStaticBatching.cs b/Runtime/Export/StaticBatching/CombineForStaticBatching.cs new file mode 100644 index 0000000..ffe5477 --- /dev/null +++ b/Runtime/Export/StaticBatching/CombineForStaticBatching.cs @@ -0,0 +1,230 @@ +//using UnityEngine; +using System; +using System.Collections; +using System.Collections.Generic; + +#if !UNITY_FLASH// no static batching in flash + +namespace UnityEngine +{ +internal class InternalStaticBatchingUtility { + // assume 16bit indices + const int MaxVerticesInBatch = 64000; // a little bit less than 64K - just in case + const string CombinedMeshPrefix = "Combined Mesh"; + + static public void Combine (UnityEngine.GameObject staticBatchRoot) + { + Combine(staticBatchRoot, false); + } + + static public void Combine (UnityEngine.GameObject staticBatchRoot, bool combineOnlyStatic) + { + GameObject[] gos = (GameObject[])UnityEngine.Object.FindObjectsOfType(typeof(GameObject)); + + List<GameObject> filteredGos = new List<GameObject>(); + foreach (GameObject go in gos) + { + if (staticBatchRoot != null) + if (!go.transform.IsChildOf(staticBatchRoot.transform)) + continue; + + if (combineOnlyStatic && !go.isStaticBatchable ) + continue; + + filteredGos.Add(go); + } + + gos = filteredGos.ToArray(); + + // Inform user about Advanced license only feature + // real license guard is baked into the native code. + bool hasProOrAdvancedLicense = Application.HasProLicense() || Application.HasAdvancedLicense(); + if (!hasProOrAdvancedLicense) + { + // Display error only if invoked from the user script + if (staticBatchRoot != null && gos.Length > 0) + Debug.LogError("Your Unity license is not sufficient for Static Batching."); + } + + Combine(gos, staticBatchRoot); + } + + static public void Combine(GameObject[] gos, UnityEngine.GameObject staticBatchRoot) + { + Matrix4x4 staticBatchInverseMatrix = Matrix4x4.identity; + Transform staticBatchRootTransform = null; + if (staticBatchRoot) + { + staticBatchInverseMatrix = staticBatchRoot.transform.worldToLocalMatrix; + staticBatchRootTransform = staticBatchRoot.transform; + } + + int batchIndex = 0; + int verticesInBatch = 0; + List<MeshSubsetCombineUtility.MeshInstance> meshes = new List<MeshSubsetCombineUtility.MeshInstance>(); + List<MeshSubsetCombineUtility.SubMeshInstance> subsets = new List<MeshSubsetCombineUtility.SubMeshInstance>(); + List<GameObject> subsetGOs = new List<GameObject> (); + + Array.Sort(gos, new SortGO()); + + foreach (GameObject go in gos) + { + MeshFilter filter = go.GetComponent(typeof(MeshFilter)) as MeshFilter; + if (filter == null) + continue; + + // reject if has no mesh + if (filter.sharedMesh == null) + continue; + + // reject if mesh not readable + if (!filter.sharedMesh.canAccess) + continue; + + // reject if has not renderer or renderer is disabled + if (filter.renderer == null || !filter.renderer.enabled) + continue; + + // reject if already combined for static batching + if (filter.renderer.staticBatchIndex != 0) + continue; + + // check if we have enough space inside the current batch + if (verticesInBatch + filter.sharedMesh.vertexCount > MaxVerticesInBatch) + { + MakeBatch (meshes, subsets, subsetGOs, staticBatchRootTransform, batchIndex++); + meshes.Clear(); + subsets.Clear(); + subsetGOs.Clear(); + verticesInBatch = 0; + } + + MeshSubsetCombineUtility.MeshInstance instance = new MeshSubsetCombineUtility.MeshInstance (); + Mesh instanceMesh = filter.sharedMesh; + instance.meshInstanceID = instanceMesh.GetInstanceID(); + instance.transform = staticBatchInverseMatrix * filter.transform.localToWorldMatrix; + instance.lightmapTilingOffset = filter.renderer.lightmapTilingOffset; + + //;;Debug.Log("New static mesh (" + go.name + ")verts: " + instance.mesh.vertexCount + + // ", tris: " + instance.mesh.triangles.Length + + // ", materials: " + filter.renderer.sharedMaterials.Length + + // ", subs: " + instance.mesh.subMeshCount + // ); + + meshes.Add(instance); + + Material[] materials = filter.renderer.sharedMaterials; + if (materials.Length > instanceMesh.subMeshCount) + { + Debug.LogWarning("Mesh has more materials (" + materials.Length + ") than subsets (" + instanceMesh.subMeshCount + ")"); + // extra materials don't have a meaning and it screws the rendering as Unity + // tries to render with those extra materials. + Material[] newMats = new Material[instanceMesh.subMeshCount]; + for (int i = 0; i < instanceMesh.subMeshCount; ++i) + newMats[i] = filter.renderer.sharedMaterials[i]; + filter.renderer.sharedMaterials = newMats; + materials = newMats; + } + + for (int m = 0; m < System.Math.Min(materials.Length, instanceMesh.subMeshCount); ++m) + { + //;;Debug.Log(" new subset : " + m + ", tris " + instance.mesh.GetTriangles(m).Length); + MeshSubsetCombineUtility.SubMeshInstance subsetInstance = new MeshSubsetCombineUtility.SubMeshInstance(); + subsetInstance.meshInstanceID = filter.sharedMesh.GetInstanceID(); + subsetInstance.vertexOffset = verticesInBatch; + subsetInstance.subMeshIndex = m; + subsetInstance.gameObjectInstanceID = go.GetInstanceID(); + subsetInstance.transform = instance.transform; + subsets.Add(subsetInstance); + subsetGOs.Add(go); + } + verticesInBatch += instanceMesh.vertexCount; + } + + MakeBatch(meshes, subsets, subsetGOs, staticBatchRootTransform, batchIndex); + } + + static private void MakeBatch(List<MeshSubsetCombineUtility.MeshInstance> meshes, List<MeshSubsetCombineUtility.SubMeshInstance> subsets, List<GameObject> subsetGOs, Transform staticBatchRootTransform, int batchIndex) + { + if (meshes.Count < 2) + return; + + MeshSubsetCombineUtility.MeshInstance[] aMeshes = meshes.ToArray(); + MeshSubsetCombineUtility.SubMeshInstance[] aSubsets = subsets.ToArray(); + + string combinedMeshName = CombinedMeshPrefix; + combinedMeshName += " (root: " + ((staticBatchRootTransform != null)? staticBatchRootTransform.name: "scene") + ")"; + if (batchIndex > 0) + combinedMeshName += " " + (batchIndex + 1); + + Mesh combinedMesh = StaticBatchingUtility.InternalCombineVertices (aMeshes, combinedMeshName); + StaticBatchingUtility.InternalCombineIndices(aSubsets, combinedMesh); + + int subsetIndex = 0; + for (int item = 0; item < aSubsets.Length; item++) + { + MeshSubsetCombineUtility.SubMeshInstance i = aSubsets[item]; + GameObject go = subsetGOs[item]; + Mesh m = combinedMesh; + + MeshFilter filter = (MeshFilter)go.GetComponent(typeof(MeshFilter)); + filter.sharedMesh = m; + + go.renderer.SetSubsetIndex(i.subMeshIndex, subsetIndex); + go.renderer.staticBatchRootTransform = staticBatchRootTransform; + + // for some reason if GOs were created dynamically + // then we need to toggle renderer to avoid caching old geometry + go.renderer.enabled = false; + go.renderer.enabled = true; + + subsetIndex++; + } + } + + internal class SortGO : IComparer + { + int IComparer.Compare( object a, object b ) + { + if (a == b) + return 0; + + Renderer aRenderer = GetRenderer(a as GameObject); + Renderer bRenderer = GetRenderer(b as GameObject); + + int compare = GetMaterialId(aRenderer).CompareTo(GetMaterialId(bRenderer)); + if (compare == 0) + compare = GetLightmapIndex(aRenderer).CompareTo(GetLightmapIndex(bRenderer)); + return compare; + } + + static private int GetMaterialId(Renderer renderer) + { + if (renderer == null || renderer.sharedMaterial == null) + return 0; + return renderer.sharedMaterial.GetInstanceID(); + } + + static private int GetLightmapIndex(Renderer renderer) + { + if (renderer == null) + return -1; + return renderer.lightmapIndex; + } + + static private Renderer GetRenderer(GameObject go) + { + if (go == null) + return null; + MeshFilter filter = go.GetComponent(typeof(MeshFilter)) as MeshFilter; + if (filter == null) + return null; + + return filter.renderer; + } + } +} + +} // namespace UnityEngine + +#endif diff --git a/Runtime/Export/StaticBatching/MeshSubsetCombineUtility.cs b/Runtime/Export/StaticBatching/MeshSubsetCombineUtility.cs new file mode 100644 index 0000000..0c76f14 --- /dev/null +++ b/Runtime/Export/StaticBatching/MeshSubsetCombineUtility.cs @@ -0,0 +1,30 @@ +using UnityEngine; +using System.Collections; + +#if !UNITY_FLASH// no static batching in flash + +namespace UnityEngine +{ + +internal class MeshSubsetCombineUtility { + + public struct MeshInstance + { + public int meshInstanceID; + public Matrix4x4 transform; + public Vector4 lightmapTilingOffset; + } + + public struct SubMeshInstance + { + public int meshInstanceID; + public int vertexOffset; + public int gameObjectInstanceID; + public int subMeshIndex; + public Matrix4x4 transform; + } +} + +} // namespace UnityEngine + +#endif diff --git a/Runtime/Export/SubstanceUtility.txt b/Runtime/Export/SubstanceUtility.txt new file mode 100644 index 0000000..d35d718 --- /dev/null +++ b/Runtime/Export/SubstanceUtility.txt @@ -0,0 +1,436 @@ +// SUBSTANCE HOOK + +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Graphics/ProceduralTexture.h" +#include "Runtime/Graphics/SubstanceArchive.h" +#include "Runtime/Graphics/ProceduralMaterial.h" +#include "Runtime/Graphics/Texture2D.h" +#include "Runtime/Math/Color.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#if ENABLE_SUBSTANCE +#include "Runtime/Graphics/SubstanceSystem.h" +#endif +#include "Runtime/Scripting/Scripting.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ +// The global Substance engine processor usage (as used for the ProceduralMaterial.substanceProcessorUsage property). +CONDITIONAL ENABLE_SUBSTANCE +ENUM ProceduralProcessorUsage + // Exact control of processor usage is not available. + Unsupported = 0, + + // A single physical processor core is used for material generation. + One = 1, + + // Half of all physical processor cores are used for material generation. + Half = 2, + + // All physical processor cores are used for material generation. + All = 3 +END + +// Substance memory budget. +CONDITIONAL ENABLE_SUBSTANCE +ENUM ProceduralCacheSize + // A limit of 128MB for the cache or the working memory. + Tiny = 0, + + // A limit of 256MB for the cache or the working memory. + Medium = 1, + + // A limit of 512MB for the cache or the working memory. + Heavy = 2, + + // No limit for the cache or the working memory. + NoLimit = 3, + + // A limit of 1B (one byte) for the cache or the working memory. + None = 4 +END + +// ProceduralMaterial loading behavior +CONDITIONAL ENABLE_SUBSTANCE +ENUM ProceduralLoadingBehavior + // Do not generate the textures, allowing a custom loading + DoNothing = 0, + + // Generate the textures when loading to favor application's size (default on supported platform) + Generate = 1, + + // Bake the textures to speed-up loading, then it may be generated later on + BakeAndKeep = 2, + + // Bake the textures and remove dependencies (default on unsupported platform) + BakeAndDiscard = 3, + + // Generate the textures when loading and cache them to speed-up subsequent startups + Cache = 4 +END + +// The type of a Procedural property. +CONDITIONAL ENABLE_SUBSTANCE +ENUM ProceduralPropertyType + // Procedural boolean property. Use with ProceduralMaterial.GetProceduralBoolean. + Boolean = 0, + + // Procedural float property. Use with ProceduralMaterial.GetProceduralFloat. + Float = 1, + + // Procedural Vector2 property. Use with ProceduralMaterial.GetProceduralVector. + Vector2 = 2, + + // Procedural Vector3 property. Use with ProceduralMaterial.GetProceduralVector. + Vector3 = 3, + + // Procedural Vector4 property. Use with ProceduralMaterial.GetProceduralVector. + Vector4 = 4, + + // Procedural Color property without alpha. Use with ProceduralMaterial.GetProceduralColor. + Color3 = 5, + + // Procedural Color property with alpha. Use with ProceduralMaterial.GetProceduralColor. + Color4 = 6, + + // Procedural Enum property. Use with ProceduralMaterial.GetProceduralEnum. + Enum = 7, + + // Procedural Texture property. Use with ProceduralMaterial.GetProceduralTexture. + Texture = 8 +END + +// The type of generated image in a Procedural Material. +CONDITIONAL ENABLE_SUBSTANCE +ENUM ProceduralOutputType + // Undefined type. + Unknown = 0, + // Diffuse type. + Diffuse = 1, + // NormalMap (BumpMap) type. + Normal = 2, + // HeightMap type. + Height = 3, + // Emmisive type. + Emissive = 4, + // Specular (GlossMap) type. + Specular = 5, + // Opacity (Tranparence) type. + Opacity = 6 +END + +// Describes a Procedural property. +CONDITIONAL ENABLE_SUBSTANCE +CSRAW [StructLayout (LayoutKind.Sequential)] +CLASS ProceduralPropertyDescription + // The name of the Procedural property. Used to get and set the values. + CSRAW public string name; + + // The user friendly label of the Procedural property. Used to display Procedural property friendly names. + CSRAW public string label; + + // The name of the GUI group. Used to display Procedural property in groups. + CSRAW public string group; + + // The [[ProceduralPropertyType]] describes what type of property this is. + CSRAW public ProceduralPropertyType type; + + // If true, the Float or Vector property is constrained to values within a specified range. + CSRAW public bool hasRange; + + // If hasRange is true, minimum specifies the minimum allowed value for this Float or Vector property. + CSRAW public float minimum; + + // If hasRange is true, maximum specifies the maximum allowed value for this Float or Vector property. + CSRAW public float maximum; + + // Specifies the step size of this Float or Vector property. Zero is no step. + CSRAW public float step; + + // The available options for a Procedural property of type Enum. + CSRAW public string[] enumOptions; +END + +C++RAW + +#if ENABLE_SUBSTANCE +struct MonoProceduralPropertyDescription +{ + ScriptingStringPtr name; + ScriptingStringPtr label; + ScriptingStringPtr group; + ProceduralPropertyType type; + bool hasRange; + float minimum; + float maximum; + float step; + ScriptingArrayPtr enumOptions; +}; + +void ProceduralPropertyDescriptionToMono (const SubstanceInput& src, MonoProceduralPropertyDescription& dest) +{ + dest.name = scripting_string_new(src.name); + dest.label = scripting_string_new(src.label); + dest.group = scripting_string_new(src.group); + dest.type = src.type; + dest.hasRange = src.IsFlagEnabled(SubstanceInput::Flag_Clamp); + dest.minimum = src.minimum; + dest.maximum = src.maximum; + dest.step = src.step; + dest.enumOptions = Scripting::StringVectorToMono (src.GetEnumOptions ()); +} +#endif + +// ProceduralMaterial class. +// TODO: Make example use material instead of sharedMaterial when instancing works. +// TODO: Make example lerp between property min and max value when GetProceduralPropertyDescription is implemented. + +CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL +CLASS ProceduralMaterial : Material + + // Default constructor. This should not be used. + // TODO: Constructor that takes a source ProceduralMaterial as parameter and clones it. + CSRAW public ProceduralMaterial () : base ("") {} + + // Get an array of descriptions of all the properties this Procedural Material has. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM ProceduralPropertyDescription[] GetProceduralPropertyDescriptions () + { + const std::vector<SubstanceInput>& inputs = self->GetSubstanceInputs (); + return VectorToScriptingClassArray<SubstanceInput, MonoProceduralPropertyDescription> (inputs, GetScriptingManager().GetCommonClasses().substancePropertyDescription, ProceduralPropertyDescriptionToMono); + } + + // Checks if the Procedural Material has a property of a given name. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM bool HasProceduralProperty (string inputName) { return self->HasSubstanceProperty (inputName); } + + // Get a named Procedural boolean property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM bool GetProceduralBoolean (string inputName) { return self->GetSubstanceBoolean (inputName); } + + // Set a named Procedural boolean property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void SetProceduralBoolean (string inputName, bool value) { self->SetSubstanceBoolean (inputName, value); } + + // Get a named Procedural float property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM float GetProceduralFloat (string inputName) { return self->GetSubstanceFloat (inputName); } + + // Set a named Procedural float property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void SetProceduralFloat (string inputName, float value) { self->SetSubstanceFloat (inputName, value); } + + // Get a named Procedural vector property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM Vector4 GetProceduralVector (string inputName) { return self->GetSubstanceVector (inputName); } + + // Set a named Procedural vector property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void SetProceduralVector (string inputName, Vector4 value) { self->SetSubstanceVector (inputName, value); } + + // Get a named Procedural color property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM Color GetProceduralColor (string inputName) { return self->GetSubstanceColor (inputName); } + + // Set a named Procedural color property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void SetProceduralColor (string inputName, Color value) { self->SetSubstanceColor (inputName, value); } + + // Get a named Procedural enum property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM int GetProceduralEnum (string inputName) { return self->GetSubstanceEnum (inputName); } + + // Set a named Procedural enum property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void SetProceduralEnum (string inputName, int value) { self->SetSubstanceEnum (inputName, value); } + + // Get a named Procedural texture property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM Texture2D GetProceduralTexture (string inputName) { return Scripting::ScriptingWrapperFor (self->GetSubstanceTexture (inputName)); } + + // Set a named Procedural texture property. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void SetProceduralTexture (string inputName, Texture2D value) { self->SetSubstanceTexture (inputName, value); } + + // Checks if a named Procedural property is cached for efficient runtime tweaking. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM bool IsProceduralPropertyCached (string inputName) { return self->IsSubstancePropertyCached (inputName); } + + // Specifies if a named Procedural property should be cached for efficient runtime tweaking. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void CacheProceduralProperty (string inputName, bool value) { self->CacheSubstanceProperty (inputName, value); } + + // Clear the Procedural cache. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void ClearCache () { self->ClearCache (); } + + // Set & get the Procedural cache budget. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP ProceduralCacheSize cacheSize + { + return self->GetProceduralMemoryBudget (); + } + { + self->SetProceduralMemoryBudget(value); + } + + // Set & get the update rate in millisecond of the animated substance + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP int animationUpdateRate + { + return self->GetAnimationUpdateRate (); + } + { + self->SetAnimationUpdateRate(value); + } + + // Triggers an asyncronous rebuild of all dirty textures. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void RebuildTextures () + { + self->RebuildTextures (); + } + + // Triggers an immediate (synchronous) rebuild of all dirty textures. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM void RebuildTexturesImmediately () + { + self->RebuildTexturesImmediately (); + } + + // Checks if the Procedural Material is currently in the process of rebuilding the textures. + // Note that it doesn't show if it has not changed. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP bool isProcessing + { + return self->IsProcessing (); + } + + // Remove the current pending rebuilds of the Procedural Material. + CUSTOM static void StopRebuilds () + { + ProceduralMaterial::StopProcessing (); + } + + // Should the Procedural Material be generated at load time? + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP bool isLoadTimeGenerated + { + return self->IsFlagEnabled (ProceduralMaterial::Flag_Animated) + || self->GetLoadingBehavior ()!=ProceduralLoadingBehavior_None; + } + { + self->SetLoadingBehavior( value ? ProceduralLoadingBehavior_Generate : ProceduralLoadingBehavior_None ); + } + + // Get Procedural Material loading behavior + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP ProceduralLoadingBehavior loadingBehavior + { + return self->GetLoadingBehavior (); + } + + // Checks if the Procedural Materials are supported on the current platform. + CUSTOM_PROP static bool isSupported + { + return IsSubstanceSupported (); + } + + // Used to specify the Substance engine CPU usage. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP static ProceduralProcessorUsage substanceProcessorUsage + { + return ProceduralMaterial::GetProceduralProcessorUsage (); + } + { + ProceduralMaterial::SetProceduralProcessorUsage (value); + } + + // XML string of "input/value" pairs (setting the preset rebuilds the textures) + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP string preset + { + return scripting_string_new(self->GetPreset ()); + } + { + self->SetPreset (value); + } + + // Get generated textures. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM Texture[] GetGeneratedTextures () + { + return CreateScriptingArrayFromUnityObjects (self->GetPingedTextures (), ClassID (Texture)); + } + + // Get generated texture by name. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM ProceduralTexture GetGeneratedTexture (string textureName) + { + return Scripting::ScriptingWrapperFor (self->GetGeneratedTexture (textureName)); + } + + // Readable substances keep the generated texture data accessible to GetPixels32 (format must be RAW (RGBA or ARGB)). + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM_PROP bool isReadable + { + return self->IsFlagEnabled (ProceduralMaterial::Flag_Readable); + } + { + self->EnableFlag (ProceduralMaterial::Flag_Readable, value); + } + +END + +CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL +CLASS ProceduralTexture : Texture + + // The output type of this Texture. + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM ProceduralOutputType GetProceduralOutputType () + { + return self->GetType (); + } + + // Retrieve the procedural material parent to this texture + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM internal ProceduralMaterial GetProceduralMaterial () + { + return Scripting::ScriptingWrapperFor(self->GetSubstanceMaterial ()); + } + + // Check if the texture has already been generated, at least one time + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM internal bool HasBeenGenerated () + { + return self->HasBeenGenerated (); + } + + // Get pixels from a generated texture. + // The ProceduralMaterial must have the flag isReadable set before a call to RebuildTexturesImmediately and be configured as 'RAW' format (RGBA/ARGB). + CONDITIONAL ENABLE_SUBSTANCE + CUSTOM Color32[] GetPixels32(int x, int y, int blockWidth, int blockHeight) + { + int w = blockWidth; if( w < 1 ) w = 1; + int h = blockHeight; if( h < 1 ) h = 1; + + ScriptingArray* colors = CreateScriptingArray<ColorRGBA32>(GetMonoManager().GetCommonClasses().color32, w * h); + ColorRGBA32* firstElement = Scripting::GetScriptingArrayStart<ColorRGBA32>(colors); + self->GetPixels32(x, y, blockWidth, blockHeight, firstElement); + return colors; + } + +END + +CSRAW +} // namespace UnityEngine diff --git a/Runtime/Export/SyntaxDefs/template-csharp.plist b/Runtime/Export/SyntaxDefs/template-csharp.plist new file mode 100644 index 0000000..c764621 --- /dev/null +++ b/Runtime/Export/SyntaxDefs/template-csharp.plist @@ -0,0 +1,140 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>beginCommand</key> + <string></string> + <key>endCommand</key> + <string></string> + <key>beginInstruction</key> + <string></string> + <key>endInstruction</key> + <string></string> + <key>beginVariable</key> + <string></string> + <key>endVariable</key> + <string></string> + <key>firstString</key> + <string>"</string> + <key>secondString</key> + <string>'</string> + <key>firstSingleLineComment</key> + <string>//</string> + <key>secondSingleLineComment</key> + <string></string> + <key>beginFirstMultiLineComment</key> + <string>/*</string> + <key>endFirstMultiLineComment</key> + <string>*/</string> + <key>beginSecondMultiLineComment</key> + <string></string> + <key>endSecondMultiLineComment</key> + <string></string> + <key>functionDefinition</key> + <string>^\s*(static|public|private|protected|internal).*\(.*\).*\n?\s*{</string> + <key>removeFromFunction</key> + <string></string> + <key>keywordsCaseSensitive</key> + <true/> + <key>recolourKeywordIfAlreadyColoured</key> + <false/> + <key>keywords</key> + <array> + <string>abstract</string> + <string>as</string> + <string>base</string> + <string>break</string> + <string>case</string> + <string>catch</string> + <string>class</string> + <string>checked</string> + <string>continue</string> + <string>default</string> + <string>delegate</string> + <string>do</string> + <string>else</string> + <string>enum</string> + <string>event</string> + <string>explicit</string> + <string>extern</string> + <string>false</string> + <string>for</string> + <string>foreach</string> + <string>finally</string> + <string>fixed</string> + <string>goto</string> + <string>if</string> + <string>implicit</string> + <string>in</string> + <string>interface</string> + <string>internal</string> + <string>is</string> + <string>lock</string> + <string>namespace</string> + <string>new</string> + <string>null</string> + <string>operator</string> + <string>out</string> + <string>override</string> + <string>params</string> + <string>private</string> + <string>protected</string> + <string>public</string> + <string>readonly</string> + <string>ref</string> + <string>return</string> + <string>sealed</string> + <string>sizeof</string> + <string>stackalloc</string> + <string>static</string> + <string>struct</string> + <string>switch</string> + <string>this</string> + <string>throw</string> + <string>true</string> + <string>try</string> + <string>typeof</string> + <string>unchecked</string> + <string>unsafe</string> + <string>using</string> + <string>virtual</string> + <string>while</string> + <string>#if</string> + <string>#else</string> + <string>#elif</string> + <string>#endif</string> + <string>#define</string> + <string>#undef</string> + <string>#warning</string> + <string>#error</string> + <string>#line</string> + <string>bool</string> + <string>byte</string> + <string>char</string> + <string>const</string> + <string>decimal</string> + <string>double</string> + <string>float</string> + <string>int</string> + <string>long</string> + <string>object</string> + <string>uint</string> + <string>ushort</string> + <string>ulong</string> + <string>sbyte</string> + <string>short</string> + <string>string</string> + <string>void</string> + </array> + <key>autocompleteWords</key> + <array> + REPLACE_SCRIPT_SYNTAX + <string>IEnumerator</string> + <string>System</string> + <string>UnityEngine</string> + <string>UnityEditor</string> + <string>ArrayList</string> + <string>Length</string> + </array> +</dict> +</plist> diff --git a/Runtime/Export/SyntaxDefs/template-javascript.plist b/Runtime/Export/SyntaxDefs/template-javascript.plist new file mode 100644 index 0000000..344065a --- /dev/null +++ b/Runtime/Export/SyntaxDefs/template-javascript.plist @@ -0,0 +1,97 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>beginCommand</key> + <string></string> + <key>endCommand</key> + <string></string> + <key>beginInstruction</key> + <string></string> + <key>endInstruction</key> + <string></string> + <key>beginVariable</key> + <string></string> + <key>endVariable</key> + <string></string> + <key>firstString</key> + <string>"</string> + <key>secondString</key> + <string>'</string> + <key>firstSingleLineComment</key> + <string>//</string> + <key>secondSingleLineComment</key> + <string></string> + <key>beginFirstMultiLineComment</key> + <string>/*</string> + <key>endFirstMultiLineComment</key> + <string>*/</string> + <key>beginSecondMultiLineComment</key> + <string></string> + <key>endSecondMultiLineComment</key> + <string></string> + <key>functionDefinition</key> + <string>^\s*function\s+.*\n?\s*{</string> + <key>removeFromFunction</key> + <string>function </string> + <key>keywordsCaseSensitive</key> + <true/> + <key>recolourKeywordIfAlreadyColoured</key> + <false/> + <key>keywords</key> + <array> + <string>if</string> + <string>else</string> + <string>for</string> + <string>in</string> + <string>while</string> + <string>do</string> + <string>continue</string> + <string>break</string> + <string>with</string> + <string>try</string> + <string>catch</string> + <string>switch</string> + <string>case</string> + <string>new</string> + <string>var</string> + <string>function</string> + <string>return</string> + <string>delete</string> + <string>true</string> + <string>false</string> + <string>void</string> + <string>throw</string> + <string>typeof</string> + <string>const</string> + <string>default</string> + <string>this</string> + <string>as</string> + <string>int</string> + <string>float</string> + <string>boolean</string> + <string>string</string> + <string>yield</string> + <string>private</string> + <string>protected</string> + <string>public</string> + <string>internal</string> + <string>import</string> + <string>String</string> + <string>System</string> + <string>UnityEngine</string> + <string>UnityEditor</string> + <string>ArrayList</string> + <string>Length</string> + <string>class</string> + <string>struct</string> + <string>enum</string> + <string>extends</string> + <string>static</string> + </array> + <key>autocompleteWords</key> + <array> + REPLACE_SCRIPT_SYNTAX + </array> +</dict> +</plist> diff --git a/Runtime/Export/SystemClock.cs b/Runtime/Export/SystemClock.cs new file mode 100644 index 0000000..a4a26c9 --- /dev/null +++ b/Runtime/Export/SystemClock.cs @@ -0,0 +1,10 @@ +namespace UnityEngine +{ +internal class SystemClock +{ + public static System.DateTime now + { + get { return System.DateTime.Now; } + } +} +} diff --git a/Runtime/Export/TextEditor.cs b/Runtime/Export/TextEditor.cs new file mode 100644 index 0000000..02672ac --- /dev/null +++ b/Runtime/Export/TextEditor.cs @@ -0,0 +1,1203 @@ +using UnityEngine; +using System.Collections; +using System.Collections.Generic; + +namespace UnityEngine { + +public class TextEditor { +#if UNITY_IPHONE || UNITY_ANDROID || UNITY_BB10 || UNITY_WP8 || UNITY_TIZEN + public TouchScreenKeyboard keyboardOnScreen = null; +#endif + + public int pos = 0; + public int selectPos = 0; + public int controlID = 0; + public GUIContent content = new GUIContent(); + public GUIStyle style = GUIStyle.none; + public Rect position; + public bool multiline = false; + public bool hasHorizontalCursorPos = false; + public bool isPasswordField = false; + internal bool m_HasFocus; + public Vector2 scrollOffset = Vector2.zero; // The text field can have a scroll offset in order to display its contents + + // are we up/downing? + public Vector2 graphicalCursorPos; + public Vector2 graphicalSelectCursorPos; + + // Clear the cursor position for vertical movement... + void ClearCursorPos () {hasHorizontalCursorPos = false; m_iAltCursorPos = -1;} + + // selection + bool m_MouseDragSelectsWholeWords = false; + int m_DblClickInitPos = 0; + DblClickSnapping m_DblClickSnap = DblClickSnapping.WORDS; + bool m_bJustSelected = false; + + int m_iAltCursorPos = -1; + + public enum DblClickSnapping : byte { WORDS, PARAGRAPHS }; + + public void OnFocus () + { + if (multiline) + pos = selectPos = 0; + else + SelectAll (); + m_HasFocus = true; + } + + public void OnLostFocus () + { + m_HasFocus = false; + scrollOffset = Vector2.zero; + } + + void GrabGraphicalCursorPos () { + if (!hasHorizontalCursorPos) { + graphicalCursorPos = style.GetCursorPixelPosition (position, content, pos); + graphicalSelectCursorPos = style.GetCursorPixelPosition (position, content, selectPos); + hasHorizontalCursorPos = false; + } + } + + // Handle a key event. + // Looks up the platform-dependent key-action table & performs the event + // return true if the event was recognized. + public bool HandleKeyEvent (Event e) { + InitKeyActions (); + EventModifiers m = e.modifiers; + e.modifiers &= ~EventModifiers.CapsLock; + if (s_Keyactions.ContainsKey(e)) { + TextEditOp op = (TextEditOp)s_Keyactions[e]; + PerformOperation (op); + e.modifiers = m; + return true; + } + e.modifiers = m; + return false; + } + + // Deletes previous text on the line + public bool DeleteLineBack() + { + if (hasSelection) + { + DeleteSelection(); + return true; + } + int p = pos; + int i = p; + while (i-- != 0) + if (content.text[i] == '\n') { + p = i + 1; + break; + } + if (i == -1) + p = 0; + if (pos != p) + { + content.text = content.text.Remove (p, pos - p); + selectPos = pos = p; + return true; + } + return false; + } + + // Deletes the previous word + public bool DeleteWordBack() + { + if (hasSelection) + { + DeleteSelection(); + return true; + } + + int prevWordEnd = FindEndOfPreviousWord(pos); + if(pos != prevWordEnd) + { + content.text = content.text.Remove(prevWordEnd, pos - prevWordEnd); + selectPos = pos = prevWordEnd; + return true; + } + return false; + } + + // Deletes the following word + public bool DeleteWordForward() + { + if (hasSelection) + { + DeleteSelection(); + return true; + } + + int nextWordStart = FindStartOfNextWord (pos); + if (pos < content.text.Length) + { + content.text = content.text.Remove(pos, nextWordStart - pos); + return true; + } + return false; + } + + // perform a right-delete + public bool Delete () { + if (hasSelection) { + DeleteSelection (); + return true; + } else + if (pos < content.text.Length) { + content.text = content.text.Remove (pos, 1); + return true; + } + return false; + } + public bool CanPaste () { + return GUIUtility.systemCopyBuffer.Length != 0; + } + // Perform a left-delete + public bool Backspace () { + if (hasSelection) { + DeleteSelection (); + return true; + } else + if (pos > 0) { + content.text = content.text.Remove (pos - 1, 1); + selectPos = pos = pos - 1; + ClearCursorPos (); + return true; + } + return false; + } + + /// Select all the text + public void SelectAll () { + pos = 0; selectPos = content.text.Length; + ClearCursorPos (); + } + + /// Select none of the text + public void SelectNone () { + selectPos = pos; + ClearCursorPos (); + } + + /// Does this text field has a selection + public bool hasSelection { get { return pos != selectPos; } } + + /// Returns the selected text + public string SelectedText { + get { + int len = content.text.Length; + if (pos > len) + pos = len; + if (selectPos > len) + selectPos = len; + if (pos == selectPos) + return ""; + if (pos < selectPos) + return content.text.Substring(pos, selectPos - pos); + else + return content.text.Substring(selectPos, pos - selectPos); + } + } + + /// Delete the current selection. If there is no selection, this function does not do anything... + public bool DeleteSelection () { + int len = content.text.Length; + if (pos > len) + pos = len; + if (selectPos > len) + selectPos = len; + if (pos == selectPos) + return false; + if (pos < selectPos) { + content.text = content.text.Substring (0, pos) + content.text.Substring (selectPos, content.text.Length - selectPos); + selectPos = pos; + } else { + content.text = content.text.Substring (0, selectPos) + content.text.Substring (pos, content.text.Length - pos); + pos = selectPos; + } + ClearCursorPos (); + + return true; + } + + /// Replace the selection with /replace/. If there is no selection, /replace/ is inserted at the current cursor point. + public void ReplaceSelection (string replace) { + DeleteSelection (); + content.text = content.text.Insert (pos, replace); + selectPos = pos += replace.Length; + ClearCursorPos (); + } + + /// Replacted the selection with /c/ + public void Insert (char c) { + ReplaceSelection (c.ToString()); + } + + /// Move selection to alt cursor /position/ + public void MoveSelectionToAltCursor() + { + if (m_iAltCursorPos == -1) + return; + int p = m_iAltCursorPos; + string tmp = SelectedText; + content.text = content.text.Insert (p, tmp); + + if (p < pos) + { + pos += tmp.Length; + selectPos += tmp.Length; + } + + DeleteSelection(); + + selectPos = pos = p; + ClearCursorPos (); + + } + + /// Move the cursor one character to the right and deselect. + public void MoveRight () { + ClearCursorPos (); + if (selectPos == pos) { + pos++; + ClampPos (); + selectPos = pos; + } else { + if (selectPos > pos) + pos = selectPos; + else + selectPos = pos; + } + } + + /// Move the cursor one character to the left and deselect. + public void MoveLeft () { + if (selectPos == pos) { + pos--; + if (pos < 0) + pos = 0; + selectPos = pos; + } else { + if (selectPos > pos) + selectPos = pos; + else + pos = selectPos; + } + ClearCursorPos (); + return; + } + + /// Move the cursor up and deselects. + public void MoveUp () { + if (selectPos < pos) + selectPos = pos; + else + pos = selectPos; + GrabGraphicalCursorPos (); + //graphicalCursorPos = style.GetCursorPixelPosition (position, content, pos); + graphicalCursorPos.y -= 1; + pos = selectPos = style.GetCursorStringIndex (position, content, graphicalCursorPos); + if (pos <= 0) + ClearCursorPos (); + } + + /// Move the cursor down and deselects. + public void MoveDown () { + if (selectPos > pos) + selectPos = pos; + else + pos = selectPos; + GrabGraphicalCursorPos (); + //graphicalCursorPos = style.GetCursorPixelPosition (position, content, pos); + graphicalCursorPos.y += style.lineHeight + 5; + pos = selectPos = style.GetCursorStringIndex (position, content, graphicalCursorPos); + if (pos == content.text.Length) + ClearCursorPos (); + + } + + + /// Moves the cursor to the start of the current line. + public void MoveLineStart () { + // we start from the left-most selected character + int p = selectPos < pos ? selectPos : pos; + // then we scan back to find the first newline + int i = p; + while (i-- != 0) + if (content.text[i] == '\n') { + selectPos = pos = i + 1; + return; + } + selectPos = pos = 0; + } + + /// Moves the selection to the end of the current line + public void MoveLineEnd () { + // we start from the right-most selected character + int p = selectPos > pos ? selectPos : pos; + // then we scan forward to find the first newline + int i = p; + int strlen = content.text.Length; + while (i < strlen) { + if (content.text[i] == '\n') { + selectPos = pos = i; + return; + } + i++; + } + selectPos = pos = strlen; + } + /// Move to the start of the current graphical line. This takes word-wrapping into consideration. + public void MoveGraphicalLineStart () { + pos = selectPos = GetGraphicalLineStart (pos < selectPos ? pos : selectPos); + } + /// Move to the end of the current graphical line. This takes word-wrapping into consideration. + public void MoveGraphicalLineEnd () { + pos = selectPos = GetGraphicalLineEnd (pos > selectPos ? pos : selectPos); + } + + /// Moves the cursor to the beginning of the text + public void MoveTextStart () { + selectPos = pos = 0; + } + + /// Moves the cursor to the end of the text + public void MoveTextEnd () { + selectPos = pos = content.text.Length; + } + + /// Move to the next paragraph + public void MoveParagraphForward () { + pos = pos > selectPos ? pos : selectPos; + if (pos < content.text.Length) { + selectPos = pos = content.text.IndexOf ('\n', pos + 1); + if (pos == -1) + selectPos = pos = content.text.Length; + } + } + /// Move to the previous paragraph + public void MoveParagraphBackward () { + pos = pos < selectPos ? pos : selectPos; + if (pos > 1) { + selectPos = pos = content.text.LastIndexOf ('\n', pos - 2) + 1; + } else + selectPos = pos = 0; + } + + // + + // Move the cursor to a graphical position. Used for moving the cursor on MouseDown events. + public void MoveCursorToPosition (Vector2 cursorPosition) { + selectPos = style.GetCursorStringIndex(position, content, cursorPosition + scrollOffset); + + if (!Event.current.shift) + { + pos = selectPos; + } + + ClampPos(); + } + public void MoveAltCursorToPosition (Vector2 cursorPosition) { + m_iAltCursorPos = style.GetCursorStringIndex (position, content, cursorPosition + scrollOffset); + ClampPos(); + } + + public bool IsOverSelection(Vector2 cursorPosition) { + int p = style.GetCursorStringIndex (position, content, cursorPosition + scrollOffset); + return ((p < Mathf.Max(pos, selectPos)) && (p > Mathf.Min(pos, selectPos))); + } + + // Do a drag selection. Used to expand the selection in MouseDrag events. + public void SelectToPosition (Vector2 cursorPosition) { + if (!m_MouseDragSelectsWholeWords) + pos = style.GetCursorStringIndex (position, content, cursorPosition + scrollOffset); + else // snap to words/paragraphs + { + int p = style.GetCursorStringIndex (position, content, cursorPosition + scrollOffset); + + + + if (m_DblClickSnap == DblClickSnapping.WORDS) + { + if (p < m_DblClickInitPos) + { + pos = FindEndOfClassification(p,-1); + selectPos = FindEndOfClassification(m_DblClickInitPos,+1) ; + } + else + { + if (p >= content.text.Length) + p = content.text.Length -1; + pos = FindEndOfClassification(p,+1); + selectPos = FindEndOfClassification(m_DblClickInitPos - 1,-1); + } + } // paragraph + else + { + if (p < m_DblClickInitPos) + { + if (p > 0) + pos = content.text.LastIndexOf('\n', p - 2) + 1; + else + pos = 0; + + selectPos = content.text.LastIndexOf('\n', m_DblClickInitPos); + } + else + { + if ( p < content.text.Length) + { + pos = content.text.IndexOf('\n', p + 1) + 1; + + if (pos <= 0) + pos = content.text.Length; + } + else + pos = content.text.Length; + + selectPos = content.text.LastIndexOf('\n', m_DblClickInitPos - 2) + 1; + } + + } + } + } + + /// Expand the selection to the left + public void SelectLeft () { + if (m_bJustSelected) + if (pos > selectPos) + { // swap + int tmp = pos; + pos = selectPos; + selectPos = tmp; + } + m_bJustSelected = false; + + pos--; + if (pos < 0) + pos = 0; + } + + public void SelectRight () { + if (m_bJustSelected) + if (pos < selectPos) + { // swap + int tmp = pos; + pos = selectPos; + selectPos = tmp; + } + m_bJustSelected = false; + + pos++; + int stringlen = content.text.Length; + if (pos > stringlen) + pos = stringlen; + } + + public void SelectUp () { + GrabGraphicalCursorPos (); + graphicalCursorPos.y -= 1; + pos = style.GetCursorStringIndex (position, content, graphicalCursorPos); + } + + public void SelectDown () { + GrabGraphicalCursorPos (); + graphicalCursorPos.y += style.lineHeight + 5; + pos = style.GetCursorStringIndex (position, content, graphicalCursorPos); + } + + /// Select to the end of the text + public void SelectTextEnd () { + // This is not quite like tha mac - there, when you select to end of text, the position of the cursor becomes somewhat i'll defined + // Hard to explain. In textedit, try: CMD-SHIFT-down, SHIFT-LEFT for case 1. then do CMD-SHIFT-down, SHIFT-RIGHT, SHIFT-LEFT for case 2. + // Anyways, it's fucked so we won't do that + pos = content.text.Length; + } + + /// Select to the start of the text + public void SelectTextStart () { + // Same thing as SelectTextEnd... + pos = 0; + } + + /// sets whether the text selection is done by dbl click or not + public void MouseDragSelectsWholeWords (bool on) + { + m_MouseDragSelectsWholeWords = on; + m_DblClickInitPos = pos; + } + + public void DblClickSnap(DblClickSnapping snapping) + { + m_DblClickSnap = snapping; + } + + int GetGraphicalLineStart (int p) { + Vector2 point = style.GetCursorPixelPosition (position, content, p); + point.x =0; + return style.GetCursorStringIndex (position, content, point); + } + + int GetGraphicalLineEnd (int p) { + Vector2 point = style.GetCursorPixelPosition (position, content, p); + point.x += 5000; + return style.GetCursorStringIndex (position, content, point); + } + + int FindNextSeperator (int startPos) { + int textLen = content.text.Length; + while (startPos < textLen && !isLetterLikeChar (content.text[startPos])) + startPos++; + while (startPos < textLen && isLetterLikeChar (content.text[startPos])) + startPos++; + return startPos; + } + + static bool isLetterLikeChar (char c) { + return System.Char.IsLetterOrDigit (c) || c == '\''; + } + + int FindPrevSeperator (int startPos) { + startPos --; + while (startPos > 0 && !isLetterLikeChar (content.text[startPos] )) + startPos--; + + while (startPos >= 0 && isLetterLikeChar (content.text[startPos] )) + startPos--; + return startPos + 1; + } + + /// Move to the end of the word. + /// If the cursor is over some space characters, these are skipped + /// Then, the cursor moves to the end of the following word. + /// This corresponds to Alt-RightArrow on a Mac + public void MoveWordRight () { + pos = pos > selectPos ? pos : selectPos; + pos = selectPos = FindNextSeperator (pos); + ClearCursorPos (); + } + + public void MoveToStartOfNextWord () { + ClearCursorPos (); + if (pos != selectPos) { + MoveRight (); + return; + } + pos = selectPos = FindStartOfNextWord (pos); + } + + public void MoveToEndOfPreviousWord () { + ClearCursorPos (); + if (pos != selectPos) { + MoveLeft (); + return; + } + pos = selectPos = FindEndOfPreviousWord (pos); + } + + + + public void SelectToStartOfNextWord () { + ClearCursorPos (); + pos = FindStartOfNextWord (pos); + } + + public void SelectToEndOfPreviousWord () { + ClearCursorPos (); + pos = FindEndOfPreviousWord (pos); + } + + enum CharacterType { + LetterLike, + Symbol, Symbol2, + WhiteSpace + } + + CharacterType ClassifyChar (char c) { + if (System.Char.IsWhiteSpace (c)) + return CharacterType.WhiteSpace; + if (System.Char.IsLetterOrDigit (c) || c == '\'') + return CharacterType.LetterLike; + return CharacterType.Symbol; + } + + /// Move to start of next word. + /// This corresponds to Ctrl-RightArrow on Windows + /// If the cursor is over a whitespace, it's moved forwards ''till the first non-whitespace character + /// If the cursor is over an alphanumeric character, it''s moved forward 'till it encounters space or a punctuation mark. + /// If the stopping character is a space, this is skipped as well. + /// If the cursor is over an punctuation mark, it's moved forward ''till it a letter or a space of a punctuation mark. If the stopping character is a space, this is skipped as well + public int FindStartOfNextWord (int p) { + int textLen = content.text.Length; + if (p == textLen) + return p; + + // Find out which char type we're at... + char c = content.text[p]; + CharacterType t = ClassifyChar (c); + if (t != CharacterType.WhiteSpace) { + p++; + while (p < textLen && ClassifyChar (content.text[p]) == t) + p++; + } else { + if ( c == '\t' || c == '\n') + return p + 1; + } + + if (p == textLen) + return p; + + // Skip spaces + c = content.text[p]; + if (c == ' ') { // If we're at a space, skip over any number of spaces + while (p < textLen && System.Char.IsWhiteSpace(content.text[p])) + p++; + } else if (c == '\t' || c == '\n') { // If we're at a tab or a newline, just step one char ahead + return p; + } + return p; + } + + int FindEndOfPreviousWord (int p) { + if (p == 0) + return p; + p--; + + // Skip spaces + while (p > 0 && content.text[p] == ' ') + p--; + + CharacterType t = ClassifyChar (content.text[p]); + if (t != CharacterType.WhiteSpace) { + while (p > 0 && ClassifyChar (content.text[p - 1]) == t) + p--; + } + return p; + } + + public void MoveWordLeft () { + pos = pos < selectPos ? pos : selectPos; + pos = FindPrevSeperator (pos); + selectPos = pos; + } + + public void SelectWordRight () { + ClearCursorPos (); + int cachedPos = selectPos; + if (pos < selectPos) { + selectPos = pos; + MoveWordRight (); + selectPos = cachedPos; + pos = pos < selectPos ? pos : selectPos; + return; + } + selectPos = pos; + MoveWordRight (); + selectPos = cachedPos; + } + + public void SelectWordLeft () { + ClearCursorPos (); + int cachedPos = selectPos; + if (pos > selectPos) { + selectPos = pos; + MoveWordLeft (); + selectPos = cachedPos; + pos = pos > selectPos ? pos : selectPos; + return; + } + selectPos = pos; + MoveWordLeft (); + selectPos = cachedPos; + } + + /// Expand the selection to the start of the line + /// Used on a mac for CMD-SHIFT-LEFT + public void ExpandSelectGraphicalLineStart () { + ClearCursorPos (); + if (pos < selectPos) + pos = GetGraphicalLineStart (pos); + else { + int temp = pos; + pos = GetGraphicalLineStart (selectPos); + selectPos = temp; + } + } + + /// Expand the selection to the end of the line + /// Used on a mac for CMD-SHIFT-RIGHT + public void ExpandSelectGraphicalLineEnd () { + ClearCursorPos (); + if (pos > selectPos) + pos = GetGraphicalLineEnd (pos); + else { + int temp = pos; + pos = GetGraphicalLineEnd (selectPos); + selectPos = temp; + } + } + + /// Move the selection point to the start of the line + /// Used on a Windows for SHIFT-Home + public void SelectGraphicalLineStart () { + ClearCursorPos (); + pos = GetGraphicalLineStart (pos); + } + + /// Expand the selection to the end of the line + /// Used on a mac for SHIFT-End + public void SelectGraphicalLineEnd () { + ClearCursorPos (); + pos = GetGraphicalLineEnd (pos); + + } + + public void SelectParagraphForward () { + ClearCursorPos (); + bool wasBehind = pos < selectPos; + if (pos < content.text.Length) { + pos = content.text.IndexOf ('\n', pos + 1); + if (pos == -1) + pos = content.text.Length; + if (wasBehind && pos > selectPos) + pos = selectPos; + } + } + + public void SelectParagraphBackward () { + ClearCursorPos (); + bool wasInFront = pos > selectPos; + if (pos > 1) { + pos = content.text.LastIndexOf ('\n', pos - 2) + 1; + if (wasInFront && pos < selectPos) + pos = selectPos; + } else + selectPos = pos = 0; + } + + /// Select the word under the cursor + public void SelectCurrentWord () { + ClearCursorPos (); + + int textLen = content.text.Length; + selectPos = pos; + + // Handle that the text box can be empty + if (textLen == 0) + return; + + if (pos >= textLen) + pos = textLen - 1; + if (selectPos >= textLen) + selectPos--; + + if (pos < selectPos) { + pos = FindEndOfClassification (pos, -1); + selectPos = FindEndOfClassification (selectPos, +1); + } else { + pos = FindEndOfClassification (pos, +1); + selectPos = FindEndOfClassification (selectPos, -1); + } + + m_bJustSelected = true; + } + + int FindEndOfClassification (int p, int dir) { + int textLen = content.text.Length; + + if ( p >= textLen || p < 0 ) + return p; + + CharacterType t = ClassifyChar(content.text[p]); + do { + p += dir; + if (p < 0) + return 0; + if (p >= textLen) + return textLen; + } while (ClassifyChar(content.text[p]) == t); + if (dir == 1) + return p; + return p + 1; + } + + // Select the entire paragraph the cursor is on (separated by \n) + public void SelectCurrentParagraph () { + ClearCursorPos (); + int textLen = content.text.Length; + + if (pos < textLen) { + pos = content.text.IndexOf ('\n', pos); + if (pos == -1) + pos = content.text.Length; + else + pos++; + } + if (selectPos != 0) + selectPos = content.text.LastIndexOf ('\n', selectPos - 1) + 1; + } + + // TODO: get the height from the font + + public void DrawCursor (string text) { + string realText = content.text; + int cursorPos = pos; + if (Input.compositionString.Length > 0) + { + content.text = text.Substring (0, pos) + Input.compositionString + text.Substring (selectPos); + cursorPos += Input.compositionString.Length; + } + else + content.text = text; + + graphicalCursorPos = style.GetCursorPixelPosition (new Rect (0,0,position.width,position.height), content, cursorPos); + + //Debug.Log("Cursor pos: " + graphicalCursorPos); + + Rect r = style.padding.Remove (position); + + Vector2 contentSize = new Vector2(style.CalcSize(content).x, style.CalcHeight(content, position.width)); + + // If there is plenty of room, simply show entire string + if (contentSize.x < position.width) + { + scrollOffset.x = 0; + } + else + { + //go right + if (graphicalCursorPos.x + 1 > scrollOffset.x + r.width) + // do we want html or apple behavior? this is html behavior + scrollOffset.x = graphicalCursorPos.x - r.width; + //go left + if (graphicalCursorPos.x < scrollOffset.x + style.padding.left) + scrollOffset.x = graphicalCursorPos.x - style.padding.left; + } + // ... and height/y as well + // If there is plenty of room, simply show entire string + // Debug.Log(contentSize.y + " < R : " + r); + if (contentSize.y < r.height) + { + scrollOffset.y = 0; + } + else + { + //go down + if (graphicalCursorPos.y + style.lineHeight > scrollOffset.y + r.height + style.padding.top) + scrollOffset.y = graphicalCursorPos.y - r.height - style.padding.top + style.lineHeight; + //go up + if (graphicalCursorPos.y < scrollOffset.y + style.padding.top ) + scrollOffset.y = graphicalCursorPos.y - style.padding.top; + } + + // This case takes many words to explain: + // 1. Text field has more text than it can fit vertically, and the cursor is at the very bottom (text field is scrolled down) + // 2. user e.g. deletes some lines of text at the bottom (backspace or select+delete) + // 3. now suddenly we have space at the bottom of text field, that is now not filled with any content + // 4. scroll text field up to fill in that space (this is what other text editors do) + if (scrollOffset.y > 0 && contentSize.y - scrollOffset.y < r.height) + scrollOffset.y = contentSize.y - r.height - style.padding.top - style.padding.bottom; + + scrollOffset.y = scrollOffset.y<0?0:scrollOffset.y; + + Vector2 originalContentOffset = style.contentOffset; + style.contentOffset -= scrollOffset; + style.Internal_clipOffset = scrollOffset; + + // Debug.Log ("ScrollOffset : " + scrollOffset); + + Input.compositionCursorPos = graphicalCursorPos + new Vector2(position.x, position.y + style.lineHeight) - scrollOffset; + + if(Input.compositionString.Length > 0) + style.DrawWithTextSelection (position, content, controlID, pos, pos + Input.compositionString.Length, true); + else + style.DrawWithTextSelection (position, content, controlID, pos, selectPos); + + if (m_iAltCursorPos != -1) + style.DrawCursor(position, content, controlID, m_iAltCursorPos); + + // reset + style.contentOffset = originalContentOffset; + style.Internal_clipOffset = Vector2.zero; + + content.text = realText; + } + + + bool PerformOperation (TextEditOp operation) { + + switch (operation) { +// NOTE the TODOs below: + case TextEditOp.MoveLeft: MoveLeft (); break; + case TextEditOp.MoveRight: MoveRight (); break; + case TextEditOp.MoveUp: MoveUp (); break; + case TextEditOp.MoveDown: MoveDown (); break; + case TextEditOp.MoveLineStart: MoveLineStart (); break; + case TextEditOp.MoveLineEnd: MoveLineEnd (); break; + case TextEditOp.MoveWordRight: MoveWordRight (); break; + case TextEditOp.MoveToStartOfNextWord: MoveToStartOfNextWord (); break; + case TextEditOp.MoveToEndOfPreviousWord: MoveToEndOfPreviousWord (); break; + case TextEditOp.MoveWordLeft: MoveWordLeft (); break; + case TextEditOp.MoveTextStart: MoveTextStart (); break; + case TextEditOp.MoveTextEnd: MoveTextEnd (); break; + case TextEditOp.MoveParagraphForward: MoveParagraphForward (); break; + case TextEditOp.MoveParagraphBackward: MoveParagraphBackward (); break; +// case TextEditOp.MovePageUp: return MovePageUp (); break; +// case TextEditOp.MovePageDown: return MovePageDown (); break; + case TextEditOp.MoveGraphicalLineStart: MoveGraphicalLineStart (); break; + case TextEditOp.MoveGraphicalLineEnd: MoveGraphicalLineEnd (); break; + case TextEditOp.SelectLeft: SelectLeft (); break; + case TextEditOp.SelectRight: SelectRight (); break; + case TextEditOp.SelectUp: SelectUp (); break; + case TextEditOp.SelectDown: SelectDown (); break; + case TextEditOp.SelectWordRight: SelectWordRight (); break; + case TextEditOp.SelectWordLeft: SelectWordLeft (); break; + case TextEditOp.SelectToEndOfPreviousWord: SelectToEndOfPreviousWord (); break; + case TextEditOp.SelectToStartOfNextWord: SelectToStartOfNextWord (); break; + + case TextEditOp.SelectTextStart: SelectTextStart (); break; + case TextEditOp.SelectTextEnd: SelectTextEnd (); break; + case TextEditOp.ExpandSelectGraphicalLineStart: ExpandSelectGraphicalLineStart (); break; + case TextEditOp.ExpandSelectGraphicalLineEnd: ExpandSelectGraphicalLineEnd (); break; + case TextEditOp.SelectParagraphForward: SelectParagraphForward (); break; + case TextEditOp.SelectParagraphBackward: SelectParagraphBackward (); break; + case TextEditOp.SelectGraphicalLineStart: SelectGraphicalLineStart (); break; + case TextEditOp.SelectGraphicalLineEnd: SelectGraphicalLineEnd (); break; +// case TextEditOp.SelectPageUp: return SelectPageUp (); break; +// case TextEditOp.SelectPageDown: return SelectPageDown (); break; + case TextEditOp.Delete: return Delete (); + case TextEditOp.Backspace: return Backspace (); + case TextEditOp.Cut: return Cut (); + case TextEditOp.Copy: Copy (); break; + case TextEditOp.Paste: return Paste (); + case TextEditOp.SelectAll: SelectAll (); break; + case TextEditOp.SelectNone: SelectNone (); break; +// case TextEditOp.ScrollStart: return ScrollStart (); break; +// case TextEditOp.ScrollEnd: return ScrollEnd (); break; +// case TextEditOp.ScrollPageUp: return ScrollPageUp (); break; +// case TextEditOp.ScrollPageDown: return ScrollPageDown (); break; + case TextEditOp.DeleteWordBack: return DeleteWordBack(); // break; // The uncoditional return makes the "break;" issue a warning about unreachable code + case TextEditOp.DeleteLineBack: return DeleteLineBack(); + case TextEditOp.DeleteWordForward: return DeleteWordForward(); // break; // The uncoditional return makes the "break;" issue a warning about unreachable code + default: + Debug.Log ("Unimplemented: " + operation); + break; + } + return false; + } + + enum TextEditOp { + MoveLeft, MoveRight, MoveUp, MoveDown, MoveLineStart, MoveLineEnd, MoveTextStart, MoveTextEnd, MovePageUp, MovePageDown, + MoveGraphicalLineStart, MoveGraphicalLineEnd, MoveWordLeft, MoveWordRight, + MoveParagraphForward, MoveParagraphBackward, MoveToStartOfNextWord, MoveToEndOfPreviousWord, + SelectLeft, SelectRight, SelectUp, SelectDown, SelectTextStart, SelectTextEnd, SelectPageUp, SelectPageDown, + ExpandSelectGraphicalLineStart, ExpandSelectGraphicalLineEnd, SelectGraphicalLineStart, SelectGraphicalLineEnd, + SelectWordLeft, SelectWordRight, SelectToEndOfPreviousWord, SelectToStartOfNextWord, + SelectParagraphBackward, SelectParagraphForward, + Delete, Backspace, DeleteWordBack, DeleteWordForward, DeleteLineBack, + Cut, Copy, Paste, SelectAll, SelectNone, + ScrollStart, ScrollEnd, ScrollPageUp, ScrollPageDown + }; + + string oldText; + int oldPos, oldSelectPos; + + public void SaveBackup () { + oldText = content.text; + oldPos = pos; + oldSelectPos = selectPos; + } + + public void Undo () { + content.text = oldText; + pos = oldPos; + selectPos = oldSelectPos; + } + + public bool Cut () { + //Debug.Log ("Cut"); + if (isPasswordField) + return false; + Copy (); + return DeleteSelection (); + } + + public void Copy () { + //Debug.Log ("Copy"); + if (selectPos == pos) + return; + + if (isPasswordField) + return; + + string copyStr; + if (pos < selectPos) + copyStr = content.text.Substring (pos, selectPos - pos); + else + copyStr = content.text.Substring (selectPos, pos - selectPos); + + GUIUtility.systemCopyBuffer = copyStr; + } + + public bool Paste () { + //Debug.Log ("Paste"); + string pasteval = GUIUtility.systemCopyBuffer; + if (pasteval != "") { + ReplaceSelection (pasteval); + return true; + } + return false; + } + + static void MapKey (string key, TextEditOp action) { + s_Keyactions [Event.KeyboardEvent (key)] = action; + } + static Dictionary<Event, TextEditOp> s_Keyactions; + /// Set up a platform independant keyboard->Edit action map. This varies depending on whether we are on mac or windows. + void InitKeyActions () { + if (s_Keyactions != null) + return; + s_Keyactions = new Dictionary<Event, TextEditOp> (); + + // key mappings shared by the platforms + MapKey ("left", TextEditOp.MoveLeft); + MapKey ("right", TextEditOp.MoveRight); + MapKey ("up", TextEditOp.MoveUp); + MapKey ("down", TextEditOp.MoveDown); + + MapKey ("#left", TextEditOp.SelectLeft); + MapKey ("#right", TextEditOp.SelectRight); + MapKey ("#up", TextEditOp.SelectUp); + MapKey ("#down", TextEditOp.SelectDown); + + MapKey ("delete", TextEditOp.Delete); + MapKey ("backspace", TextEditOp.Backspace); + MapKey ("#backspace", TextEditOp.Backspace); + + // OSX is the special case for input shortcuts + if (Application.platform == RuntimePlatform.OSXPlayer || + Application.platform == RuntimePlatform.OSXWebPlayer || + Application.platform == RuntimePlatform.OSXDashboardPlayer || + Application.platform == RuntimePlatform.OSXEditor) { + // Keyboard mappings for mac +// TODO MapKey ("home", TextEditOp.ScrollStart); +// TODO MapKey ("end", TextEditOp.ScrollEnd); +// TODO MapKey ("page up", TextEditOp.ScrollPageUp); +// TODO MapKey ("page down", TextEditOp.ScrollPageDown); + + MapKey ("^left", TextEditOp.MoveGraphicalLineStart); + MapKey ("^right", TextEditOp.MoveGraphicalLineEnd); +// TODO MapKey ("^up", TextEditOp.ScrollPageUp); +// TODO MapKey ("^down", TextEditOp.ScrollPageDown); + + MapKey ("&left", TextEditOp.MoveWordLeft); + MapKey ("&right", TextEditOp.MoveWordRight); + MapKey ("&up", TextEditOp.MoveParagraphBackward); + MapKey ("&down", TextEditOp.MoveParagraphForward); + + MapKey ("%left", TextEditOp.MoveGraphicalLineStart); + MapKey ("%right", TextEditOp.MoveGraphicalLineEnd); + MapKey ("%up", TextEditOp.MoveTextStart); + MapKey ("%down", TextEditOp.MoveTextEnd); + + MapKey ("#home", TextEditOp.SelectTextStart); + MapKey ("#end", TextEditOp.SelectTextEnd); +// TODO MapKey ("#page up", TextEditOp.SelectPageUp); +// TODO MapKey ("#page down", TextEditOp.SelectPageDown); + + MapKey ("#^left", TextEditOp.ExpandSelectGraphicalLineStart); + MapKey ("#^right", TextEditOp.ExpandSelectGraphicalLineEnd); + MapKey ("#^up", TextEditOp.SelectParagraphBackward); + MapKey ("#^down", TextEditOp.SelectParagraphForward); + + MapKey ("#&left", TextEditOp.SelectWordLeft); + MapKey ("#&right", TextEditOp.SelectWordRight); + MapKey ("#&up", TextEditOp.SelectParagraphBackward); + MapKey ("#&down", TextEditOp.SelectParagraphForward); + + MapKey ("#%left", TextEditOp.ExpandSelectGraphicalLineStart); + MapKey ("#%right", TextEditOp.ExpandSelectGraphicalLineEnd); + MapKey ("#%up", TextEditOp.SelectTextStart); + MapKey ("#%down", TextEditOp.SelectTextEnd); + + MapKey ("%a", TextEditOp.SelectAll); + MapKey ("%x", TextEditOp.Cut); + MapKey ("%c", TextEditOp.Copy); + MapKey ("%v", TextEditOp.Paste); + + // emacs-like keybindings + MapKey ("^d", TextEditOp.Delete); + MapKey ("^h", TextEditOp.Backspace); + MapKey ("^b", TextEditOp.MoveLeft); + MapKey ("^f", TextEditOp.MoveRight); + MapKey ("^a", TextEditOp.MoveLineStart); + MapKey ("^e", TextEditOp.MoveLineEnd); + // Can't be bothered to do these + // MapKey ("^o", TextEditOp.InsertNewlineRight); + // MapKey ("^t", TextEditOp.TransposeCharacters); + + MapKey("&delete", TextEditOp.DeleteWordForward); + MapKey("&backspace", TextEditOp.DeleteWordBack); + MapKey ("%backspace", TextEditOp.DeleteLineBack); + } else { + // Windows/Linux keymappings + MapKey("home", TextEditOp.MoveGraphicalLineStart); + MapKey ("end", TextEditOp.MoveGraphicalLineEnd); +// TODO MapKey ("page up", TextEditOp.MovePageUp); +// TODO MapKey ("page down", TextEditOp.MovePageDown); + + MapKey ("%left", TextEditOp.MoveWordLeft); + MapKey ("%right", TextEditOp.MoveWordRight); + MapKey ("%up", TextEditOp.MoveParagraphBackward); + MapKey ("%down", TextEditOp.MoveParagraphForward); + + MapKey ("^left", TextEditOp.MoveToEndOfPreviousWord); + MapKey ("^right", TextEditOp.MoveToStartOfNextWord); + MapKey ("^up", TextEditOp.MoveParagraphBackward); + MapKey ("^down", TextEditOp.MoveParagraphForward); + + MapKey ("#^left", TextEditOp.SelectToEndOfPreviousWord); + MapKey ("#^right", TextEditOp.SelectToStartOfNextWord); + MapKey ("#^up", TextEditOp.SelectParagraphBackward); + MapKey ("#^down", TextEditOp.SelectParagraphForward); + + MapKey ("#home", TextEditOp.SelectGraphicalLineStart); + MapKey ("#end", TextEditOp.SelectGraphicalLineEnd); +// TODO MapKey ("#page up", TextEditOp.SelectPageUp); +// TODO MapKey ("#page down", TextEditOp.SelectPageDown); + + MapKey("^delete", TextEditOp.DeleteWordForward); + MapKey("^backspace", TextEditOp.DeleteWordBack); + MapKey ("%backspace", TextEditOp.DeleteLineBack); + + MapKey ("^a", TextEditOp.SelectAll); + MapKey ("^x", TextEditOp.Cut); + MapKey ("^c", TextEditOp.Copy); + MapKey ("^v", TextEditOp.Paste); + MapKey("#delete", TextEditOp.Cut); + MapKey("^insert", TextEditOp.Copy); + MapKey("#insert", TextEditOp.Paste); + } + } + + // clamp cursor & selection to the string length + public void ClampPos () { + if (m_HasFocus == true && controlID != GUIUtility.keyboardControl) + OnLostFocus (); + if (m_HasFocus == false && controlID == GUIUtility.keyboardControl) + OnFocus (); + + if (pos < 0) pos = 0; + else if (pos > content.text.Length) pos = content.text.Length; + if (selectPos < 0) selectPos = 0; + else if (selectPos > content.text.Length) selectPos = content.text.Length; + if (m_iAltCursorPos > content.text.Length) m_iAltCursorPos = content.text.Length; + + } +} + +} // namespace diff --git a/Runtime/Export/TextureBindings.txt b/Runtime/Export/TextureBindings.txt new file mode 100644 index 0000000..cc79bb5 --- /dev/null +++ b/Runtime/Export/TextureBindings.txt @@ -0,0 +1,675 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" + +#include "Runtime/Mono/MonoExportUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/Backend/ScriptingTypeRegistry.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" +#include "Runtime/Misc/GraphicsScriptingUtility.h" + +#include "Runtime/GfxDevice/GfxDevice.h" +#include "Runtime/Graphics/Texture2D.h" +#include "Runtime/Graphics/CubemapTexture.h" +#include "Runtime/Graphics/Texture3D.h" +#include "Runtime/Graphics/RenderTexture.h" +#include "Runtime/Graphics/RenderBufferManager.h" +#include "Runtime/Graphics/ImageConversion.h" +#include "Runtime/Geometry/TextureAtlas.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Math/Rect.h" +#include "Runtime/Misc/BuildSettings.h" + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + + +NONSEALED_CLASS Texture : Object + CUSTOM_PROP static int masterTextureLimit { return Texture::GetMasterTextureLimit (); } { Texture::SetMasterTextureLimit (value); } + + CUSTOM_PROP static AnisotropicFiltering anisotropicFiltering { return Texture::GetAnisoLimit (); } { Texture::SetAnisoLimit (value); } + + CUSTOM static void SetGlobalAnisotropicFilteringLimits( int forcedMin, int globalMax ) + { + Texture::SetGlobalAnisoLimits(forcedMin, globalMax); + } + + CUSTOM private static int Internal_GetWidth (Texture mono) { return mono->GetDataWidth(); } + CUSTOM private static int Internal_GetHeight (Texture mono) { return mono->GetDataHeight(); } + + CSRAW virtual public int width { get { return Internal_GetWidth(this); } set { throw new Exception("not implemented"); } } + CSRAW virtual public int height { get { return Internal_GetHeight(this); } set { throw new Exception("not implemented"); } } + + AUTO_PROP FilterMode filterMode GetFilterMode SetFilterMode + AUTO_PROP int anisoLevel GetAnisoLevel SetAnisoLevel + AUTO_PROP TextureWrapMode wrapMode GetWrapMode SetWrapMode + AUTO_PROP float mipMapBias GetMipMapBias SetMipMapBias + + // Workaround for gcc/msvc where passing small mono structures by value does not work + CUSTOM private static void Internal_GetTexelSize (Texture tex, out Vector2 output) + { + Texture& texture = *tex; + output->x = texture.GetTexelSizeX(); + output->y = texture.GetTexelSizeY(); + } + + CSRAW public Vector2 texelSize { get { Vector2 r; Internal_GetTexelSize(this, out r); return r; } } + + CUSTOM IntPtr GetNativeTexturePtr () { + return self->GetNativeTexturePtr(); + } + + CUSTOM int GetNativeTextureID () { + return self->GetNativeTextureID(); + } + +END + + +CLASS Texture2D : Texture + C++RAW + #define CHECK_READABLE { if (!self->GetIsReadable()) Scripting::RaiseMonoException("Texture '%s' is not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings.", self->GetName()); } + + // Check if reading of texture is allowed by crossdomain security and throw if not + C++RAW + static void CheckReadAllowedAndThrow(Texture2D *tex) + { +#if ENABLE_MONO && ENABLE_SECURITY + if ( !tex->GetReadAllowed() ) + Scripting::RaiseSecurityException("No read access to the texture data: %s", tex->GetName()); +#endif + } + + C++RAW + static void CheckScreenReadAllowedAndThrow() + { + if ( !Texture2D::GetScreenReadAllowed() ) + Scripting::RaiseSecurityException("Reading from the screen is not allowed when you have used a downloaded texture without proper crossdomain.xml authorization"); + } + + AUTO_PROP int mipmapCount CountDataMipmaps + + CSRAW public Texture2D (int width, int height) + { + Internal_Create(this, width, height, TextureFormat.ARGB32, true, false, IntPtr.Zero); + } + + CSRAW public Texture2D (int width, int height, TextureFormat format, bool mipmap) + { + Internal_Create(this, width, height, format, mipmap, false, IntPtr.Zero); + } + + CSRAW public Texture2D (int width, int height, TextureFormat format, bool mipmap, bool linear) + { + Internal_Create(this, width, height, format, mipmap, linear, IntPtr.Zero); + } + + CUSTOM private static void Internal_Create ([Writable]Texture2D mono, int width, int height, TextureFormat format, bool mipmap, bool linear, IntPtr nativeTex) + { + if(!GetBuildSettings().hasAdvancedVersion && nativeTex != 0) + { + Scripting::RaiseMonoException("Creating texture from native texture is PRO only."); + return; + } + + Texture2D* texture = NEW_OBJECT_MAIN_THREAD (Texture2D); + texture->Reset(); + + if (texture->InitTexture(width, height, format, mipmap ? Texture2D::kMipmapMask : Texture2D::kNoMipmap, 1, (intptr_t)nativeTex)) + { + texture->SetStoredColorSpace (linear ? kTexColorSpaceLinear : kTexColorSpaceSRGB); + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), texture); + texture->AwakeFromLoad(kInstantiateOrCreateFromCodeAwakeFromLoad); + } + else + { + DestroySingleObject (texture); + Scripting::RaiseMonoException("Failed to create texture because of invalid parameters."); + } + } + + CONDITIONAL ENABLE_TEXTUREID_MAP + CSRAW internal Texture2D (int width, int height, TextureFormat format, bool mipmap, bool linear, IntPtr nativeTex) + { + Internal_Create(this, width, height, format, mipmap, linear, nativeTex); + } + + CONDITIONAL ENABLE_TEXTUREID_MAP + CSRAW static public Texture2D CreateExternalTexture(int width, int height, TextureFormat format, bool mipmap, bool linear, IntPtr nativeTex) + { + return new Texture2D(width, height, format, mipmap, linear, nativeTex); + } + + CONDITIONAL ENABLE_TEXTUREID_MAP + CUSTOM public void UpdateExternalTexture(IntPtr nativeTex) + { + if(!GetBuildSettings().hasAdvancedVersion) + { + Scripting::RaiseMonoException("Updating native texture is PRO only."); + return; + } + GetGfxDevice().UpdateExternalTextureFromNative(self->GetTextureID(), (intptr_t)nativeTex); + } + + AUTO_PROP TextureFormat format GetTextureFormat + + CUSTOM void SetPixel (int x, int y, Color color) + { + CHECK_READABLE + self->SetPixel (0, x, y, color); + } + CUSTOM Color GetPixel (int x, int y) { + CHECK_READABLE + CheckReadAllowedAndThrow(self); + return self->GetPixel (0, x, y); + } + CUSTOM Color GetPixelBilinear (float u, float v) { + CHECK_READABLE + CheckReadAllowedAndThrow(self); + return self->GetPixelBilinear (0, u, v); + } + CSRAW public void SetPixels(Color[] colors, int miplevel = 0) + { + int w = width >> miplevel; if( w < 1 ) w = 1; + int h = height >> miplevel; if( h < 1 ) h = 1; + SetPixels( 0, 0, w, h, colors, miplevel ); + } + CUSTOM void SetPixels(int x, int y, int blockWidth, int blockHeight, Color[] colors, int miplevel = 0) + { + CHECK_READABLE + self->SetPixels( x, y, blockWidth, blockHeight, GetScriptingArraySize(colors), Scripting::GetScriptingArrayStart<ColorRGBAf>(colors), miplevel ); + } + CUSTOM void SetPixels32(Color32[] colors, int miplevel = 0) + { + CHECK_READABLE + self->SetPixels32( miplevel, Scripting::GetScriptingArrayStart<ColorRGBA32>(colors), GetScriptingArraySize(colors) ); + } + + CUSTOM bool LoadImage (byte[] data) + { + return LoadMemoryBufferIntoTexture(*self, Scripting::GetScriptingArrayStart<UInt8>(data), GetScriptingArraySize(data), IsCompressedDXTTextureFormat(self->GetTextureFormat())?kLoadImageDXTCompressDithered:kLoadImageUncompressed); + } + + CUSTOM void LoadRawTextureData(byte[] data) + { + CHECK_READABLE + if(GetScriptingArraySize(data) < self->GetRawImageDataSize()) + { + Scripting::RaiseMonoException("LoadRawTextureData: not enough data provided (will result in overread)."); + return; + } + ::memcpy(self->GetRawImageData(), Scripting::GetScriptingArrayStart<UInt8>(data), self->GetRawImageDataSize()); + } + + CSRAW public Color[] GetPixels(int miplevel = 0) + { + int w = width >> miplevel; if( w < 1 ) w = 1; + int h = height >> miplevel; if( h < 1 ) h = 1; + return GetPixels( 0, 0, w, h, miplevel ); + } + CUSTOM Color[] GetPixels(int x, int y, int blockWidth, int blockHeight, int miplevel = 0) + { + CHECK_READABLE + CheckReadAllowedAndThrow(self); + + int res = blockWidth * blockHeight; + if (blockWidth != 0 && blockHeight != res / blockWidth) { + return SCRIPTING_NULL; + } + + + ScriptingArrayPtr colors = CreateScriptingArray<ColorRGBAf>(GetScriptingManager().GetCommonClasses().color, blockWidth * blockHeight); + ColorRGBAf* firstElement = Scripting::GetScriptingArrayStart<ColorRGBAf>(colors); + self->GetPixels( x, y, blockWidth, blockHeight, miplevel, firstElement); + return colors; + } + + CUSTOM public Color32[] GetPixels32(int miplevel = 0) + { + CHECK_READABLE + CheckReadAllowedAndThrow(self); + int w = self->GetDataWidth() >> miplevel; if( w < 1 ) w = 1; + int h = self->GetDataHeight() >> miplevel; if( h < 1 ) h = 1; + + + ScriptingArrayPtr colors = CreateScriptingArray<ColorRGBA32>(GetScriptingManager().GetCommonClasses().color32, w * h); + ColorRGBA32* firstElement = Scripting::GetScriptingArrayStart<ColorRGBA32>(colors); + self->GetPixels32( miplevel, firstElement); + return colors; + } + + CUSTOM void Apply (bool updateMipmaps=true, bool makeNoLongerReadable=false) + { + CHECK_READABLE + self->Apply(updateMipmaps, makeNoLongerReadable); + } + + CUSTOM public bool Resize (int width, int height, TextureFormat format, bool hasMipMap) + { + return self->ResizeWithFormat (width, height, format, hasMipMap ? Texture2D::kMipmapMask : Texture2D::kNoMipmap); + } + + CSRAW public bool Resize (int width, int height) { return Internal_ResizeWH(width, height); } + CUSTOM private bool Internal_ResizeWH (int width, int height) { + CHECK_READABLE + return self->Resize(width, height); + } + + AUTO void Compress (bool highQuality); + + CUSTOM Rect[] PackTextures( Texture2D[] textures, int padding, int maximumAtlasSize = 2048, bool makeNoLongerReadable = false ) + { + int textureCount = GetScriptingArraySize(textures); + Texture2D** texturePtrs = new Texture2D*[textureCount]; + for( int i = 0; i < textureCount; ++i ) + { + Texture2D* tex = ScriptingObjectToObject<Texture2D>(Scripting::GetScriptingArrayElementNoRef<ScriptingObjectPtr>(textures,i)); + if (tex && !tex->GetIsReadable()) + { + ErrorString("Texture atlas needs textures to have Readable flag set!"); + tex = NULL; + } + texturePtrs[i] = tex; + } + + ScriptingArrayPtr rects = CreateScriptingArray<Rectf>(GetScriptingManager().GetCommonClasses().rect, textureCount); + Rectf* firstElement = Scripting::GetScriptingArrayStart<Rectf>(rects); + + if( !PackTextureAtlasSimple( &*self, maximumAtlasSize, textureCount, texturePtrs, firstElement, padding, true, makeNoLongerReadable ) ) + { + delete[] texturePtrs; // TODO: error + return SCRIPTING_NULL; + } + + delete[] texturePtrs; + return rects; + } + + CUSTOM void ReadPixels (Rect source, int destX, int destY, bool recalculateMipMaps = true) { + #if !UNITY_FLASH + CHECK_READABLE + CheckScreenReadAllowedAndThrow(); + bool flipVertical = GetGfxDevice().GetInvertProjectionMatrix(); + self->ReadPixels (0, (int)source.x, (int)source.y, (int)source.Width(), (int)source.Height(), destX, destY, flipVertical, recalculateMipMaps); + #elif UNITY_FLASH + printf_console("ReadPixels is unsupported on Flash"); + #endif + } + + CUSTOM byte[] EncodeToPNG () + { + #if ENABLE_PNG_JPG + CHECK_READABLE + CheckReadAllowedAndThrow(self); + + Texture2D* tex = self; + if( !tex ) + { + ErrorString( "EncodeToPNG failed: texture is null" ); + return SCRIPTING_NULL; + } + dynamic_array<UInt8> buffer; + if( !tex->EncodeToPNG( buffer ) ) + { + return SCRIPTING_NULL; + } + return CreateScriptingArray<UInt8>( &buffer[0], buffer.size(), GetScriptingManager().GetCommonClasses().byte ); + #else + return SCRIPTING_NULL; + #endif + } + + CONDITIONAL UNITY_EDITOR + AUTO_PROP bool alphaIsTransparency GetAlphaIsTransparency SetAlphaIsTransparency + +END + + + +CLASS Cubemap : Texture + CUSTOM void SetPixel (CubemapFace face, int x, int y, Color color) { + CHECK_READABLE + self->SetPixel (face, x, y, color); + } + CUSTOM Color GetPixel (CubemapFace face, int x, int y) { + CHECK_READABLE + return self->GetPixel (face, x, y); + } + CUSTOM Color[] GetPixels(CubemapFace face, int miplevel = 0) + { + CHECK_READABLE + int size = std::max(self->GetDataWidth() >> miplevel, 1); + + ScriptingArrayPtr colors = CreateScriptingArray<ColorRGBAf>(GetScriptingManager().GetCommonClasses().color, size*size); + ColorRGBAf* firstElement = Scripting::GetScriptingArrayStart<ColorRGBAf>(colors); + self->GetPixels( 0, 0, size, size, miplevel, firstElement, (int)face ); + return colors; + } + CUSTOM void SetPixels(Color[] colors, CubemapFace face, int miplevel = 0) + { + CHECK_READABLE + int size = std::max(self->GetDataWidth() >> miplevel, 1); + self->SetPixels( 0, 0, size, size, GetScriptingArraySize(colors), Scripting::GetScriptingArrayStart<ColorRGBAf>(colors), miplevel, (int)face ); + } + + CUSTOM void Apply (bool updateMipmaps = true, bool makeNoLongerReadable=false) + { + #if !UNITY_EDITOR + CHECK_READABLE + #endif + + if(makeNoLongerReadable) + { + self->SetIsReadable(false); + self->SetIsUnreloadable(true); + } + + if (updateMipmaps) + self->UpdateImageData(); + else + self->UpdateImageDataDontTouchMipmap(); + } + + AUTO_PROP TextureFormat format GetTextureFormat + + CSRAW public Cubemap (int size, TextureFormat format, bool mipmap) + { + Internal_Create(this, size, format, mipmap); + } + + CUSTOM private static void Internal_Create ([Writable]Cubemap mono, int size, TextureFormat format, bool mipmap) + { + Cubemap* texture = NEW_OBJECT_MAIN_THREAD (Cubemap); + texture->Reset(); + + if (texture->InitTexture(size, size, format, mipmap ? Texture2D::kMipmapMask : Texture2D::kNoMipmap, 6)) + { + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), texture); + texture->AwakeFromLoad(kInstantiateOrCreateFromCodeAwakeFromLoad); + } + else + { + Scripting::RaiseMonoException("Failed to create texture because of invalid parameters."); + } + } + + CUSTOM void SmoothEdges (int smoothRegionWidthInPixels = 1) + { + self->FixupEdges (smoothRegionWidthInPixels); + } + +END + + +CLASS Texture3D : Texture + + AUTO_PROP int depth GetDepth + + CUSTOM Color[] GetPixels(int miplevel = 0) + { + int w = std::max(self->GetDataWidth() >> miplevel, 1); + int h = std::max(self->GetDataHeight() >> miplevel, 1); + int d = std::max(self->GetDepth() >> miplevel, 1); + + ScriptingArrayPtr colors = CreateScriptingArray<ColorRGBAf>(GetScriptingManager().GetCommonClasses().color, w*h*d); + ColorRGBAf* firstElement = Scripting::GetScriptingArrayStart<ColorRGBAf>(colors); + self->GetPixels (firstElement, miplevel); + return colors; + } + + CUSTOM void SetPixels(Color[] colors, int miplevel = 0) + { + int arrSize = GetScriptingArraySize(colors); + const ColorRGBAf* ptr = Scripting::GetScriptingArrayStart<ColorRGBAf>(colors); + self->SetPixels (arrSize, ptr, miplevel); + } + + CUSTOM void Apply (bool updateMipmaps = true) + { + self->UpdateImageData (updateMipmaps); + } + + AUTO_PROP TextureFormat format GetTextureFormat + + CSRAW public Texture3D (int width, int height, int depth, TextureFormat format, bool mipmap) + { + Internal_Create(this, width, height, depth, format, mipmap); + } + + CUSTOM private static void Internal_Create ([Writable]Texture3D mono, int width, int height, int depth, TextureFormat format, bool mipmap) + { + Texture3D* texture = NEW_OBJECT_MAIN_THREAD (Texture3D); + texture->Reset(); + + if (texture->InitTexture(width, height, depth, format, mipmap)) + { + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), texture); + texture->AwakeFromLoad(kInstantiateOrCreateFromCodeAwakeFromLoad); + } + else + { + Scripting::RaiseMonoException("Failed to create texture because of invalid parameters."); + } + } +END + + +CLASS RenderTexture : Texture + CUSTOM private static void Internal_CreateRenderTexture ([Writable]RenderTexture rt) + { + RenderTexture* texture = NEW_OBJECT_MAIN_THREAD (RenderTexture); + texture->SetCreatedFromScript(true); + texture->Reset(); + Scripting::ConnectScriptingWrapperToObject (rt.GetScriptingObject(), texture); + texture->AwakeFromLoad(kInstantiateOrCreateFromCodeAwakeFromLoad); + } + + CSRAW public RenderTexture (int width, int height, int depth, RenderTextureFormat format, RenderTextureReadWrite readWrite) + { + Internal_CreateRenderTexture (this); + this.width = width; + this.height = height; + this.depth = depth; + this.format = format; + + bool sRGB = readWrite == RenderTextureReadWrite.sRGB; + if (readWrite == RenderTextureReadWrite.Default) + { + sRGB = QualitySettings.activeColorSpace == ColorSpace.Linear; + } + Internal_SetSRGBReadWrite (this, sRGB); + + this.isPowerOfTwo = Mathf.IsPowerOfTwo(width) && Mathf.IsPowerOfTwo(height); + } + + CSRAW public RenderTexture (int width, int height, int depth, RenderTextureFormat format) + { + Internal_CreateRenderTexture (this); + this.width = width; + this.height = height; + this.depth = depth; + this.format = format; + Internal_SetSRGBReadWrite (this, QualitySettings.activeColorSpace == ColorSpace.Linear); + this.isPowerOfTwo = Mathf.IsPowerOfTwo(width) && Mathf.IsPowerOfTwo(height); + } + + CSRAW public RenderTexture (int width, int height, int depth) + { + Internal_CreateRenderTexture (this); + this.width = width; + this.height = height; + this.depth = depth; + this.format = RenderTextureFormat.Default; + Internal_SetSRGBReadWrite (this, QualitySettings.activeColorSpace == ColorSpace.Linear); + this.isPowerOfTwo = Mathf.IsPowerOfTwo(width) && Mathf.IsPowerOfTwo(height); + } + + CUSTOM static RenderTexture GetTemporary (int width, int height, int depthBuffer = 0, RenderTextureFormat format = RenderTextureFormat.Default, RenderTextureReadWrite readWrite = RenderTextureReadWrite.Default, int antiAliasing = 1) { + DepthBufferFormat depthFormat = DepthBufferFormatFromBits(depthBuffer); + UInt32 flags = RenderBufferManager::kRBCreatedFromScript; + return Scripting::ScriptingWrapperFor (GetRenderBufferManager().GetTempBuffer (width, height, depthFormat, static_cast<RenderTextureFormat>(format), flags, readWrite, antiAliasing)); + } + + CUSTOM static void ReleaseTemporary (RenderTexture temp) { + GetRenderBufferManager().ReleaseTempBuffer (temp); + } + + CUSTOM private static int Internal_GetWidth (RenderTexture mono) { return mono->GetWidth(); } + CUSTOM private static void Internal_SetWidth (RenderTexture mono, int width) { mono->SetWidth(width); } + CUSTOM private static int Internal_GetHeight (RenderTexture mono) { return mono->GetHeight(); } + CUSTOM private static void Internal_SetHeight (RenderTexture mono, int width) { mono->SetHeight(width); } + + CUSTOM private static void Internal_SetSRGBReadWrite (RenderTexture mono, bool sRGB) { mono->SetSRGBReadWrite(sRGB); } + + CSRAW + override public int width { get { return Internal_GetWidth(this); } set { Internal_SetWidth(this,value); } } + + CSRAW + override public int height { get { return Internal_GetHeight(this); } set { Internal_SetHeight(this,value); } } + + CUSTOM_PROP int depth + { + DepthBufferFormat depthFormat = self->GetDepthFormat(); + static int kDepthFormatBits[kDepthFormatCount] = { 0, 16, 24 }; + return kDepthFormatBits[depthFormat]; + } + { + DepthBufferFormat depthFormat = DepthBufferFormatFromBits(value); + self->SetDepthFormat( depthFormat ); + } + + CUSTOM_PROP bool isPowerOfTwo { return self->GetIsPowerOfTwo(); } { } + + CUSTOM_PROP bool sRGB { return self->GetSRGBReadWrite(); } + + CUSTOM_PROP RenderTextureFormat format { return self->GetColorFormat(); } { self->SetColorFormat( static_cast<RenderTextureFormat>(value) ); } + + AUTO_PROP bool useMipMap GetMipMap SetMipMap + + AUTO_PROP bool generateMips GetGenerateMips SetGenerateMips + + CUSTOM_PROP bool isCubemap + { + return self->GetDimension()==kTexDimCUBE; + } + { + self->SetDimension (value ? kTexDimCUBE : kTexDim2D); + } + + CUSTOM_PROP bool isVolume + { + return self->GetDimension()==kTexDim3D; + } + { + self->SetDimension (value ? kTexDim3D : kTexDim2D); + } + + CUSTOM_PROP int volumeDepth { return self->GetVolumeDepth(); } { self->SetVolumeDepth(value); } + + AUTO_PROP int antiAliasing GetAntiAliasing SetAntiAliasing + + AUTO_PROP bool enableRandomWrite GetEnableRandomWrite SetEnableRandomWrite + + + AUTO bool Create (); + AUTO void Release (); + AUTO bool IsCreated (); + + AUTO void DiscardContents(); + CUSTOM void DiscardContents(bool discardColor, bool discardDepth) + { + self->DiscardContents(discardColor, discardDepth); + } + + AUTO void MarkRestoreExpected(); + + CSRAW public RenderBuffer colorBuffer { get { RenderBuffer res; GetColorBuffer (out res); return res; } } + + CSRAW public RenderBuffer depthBuffer { get { RenderBuffer res; GetDepthBuffer (out res); return res; } } + + CUSTOM private void GetColorBuffer (out RenderBuffer res) { + RenderTexture* rt = self; + if (rt) + { + res->m_RenderTextureInstanceID = rt->GetInstanceID(); + if (!rt->IsCreated()) + rt->Create(); + res->m_BufferPtr = rt->GetColorSurfaceHandle().object; + } + else + { + res->m_RenderTextureInstanceID = 0; + res->m_BufferPtr = NULL; + } + } + + CUSTOM private void GetDepthBuffer (out RenderBuffer res) { + RenderTexture* rt = self; + if (rt) + { + res->m_RenderTextureInstanceID = rt->GetInstanceID(); + if (!rt->IsCreated()) + rt->Create(); + res->m_BufferPtr = rt->GetDepthSurfaceHandle().object; + } + else + { + res->m_RenderTextureInstanceID = 0; + res->m_BufferPtr = NULL; + } + } + + + CUSTOM void SetGlobalShaderProperty (string propertyName) { self->SetGlobalProperty (ScriptingStringToProperty (propertyName)); } + + CUSTOM_PROP static RenderTexture active { return Scripting::ScriptingWrapperFor (RenderTexture::GetActive ()); } { RenderTexture::SetActive (value); RenderTexture::FindAndSetSRGBWrite (value); } + + OBSOLETE warning Use SystemInfo.supportsRenderTextures instead. + CUSTOM_PROP static bool enabled { return RenderTexture::IsEnabled (); } { RenderTexture::SetEnabled (value); } + + CUSTOM private static void Internal_GetTexelOffset (RenderTexture tex, out Vector2 output) + { + if( GetGfxDevice().UsesHalfTexelOffset() ) + { + RenderTexture& renderTex = *tex; + output->x = renderTex.GetTexelSizeX() * 0.5f; + output->y = renderTex.GetTexelSizeY() * 0.5f; + } + else + { + output->x = 0.0f; + output->y = 0.0f; + } + } + + CSRAW public Vector2 GetTexelOffset () + { + Vector2 r; + Internal_GetTexelOffset(this, out r); + return r; + } + + CUSTOM public static bool SupportsStencil(RenderTexture rt) + { + return RenderTextureSupportsStencil(rt); + } + + OBSOLETE error RenderTexture.SetBorderColor was removed + CSRAW public void SetBorderColor (Color color) { } + +END + + + +CSRAW +} diff --git a/Runtime/Export/TrackedReference.cs b/Runtime/Export/TrackedReference.cs new file mode 100644 index 0000000..dcc3f80 --- /dev/null +++ b/Runtime/Export/TrackedReference.cs @@ -0,0 +1,39 @@ +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; +namespace UnityEngine +{ + +[StructLayout (LayoutKind.Sequential)] +//This class should be internal. Next time we can break backwardscompatibility we should do it. +public class TrackedReference +{ + [NotRenamed] + internal IntPtr m_Ptr; + + protected TrackedReference () { } + + public static bool operator == (TrackedReference x, TrackedReference y) + { + object xo = x; + object yo = y; + + if (yo == null && xo == null) return true; + if (yo == null) return x.m_Ptr == IntPtr.Zero; + if (xo == null) return y.m_Ptr == IntPtr.Zero; + return x.m_Ptr == y.m_Ptr; + } + public static bool operator != (TrackedReference x, TrackedReference y) { return !(x == y); } + + public override bool Equals(object o) { return (o as TrackedReference) == this; } + public override int GetHashCode() { return (int)m_Ptr; } + + public static implicit operator bool (TrackedReference exists) + { + return exists != null; + } +} + +} diff --git a/Runtime/Export/UnityEngineApplication.txt b/Runtime/Export/UnityEngineApplication.txt new file mode 100644 index 0000000..e79f7e6 --- /dev/null +++ b/Runtime/Export/UnityEngineApplication.txt @@ -0,0 +1,657 @@ +C++RAW + +#include "UnityPrefix.h" + +#include <ctime> + +#include "Configuration/UnityConfigure.h" +#include "Configuration/UnityConfigureVersion.h" + +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Utilities/PathNameUtility.h" +#include "Runtime/Input/InputManager.h" +#include "Runtime/Input/TimeManager.h" +#include "Runtime/Misc/ResourceManager.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/BaseClasses/Tags.h" +#include "Runtime/Misc/DebugUtility.h" +#include "Runtime/Misc/PlayerSettings.h" +#include "Runtime/GameCode/CloneObject.h" +#include "Runtime/Math/Random/Random.h" +#include "Runtime/Misc/PreloadManager.h" +#include "Runtime/Animation/Animation.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Utilities/PlayerPrefs.h" +#include "Runtime/Camera/Camera.h" +#include "Runtime/Dynamics/RigidBody.h" +#include "Runtime/Utilities/Word.h" +#include "Runtime/Camera/Light.h" +#include "Runtime/Filters/Misc/TextMesh.h" +#include "Runtime/Dynamics/ConstantForce.h" +#include "Runtime/Filters/Renderer.h" +#include "Runtime/Misc/SaveAndLoadHelper.h" +#include "Runtime/Network/NetworkView.h" +#include "Runtime/Camera/RenderLayers/GUIText.h" +#include "Runtime/Camera/RenderLayers/GUITexture.h" +#include "Runtime/Dynamics/Collider.h" +#include "Runtime/Dynamics/HingeJoint.h" +#include "Runtime/Filters/Particles/ParticleEmitter.h" +#include "Runtime/Misc/AssetBundleUtility.h" +#include "Runtime/Misc/Player.h" +#include "Runtime/BaseClasses/IsPlaying.h" +#include "Runtime/Misc/CaptureScreenshot.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Misc/Plugins.h" +#include "Runtime/Utilities/PathNameUtility.h" +#include "Runtime/Utilities/File.h" +#include "Runtime/Network/NetworkManager.h" +#include "Runtime/Input/GetInput.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Animation/AnimationManager.h" +#include "Runtime/Animation/AnimationClip.h" +#include "Runtime/BaseClasses/RefCounted.h" +#include "Runtime/Misc/GOCreation.h" +#include "Runtime/Utilities/URLUtility.h" +#include "Runtime/Graphics/ScreenManager.h" +#include "Runtime/Serialize/PersistentManager.h" +#include "Runtime/Shaders/GraphicsCaps.h" +#include "Runtime/Misc/SystemInfo.h" +#include "Runtime/Utilities/FileUtilities.h" +#include "Runtime/Misc/GraphicsDevicesDB.h" +#include "Runtime/File/ApplicationSpecificPersistentDataPath.h" +#include "Runtime/Mono/Coroutine.h" +#include "Runtime/Utilities/UserAuthorizationManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +#if WEBPLUG +# include "PlatformDependent/CommonWebPlugin/UnityWebStream.h" +# include "PlatformDependent/CommonWebPlugin/WebScripting.h" +#endif + +#if UNITY_EDITOR +# include "Editor/Src/EditorSettings.h" +# include "Editor/Src/EditorUserBuildSettings.h" +# include "Editor/Mono/MonoEditorUtility.h" +#endif + +#if UNITY_WII +# include "PlatformDependent/Wii/WiiUtility.h" +#endif + +#if UNITY_ANDROID +# include "PlatformDependent/AndroidPlayer/EntryPoint.h" +#endif + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// Describes network reachability options. +ENUM NetworkReachability + // Network is not reachable + NotReachable = 0, + // Network is reachable via carrier data network + ReachableViaCarrierDataNetwork = 1, + // Network is reachable via WiFi or cable + ReachableViaLocalAreaNetwork = 2 +END + + +// Access to application run-time data. + +CLASS Application + C++RAW + + + // Quits the player application. Quit is ignored in the editor or the web player. + CUSTOM static void Quit () + { + GetInputManager ().QuitApplication (); + } + + // Cancels quitting the application. This is useful for showing a splash screen at the end of a game. + CUSTOM static void CancelQuit () + { + GetInputManager ().CancelQuitApplication (); + } + + // The level index that was last loaded (RO). + CUSTOM_PROP static int loadedLevel { return PlayerGetLoadedLevel (); } + + // The name of the level that was last loaded (RO). + CUSTOM_PROP static string loadedLevelName { return scripting_string_new(PlayerGetLoadedLevelName()); } + + + ///*listonly* + CSRAW static public void LoadLevel (int index) { LoadLevelAsync(null, index, false, true); } + + // Loads the level by its name or index. + CSRAW static public void LoadLevel (string name) { LoadLevelAsync(name, -1, false, true); } + + + ///*listonly* + CSRAW static public AsyncOperation LoadLevelAsync (int index) { return LoadLevelAsync(null, index, false, false); } + + // Loads the level asynchronously in the background. + CSRAW static public AsyncOperation LoadLevelAsync (string levelName) + { + return LoadLevelAsync(levelName, -1, false, false); + } + + + ///*listonly* + CSRAW static public AsyncOperation LoadLevelAdditiveAsync (int index) { return LoadLevelAsync(null, index, true, false); } + + // Loads the level additively and asynchronously in the background. + CSRAW static public AsyncOperation LoadLevelAdditiveAsync (string levelName) + { + return LoadLevelAsync(levelName, -1, true, false); + } + + CUSTOM static private AsyncOperation LoadLevelAsync (string monoLevelName, int index, bool additive, bool mustCompleteNextFrame) + { + string levelName = monoLevelName; + string levelPath; + string assetPath; + + if (!GetLevelAndAssetPath (levelName, index, &levelPath, &assetPath, &index)) + return SCRIPTING_NULL; + + PreloadLevelOperation::LoadingMode mode = additive ? PreloadLevelOperation::kLoadAdditiveLevel : PreloadLevelOperation::kLoadLevel; + AsyncOperation* result = PreloadLevelOperation::LoadLevel(levelPath, assetPath, index, mode, mustCompleteNextFrame); + #if UNITY_FLASH + + result->Release(); + + // ToDo: if we're returning AsyncOperation, it throws: + // ReferenceError: Error #1069: Property http://unity3d.com/cil2as::DefaultValue not found on class UnityEngine.AsyncOperation and there is no default value. + // at UnityEngine.Marshalling::Marshaller$/GetUninitializedObject() + // at com.unity::UnityNative$/Ext_Scripting_InstantiateObject() + // ... + return SCRIPTING_NULL; + #else + ScriptingObjectPtr o = scripting_object_new(MONO_COMMON.asyncOperation); + ScriptingObjectWithIntPtrField<AsyncOperation>(o).SetPtr(result); + return o; + #endif + } + + ///*listonly* + CSRAW static public void LoadLevelAdditive (int index) { LoadLevelAsync (null, index, true, true); } + // Loads a level additively. + CSRAW static public void LoadLevelAdditive (string name) { LoadLevelAsync (name, -1, true, true); } + + // Is some level being loaded? (RO) + CUSTOM_PROP static bool isLoadingLevel { return IsLoadingLevel(); } + + // The total number of levels available (RO). + CUSTOM_PROP static int levelCount { return PlayerGetLevelCount (); } + + CUSTOM private static float GetStreamProgressForLevelByName (string levelName) { + #if WEBPLUG + return GetUnityWebStream().GetProgressForLevel(GetBuildSettings().GetLevelIndexChecked (levelName)); + #else + return 1.0F; + #endif + } + + // How far has the download progressed? [0...1] + CUSTOM public static float GetStreamProgressForLevel (int levelIndex) { + #if WEBPLUG + return GetUnityWebStream().GetProgressForLevel(levelIndex); + #else + if (levelIndex >= 0 && levelIndex < GetBuildSettings().levels.size()) + return 1.0F; + else + return 0.0F; + #endif + } + + // How far has the download progressed? [0...1] + CSRAW public static float GetStreamProgressForLevel (string levelName) { return GetStreamProgressForLevelByName(levelName); } + + // How many bytes have we downloaded from the main unity web stream (RO). + CUSTOM_PROP static int streamedBytes + { + #if WEBPLUG + return GetUnityWebStream().GetDownloadedBytes(); + #else + return 0; + #endif + } + + CUSTOM private static bool CanStreamedLevelBeLoadedByName (string levelName) { + string cppName = levelName; + #if WEBPLUG + return GetUnityWebStream().CanLevelBeLoaded(GetBuildSettings().GetLevelIndex (cppName)) || GetHasLateBoundLevelFromAssetBundle(cppName); + #else + return GetBuildSettings().GetLevelIndex (cppName) != -1 || GetHasLateBoundLevelFromAssetBundle(cppName); + #endif + } + + // Can the streamed level be loaded? + CUSTOM public static bool CanStreamedLevelBeLoaded (int levelIndex) { + #if WEBPLUG + return GetUnityWebStream().CanLevelBeLoaded(levelIndex); + #else + return levelIndex >= 0 && levelIndex < GetBuildSettings().levels.size(); + #endif + } + + // Can the streamed level be loaded? + CSRAW public static bool CanStreamedLevelBeLoaded (string levelName) { return CanStreamedLevelBeLoadedByName(levelName); } + + // Returns true when in any kind of player (RO). + CUSTOM_PROP static bool isPlaying { return IsWorldPlaying (); } + + // Are we running inside the Unity editor? (RO) + CUSTOM_PROP static bool isEditor + { + #if UNITY_EDITOR + return true; + #else + return false; + #endif + } + + // Are we running inside a web player? (RO) + CUSTOM_PROP static bool isWebPlayer + { + int platform = systeminfo::GetRuntimePlatform(); + return platform == WindowsWebPlayer || platform == OSXWebPlayer; + } + + // Returns the platform the game is running (RO). + THREAD_SAFE + CUSTOM_PROP static RuntimePlatform platform { return systeminfo::GetRuntimePlatform(); } + + + // Captures a screenshot at path /filename/ as a PNG file. + CUSTOM static void CaptureScreenshot (string filename, int superSize = 0) + { + #if CAPTURE_SCREENSHOT_AVAILABLE + QueueScreenshot (filename, superSize); + #endif + } + + // Should the player be running when the application is in the background? + CUSTOM_PROP static bool runInBackground { return GetPlayerRunInBackground(); } { SetPlayerRunInBackground(value); } + + OBSOLETE warning use Application.isEditor instead + CSRAW public static bool isPlayer { get { return !isEditor; } } + + /// Is Unity activated with the Pro License? + CUSTOM static bool HasProLicense() + { + return GetBuildSettings().hasPROVersion; + } + + CUSTOM static internal bool HasAdvancedLicense() + { + return GetBuildSettings().hasAdvancedVersion; + } + + OBSOLETE warning Use Object.DontDestroyOnLoad instead + CUSTOM static void DontDestroyOnLoad (Object mono) + { + Object* o = mono; + if (o) + DontDestroyOnLoad (*o); + } + + // Contains the path to the game data folder (RO). + CUSTOM_PROP static string dataPath { return scripting_string_new( GetAppDataPath() ); } + + // Contains the path to the StreamingAssets folder (RO). + CUSTOM_PROP static string streamingAssetsPath { return scripting_string_new( GetStreamingAssetsPath() ); } + + // Contains the path to a persistent data directory (RO). + CSRAW #if !UNITY_WP8 && !UNITY_METRO + CSRAW [System.Security.SecurityCritical] + CSRAW #endif + CUSTOM_PROP static string persistentDataPath { return scripting_string_new( GetPersistentDataPathApplicationSpecific() ); } + + // Contains the path to a temporary data / cache directory (RO). + CUSTOM_PROP static string temporaryCachePath { return scripting_string_new( GetTemporaryCachePathApplicationSpecific() ); } + + // The path to the web player data file relative to the html file (RO). + CUSTOM_PROP static string srcValue { return scripting_string_new(GetPlayerSettings().srcValue); } + + // The absolute path to the web player data file (RO). + CUSTOM_PROP static string absoluteURL { return scripting_string_new(GetPlayerSettings().absoluteURL); } + + OBSOLETE warning Please use absoluteURL instead + CSRAW public static string absoluteUrl { get { return absoluteURL; } } + + // Converts an object to a JavaScript text representation. + CONDITIONAL ENABLE_MONO + CSRAW private static string ObjectToJSString( object o ) + { + if( o == null ) { + return "null"; + } else if( o is string ) { + string s = o.ToString().Replace( "\\", "\\\\" ); // escape \ into \\, JS vulnerability. + s = s.Replace( "\"", "\\\"" ); + s = s.Replace( "\n", "\\n" ); + s = s.Replace( "\r", "\\r" ); + s = s.Replace( "\u0000", ""); // String-terminator. JS vulnerability. + s = s.Replace( "\u2028", ""); // Line-terminator via ecma-262-7.3 JS vulnerability. + s = s.Replace( "\u2029", ""); // Same as above + return '"' + s + '"'; + } else if( o is Int32 || o is Int16 || o is UInt32 || o is UInt16 || o is Byte ) { + return o.ToString(); + } else if( o is Single ) { + System.Globalization.NumberFormatInfo nf = System.Globalization.CultureInfo.InvariantCulture.NumberFormat; + return ((Single)o).ToString( nf ); + } else if( o is Double ) { + System.Globalization.NumberFormatInfo nf = System.Globalization.CultureInfo.InvariantCulture.NumberFormat; + return ((Double)o).ToString( nf ); + } else if( o is Char ) { + if( (Char)o == '"' ) + return "\"\\\"\""; // escape the '"' character + else + return '"' + o.ToString() + '"'; + } else if( o is System.Collections.IList ) { + // Any IList object is dumped as JS Array + System.Collections.IList list = (System.Collections.IList)o; + + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + sb.Append( "new Array(" ); + int size = list.Count; + for( int i = 0; i < size; ++i ) { + if( i != 0 ) + sb.Append( ", " ); + sb.Append( ObjectToJSString(list[i]) ); + } + sb.Append( ")" ); + return sb.ToString(); + } else { + // Unrecognized objects are dumped as strings + return ObjectToJSString(o.ToString()); + } + } + + // Calls a function in the containing web page __(Web Player only)__. + CSRAW public static void ExternalCall (string functionName, params object[] args) + { + #if ENABLE_MONO + Internal_ExternalCall(BuildInvocationForArguments(functionName,args)); + #elif UNITY_FLASH + Internal_ExternalCall_Flash(functionName,(object)args); + #endif + } + + CONDITIONAL UNITY_FLASH + CUSTOM private static void Internal_ExternalCall_Flash(string script, object args) + { + ScriptingObjectPtr arg = args; + if(args){ + Ext_ExternalCall(script.AsUTF8().c_str(), arg); + } + } + + CONDITIONAL ENABLE_MONO + CSRAW private static string BuildInvocationForArguments(string functionName, params object[] args) + { + var sb = new System.Text.StringBuilder(); + sb.Append( functionName ); + sb.Append( '(' ); + int size = args.Length; + for( int i = 0; i < size; ++i ) { + if( i != 0 ) + sb.Append( ", " ); + sb.Append( ObjectToJSString(args[i]) ); + } + sb.Append( ')' ); + sb.Append( ';' ); + return sb.ToString(); + } + + + // Evaluates script snippet in the containing web page __(Web Player only)__. + CONDITIONAL ENABLE_MONO + CSRAW public static void ExternalEval (string script) + { + if (script.Length > 0 && script[script.Length-1] != ';') + script += ';'; + Internal_ExternalCall(script); + } + + CONDITIONAL ENABLE_MONO + CUSTOM private static void Internal_ExternalCall(string script) { + #if WEBPLUG + WebScripting::Get().ExternalCall(script); + #else + LogString(Format ("External Call: %s", script.AsUTF8().c_str())); + #endif + } + + // The version of the Unity runtime used to play the content. + CUSTOM_PROP static string unityVersion + { + return scripting_string_new(UNITY_VERSION); + } + + CUSTOM internal static int GetBuildUnityVersion () + { + return GetBuildSettings().GetIntVersion(); + } + + CUSTOM internal static int GetNumericUnityVersion (string version) + { + return GetNumericVersion (version); + } + + + // Indicates whether Unity's webplayer security model is enabled. + THREAD_SAFE + CUSTOM_PROP static bool webSecurityEnabled + { + #if WEBPLUG + return true; + #endif + #if UNITY_EDITOR + return (GetBuildTargetGroup( GetEditorUserBuildSettings().GetActiveBuildTarget ()) == kPlatformWebPlayer); + #endif + return false; + } + + //*undocumented + THREAD_SAFE + CUSTOM_PROP static string webSecurityHostUrl + { + #if UNITY_EDITOR + return scripting_string_new(GetEditorSettings().GetWebSecurityEmulationHostUrl()); + #elif WEBPLUG + return scripting_string_new(GetPlayerSettings().absoluteURL); + #else + return scripting_string_new(""); + #endif + } + + // Opens the /url/ in a browser. + + + CUSTOM static void OpenURL (string url) + { + #if WEBPLUG + #if UNITY_OSX && !UNITY_PEPPER + if (systeminfo::IsRunningInDashboardWidget ()) + WebScripting::Get().ExternalCall("goToUrl(\"" + url.AsUTF8() + "\");"); + else + #endif + WebScripting::Get().ExternalCall("location.href=\"" + url.AsUTF8() + "\";"); + #elif UNITY_WII + wii::FatalError( "OpenURL not supported" ); + #elif UNITY_PS3 + printf("ERROR: OpenURL not supported\n"); exit(-1); + #elif UNITY_XENON + printf_console("ERROR: OpenURL not supported\n"); exit(-1); + #elif UNITY_FLASH + Ext_OpenURL(url.AsUTF8().c_str()); + #else + OpenURL (url); + #endif + } + + OBSOLETE warning For internal use only + CUSTOM public static void CommitSuicide (int mode) + { + if (mode == 0) + { + printf_console("Committing suicide -- Intentionally Dereferencing NULL pointer\n"); + int* p = NULL; + *p = 5; + } + else if (mode == 1) + { + FatalErrorString("Intentionally caused fatal error"); + } + else if (mode == 2) + { + abort(); + } + } + + // Instructs game to try to render at a specified frame rate. + CUSTOM_PROP static int targetFrameRate + { + return GetTargetFrameRateFromScripting(); + } + { + SetTargetFrameRate(value); + } + + // The language the user's operating system is running in. + CUSTOM_PROP static SystemLanguage systemLanguage + { + return (SystemLanguage)systeminfo::GetSystemLanguage(); + } + + // Register a delegate to be called on log messages. + CSRAW public static void RegisterLogCallback (Application.LogCallback handler) + { + s_LogCallback = handler; SetLogCallbackDefined(handler != null, false); + } + + // Register a delegate to be called on log messages. + CSRAW public static void RegisterLogCallbackThreaded (Application.LogCallback handler) { + s_LogCallback = handler; + SetLogCallbackDefined(handler != null, true); + } + + CSRAW private static volatile LogCallback s_LogCallback; + + CSRAW private static void CallLogCallback(string logString, string stackTrace, LogType type) + { + if ( s_LogCallback != null ) + s_LogCallback(logString, stackTrace, type); + } + + // Use this delegate type with RegisterLogCallback to monitor what gets logged. + CSRAW public delegate void LogCallback (string condition, string stackTrace, LogType type); + + // Log callback that calls into the mono log callback + C++RAW + static void LogCallbackImplementation(const std::string& condition, const std::string &stackTrace, int type) + { +#if ENABLE_MONO || UNITY_WINRT + if ( !GetMonoManagerPtr() ) + return; + + ScriptingInvocation invocation(MONO_COMMON.callLogCallback); + invocation.AddString(condition.c_str()); + invocation.AddString(stackTrace.c_str()); + invocation.AddInt(type); + invocation.Invoke<ScriptingObjectPtr>(); +#endif + } + CUSTOM private static void SetLogCallbackDefined(bool defined, bool threaded) + { + RegisterLogCallback(defined ? LogCallbackImplementation : NULL, threaded); + } + + // Priority of background loading thread. + CUSTOM_PROP static ThreadPriority backgroundLoadingPriority + { + return GetPreloadManager().GetThreadPriority(); + } + { + GetPreloadManager().SetThreadPriority(value); + } + + // Returns the type of Internet reachability currently possible on the device. + CUSTOM_PROP static NetworkReachability internetReachability + { + return GetInternetReachability (); + } + + + // Returns false if application is altered in any way after it was built. + CUSTOM_PROP static bool genuine + { + return IsApplicationGenuine (); + } + + // Returns true if application integrity can be confirmed. + CUSTOM_PROP static bool genuineCheckAvailable + { + return IsApplicationGenuineAvailable (); + } + + // Request authorization to use the webcam or microphone in the Web Player. + CUSTOM static AsyncOperation RequestUserAuthorization (UserAuthorization mode) + { + #if ENABLE_MONO + AsyncOperation* result = GetUserAuthorizationManager().RequestUserAuthorization (mode); + MonoObject* mono = mono_object_new(mono_domain_get(), MONO_COMMON.asyncOperation); + ExtractMonoObjectData<AsyncOperation*>(mono) = result; + return mono; + #else + return SCRIPTING_NULL; + #endif + } + + // Check if the user has authorized use of the webcam or microphone in the Web Player. + CUSTOM static bool HasUserAuthorization (UserAuthorization mode) + { + return GetUserAuthorizationManager().HasUserAuthorization (mode); + } + + CUSTOM static internal void ReplyToUserAuthorizationRequest (bool reply, bool remember = false) + { + return GetUserAuthorizationManager().ReplyToUserAuthorizationRequest (reply, remember); + } + + CUSTOM static private int GetUserAuthorizationRequestMode_Internal () + { + return GetUserAuthorizationManager().GetAuthorizationRequest(); + } + + CSRAW static internal UserAuthorization GetUserAuthorizationRequestMode () + { + return (UserAuthorization)GetUserAuthorizationRequestMode_Internal(); + } +END + +// Constants to pass to [[Application.RequestUserAuthorization]]. +ENUM UserAuthorization + // Request permission to use any video input sources attached to the computer. + WebCam = 1, + // Request permission to use any audio input sources attached to the computer. + Microphone = 2 +END + +CSRAW } diff --git a/Runtime/Export/UnityEngineAsyncOperation.txt b/Runtime/Export/UnityEngineAsyncOperation.txt new file mode 100644 index 0000000..1cde86e --- /dev/null +++ b/Runtime/Export/UnityEngineAsyncOperation.txt @@ -0,0 +1,81 @@ +C++RAW + + +#include "UnityPrefix.h" + +#include "Configuration/UnityConfigure.h" + +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Misc/AsyncOperation.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + + +// Asynchronous operation coroutine. +CSRAW [StructLayout (LayoutKind.Sequential)] +NONSEALED_CLASS AsyncOperation : YieldInstruction + + CSRAW [NotRenamed]internal IntPtr m_Ptr; + + THREAD_SAFE + CUSTOM private void InternalDestroy () + { + self->Release(); + } + + CSRAW ~AsyncOperation () + { + InternalDestroy(); + } + + // Has the operation finished? (RO) + CUSTOM_PROP bool isDone + { + return self->IsDone(); + } + + + // What's the operation's progress (RO) + CUSTOM_PROP float progress + { + return self->GetProgress(); + } + + // Priority lets you tweak in which order async operation calls will be performed. + CUSTOM_PROP int priority + { + return self->GetPriority(); + } + { + if (value < 0) + { + value = 0; + ErrorString ("Priority can't be set to negative value"); + } + return self->SetPriority(value); + } + + // Allow scenes to be activated as soon as it is ready. + CUSTOM_PROP bool allowSceneActivation + { + return self->GetAllowSceneActivation(); + } + { + return self->SetAllowSceneActivation(value); + } + +END + +CSRAW } diff --git a/Runtime/Export/UnityEngineBehaviour.txt b/Runtime/Export/UnityEngineBehaviour.txt new file mode 100644 index 0000000..d0e1304 --- /dev/null +++ b/Runtime/Export/UnityEngineBehaviour.txt @@ -0,0 +1,31 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// Behaviours are Components that can be enabled or disabled. +CSRAW +NONSEALED_CLASS Behaviour : Component + // Enabled Behaviours are Updated, disabled Behaviours are not. + AUTO_PROP bool enabled GetEnabled SetEnabled +END + + +CSRAW } + diff --git a/Runtime/Export/UnityEngineCamera.txt b/Runtime/Export/UnityEngineCamera.txt new file mode 100644 index 0000000..92a7930 --- /dev/null +++ b/Runtime/Export/UnityEngineCamera.txt @@ -0,0 +1,420 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Camera/Camera.h" +#include "Runtime/Camera/RenderManager.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Graphics/ScreenManager.h" +#include "Runtime/Graphics/CubemapTexture.h" +#include "Runtime/GfxDevice/GfxDevice.h" +#include "Runtime/Scripting/Scripting.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// Rendering path of a [[Camera]]. +ENUM RenderingPath + // Use Player Settings. + UsePlayerSettings = -1, + + // Vertex Lit. + VertexLit = 0, + + // Forward Rendering. + Forward = 1, + + // Deferred Lighting. + DeferredLighting = 2 +END + + +// Transparent object sorting mode of a [[Camera]]. +ENUM TransparencySortMode + // Default sorting mode. + Default = 0, + + // Perspective sorting mode. + Perspective = 1, + + // Orthographic sorting mode. + Orthographic = 2 +END + + +// A Camera is a device through which the player views the world. +CLASS Camera : Behaviour + + // *undocumented* deprecated + OBSOLETE warning use Camera.fieldOfView instead. + CSRAW public float fov { get { return fieldOfView; } set { fieldOfView = value; } } + // *undocumented* deprecated + OBSOLETE warning use Camera.nearClipPlane instead. + CSRAW public float near { get { return nearClipPlane; } set { nearClipPlane = value; } } + // *undocumented* deprecated + OBSOLETE warning use Camera.farClipPlane instead. + CSRAW public float far { get { return farClipPlane; } set { farClipPlane = value; } } + + // The field of view of the camera in degrees. + AUTO_PROP float fieldOfView GetFov SetFov + + // The near clipping plane distance. + AUTO_PROP float nearClipPlane GetNear SetNear + + // The far clipping plane distance. + AUTO_PROP float farClipPlane GetFar SetFar + + + // Rendering path. + AUTO_PROP RenderingPath renderingPath GetRenderingPath SetRenderingPath + + // Actually used rendering path (RO). + CUSTOM_PROP RenderingPath actualRenderingPath { return self->CalculateRenderingPath(); } + + // High dynamic range rendering + AUTO_PROP bool hdr CalculateUsingHDR SetHDR + + // Camera's half-size when in orthographic mode. + AUTO_PROP float orthographicSize GetOrthographicSize SetOrthographicSize + + // Is the camera orthographic (''true'') or perspective (''false'')? + AUTO_PROP bool orthographic GetOrthographic SetOrthographic + + + // Transparent object sorting mode. + AUTO_PROP TransparencySortMode transparencySortMode GetSortMode SetSortMode + + + OBSOLETE planned Use orthographic instead + CSRAW public bool isOrthoGraphic { get { return orthographic; } set { orthographic = value; } } + + // Camera's depth in the camera rendering order. + AUTO_PROP float depth GetDepth SetDepth + + // The aspect ratio (width divided by height). + AUTO_PROP float aspect GetAspect SetAspect + + // This is used to render parts of the scene selectively. + AUTO_PROP int cullingMask GetCullingMask SetCullingMask + + // The event mask used by the camera. + AUTO_PROP int eventMask GetEventMask SetEventMask + + // The color with which the screen will be cleared. + AUTO_PROP Color backgroundColor GetBackgroundColor SetBackgroundColor + + + // Where on the screen is the camera rendered in normalized coordinates. + AUTO_PROP Rect rect GetNormalizedViewportRect SetNormalizedViewportRect + + // Where on the screen is the camera rendered in pixel coordinates. + AUTO_PROP Rect pixelRect GetScreenViewportRect SetScreenViewportRect + + // Destination render texture __(Unity Pro only)__. + AUTO_PTR_PROP RenderTexture targetTexture GetTargetTexture SetTargetTexture + + CUSTOM private void SetTargetBuffersImpl(out RenderBuffer color, out RenderBuffer depth) + { + self->SetTargetBuffersScript(1, color, depth); + } + + CUSTOM private void SetTargetBuffersMRTImpl(RenderBuffer[] color, out RenderBuffer depth) + { + int count = GetScriptingArraySize(color); + if (count < 1 || count > kMaxSupportedRenderTargets) + { + ErrorString ("Invalid color buffer count for SetTargetBuffers"); + return; + } + + self->SetTargetBuffersScript(count, Scripting::GetScriptingArrayStart<ScriptingRenderBuffer>(color), depth); + } + + CSRAW public void SetTargetBuffers(RenderBuffer colorBuffer, RenderBuffer depthBuffer) + { + SetTargetBuffersImpl(out colorBuffer, out depthBuffer); + } + + CSRAW public void SetTargetBuffers(RenderBuffer[] colorBuffer, RenderBuffer depthBuffer) + { + SetTargetBuffersMRTImpl(colorBuffer, out depthBuffer); + } + + + // How wide is the camera in pixels (RO). + CUSTOM_PROP float pixelWidth { return self->GetScreenViewportRect ().Width(); } + // How tall is the camera in pixels (RO). + CUSTOM_PROP float pixelHeight { return self->GetScreenViewportRect ().Height(); } + + // Matrix that transforms from camera space to world space (RO). + AUTO_PROP Matrix4x4 cameraToWorldMatrix GetCameraToWorldMatrix + + // Matrix that transforms from world to camera space. + AUTO_PROP Matrix4x4 worldToCameraMatrix GetWorldToCameraMatrix SetWorldToCameraMatrix + + // Make the rendering position reflect the camera's position in the scene. + AUTO void ResetWorldToCameraMatrix (); + + + // Set a custom projection matrix. + AUTO_PROP Matrix4x4 projectionMatrix GetProjectionMatrix SetProjectionMatrix + + // Make the projection reflect normal camera's parameters. + AUTO void ResetProjectionMatrix (); + + // Revert the aspect ratio to the screen's aspect ratio. + AUTO void ResetAspect (); + + // Get the world-space speed of the camera (RO). + AUTO_PROP Vector3 velocity GetVelocity + + // How the camera clears the background. + AUTO_PROP CameraClearFlags clearFlags GetClearFlags SetClearFlags + + // Transforms /position/ from world space into screen space. + AUTO Vector3 WorldToScreenPoint (Vector3 position); + + // Transforms /position/ from world space into viewport space. + AUTO Vector3 WorldToViewportPoint (Vector3 position); + + + // Transforms /position/ from viewport space into world space. + AUTO Vector3 ViewportToWorldPoint (Vector3 position); + + // Transforms /position/ from screen space into world space. + AUTO Vector3 ScreenToWorldPoint (Vector3 position); + + + // Transforms /position/ from screen space into viewport space. + AUTO Vector3 ScreenToViewportPoint (Vector3 position); + + // Transforms /position/ from viewport space into screen space. + AUTO Vector3 ViewportToScreenPoint (Vector3 position); + + + // Returns a ray going from camera through a viewport point. + CUSTOM Ray ViewportPointToRay (Vector3 position) { return self->ViewportPointToRay (Vector2f (position.x, position.y)); } + + // Returns a ray going from camera through a screen point. + CUSTOM Ray ScreenPointToRay (Vector3 position) { return self->ScreenPointToRay (Vector2f (position.x, position.y)); } + + + // The first enabled camera tagged "MainCamera" (RO). + CUSTOM_PROP static Camera main + { + return Scripting::ScriptingWrapperFor(FindMainCamera()); + } + + // The camera we are currently rendering with, for low-level render control only (Read Only). + CUSTOM_PROP static Camera current { return Scripting::ScriptingWrapperFor (GetCurrentCameraPtr()); } + + // Returns all enabled cameras in the scene. + CUSTOM_PROP static Camera[] allCameras + { + const RenderManager::CameraContainer& onscreen = GetRenderManager ().GetOnscreenCameras (); + const RenderManager::CameraContainer& offscreen = GetRenderManager ().GetOffscreenCameras (); + + unsigned camCount = onscreen.size () + offscreen.size(); + + int curCameraI = 0; + + ScriptingArrayPtr scriptingcams = CreateScriptingArray<ScriptingObjectPtr>(GetScriptingManager ().GetCommonClasses ().camera, camCount); + + for ( RenderManager::CameraContainer::const_iterator camIter = onscreen.begin () ; + camIter != onscreen.end() ; + ++camIter, ++curCameraI + ) + { + Scripting::SetScriptingArrayElement (scriptingcams, curCameraI, Scripting::ScriptingWrapperFor (*camIter)); + } + + for ( RenderManager::CameraContainer::const_iterator camIter = offscreen.begin () ; + camIter != offscreen.end() ; + ++camIter, ++curCameraI + ) + { + Scripting::SetScriptingArrayElement (scriptingcams, curCameraI, Scripting::ScriptingWrapperFor (*camIter)); + } + + return scriptingcams; + } + + + // *undocumented* DEPRECATED + OBSOLETE warning use Camera.main instead. + CSRAW public static Camera mainCamera { get { return Camera.main; } } + //*undocumented* DEPRECATED + OBSOLETE warning use Screen.width instead. + CUSTOM float GetScreenWidth () { return GetScreenManager ().GetWidth (); } + //*undocumented* DEPRECATED + OBSOLETE warning use Screen.height instead. + CUSTOM float GetScreenHeight () { return GetScreenManager ().GetHeight (); } + + //*undocumented* DEPRECATED + OBSOLETE warning Camera.DoClear is deprecated and may be removed in the future. + CUSTOM void DoClear () { + self->Clear (); + } + + + // OnPreCull is called before a camera culls the scene. + CSNONE void OnPreCull (); + + // OnPreRender is called before a camera starts rendering the scene. + CSNONE void OnPreRender (); + + // OnPostRender is called after a camera has finished rendering the scene. + CSNONE void OnPostRender (); + + // OnRenderImage is called after all rendering is complete to render image + CSNONE void OnRenderImage (RenderTexture source, RenderTexture destination); + + + // OnRenderObject is called after camera has rendered the scene. + CSNONE void OnRenderObject (); + + + // OnWillRenderObject is called once for each camera if the object is visible. + + CONVERTEXAMPLE + BEGIN EX + function OnWillRenderObject() { + // Tint the object red for identification if it is + // being shown on the overhead mini-map view. + if (Camera.current.name == "MiniMapcam") { + renderer.material.color = Color.red; + } else { + renderer.material.color = Color.white; + } + } + END EX + /// + CSNONE void OnWillRenderObject(); + + // Render the camera manually. + CUSTOM void Render () { + self->StandaloneRender( Camera::kRenderFlagSetRenderTarget, NULL, "" ); + } + + // Render the camera with shader replacement. + CUSTOM void RenderWithShader (Shader shader, string replacementTag) { + self->StandaloneRender( Camera::kRenderFlagSetRenderTarget, shader, replacementTag ); + } + + // Make the camera render with shader replacement. + CUSTOM void SetReplacementShader (Shader shader, string replacementTag) { + self->SetReplacementShader( shader, replacementTag ); + } + // Remove shader replacement from camera. + AUTO void ResetReplacementShader (); + + AUTO_PROP bool useOcclusionCulling GetUseOcclusionCulling SetUseOcclusionCulling + + // These are only used by terrain engine impostor rendering and should be used with care! + //*undoc* + CUSTOM void RenderDontRestore() { + self->StandaloneRender( Camera::kRenderFlagDontRestoreRenderState | Camera::kRenderFlagSetRenderTarget, NULL, "" ); + } + //*undoc* + CUSTOM static void SetupCurrent (Camera cur) + { + if (cur) + { + cur->StandaloneSetup(); + } + else + { + GetRenderManager ().SetCurrentCamera (NULL); + RenderTexture::SetActive(NULL); + } + } + + + // Render into a static cubemap from this camera. + CSRAW public bool RenderToCubemap (Cubemap cubemap, int faceMask = 63) { + return Internal_RenderToCubemapTexture( cubemap, faceMask ); + } + + // Render into a cubemap from this camera. + CSRAW public bool RenderToCubemap (RenderTexture cubemap, int faceMask = 63) { + return Internal_RenderToCubemapRT ( cubemap, faceMask ); + } + + + CUSTOM private bool Internal_RenderToCubemapRT( RenderTexture cubemap, int faceMask ) + { + RenderTexture* rt = cubemap; + if( !rt ) + { + ErrorString( "Cubemap must not be null" ); + return false; + } + return self->StandaloneRenderToCubemap( rt, faceMask ); + } + CUSTOM private bool Internal_RenderToCubemapTexture( Cubemap cubemap, int faceMask ) + { + Cubemap* cube = cubemap; + if( !cube ) + { + ErrorString( "Cubemap must not be null" ); + return false; + } + return self->StandaloneRenderToCubemap( cube, faceMask ); + } + + // Per-layer culling distances. + CUSTOM_PROP float[] layerCullDistances + { + return CreateScriptingArray(self->GetLayerCullDistances(), 32, GetScriptingManager().GetCommonClasses().floatSingle); + } + { + Scripting::RaiseIfNull(value); + if(GetScriptingArraySize(value) != 32) + { + Scripting::RaiseMonoException(" Array needs to contain exactly 32 floats for layerCullDistances."); + return; + } + self->SetLayerCullDistances(Scripting::GetScriptingArrayStart<float> (value)); + } + + // How to perform per-layer culling for a Camera. + CUSTOM_PROP bool layerCullSpherical { return self->GetLayerCullSpherical(); } { self->SetLayerCullSpherical(value); } + + // Makes this camera's settings match other camera. + CUSTOM void CopyFrom (Camera other) { + const Camera* otherCam = other; + if(!otherCam) + { + ErrorString( "Camera to copy from must not be null" ); + return; + } + + self->CopyFrom (*otherCam); + } + + // How and if camera generates a depth texture. + CUSTOM_PROP DepthTextureMode depthTextureMode { return self->GetDepthTextureMode(); } { self->SetDepthTextureMode (value); } + + // Should the camera clear the stencil buffer after the lighting stage of the deferred rendering path? + CUSTOM_PROP bool clearStencilAfterLightingPass { return self->GetClearStencilAfterLightingPass(); } { self->SetClearStencilAfterLightingPass (value); } + + CUSTOM internal bool IsFiltered (GameObject go) { + #if UNITY_EDITOR + return true; +//@TODO +// return self->GetCuller().IsFiltered(*go); + #else + return true; + #endif + } +END + + +CSRAW } diff --git a/Runtime/Export/UnityEngineComponent.txt b/Runtime/Export/UnityEngineComponent.txt new file mode 100644 index 0000000..2fa9b9c --- /dev/null +++ b/Runtime/Export/UnityEngineComponent.txt @@ -0,0 +1,329 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/BaseClasses/Tags.h" +#if ENABLE_AUDIO +#include "Runtime/Audio/AudioClip.h" +#include "Runtime/Audio/AudioSource.h" +#include "Runtime/Audio/AudioListener.h" +#endif +#include "Runtime/Animation/Animation.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Utilities/PlayerPrefs.h" +#include "Runtime/Camera/Camera.h" +#include "Runtime/Utilities/Word.h" +#include "Runtime/Camera/Light.h" +#include "Runtime/Filters/Misc/TextMesh.h" +#include "Runtime/Dynamics/ConstantForce.h" +#include "Runtime/Filters/Renderer.h" +#include "Runtime/Network/NetworkView.h" +#include "Runtime/Camera/RenderLayers/GUIText.h" +#include "Runtime/Camera/RenderLayers/GUITexture.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/GetComponent.h" +#include "Runtime/Misc/GameObjectUtility.h" +#if ENABLE_PHYSICS +#include "Runtime/Dynamics/RigidBody.h" +#include "Runtime/Dynamics/Collider.h" +#include "Runtime/Dynamics/HingeJoint.h" +#endif +#if ENABLE_2D_PHYSICS +#include "Runtime/Physics2D/RigidBody2D.h" +#include "Runtime/Physics2D/Collider2D.h" +#endif +#include "Runtime/Filters/Particles/ParticleEmitter.h" +#include "Runtime/Graphics/ParticleSystem/ParticleSystem.h" +#include "Runtime/Animation/AnimationClip.h" +#include "Runtime/File/ApplicationSpecificPersistentDataPath.h" +#if ENABLE_MONO +#include "Runtime/Mono/Coroutine.h" +#endif + +#if UNITY_WII + #include "PlatformDependent/Wii/WiiUtility.h" +#endif + +#include "Runtime/Scripting/Scripting.h" + +using namespace Unity; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// Base class for everything attached to GameObjects. +NONSEALED_CLASS Component : Object + + C++RAW + #define FAST_COMPONENT_QUERY_COMPONENT_HANDLE(x) DISALLOW_IN_CONSTRUCTOR GameObject* go = self->GetGameObjectPtr(); if (go) {Unity::Component* com = go->QueryComponent (x); Scripting::GetComponentObjectToScriptingObject (com, *go, ClassID (x)); return com->GetGCHandle(); } else { Scripting::RaiseMonoException ("The component is not attached to any game object!"); return 0; } + + C++RAW + #define FAST_COMPONENT_QUERY_COMPONENT(x) DISALLOW_IN_CONSTRUCTOR GameObject* go = self->GetGameObjectPtr(); if (go) return Scripting::GetComponentObjectToScriptingObject (go->QueryComponent (x), *go, ClassID (x)); else { Scripting::RaiseMonoException ("The component is not attached to any game object!"); return SCRIPTING_NULL; } + + // The [[Transform]] attached to this [[GameObject]] (null if there is none attached). + CSRAW + CSRAW public Transform transform + { + get + { + return InternalGetTransform(); + } + } + + CUSTOM internal Transform InternalGetTransform() + { + FAST_COMPONENT_QUERY_COMPONENT(Transform); + } + + // The [[Rigidbody]] attached to this [[GameObject]] (null if there is none attached). + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP Rigidbody rigidbody { FAST_COMPONENT_QUERY_COMPONENT(Rigidbody) } + CONDITIONAL ENABLE_2D_PHYSICS + CUSTOM_PROP Rigidbody2D rigidbody2D { FAST_COMPONENT_QUERY_COMPONENT(Rigidbody2D) } + + // The [[Camera]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP Camera camera { FAST_COMPONENT_QUERY_COMPONENT(Camera) } + // The [[Light]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP Light light { FAST_COMPONENT_QUERY_COMPONENT(Light) } + // The [[Animation]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP Animation animation { FAST_COMPONENT_QUERY_COMPONENT(Animation) } + // The [[ConstantForce]] attached to this [[GameObject]] (null if there is none attached). + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP ConstantForce constantForce { FAST_COMPONENT_QUERY_COMPONENT(ConstantForce) } + // The [[Renderer]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP Renderer renderer { FAST_COMPONENT_QUERY_COMPONENT(Renderer) } + // The [[AudioSource]] attached to this [[GameObject]] (null if there is none attached). + CONDITIONAL ENABLE_AUDIO + CUSTOM_PROP AudioSource audio { FAST_COMPONENT_QUERY_COMPONENT(AudioSource) } + // The [[GUIText]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP GUIText guiText { FAST_COMPONENT_QUERY_COMPONENT(GUIText) } + + CONDITIONAL ENABLE_NETWORK + // The [[NetworkView]] attached to this [[GameObject]] (RO). (null if there is none attached) + CUSTOM_PROP NetworkView networkView + { + #if ENABLE_NETWORK + FAST_COMPONENT_QUERY_COMPONENT(NetworkView) + #else + return SCRIPTING_NULL; + #endif + } + + FLUSHCONDITIONS + + CSRAW +#if ENABLE_NETWORK + OBSOLETE warning Please use guiTexture instead +#endif + CUSTOM_PROP GUIElement guiElement { FAST_COMPONENT_QUERY_COMPONENT(GUIElement) } + + // The [[GUITexture]] attached to this [[GameObject]] (RO). (null if there is none attached) + CUSTOM_PROP GUITexture guiTexture { FAST_COMPONENT_QUERY_COMPONENT(GUITexture) } + + // The [[Collider]] attached to this [[GameObject]] (null if there is none attached). + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP Collider collider { FAST_COMPONENT_QUERY_COMPONENT(Collider) } + CONDITIONAL ENABLE_2D_PHYSICS + CUSTOM_PROP Collider2D collider2D { FAST_COMPONENT_QUERY_COMPONENT(Collider2D) } + + // The [[HingeJoint]] attached to this [[GameObject]] (null if there is none attached). + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP HingeJoint hingeJoint { FAST_COMPONENT_QUERY_COMPONENT(HingeJoint) } + // The [[ParticleEmitter]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP ParticleEmitter particleEmitter { FAST_COMPONENT_QUERY_COMPONENT(ParticleEmitter) } + // The [[ParticleSystem]] attached to this [[GameObject]] (null if there is none attached). + CUSTOM_PROP ParticleSystem particleSystem { FAST_COMPONENT_QUERY_COMPONENT(ParticleSystem) } + + + // The game object this component is attached to. A component is always attached to a game object. + + CSRAW public GameObject gameObject + { + get + { + return InternalGetGameObject(); + } + } + + CUSTOM internal GameObject InternalGetGameObject() + { + DISALLOW_IN_CONSTRUCTOR + return Scripting::ScriptingWrapperFor(self->GetGameObjectPtr()); + } + // Returns the component of Type /type/ if the game object has one attached, null if it doesn't. + + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CUSTOM Component GetComponent (Type type) + { + DISALLOW_IN_CONSTRUCTOR + + GameObject* go = self->GetGameObjectPtr(); + if (go) + { + return ScriptingGetComponentOfType (*go, type); + } + else + { + Scripting::RaiseMonoException ("The component is not attached to any game object!"); + return SCRIPTING_NULL; + } + } + + C++RAW + + + #if UNITY_WINRT + GameObject& GetGameObjectThrow (void* com_) + { + ReadOnlyScriptingObjectOfType<Unity::Component> com(com_); + #else + GameObject& GetGameObjectThrow (ReadOnlyScriptingObjectOfType<Unity::Component> com) + { + #endif + GameObject* go = com->GetGameObjectPtr(); + if (go) + return *go; + { + Scripting::RaiseMonoException ("The component is not attached to any game object!"); + return *go; + } + } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T GetComponent<T>() where T : Component { return GetComponent(typeof(T)) as T; } + #endif + + // Returns the component with name /type/ if the game object has one attached, null if it doesn't. + + CSRAW public Component GetComponent (string type) { return gameObject.GetComponent(type); } + + + + + // Returns the component of Type /type/ in the [[GameObject]] or any of its children using depth first search. + + + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CSRAW public Component GetComponentInChildren (Type t) { return gameObject.GetComponentInChildren (t); } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T GetComponentInChildren<T> () where T : Component { return (T) GetComponentInChildren(typeof(T)); } + #endif + + + // Returns all components of Type /type/ in the [[GameObject]] or any of its children. + + CSRAW public Component[] GetComponentsInChildren (Type t, bool includeInactive = false) { return gameObject.GetComponentsInChildren (t, includeInactive); } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T[] GetComponentsInChildren<T> (bool includeInactive) where T : Component { return gameObject.GetComponentsInChildren<T>(includeInactive); } + #endif + + CSRAW + #if ENABLE_GENERICS + // adding overload manually because lucas can't figure out how to get the cspreprocess overload generation code to deal with templates right now. + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T[] GetComponentsInChildren<T> () where T : Component { return GetComponentsInChildren<T>(false); } + #endif + + + + // Returns all components of Type /type/ in the [[GameObject]]. + + CUSTOM Component[] GetComponents (Type type) { DISALLOW_IN_CONSTRUCTOR return ScriptingGetComponentsOfType (GetGameObjectThrow(self), type, false, false, true); } + + CUSTOM private Component[] GetComponentsWithCorrectReturnType(Type type) { DISALLOW_IN_CONSTRUCTOR return ScriptingGetComponentsOfType (GetGameObjectThrow(self), type, true, false, true); } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T[] GetComponents<T>() where T : Component + { + return (T[]) GetComponentsWithCorrectReturnType(typeof(T)); + } + #endif + + + OBSOLETE warning the active property is deprecated on components. Please use gameObject.active instead. If you meant to enable / disable a single component use enabled instead. + CUSTOM_PROP bool active { DISALLOW_IN_CONSTRUCTOR return self->IsActive (); } { DISALLOW_IN_CONSTRUCTOR GameObject& go = GetGameObjectThrow(self); if (value) go.Activate (); else go.Deactivate (); } + + // The tag of this game object. + CUSTOM_PROP string tag + { + DISALLOW_IN_CONSTRUCTOR + const string& tag = TagToString (GetGameObjectThrow(self).GetTag ()); + if (!tag.empty ()) + return scripting_string_new(tag); + else + { + Scripting::RaiseMonoException ("GameObject has undefined tag!"); + return SCRIPTING_NULL; + } + } + { + DISALLOW_IN_CONSTRUCTOR + GetGameObjectThrow(self).SetTag (ExtractTagThrowing (value)); + } + + // Is this game object tagged /tag/? + CUSTOM public bool CompareTag (string tag) { DISALLOW_IN_CONSTRUCTOR return ExtractTagThrowing (tag) == GetGameObjectThrow(self).GetTag (); } + + + // Calls the method named /methodName/ on every [[MonoBehaviour]] in this game object and on every ancestor of the behaviour + CUSTOM void SendMessageUpwards (string methodName, object value = null, SendMessageOptions options = SendMessageOptions.RequireReceiver) + { + DISALLOW_IN_CONSTRUCTOR + Scripting::SendScriptingMessageUpwards(GetGameObjectThrow(self), methodName, value, options); + } + + //*undocumented* Function is for convenience and avoid coming mistakes. + CSRAW public void SendMessageUpwards (string methodName, SendMessageOptions options) + { + SendMessageUpwards(methodName, null, options); + } + + // Calls the method named /methodName/ on every [[MonoBehaviour]] in this game object. + CUSTOM void SendMessage (string methodName, object value = null, SendMessageOptions options = SendMessageOptions.RequireReceiver) + { + DISALLOW_IN_CONSTRUCTOR + Scripting::SendScriptingMessage(GetGameObjectThrow(self), methodName, value, options); + } + + //*undocumented* Function is for convenience and avoid coming mistakes. + CSRAW public void SendMessage (string methodName, SendMessageOptions options) + { + SendMessage (methodName, null, options); + } + + // Calls the method named /methodName/ on every [[MonoBehaviour]] in this game object or any of its children. + CUSTOM void BroadcastMessage (string methodName, object parameter = null, SendMessageOptions options = SendMessageOptions.RequireReceiver) + { + DISALLOW_IN_CONSTRUCTOR + Scripting::BroadcastScriptingMessage(GetGameObjectThrow(self), methodName, parameter, options); + } + + //*undocumented* Function is for convenience and avoid coming mistakes. + CSRAW public void BroadcastMessage (string methodName, SendMessageOptions options) + { + BroadcastMessage (methodName, null, options); + } +END + +CSRAW } diff --git a/Runtime/Export/UnityEngineComputeShader.txt b/Runtime/Export/UnityEngineComputeShader.txt new file mode 100644 index 0000000..8631069 --- /dev/null +++ b/Runtime/Export/UnityEngineComputeShader.txt @@ -0,0 +1,216 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Shaders/ComputeShader.h" +#include "Runtime/Graphics/Texture.h" +#include "Runtime/Math/Vector4.h" +#include "Runtime/Threads/AtomicOps.h" + +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Misc/GraphicsScriptingUtility.h" + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// Compute Shader asset. +CLASS ComputeShader : Object + + // Find [[ComputeShader]] kernel index. + CUSTOM int FindKernel (string name) { + FastPropertyName fpName = ScriptingStringToProperty(name); + return self->FindKernel (fpName); + } + + // Set a float parameter. + CUSTOM void SetFloat (string name, float val) { + FastPropertyName fpName = ScriptingStringToProperty(name); + self->SetValueParam (fpName, 4, &val); + } + + // Set an integer parameter. + CUSTOM void SetInt (string name, int val) { + FastPropertyName fpName = ScriptingStringToProperty(name); + self->SetValueParam (fpName, 4, &val); + } + + // Set a vector parameter. + CUSTOM void SetVector (string name, Vector4 val) { + FastPropertyName fpName = ScriptingStringToProperty(name); + self->SetValueParam (fpName, 16, &val.x); + } + + // Set multiple consecutive float parameters at once. + CSRAW public void SetFloats (string name, params float[] values) { + Internal_SetFloats (name, values); + } + CUSTOM private void Internal_SetFloats (string name, float[] values) { + FastPropertyName fpName = ScriptingStringToProperty(name); + int size = GetScriptingArraySize (values); + const float* arr = Scripting::GetScriptingArrayStart<float> (values); + self->SetValueParam (fpName, size*4, arr); + } + + // Set multiple consecutive integer parameters at once. + CSRAW public void SetInts (string name, params int[] values) { + Internal_SetInts (name, values); + } + CUSTOM private void Internal_SetInts (string name, int[] values) { + FastPropertyName fpName = ScriptingStringToProperty(name); + int size = GetScriptingArraySize (values); + const int* arr = Scripting::GetScriptingArrayStart<int> (values); + self->SetValueParam (fpName, size*4, arr); + } + + // Set a texture parameter. + CUSTOM void SetTexture (int kernelIndex, string name, Texture texture) { + FastPropertyName fpName = ScriptingStringToProperty(name); + Texture& tex = *texture; + self->SetTextureParam (kernelIndex, fpName, tex.GetTextureID()); + } + + // Set a [[ComputeBuffer]] parameter. + // + CUSTOM void SetBuffer (int kernelIndex, string name, ComputeBuffer buffer) { + FastPropertyName fpName = ScriptingStringToProperty(name); + self->SetBufferParam (kernelIndex, fpName, buffer->GetBufferHandle()); + } + + // Execute a compute shader. + CUSTOM void Dispatch (int kernelIndex, int threadsX, int threadsY, int threadsZ) + { + self->DispatchComputeShader (kernelIndex, threadsX, threadsY, threadsZ); + } + +END + +// [[ComputeBuffer]] type. +CSRAW [Flags] +ENUM ComputeBufferType + // Default [[ComputeBuffer]] type. + Default = 0, + // Raw [[ComputeBuffer]] type. + Raw = 1, + // Append-consume [[ComputeBuffer]] type. + Append = 2, + // [[ComputeBuffer]] with a counter. + Counter = 4, + // [[ComputeBuffer]] used for Graphics.DrawProceduralIndirect. + DrawIndirect = 256, +END + + +// Data buffer to hold data for compute shaders. +CLASS ComputeBuffer : IDisposable + + CSRAW #pragma warning disable 414 + CSRAW internal IntPtr m_Ptr; + CSRAW #pragma warning restore 414 + + // IDisposable implementation, with Release() for explicit cleanup. + + ~ComputeBuffer() + { + Dispose(false); + } + + //*undocumented* + CSRAW public void Dispose() + { + Dispose(true); + GC.SuppressFinalize(this); + } + + private void Dispose (bool disposing) + { + // we don't have any managed references, so + // 'disposing' part of standard IDisposable pattern + // does not apply + + // Release native resources + DestroyBuffer (this); + m_Ptr = IntPtr.Zero; + } + + CUSTOM private static void InitBuffer (ComputeBuffer buf, int count, int stride, ComputeBufferType type) { + buf.SetPtr(new ComputeBuffer(count, stride, type)); + } + CUSTOM private static void DestroyBuffer(ComputeBuffer buf) { + delete buf.GetPtr(); + } + + ///*listonly* + CSRAW public ComputeBuffer (int count, int stride) : this (count, stride, ComputeBufferType.Default) + { + } + + // Create a Compute Buffer. + CSRAW public ComputeBuffer (int count, int stride, ComputeBufferType type) + { + m_Ptr = IntPtr.Zero; + InitBuffer (this, count, stride, type); + } + + // Release a Compute Buffer. + CSRAW public void Release () + { + Dispose(); + } + + // Number of elements in the buffer (RO). + CUSTOM_PROP public int count { + return self->GetCount(); + } + + // Size of one element in the buffer (RO). + CUSTOM_PROP public int stride { + return self->GetStride(); + } + + // Set buffer data. + CSRAW + [System.Security.SecuritySafeCritical] // due to Marshal.SizeOf + public void SetData (System.Array data) { + #if !UNITY_FLASH + InternalSetData (data, Marshal.SizeOf(data.GetType().GetElementType())); + #endif + } + + CSRAW [System.Security.SecurityCritical] // to prevent accidentally making this public in the future + CUSTOM private void InternalSetData (System.Array data, int elemSize) { + self->SetData (Scripting::GetScriptingArrayStart<char>(data), GetScriptingArraySize(data) * elemSize); + } + + + // Read buffer data. + CSRAW + [System.Security.SecuritySafeCritical] // due to Marshal.SizeOf + public void GetData (System.Array data) { + #if !UNITY_FLASH + InternalGetData (data, Marshal.SizeOf(data.GetType().GetElementType())); + #endif + } + + CSRAW [System.Security.SecurityCritical] // to prevent accidentally making this public in the future + CUSTOM private void InternalGetData (System.Array data, int elemSize) { + self->GetData (Scripting::GetScriptingArrayStart<char>(data), GetScriptingArraySize(data) * elemSize); + } + + // Copy counter value of append/consume buffer into another buffer. + CUSTOM static void CopyCount (ComputeBuffer src, ComputeBuffer dst, int dstOffset) { + ComputeBuffer::CopyCount (src.GetPtr(), dst.GetPtr(), dstOffset); + } + +END + +CSRAW +} diff --git a/Runtime/Export/UnityEngineDebug.txt b/Runtime/Export/UnityEngineDebug.txt new file mode 100644 index 0000000..28c9832 --- /dev/null +++ b/Runtime/Export/UnityEngineDebug.txt @@ -0,0 +1,134 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Input/InputManager.h" +#include "Runtime/Input/TimeManager.h" +#include "Runtime/Misc/DeveloperConsole.h" +#include "Runtime/Misc/ResourceManager.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Misc/DebugUtility.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Misc/DeveloperConsole.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +#if UNITY_EDITOR + #include "Editor/Src/EditorSettings.h" + #include "Editor/Src/EditorUserBuildSettings.h" + #include "Editor/Mono/MonoEditorUtility.h" + #include "Editor/Src/AssetPipeline/MonoCompilationPipeline.h" +#endif + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// Class containing methods to ease debugging while developing a game. +CLASS Debug + + // Draws a line from the /point/ start to /end/ with color for a duration of time and with or without depth testing. If duration is 0 then the line is rendered 1 frame. + + CUSTOM public static void DrawLine (Vector3 start, Vector3 end, Color color = Color.white, float duration = 0.0f, bool depthTest = true) { DebugDrawLine (start, end, color, duration, depthTest); } + + + // Draws a line from /start/ to /start/ + /dir/ with color for a duration of time and with or without depth testing. If duration is 0 then the line is rendered 1 frame. + + CSRAW public static void DrawRay (Vector3 start, Vector3 dir, Color color = Color.white, float duration = 0.0f, bool depthTest = true) { DrawLine (start, start + dir, color, duration, depthTest); } + + + // Pauses the editor. + CUSTOM static void Break () { PauseEditor (); } + + // Breaks into the attached debugger, if present + CUSTOM static void DebugBreak () + { + #if DEBUGMODE && (UNITY_WIN && !UNITY_WINRT) + if( IsDebuggerPresent() ) + ::DebugBreak(); + #endif + } + + THREAD_SAFE + CUSTOM private static void Internal_Log (int level, string msg, [Writable]Object obj) + { + DebugStringToFile (msg.AsUTF8().c_str(), 0, __FILE__, __LINE__, (level==0?kScriptingLog:level==1?kScriptingWarning:kScriptingError) | kMayIgnoreLineNumber, obj.GetInstanceID()); + } + + THREAD_SAFE + CUSTOM private static void Internal_LogException(Exception exception, [Writable]Object obj) + { + Scripting::LogException(exception, obj.GetInstanceID()); + } + + // Logs /message/ to the Unity Console. + CSRAW public static void Log (object message) { Internal_Log (0, message != null ? message.ToString () : "Null", null); } + + // Logs /message/ to the Unity Console. + CSRAW public static void Log (object message, Object context) + { + Internal_Log (0, message != null ? message.ToString () : "Null", context); + } + + // A variant of Debug.Log that logs an error message to the console. + CSRAW public static void LogError (object message) { Internal_Log (2, message != null ? message.ToString () : "Null", null); } + + // A variant of Debug.Log that logs an error message to the console. + CSRAW public static void LogError (object message, Object context) { Internal_Log (2,message.ToString (), context); } + + // Clears errors from the developer console. + CUSTOM public static void ClearDeveloperConsole () + { + #if UNITY_HAS_DEVELOPER_CONSOLE + if (GetDeveloperConsolePtr() != NULL) GetDeveloperConsolePtr()->Clear(); + #endif + } + + // Opens or closes developer console. + CUSTOM_PROP static bool developerConsoleVisible + { + #if UNITY_HAS_DEVELOPER_CONSOLE + if (GetDeveloperConsolePtr() != NULL) return GetDeveloperConsolePtr()->IsVisible(); + #endif + return false; + } + { + #if UNITY_HAS_DEVELOPER_CONSOLE + if (GetDeveloperConsolePtr() != NULL) return GetDeveloperConsolePtr()->SetOpen(value); + #endif + } + + // A variant of Debug.Log that logs an error message from an exception to the console. + CSRAW public static void LogException(Exception exception) { Internal_LogException(exception, null); } + + // A variant of Debug.Log that logs an error message to the console. + CSRAW public static void LogException(Exception exception, Object context) { Internal_LogException(exception, context); } + + CONDITIONAL UNITY_EDITOR + CUSTOM internal static void LogPlayerBuildError (string message,string file,int line, int column) + { + DebugStringToFilePostprocessedStacktrace (message.AsUTF8().c_str(), "", "", 1, file.AsUTF8().c_str(), line, kScriptingError | kDontExtractStacktrace, 0, GetBuildErrorIdentifier()); + } + + // A variant of Debug.Log that logs a warning message to the console. + CSRAW public static void LogWarning (object message) { Internal_Log (1,message.ToString (), null); } + + // A variant of Debug.Log that logs a warning message to the console. + CSRAW public static void LogWarning (object message, Object context) { Internal_Log (1,message.ToString (), context); } + + // In the Build Settings dialog there is a check box called "Development Build". + CUSTOM_PROP static bool isDebugBuild { return GetBuildSettings().isDebugBuild; } + + CUSTOM internal static void OpenConsoleFile() { DeveloperConsole_OpenConsoleFile(); } +END + +CSRAW } diff --git a/Runtime/Export/UnityEngineDisplay.txt b/Runtime/Export/UnityEngineDisplay.txt new file mode 100644 index 0000000..67c871c --- /dev/null +++ b/Runtime/Export/UnityEngineDisplay.txt @@ -0,0 +1,127 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Graphics/RenderTexture.h" +#include "Runtime/Graphics/DisplayManager.h" + +CSRAW +using System; +using System.Collections; + +namespace UnityEngine +{ +CLASS Display + + CSRAW + internal IntPtr nativeDisplay; + internal Display() { + #if UNITY_FLASH + this.nativeDisplay = new IntPtr(); + #else + this.nativeDisplay = new IntPtr(0); + #endif + } + internal Display(IntPtr nativeDisplay) { this.nativeDisplay = nativeDisplay; } + + CSRAW public int renderingWidth { get + { + int w=0, h=0; + GetRenderingExtImpl(nativeDisplay, out w, out h); + return w; + } + } + CSRAW public int renderingHeight { get + { + int w=0, h=0; + GetRenderingExtImpl(nativeDisplay, out w, out h); + return h; + } + } + + CSRAW public int systemWidth { get + { + int w=0, h=0; + GetSystemExtImpl(nativeDisplay, out w, out h); + return w; + } + } + CSRAW public int systemHeight { get + { + int w=0, h=0; + GetSystemExtImpl(nativeDisplay, out w, out h); + return h; + } + } + + CSRAW public RenderBuffer colorBuffer { get + { + RenderBuffer color, depth; + GetRenderingBuffersImpl(nativeDisplay, out color, out depth); + return color; + } + } + + CSRAW public RenderBuffer depthBuffer { get + { + RenderBuffer color, depth; + GetRenderingBuffersImpl(nativeDisplay, out color, out depth); + return depth; + } + } + + CSRAW public void SetRenderingResolution(int w, int h) + { + SetRenderingResolutionImpl(nativeDisplay, w, h); + } + + public static Display[] displays = new Display[1] { new Display() }; + + private static Display _mainDisplay = displays[0]; + public static Display main { get{return _mainDisplay;} } + + CSRAW private static void RecreateDisplayList(IntPtr[] nativeDisplay) + { + Display.displays = new Display[nativeDisplay.Length]; + for(int i = 0 ; i < nativeDisplay.Length ; ++i) + Display.displays[i] = new Display(nativeDisplay[i]); + + _mainDisplay = displays[0]; + } + + CSRAW private static void FireDisplaysUpdated() + { + if(onDisplaysUpdated != null) + onDisplaysUpdated(); + } + + CSRAW public delegate void DisplaysUpdatedDelegate(); + CSRAW public static event DisplaysUpdatedDelegate onDisplaysUpdated = null; + + + + CUSTOM private static void GetSystemExtImpl(IntPtr nativeDisplay, out int w, out int h) + { + UnityDisplayManager_DisplaySystemResolution(nativeDisplay,w,h); + } + + CUSTOM private static void GetRenderingExtImpl(IntPtr nativeDisplay, out int w, out int h) + { + UnityDisplayManager_DisplaySystemResolution(nativeDisplay,w,h); + } + + CUSTOM private static void GetRenderingBuffersImpl(IntPtr nativeDisplay, out RenderBuffer color, out RenderBuffer depth) + { + UnityDisplayManager_DisplayRenderingBuffers(nativeDisplay, &color->m_BufferPtr, &depth->m_BufferPtr); + } + + CUSTOM private static void SetRenderingResolutionImpl(IntPtr nativeDisplay, int w, int h) + { + UnityDisplayManager_SetRenderingResolution(nativeDisplay,w,h); + } + +END + +CSRAW } + diff --git a/Runtime/Export/UnityEngineFlash.txt b/Runtime/Export/UnityEngineFlash.txt new file mode 100644 index 0000000..2df69d4 --- /dev/null +++ b/Runtime/Export/UnityEngineFlash.txt @@ -0,0 +1,80 @@ +CSRAW +using System; +using System.Diagnostics; + +namespace UnityEngine.Flash +{ +// Inline ActionScript support. +CSRAW [NotConverted] +CLASS ActionScript + + // Causes an import directive to be emitted in the ActionScript code generated for the current type. + CSRAW [Conditional("UNITY_FLASH")] + CSRAW public static void Import(string package) + { + } + + // Emits a block of ActionScript code in the current method translating variable and field references to their ActionScript names. + CSRAW [Conditional("UNITY_FLASH")] + CSRAW public static void Statement(string formatString, params object[] arguments) + { + } + + // Emits an ActionScript expression translating variable and field references to their ActionScript names. + CSRAW public static T Expression<T>(string formatString, params object[] arguments) + { + throw new InvalidOperationException(); + } +END + +CSRAW +} + +namespace UnityEngine.Flash +{ +// Runtime FlashPlayer support. +CLASS FlashPlayer + + // Get a string representing the version of the Flash Player which the current project has been compiled against. + CSRAW public static String TargetVersion { + get { return GetUnityAppConstants("TargetFlashPlayerVersion"); } + } + + // Get a string representing the version of the SWF which the current project has been compiled against. + CSRAW public static String TargetSwfVersion { + get { return GetUnityAppConstants("TargetSwfVersion"); } + } + + CSRAW internal static String GetUnityAppConstants(String name) + { + ActionScript.Import("com.unity.UnityNative"); + var value = ActionScript.Expression<String>("UnityNative.getUnityAppConstants()[{0}]", name); + return value; + } +END + +CSRAW +} + +namespace UnityEngine +{ + +// Instructs the build pipeline not to convert a type or member to the target platform. +CSRAW [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] +CLASS NotConvertedAttribute : Attribute +END + +// Instructs the build pipeline not to try and validate a type or member for the flash platform. +CSRAW [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field)] +CSRAW [NotConverted] +CLASS NotFlashValidatedAttribute : Attribute +END + +// Prevent name mangling of constructors, methods, fields and properties. +CSRAW [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field)] +CSRAW [NotConverted] +CLASS NotRenamedAttribute : Attribute +END + +CSRAW +} diff --git a/Runtime/Export/UnityEngineGameObject.txt b/Runtime/Export/UnityEngineGameObject.txt new file mode 100644 index 0000000..1915db0 --- /dev/null +++ b/Runtime/Export/UnityEngineGameObject.txt @@ -0,0 +1,439 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/BaseClasses/Tags.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Export/GameObjectExport.h" +#if ENABLE_AUDIO +#include "Runtime/Audio/AudioSource.h" +#endif + +#include "Runtime/Animation/Animation.h" +#include "Runtime/Camera/Camera.h" + +#if ENABLE_PHYSICS +#include "Runtime/Dynamics/RigidBody.h" +#include "Runtime/Dynamics/ConstantForce.h" +#include "Runtime/Dynamics/HingeJoint.h" +#include "Runtime/Dynamics/Collider.h" +#endif +#if ENABLE_2D_PHYSICS +#include "Runtime/Physics2D/RigidBody2D.h" +#include "Runtime/Physics2D/Collider2D.h" +#endif +#include "Runtime/Camera/Light.h" +#include "Runtime/Filters/Renderer.h" +#if ENABLE_NETWORK +#include "Runtime/Network/NetworkView.h" +#endif +#include "Runtime/Camera/RenderLayers/GUIText.h" +#include "Runtime/Camera/RenderLayers/GUITexture.h" +#include "Runtime/Filters/Particles/ParticleEmitter.h" +#include "Runtime/Graphics/ParticleSystem/ParticleSystem.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Misc/GOCreation.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/GetComponent.h" +#include "Runtime/Scripting/Scripting.h" + + +using namespace Unity; + +/* + Mono defines a bool as either 1 or 2 bytes. + On windows a bool on the C++ side needs to be 2 bytes. + We use the typemap to map bool's to short's. + When using the C++ keyword and you want to export a bool value + to mono you have to use a short on the C++ side. +*/ + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + + + +// Base class for all entities in Unity scenes. +CSRAW +CLASS GameObject : Object + + // Creates a game object with a primitive mesh renderer and appropriate collider. + CSRAW + CUSTOM static GameObject CreatePrimitive (PrimitiveType type) + { + return Scripting::ScriptingWrapperFor(CreatePrimitive(type)); + } + + + + // Returns the component of Type /type/ if the game object has one attached, null if it doesn't. You can access both builtin components or scripts with this function. + + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CUSTOM Component GetComponent (Type type) { return ScriptingGetComponentOfType (*self, type); } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T GetComponent<T>() where T : Component { return GetComponent(typeof(T)) as T; } + #endif + + + // Returns the component with name /type/ if the game object has one attached, null if it doesn't. + + CSRAW + public Component GetComponent (string type) { return GetComponentByName(type); } + CUSTOM private Component GetComponentByName (string type) { return Scripting::GetScriptingWrapperOfComponentOfGameObject (*self, type); } + + + + + // Returns the component of Type /type/ in the GameObject or any of its children using depth first search. + + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CSRAW public Component GetComponentInChildren (Type type) + { + if( activeInHierarchy ) { + + Component attachedCom = GetComponent (type); + if ( attachedCom != null ) + return attachedCom; + } + + Transform transform = this.transform; + if ( transform != null ) + { + foreach (Transform child in transform) + { + Component childCom = child.gameObject.GetComponentInChildren (type); + if (childCom != null) + return childCom; + } + } + + return null; + } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T GetComponentInChildren<T>() where T : Component { return GetComponentInChildren(typeof(T)) as T; } + #endif + + // Editor only API that specifies if a game object is static. + AUTO_PROP bool isStatic GetIsStaticDeprecated SetIsStaticDeprecated + + CUSTOM_PROP internal bool isStaticBatchable { return self->IsStaticBatchable (); } + + // Returns all components of Type /type/ in the GameObject. + + CSRAW [CanConvertToFlash] + CSRAW public Component[] GetComponents (Type type) { return (Component[])GetComponentsInternal (type, false, false, true); } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T[] GetComponents<T>() where T : Component + { + return (T[]) GetComponentsInternal(typeof(T), true, false, true); + } + #endif + + // Returns all components of Type /type/ in the GameObject or any of its children. + + CSRAW public Component[] GetComponentsInChildren (Type type, bool includeInactive = false) + { + return (Component[])GetComponentsInternal(type, false, true, includeInactive); + } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T[] GetComponentsInChildren<T>(bool includeInactive) where T : Component + { + return (T[])GetComponentsInternal(typeof(T), true, true, includeInactive); + } + #endif + + CSRAW + #if ENABLE_GENERICS + // Manually supplying the overload because lucas cannot figure out how to patch cspreprocess to add template support to the overload generation code. + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T[] GetComponentsInChildren<T>() where T : Component { return GetComponentsInChildren<T>(false); } + #endif + + + + CUSTOM private Component[] GetComponentsInternal(Type type, bool isGenericTypeArray, bool recursive, bool includeInactive) + { + DISALLOW_IN_CONSTRUCTOR return ScriptingGetComponentsOfType (*self, type, isGenericTypeArray, recursive, includeInactive); + } + + + C++RAW + #define FASTGO_QUERY_COMPONENT(x) GameObject& go = *self; return Scripting::GetComponentObjectToScriptingObject (go.QueryComponent (x), go, ClassID (x)); + + + // The [[Transform]] attached to this GameObject. (null if there is none attached) + CSRAW + CUSTOM_PROP Transform transform { FASTGO_QUERY_COMPONENT(Transform) } + + CONDITIONAL ENABLE_PHYSICS + // The [[Rigidbody]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP Rigidbody rigidbody { FASTGO_QUERY_COMPONENT(Rigidbody) } + + CONDITIONAL ENABLE_2D_PHYSICS + CUSTOM_PROP Rigidbody2D rigidbody2D { FASTGO_QUERY_COMPONENT(Rigidbody2D) } + + // The [[Camera]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP Camera camera { FASTGO_QUERY_COMPONENT(Camera) } + + // The [[Light]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP Light light { FASTGO_QUERY_COMPONENT(Light) } + + // The [[Animation]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP Animation animation { FASTGO_QUERY_COMPONENT(Animation) } + + // The [[ConstantForce]] attached to this GameObject (RO). (null if there is none attached) + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP ConstantForce constantForce { FASTGO_QUERY_COMPONENT(ConstantForce) } + + // The [[Renderer]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP Renderer renderer { FASTGO_QUERY_COMPONENT(Renderer) } + + // The [[AudioSource]] attached to this GameObject (RO). (null if there is none attached) + CONDITIONAL ENABLE_AUDIO + CUSTOM_PROP AudioSource audio { FASTGO_QUERY_COMPONENT(AudioSource) } + + // The [[GUIText]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP GUIText guiText { FASTGO_QUERY_COMPONENT(GUIText) } + + CONDITIONAL ENABLE_NETWORK + // The [[NetworkView]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP NetworkView networkView + { + #if ENABLE_NETWORK + FASTGO_QUERY_COMPONENT(NetworkView) + #else + return SCRIPTING_NULL; + #endif + } + + FLUSHCONDITIONS + + CSRAW +#if ENABLE_NETWORK + OBSOLETE warning Please use guiTexture instead +#endif + CUSTOM_PROP GUIElement guiElement { FASTGO_QUERY_COMPONENT(GUIElement) } + + // The [[GUITexture]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP GUITexture guiTexture { FASTGO_QUERY_COMPONENT(GUITexture) } + + // The [[Collider]] attached to this GameObject (RO). (null if there is none attached) + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP Collider collider { FASTGO_QUERY_COMPONENT(Collider) } + + CONDITIONAL ENABLE_2D_PHYSICS + CUSTOM_PROP Collider2D collider2D { FASTGO_QUERY_COMPONENT(Collider2D) } + + // The [[HingeJoint]] attached to this GameObject (RO). (null if there is none attached) + CONDITIONAL ENABLE_PHYSICS + CUSTOM_PROP HingeJoint hingeJoint { FASTGO_QUERY_COMPONENT(HingeJoint) } + + // The [[ParticleEmitter]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP ParticleEmitter particleEmitter { FASTGO_QUERY_COMPONENT(ParticleEmitter) } + + // The [[ParticleSystem]] attached to this GameObject (RO). (null if there is none attached) + CUSTOM_PROP ParticleSystem particleSystem { FASTGO_QUERY_COMPONENT(ParticleSystem) } + + // The layer the game object is in. A layer is in the range [0...31] + AUTO_PROP int layer GetLayer SetLayer + + OBSOLETE warning GameObject.active is obsolete. Use GameObject.SetActive(), GameObject.activeSelf or GameObject.activeInHierarchy. + CSRAW + CUSTOM_PROP bool active { return self->IsActive (); } { self->SetSelfActive (value); } + + // Activates/Deactivates the GameObject. + CUSTOM void SetActive (bool value) { self->SetSelfActive (value); } + + // The local active state of this GameObject. + CUSTOM_PROP public bool activeSelf { return self->IsSelfActive (); } + + // Is the GameObject active in the scene? + CUSTOM_PROP public bool activeInHierarchy { return self->IsActive (); } + + OBSOLETE warning gameObject.SetActiveRecursively() is obsolete. Use GameObject.SetActive(), which is now inherited by children. + CUSTOM public void SetActiveRecursively (bool state) + { + self->SetActiveRecursivelyDeprecated (state); + } + + // The tag of this game object. + CUSTOM_PROP string tag + { + const string& tag = TagToString (self->GetTag ()); + if (!tag.empty ()) + return scripting_string_new(tag); + else + { + Scripting::RaiseMonoException ("GameObject has undefined tag!"); + return SCRIPTING_NULL; + } + } + { + self->SetTag (ExtractTagThrowing (value)); + } + + // Is this game object tagged with /tag/? + CUSTOM public bool CompareTag (string tag) + { + return ExtractTagThrowing (tag) == self->GetTag (); + } + + //*undocumented* + CUSTOM static GameObject FindGameObjectWithTag (string tag) + { + DISALLOW_IN_CONSTRUCTOR + int tagInt = ExtractTagThrowing (tag); + return Scripting::ScriptingWrapperFor(FindGameObjectWithTag (tagInt)); + } + + // Returns one active GameObject tagged /tag/. Returns null if no GameObject was found. + CSRAW static public GameObject FindWithTag (string tag) + { + return FindGameObjectWithTag(tag); + } + + // Returns a list of active GameObjects tagged /tag/. Returns null if no GameObject was found. + CUSTOM static GameObject[] FindGameObjectsWithTag (string tag) + { + DISALLOW_IN_CONSTRUCTOR + static vector<GameObject*> go; go.clear (); + int tagInt = ExtractTagThrowing (tag); + FindGameObjectsWithTag (tagInt, go); + ScriptingClassPtr goClass = Scripting::ClassIDToScriptingType (ClassID (GameObject)); + return CreateScriptingArrayFromUnityObjects(go,goClass); + } + + // Calls the method named /methodName/ on every [[MonoBehaviour]] in this game object and on every ancestor of the behaviour + CUSTOM void SendMessageUpwards (string methodName, object value = null, SendMessageOptions options = SendMessageOptions.RequireReceiver) + { + Scripting::SendScriptingMessageUpwards(*self, methodName, value, options); + } + + //*undocumented* Function is for convenience and avoid coming mistakes. + CSRAW public void SendMessageUpwards (string methodName, SendMessageOptions options) + { + SendMessageUpwards (methodName, null, options); + } + + // Calls the method named /methodName/ on every [[MonoBehaviour]] in this game object. + CUSTOM void SendMessage (string methodName, object value = null, SendMessageOptions options = SendMessageOptions.RequireReceiver) + { + Scripting::SendScriptingMessage(*self, methodName, value, options); + } + + //*undocumented* Function is for convenience and avoid coming mistakes. + CSRAW public void SendMessage (string methodName, SendMessageOptions options) + { + SendMessage (methodName, null, options); + } + + // Calls the method named /methodName/ on every [[MonoBehaviour]] in this game object or any of its children. + CUSTOM void BroadcastMessage (string methodName, object parameter = null, SendMessageOptions options = SendMessageOptions.RequireReceiver) + { + Scripting::BroadcastScriptingMessage(*self, methodName, parameter, options); + } + + //*undocumented* Function is for convenience and avoid coming mistakes. + CSRAW public void BroadcastMessage (string methodName, SendMessageOptions options) + { + BroadcastMessage (methodName, null, options); + } + + // Adds a component class named /className/ to the game object. + + CUSTOM Component AddComponent (string className) { return MonoAddComponent (*self, className.AsUTF8().c_str()); } + + // Adds a component class of type /componentType/ to the game object. C# Users can use a generic version + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CSRAW public Component AddComponent (Type componentType) + { + return Internal_AddComponentWithType(componentType); + } + + CSRAW + CUSTOM private Component Internal_AddComponentWithType (Type componentType) + { + return MonoAddComponentWithType(*self, componentType); + } + + CSRAW + #if ENABLE_GENERICS + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public T AddComponent<T>() where T : Component + { + return AddComponent(typeof(T)) as T; + } + #endif + + CUSTOM private static void Internal_CreateGameObject ([Writable]GameObject mono, string name) + { + DISALLOW_IN_CONSTRUCTOR + GameObject* go = MonoCreateGameObject (name.IsNull() ? NULL : name.AsUTF8().c_str() ); + Scripting::ConnectScriptingWrapperToObject (mono.GetScriptingObject(), go); + } + + // Creates a new game object, named __name__. + CSRAW public GameObject (string name) { Internal_CreateGameObject (this, name); } + + // Creates a new game object. + CSRAW public GameObject () { Internal_CreateGameObject (this, null); } + + // Creates a game object and attaches the specified components. + CSRAW public GameObject (string name, params Type[] components) + { + Internal_CreateGameObject (this, name); + foreach (Type t in components) + AddComponent (t); + } + + OBSOLETE warning gameObject.PlayAnimation is not supported anymore. Use animation.Play + CUSTOM void PlayAnimation (AnimationClip animation) { ErrorString("gameObject.PlayAnimation(); is not supported anymore. Use animation.Stop();"); } + + OBSOLETE warning gameObject.StopAnimation is not supported anymore. Use animation.Stop + CUSTOM void StopAnimation () { ErrorString("gameObject.StopAnimation(); is not supported anymore. Use animation.Stop();"); } + + // Finds a game object by /name/ and returns it. + CSRAW + CUSTOM static GameObject Find (string name) + { + DISALLOW_IN_CONSTRUCTOR + Transform* transform = FindActiveTransformWithPath (name.AsUTF8().c_str ()); + GameObject* go = NULL; + if (transform) + go = transform->GetGameObjectPtr (); + return Scripting::ScriptingWrapperFor (go); + } + + //*undocumented - just for convenience + CSRAW public GameObject gameObject { get { return this; } } +} +END + + diff --git a/Runtime/Export/UnityEngineInput.txt b/Runtime/Export/UnityEngineInput.txt new file mode 100644 index 0000000..04e421b --- /dev/null +++ b/Runtime/Export/UnityEngineInput.txt @@ -0,0 +1,700 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Input/InputManager.h" +#include "Runtime/Input/GetInput.h" +#include "Runtime/Input/LocationService.h" +#include "Runtime/Misc/BuildSettings.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/Scripting.h" + +#if SUPPORT_REPRODUCE_LOG +#include "Runtime/Misc/ReproductionLog.h" +#endif + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + + +// Describes phase of a finger touch. +ENUM TouchPhase + // A finger touched the screen. + Began = 0, + // A finger moved on the screen. + Moved = 1, + // A finger is touching the screen but hasn't moved. + Stationary = 2, + // A finger was lifted from the screen. This is the final phase of a touch. + Ended = 3, + // The system cancelled tracking for the touch, as when (for example) the user puts the device to her face or more than five touches happened simultaneously. This is the final phase of a touch. + Canceled = 4 +END + +// Controls IME input +ENUM IMECompositionMode + // Enable IME input only when a text field is selected (default). + Auto = 0, + // Enable IME input. + On = 1, + // Disable IME input. + Off = 2 +END + +// Structure describing status of a finger touching the screen. +STRUCT Touch + CSRAW + private int m_FingerId; + private Vector2 m_Position; + private Vector2 m_RawPosition; +#if ENABLE_NEW_EVENT_SYSTEM + private Vector2 m_OldPosition; + private Vector2 m_PositionDelta; + private Vector2 m_ScrollDelta; + private Vector3 m_WorldPosition; + private float m_TimeDelta; + private int m_TapCount; + private TouchPhase m_Phase; + private IntPtr m_Hover; + private IntPtr m_Press; +#else + private Vector2 m_PositionDelta; + private float m_TimeDelta; + private int m_TapCount; + private TouchPhase m_Phase; +#endif + + // The unique index for touch. + CSRAW public int fingerId { get { return m_FingerId; } } + + // The position of the touch. + CSRAW public Vector2 position { get { return m_Position; } } + + // Raw Position of the touch (taken from os without tweaking) + CSRAW public Vector2 rawPosition { get { return m_RawPosition; } } + + // The position delta since last change. + CSRAW public Vector2 deltaPosition { get { return m_PositionDelta; } } + + // The scroll delta position. X = horizontal, Y = vertical. + CONDITIONAL ENABLE_NEW_EVENT_SYSTEM + CSRAW public Vector2 deltaScroll { get { return m_ScrollDelta; } } + + // The world position of the touch (raycast into the screen hitting a collider). + CONDITIONAL ENABLE_NEW_EVENT_SYSTEM + public Vector3 worldPosition { get { return m_WorldPosition; } } + + // Amount of time passed since last change. + CSRAW public float deltaTime { get { return m_TimeDelta; } } + + // Number of taps. + CSRAW public int tapCount { get { return m_TapCount; } } + + // Describes the phase of the touch. + CSRAW public TouchPhase phase { get { return m_Phase; } } + + CUSTOM static private GameObject Internal_GetPtr (IntPtr ptr) { return Scripting::ScriptingWrapperFor((GameObject*)ptr); } + + // The object the mouse is hovering over (only works for mouse events) + CONDITIONAL ENABLE_NEW_EVENT_SYSTEM + CSRAW public GameObject hoveredObject { get { return Internal_GetPtr(m_Hover); } } + + // The object this mouse or touch has pressed on + CONDITIONAL ENABLE_NEW_EVENT_SYSTEM + CSRAW public GameObject pressedObject { get { return Internal_GetPtr(m_Press); } } +END + +// Describes physical orientation of the device as determined by the OS. +ENUM DeviceOrientation + // The orientation of the device cannot be determined. + Unknown = 0, + // The device is in portrait mode, with the device held upright and the home button at the bottom. + Portrait = 1, + // The device is in portrait mode but upside down, with the device held upright and the home button at the top. + PortraitUpsideDown = 2, + // The device is in landscape mode, with the device held upright and the home button on the right side. + LandscapeLeft = 3, + // The device is in landscape mode, with the device held upright and the home button on the left side. + LandscapeRight = 4, + // The device is held parallel to the ground with the screen facing upwards. + FaceUp = 5, + // The device is held parallel to the ground with the screen facing downwards. + FaceDown = 6 +END + +// Structure describing acceleration status of the device. +STRUCT AccelerationEvent + CSRAW private Vector3 m_Acceleration; + CSRAW private float m_TimeDelta; + + // Value of acceleration. + CSRAW public Vector3 acceleration { get { return m_Acceleration; } } + + // Amount of time passed since last accelerometer measurement. + CSRAW public float deltaTime { get { return m_TimeDelta; } } +END + +// Interface into the Gyroscope. +CLASS Gyroscope + + CSRAW internal Gyroscope(int index) { + m_GyroIndex = index; + } + + CSRAW private int m_GyroIndex; + CUSTOM private static Vector3 rotationRate_Internal(int idx) { return GetGyroRotationRate(idx); } + CUSTOM private static Vector3 rotationRateUnbiased_Internal(int idx) { return GetGyroRotationRateUnbiased(idx); } + CUSTOM private static Vector3 gravity_Internal(int idx) { return GetGravity(idx); } + CUSTOM private static Vector3 userAcceleration_Internal(int idx) { return GetUserAcceleration(idx); } + CUSTOM private static Quaternion attitude_Internal(int idx) { return GetAttitude(idx); } + CUSTOM private static bool getEnabled_Internal(int idx) { return IsGyroEnabled(idx); } + CUSTOM private static void setEnabled_Internal(int idx, bool enabled) { SetGyroEnabled(idx, enabled); } + CUSTOM private static float getUpdateInterval_Internal(int idx) { return GetGyroUpdateInterval(idx); } + CUSTOM private static void setUpdateInterval_Internal(int idx, float interval) { SetGyroUpdateInterval(idx, interval); } + + // Returns rotation rate as measured by the device's gyroscope. + CSRAW public Vector3 rotationRate { get { return rotationRate_Internal(m_GyroIndex); } } + + // Returns unbiased rotation rate as measured by the device's gyroscope. + CSRAW public Vector3 rotationRateUnbiased { get { return rotationRateUnbiased_Internal(m_GyroIndex); } } + + // Returns the gravity acceleration vector expressed in the device's reference frame. + CSRAW public Vector3 gravity { get { return gravity_Internal(m_GyroIndex); } } + + // Returns the acceleration that the user is giving to the device. + CSRAW public Vector3 userAcceleration { get { return userAcceleration_Internal(m_GyroIndex); } } + + // Returns the attitude of the device. + CSRAW public Quaternion attitude { get { return attitude_Internal(m_GyroIndex); } } + + // Sets or retrieves status of this gyroscope. + CSRAW public bool enabled { get { return getEnabled_Internal(m_GyroIndex); } set { setEnabled_Internal(m_GyroIndex, value); } } + + // Sets or retrieves gyroscope interval in seconds. + CSRAW public float updateInterval { get { return getUpdateInterval_Internal(m_GyroIndex); } set { setUpdateInterval_Internal(m_GyroIndex, value); } } + +END + +// Structure describing device location. +STRUCT LocationInfo + CSRAW private double m_Timestamp; + CSRAW private float m_Latitude; + CSRAW private float m_Longitude; + CSRAW private float m_Altitude; + CSRAW private float m_HorizontalAccuracy; + CSRAW private float m_VerticalAccuracy; + + // Geographical device location latitude + CSRAW public float latitude { get { return m_Latitude; } } + + // Geographical device location latitude + CSRAW public float longitude { get { return m_Longitude; } } + + // Geographical device location altitude + CSRAW public float altitude { get { return m_Altitude; } } + + // Horizontal accuracy of the location + CSRAW public float horizontalAccuracy { get { return m_HorizontalAccuracy; } } + + // Vertical accuracy of the location + CSRAW public float verticalAccuracy { get { return m_VerticalAccuracy; } } + + // Timestamp (in seconds since 1970) when location was last time updated + CSRAW public double timestamp { get { return m_Timestamp; } } +END + +// Describes location service status. +ENUM LocationServiceStatus + // Location service is stopped. + Stopped = 0, + // Location service is initializing, some time later it will switch to + Initializing = 1, + // Location service is running and locations could be queried. + Running = 2, + // Location service failed (user denied access to location service). + Failed = 3 +END + +// Interface into location functionality. +CLASS LocationService + // Specifies whether location service is enabled in user settings. + CUSTOM_PROP bool isEnabledByUser + { + return LocationService::IsServiceEnabledByUser (); + } + + // Returns location service status. + CUSTOM_PROP LocationServiceStatus status + { + return LocationService::GetLocationStatus (); + } + + // Last measured device geographical location. + CUSTOM_PROP LocationInfo lastData + { + if (LocationService::GetLocationStatus () != kLocationServiceRunning) + printf_console ("Location service updates are not enabled. Check Handheld.locationServiceStatus before querying last location.\n"); + + return LocationService::GetLastLocation (); + } + + // Starts location service updates. Last location coordinates could be + CUSTOM void Start (float desiredAccuracyInMeters = 10f, float updateDistanceInMeters = 10f) + { + LocationService::SetDesiredAccuracy (desiredAccuracyInMeters); + LocationService::SetDistanceFilter (updateDistanceInMeters); + LocationService::StartUpdatingLocation (); + } + + // Stops location service updates. This could be useful for saving battery + CUSTOM void Stop () + { + LocationService::StopUpdatingLocation (); + } +END + +// Interface into compass functionality. +CLASS Compass + // The heading in degrees relative to the magnetic North Pole. + CUSTOM_PROP public float magneticHeading + { + return LocationService::GetLastHeading().magneticHeading; + } + + // The heading in degrees relative to the geographic North Pole. + CUSTOM_PROP public float trueHeading + { + return LocationService::GetLastHeading().trueHeading; + } + + // The raw geomagnetic data measured in microteslas. (RO) + CUSTOM_PROP public Vector3 rawVector + { + return LocationService::GetLastHeading().raw; + } + + // Timestamp (in seconds since 1970) when the heading was last time updated. (RO) + CUSTOM_PROP public double timestamp + { + return LocationService::GetLastHeading().timestamp; + } + + // Used to enable or disable compass. Note, that if you want @@Input.compass.trueHeading@@ property to contain a valid value, you must also enable location updates by calling @@Input.location.Start()@@. + CUSTOM_PROP public bool enabled + { + return LocationService::IsHeadingUpdatesEnabled(); + } + { + LocationService::SetHeadingUpdatesEnabled(value); + } +END + +// Interface into the Input system. +CLASS Input + + CUSTOM private static int mainGyroIndex_Internal() { return GetGyro(); } + + CONDITIONAL ENABLE_MONO || UNITY_WINRT + CSRAW private static Gyroscope m_MainGyro = null; + + CUSTOM private static bool GetKeyInt (int key) + { + if (key > 0 && key < kKeyAndJoyButtonCount) + return GetInputManager ().GetKey (key); + else if (key == 0) + return false; + else + { + Scripting::RaiseMonoException ("Invalid KeyCode enum."); + return false; + } + } + + CUSTOM private static bool GetKeyString (string name) + { + string cname = name; + int key = StringToKey (cname); + if (key != 0) + return GetInputManager ().GetKey (key); + else + { + Scripting::RaiseMonoException ("Input Key named: %s is unknown", cname.c_str()); + return false; + } + } + + CUSTOM private static bool GetKeyUpInt (int key) + { + if (key > 0 && key < kKeyAndJoyButtonCount) + return GetInputManager ().GetKeyUp (key); + else if (key == 0) + return false; + else + { + Scripting::RaiseMonoException ("Invalid KeyCode enum."); + return false; + } + } + + CUSTOM private static bool GetKeyUpString (string name) + { + string cname = name; + int key = StringToKey (cname); + if (key != 0) + return GetInputManager ().GetKeyUp (key); + else + { + Scripting::RaiseMonoException ("Input Key named: %s is unknown", cname.c_str()); + return false; + } + } + + CUSTOM private static bool GetKeyDownInt (int key) + { + if (key > 0 && key < kKeyAndJoyButtonCount) + return GetInputManager ().GetKeyDown (key); + else if (key == 0) + return false; + else + { + Scripting::RaiseMonoException ("Invalid KeyCode enum."); + return false; + } + } + + CUSTOM private static bool GetKeyDownString (string name) + { + string cname = name; + int key = StringToKey (cname); + if (key != 0) + return GetInputManager ().GetKeyDown (key); + else + { + Scripting::RaiseMonoException ("Input Key named: %s is unknown", cname.c_str()); + return false; + } + } + + C++RAW + static void CheckInputAxis (const string& name, bool button) + { + #if !GAMERELEASE + if (!GetInputManager ().HasAxisOrButton (name)) + { + if (button) + Scripting::RaiseMonoException ("Input Button %s is not setup.\n To change the input settings use: Edit -> Project Settings -> Input", name.c_str()); + else + Scripting::RaiseMonoException ("Input Axis %s is not setup.\n To change the input settings use: Edit -> Project Settings -> Input", name.c_str()); + } + + #endif + } + + + // Returns the value of the virtual axis identified by /axisName/. + CUSTOM static float GetAxis (string axisName) + { + string name = axisName; + CheckInputAxis (name, false); + return GetInputManager ().GetAxis (name); + } + + + // Returns the value of the virtual axis identified by /axisName/ with no smoothing filtering applied. + CUSTOM static float GetAxisRaw (string axisName) + { + string name = axisName; + CheckInputAxis (name, false); + return GetInputManager ().GetAxisRaw (name); + } + + // Returns true while the virtual button identified by /buttonName/ is held down. + CUSTOM static bool GetButton (string buttonName) + { + string name = buttonName; + CheckInputAxis (name, true); + return GetInputManager ().GetButton (name); + } + + // This property controls if input sensors should be compensated for screen orientation. + CUSTOM_PROP static bool compensateSensors { return IsCompensatingSensors(); } { SetCompensatingSensors(value); } + + OBSOLETE warning isGyroAvailable property is deprecated. Please use SystemInfo.supportsGyroscope instead. + CUSTOM_PROP static bool isGyroAvailable { return IsGyroAvailable(); } + + // Returns default gyroscope. + CONDITIONAL ENABLE_MONO || UNITY_WINRT + CSRAW public static Gyroscope gyro { get { if (m_MainGyro == null) m_MainGyro = new Gyroscope(mainGyroIndex_Internal()); return m_MainGyro; } } + + // Returns true during the frame the user pressed down the virtual button identified by /buttonName/. + CUSTOM static bool GetButtonDown (string buttonName) + { + string name = buttonName; + CheckInputAxis (name, true); + return GetInputManager ().GetButtonDown (name); + } + + // Returns true the first frame the user releases the virtual button identified by /buttonName/. + CUSTOM static bool GetButtonUp (string buttonName) + { + string name = buttonName; + CheckInputAxis (name, true); + return GetInputManager ().GetButtonUp (name); + } + + // Returns true while the user holds down the key identified by /name/. Think auto fire. + CSRAW public static bool GetKey (string name) + { + return GetKeyString(name); + } + + // Returns true while the user holds down the key identified by the /key/ [[KeyCode]] enum parameter. + CSRAW public static bool GetKey (KeyCode key) + { + return GetKeyInt((int)key); + } + + // Returns true during the frame the user starts pressing down the key identified by /name/. + CSRAW public static bool GetKeyDown (string name) + { + return GetKeyDownString(name); + } + + // Returns true during the frame the user starts pressing down the key identified by the /key/ [[KeyCode]] enum parameter. + CSRAW public static bool GetKeyDown (KeyCode key) + { + return GetKeyDownInt((int)key); + } + + // Returns true during the frame the user releases the key identified by /name/. + CSRAW public static bool GetKeyUp (string name) + { + return GetKeyUpString(name); + } + + // Returns true during the frame the user releases the key identified by the /key/ [[KeyCode]] enum parameter. + CSRAW public static bool GetKeyUp (KeyCode key) + { + return GetKeyUpInt((int)key); + } + + + // Returns an array of strings describing the connected joysticks. + CONDITIONAL ENABLE_MONO || UNITY_METRO + CUSTOM static string[] GetJoystickNames() + { + std::vector<std::string> names; + + GetJoystickNames(names); + + return Scripting::StringVectorToMono(names); + } + + // Returns whether the given mouse button is held down. + CUSTOM static bool GetMouseButton (int button) + { + return GetInputManager ().GetMouseButton (button); + } + + // Returns true during the frame the user pressed the given mouse button. + CUSTOM static bool GetMouseButtonDown (int button) + { + return GetInputManager ().GetMouseButtonDown (button); + } + + // Returns true during the frame the user releases the given mouse button. + CUSTOM static bool GetMouseButtonUp (int button) + { + return GetInputManager ().GetMouseButtonUp (button); + } + + // Resets all input. After ResetInputAxes all axes return to 0 and all buttons return to 0 for one frame. + CUSTOM static void ResetInputAxes () { ResetInput(); } + + // The current mouse position in pixel coordinates. (RO) + CUSTOM_PROP static Vector3 mousePosition + { + Vector2f p = GetInputManager ().GetMousePosition(); + return Vector3f (p.x, p.y, 0.0F); + } + + + CUSTOM_PROP static bool mousePresent + { + #if UNITY_METRO + return GetMousePresent(); + #else + return true; + #endif + } + + CUSTOM_PROP static bool simulateMouseWithTouches + { + return GetInputManager ().GetSimulateMouseWithTouches(); + } + { + GetInputManager ().SetSimulateMouseWithTouches(value); + } + // Is any key or mouse button currently held down? (RO) + CUSTOM_PROP static bool anyKey { return GetInputManager ().GetAnyKey (); } + + // Returns true the first frame the user hits any key or mouse button. (RO) + CUSTOM_PROP static bool anyKeyDown { return GetInputManager ().GetAnyKeyThisFrame (); } + + // Returns the keyboard input entered this frame. (RO) + CUSTOM_PROP static string inputString { return scripting_string_new(GetInputManager ().GetInputString ()); } + + // Last measured linear acceleration of a device in three-dimensional space. (RO) + + CUSTOM_PROP static Vector3 acceleration { return GetAcceleration (); } + + // Returns list of acceleration measurements which occurred during the last frame. (RO) (Allocates temporary variables) + + CSRAW public static AccelerationEvent[] accelerationEvents { get { + int count = accelerationEventCount; + AccelerationEvent[] events = new AccelerationEvent[count]; + for (int q = 0; q < count; ++q) + events[q] = GetAccelerationEvent (q); + return events; + } + } + + // Returns specific acceleration measurement which occurred during last frame. (Does not allocate temporary variables) + + CUSTOM static AccelerationEvent GetAccelerationEvent (int index) + { + Acceleration acc; + if (index >= 0 && index < GetAccelerationCount ()) + GetAcceleration (index, acc); + else + Scripting::RaiseMonoException ("Index out of bounds."); + return acc; + } + // Number of acceleration measurements which occurred during last frame. + + CUSTOM_PROP static int accelerationEventCount { return GetAccelerationCount (); } + + // Returns list of objects representing status of all touches during last frame. (RO) (Allocates temporary variables) + + CSRAW public static Touch[] touches { get { + int count = touchCount; + Touch[] touches = new Touch[count]; + for (int q = 0; q < count; ++q) + touches[q] = GetTouch (q); + return touches; + } + } + + // Returns object representing status of a specific touch. (Does not allocate temporary variables) + CUSTOM static Touch GetTouch (int index) + { + #if ENABLE_NEW_EVENT_SYSTEM + if (index >= 0 && index < GetTouchCount ()) + { + Touch* t = GetTouch(index); + + if (t != NULL) + { + return *t; + } + else + { + Scripting::RaiseMonoException ("GetTouch() failed!"); + } + } + else + { + Scripting::RaiseMonoException ("Index specified to GetTouch() is out of bounds! Must be less than Touch.touchCount."); + } + Touch dummy; + return dummy; + #else + Touch touch; + + if (index >= 0 && index < GetTouchCount ()) + { + if (!GetTouch (index, touch)) + Scripting::RaiseMonoException ("Internal error."); + } + else + Scripting::RaiseMonoException ("Index out of bounds."); + return touch; + #endif //ENABLE_NEW_EVENT_SYSTEM + } + + // Number of touches. Guaranteed not to change throughout the frame. (RO) + + CUSTOM_PROP static int touchCount { return GetTouchCount (); } + + OBSOLETE warning eatKeyPressOnTextFieldFocus property is deprecated, and only provided to support legacy behavior. + // Property indicating whether keypresses are eaten by a textinput if it has focus (default true). + CUSTOM_PROP static bool eatKeyPressOnTextFieldFocus { return GetInputManager().GetEatKeyPressOnTextFieldFocus(); } { return GetInputManager().SetEatKeyPressOnTextFieldFocus(value); } + + // Property indicating whether the system handles multiple touches. + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + CUSTOM_PROP static bool multiTouchEnabled { return IsMultiTouchEnabled (); } { return SetMultiTouchEnabled (value); } + + CSRAW private static LocationService locationServiceInstance; + // Property for accessing device location (handheld devices only). (RO) + CSRAW public static LocationService location { get { + if (locationServiceInstance == null) + locationServiceInstance = new LocationService (); + + return locationServiceInstance; + } + } + + CSRAW private static Compass compassInstance; + // Property for accessing compass (handheld devices only). (RO) + CSRAW public static Compass compass { get { + if (compassInstance == null) + compassInstance = new Compass(); + return compassInstance; + } + } + + // Device physical orientation as reported by OS. (RO) + CUSTOM_PROP static DeviceOrientation deviceOrientation { return GetOrientation(); } + + + OBSOLETE error Use ps3 move API instead + CSRAW public static Quaternion GetRotation (int deviceID) { return Quaternion.identity; } + + OBSOLETE error Use ps3 move API instead + CSRAW public static Vector3 GetPosition (int deviceID) { return Vector3.zero; } + + // Controls enabling and disabling of IME input composition. + CUSTOM_PROP static IMECompositionMode imeCompositionMode + { return GetInputManager().GetIMECompositionMode(); } + { GetInputManager().SetIMECompositionMode (value); } + + // The current IME composition string being typed by the user. + CUSTOM_PROP static string compositionString { return scripting_string_new(GetInputManager ().GetCompositionString ()); } + + // Indicates if the user has an IME keyboard input source selected. + CUSTOM_PROP static bool imeIsSelected { return (GetInputManager().GetIMEIsSelected()); } + + // The current text input position used by IMEs to open windows. + CUSTOM_PROP static Vector2 compositionCursorPos + { return GetInputManager().GetTextFieldCursorPos (); } + { GetInputManager().GetTextFieldCursorPos () = value; } + + // Information about the current mouse or touch event, available during OnInput* series of callbacks. + //CONDITIONAL ENABLE_NEW_EVENT_SYSTEM + //CUSTOM_PROP static Touch currentTouch { return GetInputManager().GetCurrentTouch(); } +END + +CSRAW } diff --git a/Runtime/Export/UnityEngineInternal/TypeInferenceRuleAttribute.cs b/Runtime/Export/UnityEngineInternal/TypeInferenceRuleAttribute.cs new file mode 100644 index 0000000..f2c7fc2 --- /dev/null +++ b/Runtime/Export/UnityEngineInternal/TypeInferenceRuleAttribute.cs @@ -0,0 +1,52 @@ +using System; + +namespace UnityEngineInternal +{ + public enum TypeInferenceRules + { + /// <summary> + /// (typeof(T)) as T + /// </summary> + TypeReferencedByFirstArgument, + + /// <summary> + /// (, typeof(T)) as T + /// </summary> + TypeReferencedBySecondArgument, + + /// <summary> + /// (typeof(T)) as (T) + /// </summary> + ArrayOfTypeReferencedByFirstArgument, + + /// <summary> + /// (T) as T + /// </summary> + TypeOfFirstArgument, + } + + /// <summary> + /// Adds a special type inference rule to a method. + /// </summary> + [Serializable] + [AttributeUsage(AttributeTargets.Method)] + public class TypeInferenceRuleAttribute : Attribute + { + private readonly string _rule; + + public TypeInferenceRuleAttribute(TypeInferenceRules rule) + : this(rule.ToString()) + { + } + + public TypeInferenceRuleAttribute(string rule) + { + _rule = rule; + } + + public override string ToString() + { + return _rule; + } + } +}
\ No newline at end of file diff --git a/Runtime/Export/UnityEngineInternal/WrappedTypes.cs b/Runtime/Export/UnityEngineInternal/WrappedTypes.cs new file mode 100644 index 0000000..54c2444 --- /dev/null +++ b/Runtime/Export/UnityEngineInternal/WrappedTypes.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +namespace UnityEngineInternal +{ + // This is a solution to problem where we cannot use: + // * System.Collections.Stack on WP8 and Metro, because it was stripped from .NET + // * System.Collections.Generic.Stack cannot use on iOS because it creates a dependency to System.dll thus increasing overall executable size +#if UNITY_WINRT + public class GenericStack : Stack<Object> + { + + } +#else + public class GenericStack : System.Collections.Stack + { + + } +#endif + +}
\ No newline at end of file diff --git a/Runtime/Export/UnityEngineLight.txt b/Runtime/Export/UnityEngineLight.txt new file mode 100644 index 0000000..5880e58 --- /dev/null +++ b/Runtime/Export/UnityEngineLight.txt @@ -0,0 +1,133 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Camera/Camera.h" +#include "Runtime/Camera/Light.h" +#include "Runtime/Camera/Skybox.h" +#include "Runtime/Graphics/LightmapSettings.h" +#include "Runtime/Filters/Renderer.h" +#include "Runtime/Camera/IntermediateRenderer.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Shaders/Material.h" +#include "Runtime/Filters/Misc/TextMesh.h" +#include "Runtime/Shaders/Shader.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Camera/LightManager.h" +#include "Runtime/Misc/QualitySettings.h" +#include "Runtime/Camera/RenderSettings.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" + +#include <list> +#include <vector> + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +// Script interface for [[wiki:class-Light|light components]]. +CLASS Light : Behaviour + // The type of the light. + AUTO_PROP LightType type GetType SetType + + // The color of the light. + AUTO_PROP Color color GetColor SetColor + + // The Intensity of a light is multiplied with the Light color. + AUTO_PROP float intensity GetIntensity SetIntensity + + // How this light casts shadows? + AUTO_PROP LightShadows shadows GetShadows SetShadows + + + // Strength of light's shadows + AUTO_PROP float shadowStrength GetShadowStrength SetShadowStrength + + + // Shadow mapping bias + AUTO_PROP float shadowBias GetShadowBias SetShadowBias + + + // Softness of directional light's soft shadows + AUTO_PROP float shadowSoftness GetShadowSoftness SetShadowSoftness + + + // Fadeout speed of directional light's soft shadows + AUTO_PROP float shadowSoftnessFade GetShadowSoftnessFade SetShadowSoftnessFade + + + + // The range of the light. + AUTO_PROP float range GetRange SetRange + + // The angle of the light's spotlight cone in degrees. + AUTO_PROP float spotAngle GetSpotAngle SetSpotAngle + + AUTO_PROP float cookieSize GetCookieSize SetCookieSize + + // The cookie texture projected by the light. + AUTO_PTR_PROP Texture cookie GetCookie SetCookie + + // The [[wiki:class-Flare|flare asset]] to use for this light. + AUTO_PTR_PROP Flare flare GetFlare SetFlare + + // How to render the light. + AUTO_PROP LightRenderMode renderMode GetRenderMode SetRenderMode + + // Has the light been already lightmapped. + AUTO_PROP bool alreadyLightmapped GetActuallyLightmapped SetActuallyLightmapped + + + // This is used to light certain objects in the scene selectively. + AUTO_PROP int cullingMask GetCullingMask SetCullingMask + + // The size of the area light. Editor only. + CONDITIONAL UNITY_EDITOR + AUTO_PROP Vector2 areaSize GetAreaSize SetAreaSize + + FLUSHCONDITIONS + + CSRAW +#if UNITY_EDITOR + OBSOLETE warning Use QualitySettings.pixelLightCount instead. +#endif + CUSTOM_PROP static int pixelLightCount { return GetQualitySettings().GetCurrent().pixelLightCount; } { GetQualitySettings().SetPixelLightCount(value); } + + //*undocumented For terrain engine only + CUSTOM public static Light[] GetLights (LightType type, int layer) + { + UNITY_TEMP_VECTOR(Light*) lightsvector; + + layer = 1 << layer; + LightManager::Lights& lights = GetLightManager().GetAllLights(); + for (LightManager::Lights::iterator i=lights.begin();i != lights.end();i++) + { + Light* light = &*i; + if (!light) + continue; + if (light->GetType() == type && (light->GetCullingMask() & layer) != 0) + lightsvector.push_back(light); + } + + return CreateScriptingArrayFromUnityObjects(lightsvector,Scripting::ClassIDToScriptingType(ClassID(Light))); + } + + OBSOLETE error light.shadowConstantBias was removed, use light.shadowBias + CSRAW public float shadowConstantBias { get { return 0.0f; } set {} } + + OBSOLETE error light.shadowObjectSizeBias was removed, use light.shadowBias + CSRAW public float shadowObjectSizeBias { get { return 0.0f; } set {} } + + OBSOLETE error light.attenuate was removed; all lights always attenuate now + CSRAW public bool attenuate { get { return true; } set {} } + +END + + +CSRAW } diff --git a/Runtime/Export/UnityEngineMonoBehaviour.txt b/Runtime/Export/UnityEngineMonoBehaviour.txt new file mode 100644 index 0000000..69028db --- /dev/null +++ b/Runtime/Export/UnityEngineMonoBehaviour.txt @@ -0,0 +1,350 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/DelayedCallUtility.h" + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// MonoBehaviour is the base class every script derives from. +CSRAW +NONSEALED_CLASS MonoBehaviour : Behaviour + + //*undocumented* + THREAD_SAFE + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + CUSTOM public MonoBehaviour () + { + #if UNITY_EDITOR + if (self.GetInstanceID() == 0) + { + ScriptWarning ("You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all", NULL); + } + #endif + } + + // Update is called every frame, if the MonoBehaviour is enabled. + CSNONE void Update (); + + + // LateUpdate is called every frame, if the [[Behaviour]] is enabled. + CSNONE void LateUpdate (); + + + // This function is called every fixed framerate frame, if the MonoBehaviour is enabled. + CSNONE void FixedUpdate (); + + + // Awake is called when the script instance is being loaded. + CSNONE void Awake (); + + + // Start is called just before any of the Update methods is called the first time. + CSNONE void Start (); + + + // Reset to default values. + CSNONE void Reset (); + + + // OnMouseEnter is called when the mouse entered the [[GUIElement]] or [[Collider]]. + CSNONE void OnMouseEnter (); + + + // OnMouseOver is called every frame while the mouse is over the [[GUIElement]] or [[Collider]]. + CSNONE void OnMouseOver (); + + + // OnMouseExit is called when the mouse is not any longer over the [[GUIElement]] or [[Collider]]. + CSNONE void OnMouseExit (); + + + // OnMouseDown is called when the user has pressed the mouse button while over the [[GUIElement]] or [[Collider]]. + CSNONE void OnMouseDown (); + + // OnMouseUp is called when the user has released the mouse button. + CSNONE void OnMouseUp (); + + + // OnMouseUpAsButton is only called when the mouse is released over the same [[GUIElement]] or [[Collider]] as it was pressed. + CSNONE void OnMouseUpAsButton (); + + + // OnMouseDrag is called when the user has clicked on a [[GUIElement]] or [[Collider]] and is still holding down the mouse. + CSNONE void OnMouseDrag (); + + // OnTriggerEnter is called when the [[Collider]] /other/ enters the [[class-BoxCollider|trigger]]. + CSNONE void OnTriggerEnter (Collider other); + + // OnTriggerExit is called when the [[Collider]] /other/ has stopped touching the [[class-BoxCollider|trigger]]. + CSNONE void OnTriggerExit (Collider other); + + // OnTriggerStay is called once per frame for every [[Collider]] /other/ that is touching the [[class-BoxCollider|trigger]]. + CSNONE void OnTriggerStay (Collider other); + + // OnCollisionEnter is called when this collider/rigidbody has begun touching another rigidbody/collider. + CSNONE void OnCollisionEnter (Collision collisionInfo); + + // OnCollisionExit is called when this collider/rigidbody has stopped touching another rigidbody/collider. + CSNONE void OnCollisionExit (Collision collisionInfo); + + // OnCollisionStay is called once per frame for every collider/rigidbody that is touching rigidbody/collider. + CSNONE void OnCollisionStay (Collision collisionInfo); + + // OnControllerColliderHit is called when the controller hits a collider while performing a Move. + CSNONE void OnControllerColliderHit (ControllerColliderHit hit); + + // Called when a joint attached to the same game object broke. + CSNONE void OnJointBreak (float breakForce); + +#if ENABLE_2D_PHYSICS + // OnCollisionEnter2D is called when this [[Collider2D]] has begun touching another [[Collider2D]]. + CSNONE void OnCollisionEnter2D (Collision2D info); + + // OnCollisionStay2D is called once per frame for this [[Collider2D]] if it is continuing to touch another [[Collider2D]]. + CSNONE void OnCollisionStay2D (Collision2D info); + + // OnCollisionExit2D is called when this [[Collider2D]] has stopped touching another [[Collider2D]]. + CSNONE void OnCollisionExit2D (Collision2D info); + + // OnTriggerEnter2D is called when a [[Collider2D]] has begun touching another [[Collider2D]] configured as a trigger. + CSNONE void OnTriggerEnter2D (Collider2D other); + + // OnTriggerStay2D is called once per frame for a [[Collider2D]] if it is continuing to touch another [[Collider2D]] configured as a trigger. + CSNONE void OnTriggerStay2D (Collider2D other); + + // OnTriggerExit2D is called when a [[Collider2D]] has stopped touching another [[Collider2D]] configured as a trigger. + CSNONE void OnTriggerExit2D (Collider2D other); +#endif + + // OnParticleCollision is called when a particle hits a collider (legacy particle system only). + CSNONE void OnParticleCollision (GameObject other); + + // OnBecameVisible is called when the renderer became visible by any camera. + CSNONE void OnBecameVisible(); + + // OnBecameInvisible is called when the renderer is no longer visible by any camera. + CSNONE void OnBecameInvisible(); + + // This function is called after a new level was loaded. + CSNONE void OnLevelWasLoaded (int level); + + // This function is called when the object becomes enabled and active. + CSNONE void OnEnable (); + + + // This function is called when the behaviour becomes disabled () or inactive. + CSNONE void OnDisable(); + + + // This function is called when the script is loaded or a value is changed in the inspector, use it to validate your data. + CSNONE void OnValidate (); + + + // This function is called when the MonoBehaviour will be destroyed. + CSNONE void OnDestroy(); + + + // OnPreCull is called before a camera culls the scene. + CSNONE void OnPreCull (); + + // OnPreRender is called before a camera starts rendering the scene. + CSNONE void OnPreRender (); + + // OnPostRender is called after a camera finished rendering the scene. + CSNONE void OnPostRender (); + + + // OnRenderObject is called after camera has rendered the scene. + CSNONE void OnRenderObject (); + + + // OnWillRenderObject is called once for each camera if the object is visible. + CSNONE void OnWillRenderObject (); + + // OnGUI is called for rendering and handling GUI events. + CSNONE void OnGUI (); + + // OnRenderImage is called after all rendering is complete to render image + CSNONE void OnRenderImage (RenderTexture source, RenderTexture destination); + + + // Implement this OnDrawGizmosSelected if you want to draw gizmos only if the object is selected. + CSNONE void OnDrawGizmosSelected (); + + // Implement this OnDrawGizmos if you want to draw gizmos that are also pickable and always drawn. + CSNONE void OnDrawGizmos (); + + // Sent to all game objects when the player pauses. + CSNONE void OnApplicationPause(bool pause); + + // Sent to all game objects when the player gets or loses focus. + CSNONE void OnApplicationFocus(bool focus); + + // Sent to all game objects before the application is quit. + CSNONE void OnApplicationQuit (); + + // Called on the server whenever a new player has successfully connected. + CSNONE void OnPlayerConnected (NetworkPlayer player); + + // Called on the server whenever a Network.InitializeServer was invoked and has completed. + CSNONE void OnServerInitialized (); + + // Called on the client when you have successfully connected to a server + CSNONE void OnConnectedToServer (); + + // Called on the server whenever a player disconnected from the server. + CSNONE void OnPlayerDisconnected (NetworkPlayer player); + + // Called on the client when the connection was lost or you disconnected from the server. + CSNONE void OnDisconnectedFromServer (NetworkDisconnection mode); + + // Called on the client when a connection attempt fails for some reason. + CSNONE void OnFailedToConnect (NetworkConnectionError error); + + // Called on clients or servers when there is a problem connecting to the MasterServer. + CSNONE void OnFailedToConnectToMasterServer (NetworkConnectionError error); + + // Called on clients or servers when reporting events from the MasterServer. + CSNONE void OnMasterServerEvent (MasterServerEvent msEvent); + + // Called on objects which have been network instantiated with Network.Instantiate + CSNONE void OnNetworkInstantiate (NetworkMessageInfo info); + + // Used to customize synchronization of variables in a script watched by a network view. + CSNONE void OnSerializeNetworkView (BitStream stream, NetworkMessageInfo info); + + // If OnAudioFilterRead is implemented, Unity will insert a custom filter into the audio DSP chain. + CSNONE void OnAudioFilterRead (); + + + + // Callback for processing animation movements for modifying root motion. + CSNONE void OnAnimatorMove (); + + // Callback for setting up animation IK (inverse kinematics) + CSNONE void OnAnimatorIK (int layerIndex); + + CUSTOM private void Internal_CancelInvokeAll () + { + CancelInvoke (*self); + } + + CUSTOM private bool Internal_IsInvokingAll () + { + return IsInvoking (*self); + } + + // Invokes the method /methodName/ in time seconds. + CUSTOM void Invoke (string methodName, float time) + { + InvokeDelayed (*self, methodName, time, 0.0F); + } + + // Invokes the method /methodName/ in /time/ seconds. + CUSTOM void InvokeRepeating (string methodName, float time, float repeatRate) + { + InvokeDelayed (*self, methodName, time, repeatRate); + } + + + // Cancels all Invoke calls on this MonoBehaviour. + CSRAW public void CancelInvoke () + { + Internal_CancelInvokeAll (); + } + + // Cancels all Invoke calls with name /methodName/ on this behaviour. + CUSTOM void CancelInvoke (string methodName) { CancelInvoke (*self, methodName); } + + + // Is any invoke on /methodName/ pending? + CUSTOM bool IsInvoking (string methodName) { return IsInvoking (*self, methodName); } + + // Is any invoke pending on this MonoBehaviour? + CSRAW public bool IsInvoking () + { + return Internal_IsInvokingAll (); + } + + // Starts a coroutine. + CSRAW public Coroutine StartCoroutine (IEnumerator routine) + { + return StartCoroutine_Auto(routine); + } + //*undocumented* + + CUSTOM Coroutine StartCoroutine_Auto (IEnumerator routine) + { + Scripting::RaiseIfNull(routine); + if (!self->IsInstanceIDCreated () || !self->IsDerivedFrom (ClassID (MonoBehaviour))) + Scripting::RaiseArgumentException ("Coroutines can only be started from a MonoBehaviour"); + return self->StartCoroutineManaged2(routine); + } + + + // Starts a coroutine named /methodName/. + CUSTOM Coroutine StartCoroutine (string methodName, object value = null) + { + Scripting::RaiseIfNull((void*)(!methodName.IsNull())); + if (!self->IsInstanceIDCreated () || !self->IsDerivedFrom (ClassID (MonoBehaviour))) + Scripting::RaiseArgumentException ("Coroutines can only be started from a MonoBehaviour"); + char* cString = ScriptingStringToAllocatedChars (methodName); + ScriptingObjectPtr coroutine = self->StartCoroutineManaged (cString, value); + ScriptingStringToAllocatedChars_Free (cString); + return coroutine; + } + + // Stops all coroutines named /methodName/ running on this behaviour. + CUSTOM void StopCoroutine (string methodName) { self->StopCoroutine(methodName.AsUTF8().c_str()); } + + + // Stops all coroutines running on this behaviour. + CUSTOM void StopAllCoroutines () { self->StopAllCoroutines(); } + + // Logs message to the Unity Console. This function is identical to [[Debug.Log]]. + CSRAW public static void print (object message) + { + Debug.Log (message); + } + + // Disabling this lets you skip the GUI layout phase. + CONDITIONAL !UNITY_WEBGL + AUTO_PROP bool useGUILayout GetUseGUILayout SetUseGUILayout + + CSRAW #if UNITY_WINRT + CSRAW private static FastCallExceptionHandler _fastCallExceptionHandler; + + CSRAW internal static void SetupFastCallExceptionHandler(FastCallExceptionHandler handler) + { + _fastCallExceptionHandler = handler; + } + + CSRAW protected static void HandleFastCallException(Exception ex) + { + if (_fastCallExceptionHandler != null) + _fastCallExceptionHandler(ex); + else throw ex; + } + CSRAW #endif + +END + + + +CSRAW } + diff --git a/Runtime/Export/UnityEngineObject.txt b/Runtime/Export/UnityEngineObject.txt new file mode 100644 index 0000000..2700188 --- /dev/null +++ b/Runtime/Export/UnityEngineObject.txt @@ -0,0 +1,226 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Misc/SaveAndLoadHelper.h" +#include "Runtime/GameCode/CloneObject.h" +#include "Runtime/Misc/Player.h" +#include "Runtime/Misc/GameObjectUtility.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/Scripting.h" + + +#if UNITY_WII + #include "PlatformDependent/Wii/WiiUtility.h" +#endif + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + + +namespace UnityEngine +{ + + + + +BEGIN DOC +Base class for all objects Unity can reference. +Any public variable you make that derives from Object gets shown in the inspector as a drop target, +allowing you to set the value from the GUI. +END DOC + +CSRAW +[StructLayout (LayoutKind.Sequential)] +NONSEALED_CLASS Object + CSRAW +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + private ReferenceData m_UnityRuntimeReferenceData; + + #if UNITY_EDITOR + private string m_UnityRuntimeErrorString; + #endif +#else //UNITY_FLASH + //*undocumented* + [NotRenamed] + public int m_InstanceID; + //*undocumented* + [NotRenamed] + public int m_CachedPtr; +#endif + + public override bool Equals(object o) { return CompareBaseObjects (this, o as Object); } + public override int GetHashCode() { return GetInstanceID(); } + + // Does the object exist? + public static implicit operator bool (Object exists) + { + return !CompareBaseObjects (exists, null); + } + + CSRAW private static bool CompareBaseObjects (Object lhs, Object rhs) + { + #if UNITY_WINRT + return UnityEngineInternal.ScriptingUtils.CompareBaseObjects(lhs, rhs); + #else + return CompareBaseObjectsInternal (lhs, rhs); + #endif + } + + CONSTRUCTOR_SAFE + CUSTOM private static bool CompareBaseObjectsInternal ([Writable]Object lhs, [Writable]Object rhs) + { + return Scripting::CompareBaseObjects (lhs.GetScriptingObject(), rhs.GetScriptingObject()); + } + + // Returns the instance id of the object. + CSRAW [NotRenamed] + CSRAW public int GetInstanceID () + { +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + return m_UnityRuntimeReferenceData.instanceID; +#else + return m_InstanceID; +#endif + } + + CUSTOM private static Object Internal_CloneSingle (Object data) + { + DISALLOW_IN_CONSTRUCTOR + return Scripting::ScriptingWrapperFor (&CloneObject (*data)); + } + CUSTOM private static Object Internal_InstantiateSingle (Object data, Vector3 pos, Quaternion rot) + { + DISALLOW_IN_CONSTRUCTOR + Object* obj = &InstantiateObject (*data, pos, rot); + return Scripting::ScriptingWrapperFor(obj); + } + + + // Clones the object /original/ and returns the clone. + + + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeOfFirstArgument)] + CSRAW public static Object Instantiate (Object original, Vector3 position, Quaternion rotation) + { + CheckNullArgument(original,"The prefab you want to instantiate is null."); + return Internal_InstantiateSingle (original, position, rotation); + } + + + // Clones the object /original/ and returns the clone. + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeOfFirstArgument)] + public static Object Instantiate (Object original) + { + CheckNullArgument(original,"The thing you want to instantiate is null."); + return Internal_CloneSingle (original); + } + #if ENABLE_GENERICS_BUT_CURRENTLY_DISABLED + // Generic version. See the [[wiki:Generic Functions|Generic Functions]] page for more details. + public static T Instantiate<T>(T original) where T : UnityEngine.Object + { + CheckNullArgument(original,"The thing you want to instantiate is null."); + return (T)Internal_CloneSingle (original); + } + #endif + + static private void CheckNullArgument(object arg, string message) + { + if (arg==null) + throw new ArgumentException(message); + } + + // Removes a gameobject, component or asset. + CSRAW + CUSTOM static void Destroy (Object obj, float t = 0.0F) { DISALLOW_IN_CONSTRUCTOR Scripting::DestroyObjectFromScripting (obj, t); } + + + // Destroys the object /obj/ immediately. It is strongly recommended to use Destroy instead. + CSRAW + CUSTOM static void DestroyImmediate (Object obj, bool allowDestroyingAssets = false) { Scripting::DestroyObjectFromScriptingImmediate (obj, allowDestroyingAssets); } + + // Returns a list of all active loaded objects of Type /type/. + CSRAW [TypeInferenceRule(TypeInferenceRules.ArrayOfTypeReferencedByFirstArgument)] + CUSTOM static Object[] FindObjectsOfType (Type type) { DISALLOW_IN_CONSTRUCTOR return Scripting::FindObjectsOfType (type, Scripting::kFindActiveSceneObjects); } + + CONDITIONAL (ENABLE_GENERICS && !UNITY_FLASH) + CSRAW public static T[] FindObjectsOfType<T> () where T: Object + { + return Resources.ConvertObjects<T> (FindObjectsOfType (typeof (T))); + } + + // Returns the first active loaded object of Type /type/. + CSRAW + [TypeInferenceRule(TypeInferenceRules.TypeReferencedByFirstArgument)] + CSRAW public static Object FindObjectOfType (Type type) + { + Object[] objects = FindObjectsOfType (type); + if (objects.Length > 0) + return objects[0]; + else + return null; + } + + CONDITIONAL (ENABLE_GENERICS && !UNITY_FLASH) + CSRAW public static T FindObjectOfType<T> () where T: Object + { + return (T)FindObjectOfType (typeof (T)); + } + + // Compares if two objects refer to the same + CSRAW public static bool operator == (Object x, Object y) { return CompareBaseObjects (x, y); } + + // Compares if two objects refer to a different object + CSRAW public static bool operator != (Object x, Object y) { return !CompareBaseObjects (x, y); } + + // The name of the object. + CUSTOM_PROP string name { return scripting_string_new(self->GetName ()); } { self->SetName ( value.AsUTF8().c_str()); } + + // Makes the object /target/ not be destroyed automatically when loading a new scene. + CUSTOM static void DontDestroyOnLoad (Object target) + { + Object* o = target; + if (o) + DontDestroyOnLoad (*o); + } + + // Should the object be hidden, saved with the scene or modifiable by the user? + CONSTRUCTOR_SAFE + AUTO_PROP HideFlags hideFlags GetHideFlags SetHideFlags + + //*undocumented* deprecated + // We cannot properly deprecate this in C# right now, since the optional parameter creates + // another method calling this, which creates compiler warnings when deprecated. + // OBSOLETE warning use Object.Destroy instead. + CUSTOM static void DestroyObject (Object obj, float t = 0.0F) { Scripting::DestroyObjectFromScripting (obj, t); } + + //*undocumented* DEPRECATED + OBSOLETE warning use Object.FindObjectsOfType instead. + CUSTOM static Object[] FindSceneObjectsOfType (Type type) { DISALLOW_IN_CONSTRUCTOR return Scripting::FindObjectsOfType (type, Scripting::kFindActiveSceneObjects); } + + //*undocumented* DEPRECATED + OBSOLETE warning use Resources.FindObjectsOfTypeAll instead. + CUSTOM static Object[] FindObjectsOfTypeIncludingAssets (Type type) { DISALLOW_IN_CONSTRUCTOR return Scripting::FindObjectsOfType (type, Scripting::kFindAssets); } + + CONDITIONAL ENABLE_MONO + OBSOLETE warning Please use Resources.FindObjectsOfTypeAll instead + CSRAW public static Object[] FindObjectsOfTypeAll (Type type) { return Resources.FindObjectsOfTypeAll (type); } + + // Returns the name of the game object. + CUSTOM public override string ToString() { + return scripting_string_new(GetSafeString(BaseObject, UnityObjectToString (self))); + } + +END +CSRAW } diff --git a/Runtime/Export/UnityEngineRandom.txt b/Runtime/Export/UnityEngineRandom.txt new file mode 100644 index 0000000..a5ab72f --- /dev/null +++ b/Runtime/Export/UnityEngineRandom.txt @@ -0,0 +1,70 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Runtime/Math/Random/Random.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include <ctime> + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// Class for generating random data. +CLASS Random + + C++RAW + Rand gScriptingRand (time(NULL)); + + // Sets the seed for the random number generator. + CUSTOM_PROP static int seed { return gScriptingRand.GetSeed(); } { gScriptingRand.SetSeed(value); } + + // Returns a random float number between and /min/ [inclusive] and /max/ [inclusive] (RO). + CUSTOM static float Range (float min, float max) { return RangedRandom (gScriptingRand, min, max); } + + // Returns a random integer number between /min/ [inclusive] and /max/ [exclusive] (RO). + CSRAW public static int Range (int min, int max) { return RandomRangeInt (min, max); } + + CUSTOM private static int RandomRangeInt (int min, int max) { return RangedRandom (gScriptingRand, min, max); } + + // Returns a random number between 0.0 [inclusive] and 1.0 [inclusive] (RO). + CUSTOM_PROP static float value { return Random01 (gScriptingRand); } + + // Returns a random point inside a sphere with radius 1 (RO). + CUSTOM_PROP static Vector3 insideUnitSphere { return RandomPointInsideUnitSphere (gScriptingRand); } + + // Workaround for gcc/msvc where passing small mono structures by value does not work + CUSTOM private static void GetRandomUnitCircle (out Vector2 output) + { + *output = RandomPointInsideUnitCircle (gScriptingRand); + } + + // Returns a random point inside a circle with radius 1 (RO). + CSRAW public static Vector2 insideUnitCircle { get { Vector2 r; GetRandomUnitCircle(out r); return r; } } + + // Returns a random point on the surface of a sphere with radius 1 (RO). + CUSTOM_PROP static Vector3 onUnitSphere { return RandomUnitVector (gScriptingRand); } + + // Returns a random rotation (RO). + CUSTOM_PROP static Quaternion rotation { return RandomQuaternion (gScriptingRand); } + + // Returns a random rotation with uniform distribution(RO). + CUSTOM_PROP static Quaternion rotationUniform { return RandomQuaternionUniformDistribution (gScriptingRand); } + + + OBSOLETE warning Use Random.Range instead + CSRAW public static float RandomRange (float min, float max) { return Range (min, max); } + OBSOLETE warning Use Random.Range instead + CSRAW public static int RandomRange (int min, int max) { return Range (min, max); } +END + + +CSRAW } diff --git a/Runtime/Export/UnityEngineTime.txt b/Runtime/Export/UnityEngineTime.txt new file mode 100644 index 0000000..9119d4b --- /dev/null +++ b/Runtime/Export/UnityEngineTime.txt @@ -0,0 +1,65 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Input/TimeManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include <ctime> + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// The interface to get time information from Unity. +CLASS Time + + // The time this frame has started (RO). This is the time in seconds since the start of the game. + CUSTOM_PROP static float time { return GetTimeManager ().GetCurTime (); } + + // The time this frame has started (RO). This is the time in seconds since the last level has been loaded. + CUSTOM_PROP static float timeSinceLevelLoad { return GetTimeManager ().GetTimeSinceLevelLoad (); } + + // The time in seconds it took to complete the last frame (RO). + CUSTOM_PROP static float deltaTime { return GetTimeManager ().GetDeltaTime (); } + + // The time the latest MonoBehaviour::pref::FixedUpdate has started (RO). This is the time in seconds since the start of the game. + CUSTOM_PROP static float fixedTime { return GetTimeManager ().GetFixedTime (); } + + + // The interval in seconds at which physics and other fixed frame rate updates (like MonoBehaviour's MonoBehaviour::pref::FixedUpdate) are performed. + CUSTOM_PROP static float fixedDeltaTime { return GetTimeManager ().GetFixedDeltaTime (); } { GetTimeManager ().SetFixedDeltaTime (value); } + + // The maximum time a frame can take. Physics and other fixed frame rate updates (like MonoBehaviour's MonoBehaviour::pref::FixedUpdate) + CUSTOM_PROP static float maximumDeltaTime { return GetTimeManager ().GetMaximumDeltaTime (); } { GetTimeManager ().SetMaximumDeltaTime (value); } + + // A smoothed out Time.deltaTime (RO). + CUSTOM_PROP static float smoothDeltaTime { return GetTimeManager ().GetSmoothDeltaTime (); } + + // The scale at which the time is passing. This can be used for slow motion effects. + CUSTOM_PROP static float timeScale { return GetTimeManager ().GetTimeScale (); } { GetTimeManager ().SetTimeScale (value); } + + // The total number of frames that have passed (RO). + CUSTOM_PROP static int frameCount { return GetTimeManager ().GetFrameCount (); } + + //*undocumented* + CUSTOM_PROP static int renderedFrameCount { return GetTimeManager ().GetRenderFrameCount (); } + + // The real time in seconds since the game started (RO). + CUSTOM_PROP static float realtimeSinceStartup { return GetTimeManager().GetRealtime (); } + + // If /captureFramerate/ is set to a value larger than 0, time will advance in + CUSTOM_PROP static int captureFramerate { return GetTimeManager().GetCaptureFramerate(); } { GetTimeManager().SetCaptureFramerate (value); } +END + +CSRAW } + diff --git a/Runtime/Export/UnityEngineTransform.txt b/Runtime/Export/UnityEngineTransform.txt new file mode 100644 index 0000000..f9eb906 --- /dev/null +++ b/Runtime/Export/UnityEngineTransform.txt @@ -0,0 +1,302 @@ +C++RAW + + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Graphics/Transform.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/Scripting.h" + +using namespace Unity; +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using UnityEngineInternal; + +namespace UnityEngine +{ + +// Position, rotation and scale of an object. +CSRAW +CLASS Transform : Component, IEnumerable + + CSRAW private Transform () { } + + // The position of the transform in world space. + CSRAW + AUTO_PROP Vector3 position GetPosition SetPosition + + // Position of the transform relative to the parent transform. + CSRAW + AUTO_PROP Vector3 localPosition GetLocalPosition SetLocalPosition + + // The rotation as Euler angles in degrees. + CSRAW public Vector3 eulerAngles { get { return rotation.eulerAngles; } set { rotation = Quaternion.Euler(value); } } + + // The rotation as Euler angles in degrees relative to the parent transform's rotation. + AUTO_PROP Vector3 localEulerAngles GetLocalEulerAngles SetLocalEulerAngles + + // The red axis of the transform in world space. + CSRAW public Vector3 right { get { return rotation * Vector3.right; } set { rotation = Quaternion.FromToRotation(Vector3.right, value); } } + + // The green axis of the transform in world space. + CSRAW public Vector3 up { get { return rotation * Vector3.up; } set { rotation = Quaternion.FromToRotation(Vector3.up, value); } } + + // The blue axis of the transform in world space. + CSRAW public Vector3 forward { get { return rotation * Vector3.forward; } set { rotation = Quaternion.LookRotation(value); } } + + // The rotation of the transform in world space stored as a [[Quaternion]]. + AUTO_PROP Quaternion rotation GetRotation SetRotationSafe + + // The rotation of the transform relative to the parent transform's rotation. + AUTO_PROP Quaternion localRotation GetLocalRotation SetLocalRotationSafe + + // The scale of the transform relative to the parent. + AUTO_PROP Vector3 localScale GetLocalScale SetLocalScale + + // The parent of the transform. + CSRAW + AUTO_PTR_PROP Transform parent GetParent SetParent + + // Matrix that transforms a point from world space into local space (RO). + AUTO_PROP Matrix4x4 worldToLocalMatrix GetWorldToLocalMatrix + // Matrix that transforms a point from local space into world space (RO). + AUTO_PROP Matrix4x4 localToWorldMatrix GetLocalToWorldMatrix + + // Moves the transform in the direction and distance of /translation/. + CSRAW public void Translate (Vector3 translation, Space relativeTo = Space.Self) + { + if (relativeTo == Space.World) + position += translation; + else + position += TransformDirection (translation); + } + + // Moves the transform by /x/ along the x axis, /y/ along the y axis, and /z/ along the z axis. + CSRAW public void Translate (float x, float y, float z, Space relativeTo = Space.Self) + { + Translate (new Vector3 (x, y, z), relativeTo); + } + + // Moves the transform in the direction and distance of /translation/. + CSRAW public void Translate (Vector3 translation, Transform relativeTo) + { + if (relativeTo) + position += relativeTo.TransformDirection (translation); + else + position += translation; + } + + // Moves the transform by /x/ along the x axis, /y/ along the y axis, and /z/ along the z axis. + CSRAW public void Translate (float x, float y, float z, Transform relativeTo) + { + Translate (new Vector3 (x, y, z), relativeTo); + } + + // Applies a rotation of /eulerAngles.z/ degrees around the z axis, /eulerAngles.x/ degrees around the x axis, and /eulerAngles.y/ degrees around the y axis (in that order). + CSRAW public void Rotate (Vector3 eulerAngles, Space relativeTo = Space.Self) + { + Quaternion eulerRot = Quaternion.Euler (eulerAngles.x, eulerAngles.y, eulerAngles.z); + if (relativeTo == Space.Self) + localRotation = localRotation * eulerRot; + else + { + rotation = rotation * (Quaternion.Inverse (rotation) * eulerRot * rotation); + } + } + + // Applies a rotation of /zAngle/ degrees around the z axis, /xAngle/ degrees around the x axis, and /yAngle/ degrees around the y axis (in that order). + CSRAW public void Rotate (float xAngle, float yAngle, float zAngle, Space relativeTo = Space.Self) + { + Rotate (new Vector3 (xAngle, yAngle, zAngle), relativeTo); + } + + CUSTOM internal void RotateAroundInternal (Vector3 axis, float angle) { self->RotateAroundSafe (axis, angle); } + + // Rotates the transform around /axis/ by /angle/ degrees. + CSRAW public void Rotate (Vector3 axis, float angle, Space relativeTo = Space.Self) + { + if (relativeTo == Space.Self) + RotateAroundInternal (transform.TransformDirection (axis), angle * Mathf.Deg2Rad); + else + RotateAroundInternal (axis, angle * Mathf.Deg2Rad); + } + + // Rotates the transform about /axis/ passing through /point/ in world coordinates by /angle/ degrees. + CSRAW public void RotateAround (Vector3 point, Vector3 axis, float angle) + { + Vector3 worldPos = position; + Quaternion q = Quaternion.AngleAxis (angle , axis); + Vector3 dif = worldPos - point; + dif = q * dif; + worldPos = point + dif; + position = worldPos; + RotateAroundInternal (axis, angle * Mathf.Deg2Rad); + } + + // Rotates the transform so the forward vector points at /target/'s current position. + CSRAW public void LookAt (Transform target, Vector3 worldUp = Vector3.up) { if (target) LookAt (target.position, worldUp); } + + // Rotates the transform so the forward vector points at /worldPosition/. + CUSTOM void LookAt (Vector3 worldPosition, Vector3 worldUp = Vector3.up) + { + Vector3f forward = worldPosition - self->GetPosition (); + Quaternionf q = Quaternionf::identity (); + if (LookRotationToQuaternion (forward, worldUp, &q)) + self->SetRotationSafe (q); + else + { + float mag = Magnitude (forward); + if (mag > Vector3f::epsilon) + { + Matrix3x3f m; + m.SetFromToRotation (Vector3f::zAxis, forward / mag); + MatrixToQuaternion (m, q); + self->SetRotationSafe (q); + } + } + } + + // Transforms /direction/ from local space to world space. + AUTO Vector3 TransformDirection (Vector3 direction); + + // Transforms direction /x/, /y/, /z/ from local space to world space. + CSRAW public Vector3 TransformDirection (float x, float y, float z) { return TransformDirection (new Vector3 (x, y, z)); } + + + // Transforms a /direction/ from world space to local space. The opposite of Transform.TransformDirection. + AUTO Vector3 InverseTransformDirection (Vector3 direction); + + // Transforms the direction /x/, /y/, /z/ from world space to local space. The opposite of Transform.TransformDirection. + CSRAW public Vector3 InverseTransformDirection (float x, float y, float z) { return InverseTransformDirection (new Vector3 (x, y, z)); } + + // Transforms /position/ from local space to world space. + AUTO Vector3 TransformPoint (Vector3 position); + + // Transforms the position /x/, /y/, /z/ from local space to world space. + CSRAW public Vector3 TransformPoint (float x, float y, float z) { return TransformPoint (new Vector3 (x, y, z)); } + + + // Transforms /position/ from world space to local space. The opposite of Transform.TransformPoint. + AUTO Vector3 InverseTransformPoint (Vector3 position); + + + // Transforms the position /x/, /y/, /z/ from world space to local space. The opposite of Transform.TransformPoint. + CSRAW public Vector3 InverseTransformPoint (float x, float y, float z) { return InverseTransformPoint (new Vector3 (x, y, z)); } + + + // Returns the topmost transform in the hierarchy. + CUSTOM_PROP Transform root { return Scripting::ScriptingWrapperFor(&self->GetRoot()); } + + // The number of children the Transform has. + CUSTOM_PROP int childCount { return self->GetChildrenCount (); } + + // Unparents all children. + CUSTOM void DetachChildren () + { + Transform& transform = *self; + while (transform.begin () != transform.end ()) + (**transform.begin ()).SetParent (NULL); + } + + // Finds a child by /name/ and returns it. + CUSTOM Transform Find (string name) + { + return Scripting::ScriptingWrapperFor (FindRelativeTransformWithPath (*self, name.AsUTF8().c_str ())); + } + + //*undocumented + CONDITIONAL UNITY_EDITOR + CUSTOM internal void SendTransformChangedScale () + { + self->SendTransformChanged ( Transform::kScaleChanged ); + } + + + // The global scale of the object (RO). + AUTO_PROP Vector3 lossyScale GetWorldScaleLossy + + // Is this transform a child of /parent/? + CUSTOM bool IsChildOf (Transform parent) + { + return IsChildOrSameTransform(*self, *parent); + } + + // Has the transform changed since the last time the flag was set to 'false'? + CUSTOM_PROP bool hasChanged { return self->GetChangedFlag(); } { self->SetChangedFlag(value); } + + //*undocumented* + CSRAW public Transform FindChild (string name) { return Find(name); } + + //*undocumented* Documented separately + CSRAW public IEnumerator GetEnumerator () + { + return new Transform.Enumerator (this); + } + + CLASS private Enumerator : IEnumerator + CSRAW + Transform outer; + int currentIndex = -1; + + internal Enumerator (Transform outer) { this.outer = outer; } + //*undocumented* + public object Current + { + get { return outer.GetChild (currentIndex); } + } + + //*undocumented* + public bool MoveNext () + { + int childCount = outer.childCount; + return ++currentIndex < childCount; + } + + //*undocumented* + public void Reset () { currentIndex = -1; } + END + + // *undocumented* DEPRECATED + CSRAW + OBSOLETE warning use Transform.Rotate instead. + CUSTOM void RotateAround (Vector3 axis, float angle) { self->RotateAroundSafe (axis, angle); } + + // *undocumented* DEPRECATED + OBSOLETE warning use Transform.Rotate instead. + CUSTOM void RotateAroundLocal (Vector3 axis, float angle) { self->RotateAroundLocalSafe (axis, angle); } + + // Get a transform child by index + CUSTOM Transform GetChild (int index) + { + Transform& transform = *self; + if (index >= 0 && index < transform.GetChildrenCount ()) + return Scripting::ScriptingWrapperFor (&transform.GetChild (index)); + else + { + Scripting::RaiseMonoException ("Transform child out of bounds"); + return SCRIPTING_NULL; + } + } + + //*undocumented* DEPRECATED + OBSOLETE warning use Transform.childCount instead. + CUSTOM int GetChildCount () { return self->GetChildrenCount (); } + + CONDITIONAL UNITY_EDITOR + CUSTOM internal bool IsNonUniformScaleTransform () + { + Transform& transform = *self; + Matrix4x4f temp; + TransformType scaleType = transform.CalculateTransformMatrix (temp); + return IsNonUniformScaleTransform (scaleType); + } + +END + +CSRAW } diff --git a/Runtime/Export/UnityEngineYieldOperation.txt b/Runtime/Export/UnityEngineYieldOperation.txt new file mode 100644 index 0000000..bbaca7e --- /dev/null +++ b/Runtime/Export/UnityEngineYieldOperation.txt @@ -0,0 +1,14 @@ +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UnityEngine +{ + +// Base class for all /yield/ instructions. +CSRAW [StructLayout (LayoutKind.Sequential)] +NONSEALED_CLASS YieldInstruction +END + +CSRAW } diff --git a/Runtime/Export/UserAuthorizationDialog.cs b/Runtime/Export/UserAuthorizationDialog.cs new file mode 100644 index 0000000..c2cb011 --- /dev/null +++ b/Runtime/Export/UserAuthorizationDialog.cs @@ -0,0 +1,166 @@ +using UnityEngine; +namespace UnityEngine +{ + +[AddComponentMenu("")] +class UserAuthorizationDialog : MonoBehaviour +{ +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + private Rect windowRect; + private const int width = 385; + private const int height = 155; + + private Texture warningIcon; +#endif + + private void Start () + { +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + warningIcon = Resources.GetBuiltinResource(typeof (Texture2D), "WarningSign.psd") as Texture2D; + if (Screen.width < width || Screen.height < height) + { + Debug.LogError ("Screen is to small to display authorization dialog. Authorization denied."); + Application.ReplyToUserAuthorizationRequest (false); + } + + windowRect = new Rect (Screen.width / 2 - width/2, Screen.height / 2 - height/2, width, height); +#endif + } + + private void OnGUI () { +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + GUISkin oldSkin = GUI.skin; + + // Create a custom GUISkin from scratch so users cannot change + // the look of the security dialog by changing the default GUI skins. + GUISkin skin = ScriptableObject.CreateInstance ("GUISkin") as GUISkin; + + skin.box.normal.background = (Texture2D)Resources.GetBuiltinResource(typeof(Texture2D), "GameSkin/box.png"); + skin.box.normal.textColor = new Color (0.9f, 0.9f, 0.9f, 1.0f); + skin.box.padding.left = 6; + skin.box.padding.right = 6; + skin.box.padding.top = 4; + skin.box.padding.bottom = 4; + skin.box.border.left = 6; + skin.box.border.right = 6; + skin.box.border.top = 6; + skin.box.border.bottom = 6; + skin.box.margin.left = 4; + skin.box.margin.right = 4; + skin.box.margin.top = 4; + skin.box.margin.bottom = 4; + + skin.button.normal.background = (Texture2D)Resources.GetBuiltinResource(typeof(Texture2D), "GameSkin/button.png"); + skin.button.normal.textColor = new Color (0.9f, 0.9f, 0.9f, 1.0f); + skin.button.hover.background = (Texture2D)Resources.GetBuiltinResource(typeof(Texture2D), "GameSkin/button hover.png"); + skin.button.hover.textColor = Color.white; + skin.button.active.background = (Texture2D)Resources.GetBuiltinResource(typeof(Texture2D), "GameSkin/button active.png"); + skin.button.active.textColor = new Color (0.9f, 0.9f, 0.9f, 1.0f); + skin.button.border.left = 6; + skin.button.border.right = 6; + skin.button.border.top = 6; + skin.button.border.bottom = 6; + skin.button.padding.left = 8; + skin.button.padding.right = 8; + skin.button.padding.top = 4; + skin.button.padding.bottom = 4; + skin.button.margin.left = 4; + skin.button.margin.right = 4; + skin.button.margin.top = 4; + skin.button.margin.bottom = 4; + + skin.label.normal.textColor = new Color (0.9f, 0.9f, 0.9f, 1.0f); + skin.label.padding.left = 6; + skin.label.padding.right = 6; + skin.label.padding.top = 4; + skin.label.padding.bottom = 4; + skin.label.margin.left = 4; + skin.label.margin.right = 4; + skin.label.margin.top = 4; + skin.label.margin.bottom = 4; + skin.label.alignment = TextAnchor.UpperLeft; + + skin.window.normal.background = (Texture2D)Resources.GetBuiltinResource(typeof(Texture2D), "GameSkin/window.png"); + skin.window.normal.textColor = Color.white; + skin.window.border.left = 8; + skin.window.border.right = 8; + skin.window.border.top = 18; + skin.window.border.bottom = 8; + skin.window.padding.left = 8; + skin.window.padding.right = 8; + skin.window.padding.top = 20; + skin.window.padding.bottom = 5; + skin.window.alignment = TextAnchor.UpperCenter; + skin.window.contentOffset = new Vector2 (0, -18); + + GUI.skin = skin; + windowRect = GUI.Window (0, windowRect, DoUserAuthorizationDialog, "Unity Web Player Authorization Request"); + GUI.skin = oldSkin; +#endif + } + + // Make the contents of the window + private void DoUserAuthorizationDialog (int windowID) { +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + UserAuthorization auth = Application.GetUserAuthorizationRequestMode(); + + GUILayout.FlexibleSpace (); + + GUI.backgroundColor = new Color (0.9f, 0.9f, 0.9f, 0.7f); + GUILayout.BeginHorizontal ("box"); + GUILayout.FlexibleSpace (); + + GUILayout.BeginVertical(); + GUILayout.FlexibleSpace (); + + GUILayout.Label(warningIcon); + + GUILayout.FlexibleSpace (); + GUILayout.EndVertical(); + + GUILayout.FlexibleSpace (); + + GUILayout.BeginVertical(); + GUILayout.FlexibleSpace (); + + if (auth == (UserAuthorization.WebCam | UserAuthorization.Microphone)) + GUILayout.Label ("The content on this site would like to use your\ncomputer's web camera and microphone.\nThese images and sounds may be recorded."); + else + if (auth == UserAuthorization.WebCam) + GUILayout.Label ("The content on this site would like to use\nyour computer's web camera. The images\nfrom your web camera may be recorded."); + else + if (auth == UserAuthorization.Microphone) + GUILayout.Label ("The content on this site would like to use\nyour computer's microphone. The sounds\nfrom your microphone may be recorded."); + else + return; + + GUILayout.FlexibleSpace (); + GUILayout.EndVertical(); + + GUILayout.FlexibleSpace (); + GUILayout.EndHorizontal (); + + GUILayout.FlexibleSpace (); + + GUI.backgroundColor = Color.white; + GUILayout.BeginHorizontal (); + + if (GUILayout.Button ("Deny")) + Application.ReplyToUserAuthorizationRequest (false); + + GUILayout.FlexibleSpace (); + + if (GUILayout.Button ("Always Allow for this Site")) + Application.ReplyToUserAuthorizationRequest (true, true); + + GUILayout.Space (5); + + if (GUILayout.Button ("Allow")) + Application.ReplyToUserAuthorizationRequest (true); + + GUILayout.EndHorizontal (); + GUILayout.FlexibleSpace (); +#endif + } +} +} diff --git a/Runtime/Export/Utils.txt b/Runtime/Export/Utils.txt new file mode 100644 index 0000000..18fbfe1 --- /dev/null +++ b/Runtime/Export/Utils.txt @@ -0,0 +1,1235 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Configuration/UnityConfigure.h" +#include "Runtime/Graphics/Texture2D.h" +#include "Runtime/Graphics/ImageConversion.h" +#include "Runtime/Misc/Player.h" +#include "Runtime/Export/WWW.h" +#include "Runtime/Misc/WWWCached.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Scripting/Backend/ScriptingTypes.h" +#include "Runtime/Scripting/ScriptingManager.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingObjectWithIntPtrField.h" +#include "Runtime/Interfaces/IAudio.h" + +#if WEBPLUG +#include "PlatformDependent/CommonWebPlugin/UnityWebStream.h" +#include "PlatformDependent/CommonWebPlugin/CompressedFileStreamMemory.h" +#endif +#include "Runtime/Misc/AssetBundle.h" +#include "Runtime/Serialize/PersistentManager.h" +#include "Runtime/Misc/Player.h" +#include "Runtime/Utilities/GUID.h" +#include "Runtime/Misc/CachingManager.h" +#include "Runtime/Misc/AssetBundleUtility.h" + +#if UNITY_EDITOR +#include "Editor/Src/LicenseInfo.h" +#include "Editor/Src/EditorUserBuildSettings.h" +#endif + +#if UNITY_FLASH +#include "PlatformDependent/FlashSupport/cpp/WWWFlash.h" +#endif + +#if ENABLE_MOVIES +#include "Runtime/Video/MovieTexture.h" +#endif +#if ENABLE_AUDIO +#include "Runtime/Audio/AudioClip.h" +#endif +#include "Runtime/Misc/Player.h" +#include "Runtime/Utilities/PathNameUtility.h" + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Text; + +namespace UnityEngine +{ +#if ENABLE_WWW +// Simple access to web pages. + +CONDITIONAL ENABLE_WWW +CLASS WWW : IDisposable + // We are matching the WWW class here so we can directly access it. + CSRAW internal IntPtr m_Ptr; + + C++RAW + + #if ENABLE_WWW + inline WWW* GetWWWChecked (ScriptingObjectWithIntPtrField<WWW>& self) + { + WWW* www = self.GetPtr(); + + if (!www) + Scripting::RaiseNullException("WWW class has already been disposed."); + + return www; + } + #endif + + C++RAW + #define GET GetWWWChecked (self) + + //*undocumented* + CSRAW public void Dispose () + { + DestroyWWW(true); + } + + CSRAW ~WWW() { + DestroyWWW(false); + } + + //*undocumented* + THREAD_SAFE + CUSTOM private void DestroyWWW(bool cancel) { + WWW* www = self.GetPtr(); + + // no-op if already 0 + self.SetPtr(0); + + if (www) + { + if (cancel) + www->Cancel(); + www->Release(); + } + } + + //*undocumented* + CUSTOM void InitWWW( string url , byte[] postData, string[] iHeaders ) { + string cpp_string = url; + map<string,string> headers; + // Copy in headers from the MonoArray if available + int headersSize = GetScriptingArraySize(iHeaders); + for(int i=0; i < headersSize-1 ; i += 2) { + headers[scripting_cpp_string_for(Scripting::GetScriptingArrayElementNoRef<ScriptingStringPtr>(iHeaders,i))] = scripting_cpp_string_for(Scripting::GetScriptingArrayElementNoRef<ScriptingStringPtr>(iHeaders,i+1)); + } + int rawPostDataLength = -1; + char* rawPostDataPtr = NULL; + if(postData != SCRIPTING_NULL) { + rawPostDataPtr = Scripting::GetScriptingArrayStart<char>(postData); // Will be copied by WWW::Create + rawPostDataLength = GetScriptingArraySize(postData); + } + WWW* www = WWW::Create (cpp_string.c_str(), rawPostDataPtr, rawPostDataLength, headers); + self.SetPtr(www); + } + + // Creates a WWW request with the given URL. + CSRAW public WWW(string url) { + InitWWW(url, null, null); + } + + // Creates a WWW request with the given URL. + CONDITIONAL !UNITY_WEBGL + CSRAW public WWW(string url, WWWForm form ) { + string[] flattenedHeaders = FlattenedHeadersFrom(form.headers); + + #if UNITY_WEBPLAYER || UNITY_EDITOR + if(enforceWebSecurityRestrictions()) { + CheckSecurityOnHeaders(flattenedHeaders); + } + #endif + + InitWWW(url, form.data, flattenedHeaders); + } + + // Creates a WWW request with the given URL. + CSRAW public WWW(string url, byte[] postData) { + InitWWW(url, postData, null); + } + + // Creates a WWW request with the given URL. + CSRAW #if !UNITY_METRO_API && !UNITY_WP8_API + CSRAW public WWW(string url, byte[] postData, Hashtable headers ) { + string[] flattenedHeaders = FlattenedHeadersFrom(headers); + + #if UNITY_WEBPLAYER || UNITY_EDITOR + if(enforceWebSecurityRestrictions()) { + CheckSecurityOnHeaders(flattenedHeaders); + } + #endif + + InitWWW(url, postData, flattenedHeaders); + } + + CSRAW #else + CSRAW public WWW(string url, byte[] postData, Dictionary<string, string> headers ) { + string[] flattenedHeaders = FlattenedHeadersFrom(headers); + + #if UNITY_WEBPLAYER || UNITY_EDITOR + if(enforceWebSecurityRestrictions()) { + CheckSecurityOnHeaders(flattenedHeaders); + } + #endif + + InitWWW(url, postData, flattenedHeaders); + } + CSRAW #endif + + CUSTOM internal bool enforceWebSecurityRestrictions() { + #if UNITY_WEBPLAYER + return true; + #elif UNITY_EDITOR + BuildTargetPlatform buildTarget = GetEditorUserBuildSettings().GetActiveBuildTarget(); + return buildTarget == kBuildWebPlayerLZMA || buildTarget == kBuildWebPlayerLZMAStreamed; + #else + return false; + #endif + } + + // Encodes string into an URL-friendly format. + + CSRAW +#if !UNITY_WEBGL + public static string EscapeURL(string s, Encoding e=System.Text.Encoding.UTF8) + { + if (s == null) + return null; + + if (s == "") + return ""; + + if (e == null) + return null; + + return WWWTranscoder.URLEncode(s,e); + } +#endif + + // Decodes string from an URL-friendly format. + + CSRAW +#if !UNITY_WEBGL + public static string UnEscapeURL(string s, Encoding e=System.Text.Encoding.UTF8) + { + if (null == s) + return null; + + if (s.IndexOf ('%') == -1 && s.IndexOf ('+') == -1) + return s; + + return WWWTranscoder.URLDecode(s,e); + + } +#endif + + + // The headers from the HTTP response. + + CSRAW +#if ENABLE_GENERICS + public System.Collections.Generic.Dictionary<string,string> responseHeaders + { + get { + #if UNITY_FLASH + UnityEngine.Flash.ActionScript.Import("System.UnityException"); + #endif + if (!isDone) throw new UnityException("WWW is not finished downloading yet"); + return ParseHTTPHeaderString(responseHeadersString); + } + } +#endif + CUSTOM_PROP private string responseHeadersString + { + WWW& www = *GET; + + ScriptingStringPtr res = scripting_string_new(www.GetResponseHeaders().c_str()); + return res; + } + + + // Returns the contents of the fetched web page as a string (RO). + CONDITIONAL !UNITY_WEBGL + CSRAW public string text { get { +#if !UNITY_FLASH + if (!isDone) throw new UnityException("WWW is not ready downloading yet"); + return GetTextEncoder().GetString(this.bytes, 0, this.bytes.Length); +#else + //Flash can't access responsheaders correctly, so we always asume utf8 and use native parsing, directly from the bytearray, and let flash try and deal with it. + return stringFromByteArray; +#endif + } + } + CSRAW internal static System.Text.Encoding DefaultEncoding + { + get + { + #if UNITY_WINRT + return System.Text.Encoding.UTF8; + #else + return System.Text.Encoding.ASCII; + #endif + } + } + + CONDITIONAL UNITY_FLASH + CUSTOM_PROP internal string stringFromByteArray { + WWWFlash *wwwflash = (WWWFlash*)GET; + ScriptingString* str = scripting_string_new("");//We don't really care about the return string, as we'll emit as3 to parse bytearray below, no need to marshall the bytearray into native first. + __asm __volatile__("var heapPos:int = heap.position;"); + __asm __volatile__("heap.position = %0;"::"r"(wwwflash->m_Buffer)); + __asm __volatile__("returnString = heap.readUTFBytes(%0); "::"r"(wwwflash->m_SizeLoaded)); + __asm __volatile__("heap.position = heapPos;"); + return str; + } + + + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + CSRAW private Encoding GetTextEncoder() + { +#if ENABLE_GENERICS + // Check for charset type + string contentType=null; + if (responseHeaders.TryGetValue("CONTENT-TYPE",out contentType)) + { + int charsetKeyIndex = contentType.IndexOf("charset", StringComparison.OrdinalIgnoreCase); + if (charsetKeyIndex > -1) + { + int charsetValueIndex = contentType.IndexOf('=', charsetKeyIndex); + if (charsetValueIndex > -1) + { + string encoding = contentType.Substring(charsetValueIndex + 1).Trim().Trim(new []{'\'', '"'}).Trim(); + int semicolonIndex = encoding.IndexOf(';'); + if (semicolonIndex > -1) + encoding = encoding.Substring(0, semicolonIndex); + try + { + return System.Text.Encoding.GetEncoding(encoding); + } catch (Exception) { + Debug.Log("Unsupported encoding: '" + encoding + "'"); + } + } + } + } +#endif + // Use default (utf8) + return System.Text.Encoding.UTF8; + } + + FLUSHCONDITIONS + + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + OBSOLETE warning Please use WWW.text instead + CSRAW public string data { get { return text; } } + + // Returns the contents of the fetched web page as a byte array (RO). + CUSTOM_PROP byte[] bytes { + WWW& www = *GET; + if (www.GetType() == kWWWTypeCached) + { + ErrorString(kWWWCachedAccessError); + return SCRIPTING_NULL; + } + if (www.GetSecurityPolicy() != WWW::kSecurityPolicyAllowAccess) + Scripting::RaiseSecurityException("No valid crossdomain policy available to allow access"); + + if (!www.HasDownloadedOrMayBlock ()) + return CreateEmptyStructArray(GetScriptingManager().GetCommonClasses().byte); + + return CreateScriptingArray<UInt8>( www.GetData(), www.GetSize(), GetScriptingManager().GetCommonClasses().byte ); + } + + //*undocumented* OBSOLETE Can do the same with bytes.Length + CUSTOM_PROP int size { + WWW& www = *GET; + if (!www.HasDownloadedOrMayBlock ()) + return 0; + return www.GetSize(); + } + + //*undocumented* + CONDITIONAL UNITY_WINRT + CUSTOM private IntPtr GetError() + { + WWW *www = GET; + if (www) + return (void*)self->GetError(); + else + return (void*)kWWWErrCancelled; + } + + // Returns an error message if there was an error during the download (RO). + CSRAW + #if UNITY_WINRT + public string error + { + get + { + return Marshal.PtrToStringAnsi(GetError()); + } + } + #endif + + // Returns an error message if there was an error during the download (RO). + CONDITIONAL !UNITY_WINRT + CUSTOM_PROP string error { + WWW *www = GET; + if (www) + { + const char* e = self->GetError(); + if (e) + return scripting_string_new(e); + else + return SCRIPTING_NULL; + } + else + return scripting_string_new(kWWWErrCancelled); + } + + //*undocumented* + CUSTOM private Texture2D GetTexture(bool markNonReadable) + { + WWW& www = *GET; + if (www.GetType() == kWWWTypeCached) + { + ErrorString(kWWWCachedAccessError); + return SCRIPTING_NULL; + } + + // create the texture + Texture2D* tex = CreateObjectFromCode<Texture2D>(); + + if (www.HasDownloadedOrMayBlock ()) + { + LoadMemoryBufferIntoTexture( *tex, self->GetData(), self->GetSize(), kLoadImageUncompressed, markNonReadable ); + WWW::SecurityPolicy policy = self->GetSecurityPolicy(); + if (policy != WWW::kSecurityPolicyAllowAccess) + tex->SetReadAllowed(false); + } + else + { + LoadMemoryBufferIntoTexture( *tex, NULL, 0, kLoadImageUncompressed, markNonReadable ); + } + + return Scripting::ScriptingWrapperFor(tex); + } + + // Returns a [[Texture2D]] generated from the downloaded data (RO). + CSRAW public Texture2D texture { get { return GetTexture(false); } } + + // Returns a non-readable [[Texture2D]] generated from the downloaded data (RO). + CSRAW public Texture2D textureNonReadable { get { return GetTexture(true); } } + + // Returns a [[AudioClip]] generated from the downloaded data (RO). + + CONDITIONAL !UNITY_WEBGL && ENABLE_AUDIO + CSRAW public AudioClip audioClip { + get { return GetAudioClip(true); } + } + + FLUSHCONDITIONS + + /// *listonly* + CONDITIONAL !UNITY_WEBGL && ENABLE_AUDIO + CSRAW public AudioClip GetAudioClip(bool threeD) + { + return GetAudioClip(threeD, false); + } + + /// *listonly* + CONDITIONAL !UNITY_WEBGL && ENABLE_AUDIO + CSRAW public AudioClip GetAudioClip(bool threeD, bool stream) + { + return GetAudioClip(threeD, stream, AudioType.UNKNOWN); + } + + // Returns an [[AudioClip]] generated from the downloaded data (RO). + CONDITIONAL !UNITY_WEBGL && ENABLE_AUDIO + CUSTOM public AudioClip GetAudioClip(bool threeD, bool stream, AudioType audioType) + { + IAudio *audio = GetIAudio(); + if(audio == NULL) + return SCRIPTING_NULL; + + WWW& www = *GET; + if (www.GetType() == kWWWTypeCached) + { + ErrorString(kWWWCachedAccessError); + return SCRIPTING_NULL; + } + + AudioClip* clip = audio->CreateAudioClipFromWWW(*GET, threeD, stream, audioType); + return Scripting::ScriptingWrapperFor (clip); + } + + + // Returns a [[MovieTexture]] generated from the downloaded data (RO). + CONDITIONAL ENABLE_MOVIES + CUSTOM_PROP MovieTexture movie + { + + WWW& www = *GET; + if (www.GetType() == kWWWTypeCached) + { + ErrorString(kWWWCachedAccessError); + return SCRIPTING_NULL; + } + #if UNITY_EDITOR + if (!LicenseInfo::Flag(lf_pro_version)) + { + ErrorString("Movie playback is only possible with Unity Pro"); + return SCRIPTING_NULL; + } + #endif + + MovieTexture* tex = NULL; + IAudio *audio = GetIAudio(); + if(audio) + tex = audio->CreateMovieTextureFromWWW(*GET); + + + //Not applying any security restrictions here, because currently our API does not allow grabbing samples from the movieclip + //It's impossible for a hacker to get his hands on the data, or xfer it somewhere. When we start supporting this, we should + //add a crossdomain securitycheck here. + return Scripting::ScriptingWrapperFor (tex); + } + + // Replaces the contents of an existing [[Texture2D]] with an image from the downloaded data. + CUSTOM void LoadImageIntoTexture(Texture2D tex) { + WWW& www = *GET; + if (www.GetType() == kWWWTypeCached) + { + ErrorString(kWWWCachedAccessError); + return; + } + + if (!www.HasDownloadedOrMayBlock ()) + return; + + LoadMemoryBufferIntoTexture( *tex, www.GetData(), www.GetSize(), IsCompressedDXTTextureFormat(tex->GetTextureFormat())?kLoadImageDXTCompressDithered:kLoadImageUncompressed ); + if (www.GetSecurityPolicy() != WWW::kSecurityPolicyAllowAccess) tex->SetReadAllowed(false); + } + + // Is the download already finished? (RO) + CUSTOM_PROP bool isDone { + return (short)GET->IsDone(); + } + + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + OBSOLETE error All blocking WWW functions have been deprecated, please use one of the asynchronous functions instead. + CUSTOM static string GetURL(string url) { + map<string,string> headers; + const char* c_string = url.AsUTF8().c_str(); + WWW* fetcher = WWW::Create(c_string, NULL, -1, headers); + + MonoString* result; + + if (fetcher->GetSecurityPolicy() != WWW::kSecurityPolicyAllowAccess) + { + Scripting::RaiseSecurityException("No valid crossdomain policy available to allow access"); + return scripting_string_new(""); + } + + if (!fetcher->HasDownloadedOrMayBlock ()) + result = scripting_string_new(""); + else + result = scripting_string_new((char*)fetcher->GetData(), fetcher->GetSize()); + + fetcher->Release(); + return result; + } + + FLUSHCONDITIONS + + CSRAW +#if !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT + OBSOLETE error All blocking WWW functions have been deprecated, please use one of the asynchronous functions instead. +#endif + public static Texture2D GetTextureFromURL(string url) { + return new WWW(url).texture; + } + + // How far has the download progressed (RO). + CUSTOM_PROP float progress + { + return GET->GetProgress(); + } + + // How far has the upload progressed (RO). + CUSTOM_PROP float uploadProgress + { + return GET->GetUploadProgress(); + } + + // How many bytes have been downloaded (RO). + CUSTOM_PROP int bytesDownloaded + { + return GET->GetSize(); + } + + // Loads the new web player data file. + CUSTOM void LoadUnityWeb () + { + WWW& www = *GET; + if (!www.HasDownloadedOrMayBlock ()) + return; + + if (www.GetSecurityPolicy() != WWW::kSecurityPolicyAllowAccess) + { + Scripting::RaiseSecurityException("No valid crossdomain policy available to allow access"); + return; //is this return required? + } + + #if WEBPLUG + QueuePlayerLoadWebData (www.GetUnityWebStream()); + www.GetUnityWebStream()->RetainDownload (&www); + #else + LogString (Format("Requested loading unity web file %s. This will only be loaded in the web player.", www.GetUrl ())); + #endif + } + + // Load an Ogg Vorbis file into the audio clip. + + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT && ENABLE_AUDIO + OBSOLETE warning .oggVorbis accessor is deprecated, use .audioClip or GetAudioClip() instead. + CUSTOM_PROP AudioClip oggVorbis + { + IAudio *audio = GetIAudio(); + if(audio == NULL) + return SCRIPTING_NULL; + + if (audio->IsFormatSupportedByPlatform("ogg")) + { + ErrorString("Streaming of 'ogg' on this platform is not supported"); + return SCRIPTING_NULL; + } + + WWW& www = *GET; + if (www.GetType() == kWWWTypeCached) + { + ErrorString(kWWWCachedAccessError); + return SCRIPTING_NULL; + } + + if (!www.HasDownloadedOrMayBlock ()) + return SCRIPTING_NULL; + + AudioClip *clip = audio->CreateAudioClipOGGFromWWW(*GET); + return Scripting::ScriptingWrapperFor(clip); + } + + + // The URL of this WWW request (RO). + CUSTOM_PROP string url { return scripting_string_new(GET->GetUrl()); } + + // Streams an AssetBundle that can contain any kind of asset from the project folder. + CUSTOM_PROP AssetBundle assetBundle + { + return Scripting::ScriptingWrapperFor (ExtractAssetBundle (*GET)); + } + + // Priority of [[AssetBundle]] decompression thread. + // SA: [[ThreadPriority]] enum. + CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL + CUSTOM_PROP ThreadPriority threadPriority { return GET->GetThreadPriority(); } { GET->SetThreadPriority(value); } + + CUSTOM internal WWW (string url, int version, uint crc) + { + string cpp_string = url; + #if ENABLE_CACHING + WWW* www = new WWWCached(cpp_string.c_str(), version, crc); + #else + WWW* www = WWW::Create (cpp_string.c_str(), NULL, 0, WWW::WWWHeaders(), 0, crc); + #endif + self.SetPtr(www); + } + + // Loads an AssetBundle with the specified version number from the cache. If the AssetBundle is not currently cached, it will automatically be downloaded and stored in the cache for future retrieval from local storage. + + + CSRAW public static WWW LoadFromCacheOrDownload( string url, int version, uint crc = 0) { + return new WWW(url, version, crc); + } + C++RAW + #undef GET +END + +// Helper class to generate form data to post to web servers using the [[WWW]] class. + + + +CONDITIONAL !UNITY_WEBGL +CLASS WWWForm + +CSRAW private List<byte[]> formData; // <byte[]> +CSRAW private List<string> fieldNames; // <string> +CSRAW private List<string> fileNames; // <string> +CSRAW private List<string> types; // <string> +CSRAW private byte[] boundary; +CSRAW private bool containsFiles = false; + +// Creates an empty WWWForm object. +CSRAW public WWWForm() { + formData = new List<byte[]>(); + fieldNames = new List<string>(); + fileNames = new List<string>(); + types = new List<string>(); + + // Generate a random boundary + boundary=new byte[40]; + for(int i=0; i<40; i++) { + int randomChar=Random.Range(48,110); + if(randomChar > 57) // skip unprintable chars between 57 and 64 (inclusive) + randomChar+=7; + if(randomChar > 90) // and 91 and 96 (inclusive) + randomChar+=6; + boundary[i]=(byte)randomChar; + } + +} + +// Add a simple field to the form. +CSRAW public void AddField(string fieldName, string value, Encoding e=System.Text.Encoding.UTF8) { + fieldNames.Add(fieldName); + fileNames.Add(null); + formData.Add(e.GetBytes(value)); + types.Add("text/plain; charset=\"" + e.WebName + "\""); +} + +// Adds a simple field to the form. +CSRAW public void AddField(string fieldName, int i) { + AddField(fieldName, i.ToString()); +} + +// Add binary data to the form. +CSRAW public void AddBinaryData(string fieldName, byte[] contents, string fileName=null, string mimeType = null) { + containsFiles=true; + + // We handle png files automatically as we suspect people will be uploading png files a lot due to the new + // screen shot feature. If we want to add support for detecting other file types, we will need to do it in a more extensible way. + bool isPng = contents.Length > 8 && contents[0] == 0x89 && contents[1] == 0x50 && contents[2] == 0x4e && contents[3] == 0x47 + && contents[4] == 0x0d && contents[5] == 0x0a && contents[6] == 0x1a && contents[7] == 0x0a; + if(fileName == null) { + fileName = fieldName + (isPng?".png":".dat"); + } + if(mimeType == null) { + if(isPng) + mimeType="image/png"; + else + mimeType="application/octet-stream"; + } + + fieldNames.Add(fieldName); + fileNames.Add(fileName); + formData.Add(contents); + types.Add(mimeType); +} + +// (RO) Returns the correct request headers for posting the form using the [[WWW]] class. +CSRAW #if !UNITY_METRO_API && !UNITY_WP8_API +CSRAW public Hashtable headers { get { + Hashtable retval = new Hashtable(); + if(containsFiles) + retval["Content-Type"]="multipart/form-data; boundary=\"" + System.Text.Encoding.UTF8.GetString(boundary) + "\""; + else + retval["Content-Type"]="application/x-www-form-urlencoded"; + return retval; + } +} + +CSRAW #else +CSRAW public Dictionary<string, string> headers { get { + Dictionary<string, string> retval = new Dictionary<string, string>(); + if(containsFiles) + retval["Content-Type"]="multipart/form-data; boundary=\"" + System.Text.Encoding.UTF8.GetString(boundary, 0, boundary.Length) + "\""; + else + retval["Content-Type"]="application/x-www-form-urlencoded"; + return retval; + } +} + +CSRAW #endif + +// (RO) The raw data to pass as the POST request body when sending the form. +CSRAW public byte[] data { get { + + if(containsFiles) { + byte[] dDash = WWW.DefaultEncoding.GetBytes("--"); + byte[] crlf = WWW.DefaultEncoding.GetBytes("\r\n"); + byte[] contentTypeHeader = WWW.DefaultEncoding.GetBytes("Content-Type: "); + byte[] dispositionHeader = WWW.DefaultEncoding.GetBytes("Content-disposition: form-data; name=\""); + byte[] endQuote = WWW.DefaultEncoding.GetBytes("\""); + byte[] fileNameField = WWW.DefaultEncoding.GetBytes("; filename=\""); + + + using(MemoryStream memStream = new MemoryStream(1024)) + { + for(int i=0; i < formData.Count; i++) { + memStream.Write(crlf, 0, (int) crlf.Length); + memStream.Write(dDash, 0, (int) dDash.Length); + memStream.Write(boundary, 0, (int) boundary.Length); + memStream.Write(crlf, 0, (int) crlf.Length); + memStream.Write(contentTypeHeader, 0, (int) contentTypeHeader.Length); + + byte[] type=System.Text.Encoding.UTF8.GetBytes((string)types[i]); + memStream.Write(type, 0, (int) type.Length); + memStream.Write(crlf, 0, (int) crlf.Length); + memStream.Write(dispositionHeader, 0, (int) dispositionHeader.Length); + + #if !UNITY_METRO_API && !UNITY_WP8_API + string headerName = System.Text.Encoding.UTF8.HeaderName; + #else + string headerName = ""; + #endif + // Headers must be 7 bit clean, so encode as per rfc1522 using quoted-printable if needed. + string encodedFieldName=(string)fieldNames[i]; + if(!WWWTranscoder.SevenBitClean(encodedFieldName, System.Text.Encoding.UTF8) || encodedFieldName.IndexOf("=?") > -1) { + encodedFieldName="=?"+headerName+"?Q?"+WWWTranscoder.QPEncode(encodedFieldName, System.Text.Encoding.UTF8) + "?="; + } + byte[] name=System.Text.Encoding.UTF8.GetBytes(encodedFieldName); + memStream.Write(name, 0, (int) name.Length); + memStream.Write(endQuote, 0, (int) endQuote.Length); + + if(fileNames[i] != null) { + // Headers must be 7 bit clean, so encode as per rfc1522 using quoted-printable if needed. + string encodedFileName=(string)fileNames[i]; + if(!WWWTranscoder.SevenBitClean(encodedFileName, System.Text.Encoding.UTF8) || encodedFileName.IndexOf("=?") > -1) { + encodedFileName="=?"+headerName+"?Q?"+WWWTranscoder.QPEncode(encodedFileName, System.Text.Encoding.UTF8) + "?="; + } + byte[] fileName=System.Text.Encoding.UTF8.GetBytes(encodedFileName); + + memStream.Write(fileNameField, 0, (int) fileNameField.Length); + memStream.Write(fileName, 0, (int) fileName.Length); + memStream.Write(endQuote, 0, (int) endQuote.Length); + + } + memStream.Write(crlf, 0, (int) crlf.Length); + memStream.Write(crlf, 0, (int) crlf.Length); + + byte[] formBytes = (byte[])formData[i]; + memStream.Write(formBytes, 0, (int) formBytes.Length); + } + memStream.Write(crlf, 0, (int) crlf.Length); + memStream.Write(dDash, 0, (int) dDash.Length); + memStream.Write(boundary, 0, (int) boundary.Length); + memStream.Write(dDash, 0, (int) dDash.Length); + memStream.Write(crlf, 0, (int) crlf.Length); + + return memStream.ToArray(); + } + } + else { + byte[] ampersand = WWW.DefaultEncoding.GetBytes("&"); + byte[] equal = WWW.DefaultEncoding.GetBytes("="); + + using(MemoryStream memStream = new MemoryStream(1024)) + { + for(int i=0; i < formData.Count; i++) { + byte[] name=WWWTranscoder.URLEncode(System.Text.Encoding.UTF8.GetBytes((string)fieldNames[i])); + byte[] formBytes = (byte[])formData[i]; + byte[] value=WWWTranscoder.URLEncode(formBytes); + + if(i>0) memStream.Write(ampersand, 0, (int) ampersand.Length); + memStream.Write(name, 0, (int) name.Length); + memStream.Write(equal, 0, (int) equal.Length); + memStream.Write(value, 0, (int) value.Length); + } + return memStream.ToArray(); + } + } + } +} + + +END +//*undocumented* +CONDITIONAL !UNITY_WEBGL +CLASS internal WWWTranscoder + + CSRAW private static byte [] ucHexChars = WWW.DefaultEncoding.GetBytes("0123456789ABCDEF"); + CSRAW private static byte [] lcHexChars = WWW.DefaultEncoding.GetBytes("0123456789abcdef"); + CSRAW private static byte urlEscapeChar=(byte)'%'; + CSRAW private static byte urlSpace=(byte)'+'; + CSRAW private static byte [] urlForbidden=WWW.DefaultEncoding.GetBytes("@&;:<>=?\"'/\\!#%+$,{}|^[]`"); + CSRAW private static byte qpEscapeChar=(byte)'='; + CSRAW private static byte qpSpace=(byte)'_'; + CSRAW private static byte [] qpForbidden=WWW.DefaultEncoding.GetBytes("&;=?\"'%+_"); + + CSRAW private static byte Hex2Byte (byte[] b, int offset) { + byte result=(byte)0; + + for (int i = offset; i < offset+2; i++ ) { + result *= 16; + int d=b[i]; + + if (d >= 48 && d <= 57) // 0 - 9 + d -= 48; + else if (d >= 65 && d <= 75) // A -F + d -= 55; + else if (d >= 97 && d <= 102) // a - f + d -= 87; + if (d>15) { + return 63; // ? + } + + result += (byte)d; + } + + return result; + } + + CSRAW private static byte[] Byte2Hex (byte b, byte[] hexChars) { + byte[] dest= new byte[2]; + dest[0]=hexChars[ b >> 4 ]; + dest[1]=hexChars[ b &0xf ]; + return dest; + } + + + CSRAW public static string URLEncode(string toEncode, Encoding e = Encoding.UTF8) { + byte[] data = Encode(e.GetBytes(toEncode), urlEscapeChar, urlSpace, urlForbidden, false); + return WWW.DefaultEncoding.GetString(data, 0, data.Length); + } + + CSRAW public static byte[] URLEncode(byte[] toEncode) { + return Encode(toEncode, urlEscapeChar, urlSpace, urlForbidden, false); + } + + CSRAW public static string QPEncode(string toEncode, Encoding e = Encoding.UTF8) { + byte[] data = Encode(e.GetBytes(toEncode), qpEscapeChar, qpSpace, qpForbidden, true); + return WWW.DefaultEncoding.GetString(data, 0, data.Length); + } + + CSRAW public static byte[] QPEncode(byte[] toEncode) { + return Encode(toEncode, qpEscapeChar, qpSpace, qpForbidden, true); + } + + CSRAW public static byte[] Encode(byte[] input, byte escapeChar, byte space, byte[] forbidden, bool uppercase) { + using(MemoryStream memStream = new MemoryStream(input.Length*2)) { + // encode + for(int i=0; i < input.Length; i++) { + if(input[i] == 32) { + memStream.WriteByte(space); + } else if(input[i] < 32 || input[i] > 126 || ByteArrayContains(forbidden, input[i])){ + memStream.WriteByte(escapeChar); + memStream.Write(Byte2Hex(input[i],uppercase?ucHexChars:lcHexChars),0,2); + } else { + memStream.WriteByte(input[i]); + } + } + + return memStream.ToArray(); + } + + } + + CSRAW private static bool ByteArrayContains(byte[] array, byte b) + { +#if !UNITY_FLASH + return (System.Array.IndexOf(array, b) != -1); +#else + for(int i = 0; i<array.Length; i++){ + if(array[i] == b) + return true; + } + return false; +#endif + } + + CSRAW public static string URLDecode(string toEncode, Encoding e = Encoding.UTF8) { + byte []data = Decode(WWW.DefaultEncoding.GetBytes(toEncode), urlEscapeChar, urlSpace); + return e.GetString(data, 0, data.Length); + } + + CSRAW public static byte[] URLDecode(byte[] toEncode) { + return Decode(toEncode, urlEscapeChar, urlSpace); + } + + CSRAW public static string QPDecode(string toEncode, Encoding e = Encoding.UTF8) { + byte[] data = Decode(WWW.DefaultEncoding.GetBytes(toEncode), qpEscapeChar, qpSpace); + return e.GetString(data, 0, data.Length); + } + + CSRAW public static byte[] QPDecode(byte[] toEncode){ + return Decode(toEncode, qpEscapeChar, qpSpace); + } + + CSRAW public static byte[] Decode(byte[] input, byte escapeChar, byte space) { + using(MemoryStream memStream = new MemoryStream(input.Length)) { + // decode + for(int i=0; i < input.Length; i++) { + if(input[i] == space) { + memStream.WriteByte((byte)32); + } else if(input[i] == escapeChar && i+2 < input.Length) { + i++; + memStream.WriteByte(Hex2Byte(input,i++)); + } else { + memStream.WriteByte(input[i]); + } + } + + return memStream.ToArray(); + } + + } + + CSRAW public static bool SevenBitClean(string s, Encoding e = Encoding.UTF8) { + return SevenBitClean(e.GetBytes(s)); + } + + CSRAW public static bool SevenBitClean(byte[] input) { + for(int i= 0; i<input.Length; i++) { + if (input[i] < 32 || input[i] > 126 ) + return false; + } + + return true; + } + + +END + +CSRAW +[System.Obsolete ("this API is not for public use.")] +public struct CacheIndex { + public string name; + public int bytesUsed; + public int expires; +} + +C++RAW + +struct MonoCacheIndex { + ScriptingStringPtr name; + int bytesUsed; + int expires; +}; + +// The Caching class lets you manage cached AssetBundles, downloaded using WWW::ref::LoadFromCacheOrDownload. +CONDITIONAL ENABLE_CACHING +CLASS Caching + +// (This is a WebPlayer-only function) +CSRAW public static bool Authorize (string name, string domain, long size, string signature) +{ + return Authorize(name, domain, size, -1, signature); +} +///*listonly* +CUSTOM static bool Authorize(string name, string domain, long size, int expiration, string signature) +{ + return GetCachingManager().Authorize(name, domain, size, expiration, signature); +} + +OBSOLETE warning Size is now specified as a long +CSRAW public static bool Authorize(string name, string domain, int size, int expiration, string signature) +{ + return Authorize(name, domain, (long)size, expiration, signature); +} + +OBSOLETE warning Size is now specified as a long +CSRAW public static bool Authorize (string name, string domain, int size, string signature) +{ + return Authorize( name, domain, (long)size, signature); +} + +// Delete all AssetBundle content that has been cached by the current application. +CUSTOM static bool CleanCache () +{ + if (GetCachingManager().GetAuthorizationLevel() >= CachingManager::kAuthorizationUser) + return GetCachingManager().GetCurrentCache().CleanCache(); + else + { + ErrorString("Unauthorized use of Caching API."); + return false; + } +} + +OBSOLETE warning this API is not for public use. +CUSTOM static bool CleanNamedCache (string name) +{ + if (GetCachingManager().GetAuthorizationLevel() >= CachingManager::kAuthorizationAdmin) + return GetCachingManager().CleanCache(name); + else + { + ErrorString("Unauthorized use of Caching API."); + return false; + } +} + +OBSOLETE warning This function is obsolete and has no effect. +CUSTOM static bool DeleteFromCache (string url) +{ + return false; +} + +OBSOLETE warning This function is obsolete and will always return -1. Use IsVersionCached instead. +CUSTOM static int GetVersionFromCache (string url) +{ + return -1; +} + +// Checks if an AssetBundle is cached. +CUSTOM static bool IsVersionCached (string url, int version) +{ + return GetCachingManager().IsCached(url, version); +} + +// Bumps the timestamp of a cached file to be the current time. +CUSTOM static bool MarkAsUsed (string url, int version) +{ + return GetCachingManager().MarkAsUsed(url, version); +} + +OBSOLETE warning this API is not for public use. +CUSTOM_PROP static CacheIndex[] index +{ +#if !UNITY_WINRT && ENABLE_WWW + if (GetCachingManager().GetAuthorizationLevel() < CachingManager::kAuthorizationAdmin) + { + ErrorString("Unauthorized use of Caching API."); + return NULL; + } + vector<Cache*> &indices = GetGlobalCachingManager().GetCacheIndices(); + MonoArray *monoIndices = mono_array_new (mono_domain_get (), GetMonoManager().GetCommonClasses().cacheIndex, indices.size() ); + + for(int i=0; i<indices.size(); i++) + { + GetMonoArrayElement<MonoCacheIndex>(monoIndices, i).name = scripting_string_new (indices[i]->m_Name); + GetMonoArrayElement<MonoCacheIndex>(monoIndices, i).bytesUsed = indices[i]->m_BytesUsed; + GetMonoArrayElement<MonoCacheIndex>(monoIndices, i).expires = indices[i]->m_Expires; + } + return monoIndices; +#else + return SCRIPTING_NULL; +#endif +} + +// The number of currently unused bytes in the cache. +CUSTOM_PROP static long spaceFree +{ + return GetCachingManager().GetCachingDiskSpaceFree(); +} + +// The total number of bytes that can potentially be allocated for caching. +CUSTOM_PROP static long maximumAvailableDiskSpace +{ + return GetCachingManager().GetMaximumDiskSpaceAvailable(); +} +{ + GetCachingManager().SetMaximumDiskSpaceAvailable(value); +} + +// Used disk space in bytes. +CUSTOM_PROP static long spaceOccupied +{ + return GetCachingManager().GetCachingDiskSpaceUsed(); +} + +OBSOLETE warning Please use Caching.spaceFree instead +CUSTOM_PROP static int spaceAvailable +{ + return GetCachingManager().GetCachingDiskSpaceFree(); +} + +OBSOLETE warning Please use Caching.spaceOccupied instead +CUSTOM_PROP static int spaceUsed +{ + return GetCachingManager().GetCachingDiskSpaceUsed(); +} + +// The number of seconds that an AssetBundle may remain unused in the cache before it is automatically deleted. +CUSTOM_PROP static int expirationDelay +{ + return GetCachingManager().GetExpirationDelay(); +} +{ + if (GetCachingManager().GetAuthorizationLevel() >= CachingManager::kAuthorizationUser) + GetCachingManager().GetCurrentCache().SetExpirationDelay(value); +} + +// Is Caching enabled? +CUSTOM_PROP static bool enabled +{ + return GetCachingManager().GetEnabled(); +} +{ + if (GetCachingManager().GetAuthorizationLevel() >= CachingManager::kAuthorizationAdmin) + GetCachingManager().SetEnabled(value); + else + ErrorString("Unable to assign a value to Caching.enabled. This property is read-only."); +} + +// Is caching ready? +CUSTOM_PROP static bool ready +{ + return GetCachingManager().GetIsReady(); +} + +CONDITIONAL UNITY_IPHONE_API +CUSTOM static void SetNoBackupFlag (string url, int version) +{ +#if UNITY_IPHONE + GetCachingManager().SetNoBackupFlag(url, version); +#endif +} + +CONDITIONAL UNITY_IPHONE_API +CUSTOM static void ResetNoBackupFlag (string url, int version) +{ +#if UNITY_IPHONE + GetCachingManager().ResetNoBackupFlag(url, version); +#endif +} + +END + +CSRAW + +#endif //ENABLE_WWW + +CONDITIONAL !UNITY_FLASH && !UNITY_WEBGL && !UNITY_WINRT +CLASS internal UnityLogWriter : System.IO.TextWriter + + THREAD_SAFE + CUSTOM static void WriteStringToUnityLog(string s) + { + //this userstring could contains things like "%20", which we should make sure printf does not interpet + //as if we wanted to print some argument. + if (s.IsNull()) + return; + + std::string utf8 = s.AsUTF8(); + printf_console("%s",utf8.c_str()); + } + + CSRAW + public static void Init() + { + System.Console.SetOut(new UnityLogWriter()); + } + public override System.Text.Encoding Encoding + { + get { return System.Text.Encoding.UTF8; } + } + public override void Write(char value) + { + WriteStringToUnityLog(value.ToString()); + } + public override void Write(string s) + { + WriteStringToUnityLog(s); + } + +END + +CLASS internal UnityString + CSRAW + public static string Format(string fmt, params object[] args) + { + return String.Format(fmt, args); + } +END + +}
\ No newline at end of file diff --git a/Runtime/Export/WP8.cs b/Runtime/Export/WP8.cs new file mode 100644 index 0000000..773886c --- /dev/null +++ b/Runtime/Export/WP8.cs @@ -0,0 +1,20 @@ +#if UNITY_WP8 && UNITY_WP8_NATIVE_COMPILER +using System; +using System.Runtime.InteropServices; + +namespace System +{ + [AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Struct|AttributeTargets.Enum|AttributeTargets.Delegate, Inherited = false)] + [ComVisible(true)] + public class SerializableAttribute : Attribute + { + + }; + + [AttributeUsageAttribute(AttributeTargets.Field, Inherited = false)] + [ComVisibleAttribute(true)] + public class NonSerializedAttribute : Attribute + { + }; +} +#endif diff --git a/Runtime/Export/WP8/WindowsPhone.txt b/Runtime/Export/WP8/WindowsPhone.txt new file mode 100644 index 0000000..cf0ea9b --- /dev/null +++ b/Runtime/Export/WP8/WindowsPhone.txt @@ -0,0 +1,32 @@ +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine.WindowsPhone +{ +CONDITIONAL UNITY_WP8_API +CLASS Media + + CSRAW public enum MediaState + { + Stopped, + Playing, + Paused + } + + /// BE CAREFUL WHEN CHANGING THIS. It's rewritten in DLL postprocessing, so any changes you make here will be overwritten + CSRAW public static MediaState mediaPlayerState + { + get + { + return (MediaState)0; + } + } + +CSRAW +END + +CSRAW +} diff --git a/Runtime/Export/WSA/WSAApplication.txt b/Runtime/Export/WSA/WSAApplication.txt new file mode 100644 index 0000000..79a6c2f --- /dev/null +++ b/Runtime/Export/WSA/WSAApplication.txt @@ -0,0 +1,130 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#if UNITY_METRO +#include "PlatformDependent/MetroPlayer/AppCallbacks.h" +#endif + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine.WSA +{ +CONDITIONAL UNITY_METRO_API +public delegate void AppCallbackItem(); + +CONDITIONAL UNITY_METRO_API +public delegate void WindowSizeChanged(int width, int height); + +CONDITIONAL UNITY_METRO_API +ENUM WindowActivationState + CodeActivated = 0, + + Deactivated = 1, + + PointerActivated = 2 +END + +CONDITIONAL UNITY_METRO_API +public delegate void WindowActivated(WindowActivationState state); + +CONDITIONAL UNITY_METRO_API +CLASS Application + + public static event WindowSizeChanged windowSizeChanged; + public static event WindowActivated windowActivated; + + CSRAW public static string arguments + { + get { + return GetAppArguments(); + } + } + + CUSTOM private static string GetAppArguments() + { + #if UNITY_METRO + std::string args = ConvertStringToUtf8(UnityPlayer::AppCallbacks::Instance->GetAppArguments()); + return scripting_string_new(args); + #else + return scripting_string_new(""); + #endif + } + + CSRAW internal static void InvokeWindowSizeChangedEvent(int width, int height) + { + if (windowSizeChanged != null) + windowSizeChanged.Invoke(width, height); + } + + CSRAW internal static void InvokeWindowActivatedEvent(WindowActivationState state) + { + if (windowActivated != null) windowActivated.Invoke(state); + } + + CSRAW public static void InvokeOnAppThread(AppCallbackItem item, bool waitUntilDone) + { + #if UNITY_EDITOR + item(); + #else + InternalInvokeOnAppThread(item, waitUntilDone); + #endif + } + CSRAW public static void InvokeOnUIThread(AppCallbackItem item, bool waitUntilDone) + { + #if UNITY_EDITOR + item(); + #else + InternalInvokeOnUIThread(item, waitUntilDone); + #endif + } + + CUSTOM internal static void InternalInvokeOnAppThread(AppCallbackItem item, bool waitUntilDone) + { + #if UNITY_METRO + UnityPlayer::AppCallbacks::Instance->InvokeOnAppThread(ref new UnityPlayer::AppCallbackItem( + GetWinRTTypeInformation()->CastScriptingObjectToAppCallbackItemStub(item)), waitUntilDone); + #endif + } + CUSTOM internal static void InternalInvokeOnUIThread(AppCallbackItem item, bool waitUntilDone) + { + #if UNITY_METRO + UnityPlayer::AppCallbacks::Instance->InvokeOnUIThread(ref new UnityPlayer::AppCallbackItem( + GetWinRTTypeInformation()->CastScriptingObjectToAppCallbackItemStub(item)), waitUntilDone); + #endif + } + + CUSTOM public static bool RunningOnAppThread() + { + #if UNITY_METRO + return UnityPlayer::AppCallbacks::Instance->RunningOnAppThread(); + #else + return true; + #endif + } + + CUSTOM public static bool RunningOnUIThread() + { + #if UNITY_METRO + return UnityPlayer::AppCallbacks::Instance->RunningOnUIThread(); + #else + return true; + #endif + } + + +CSRAW +END + +CSRAW +} diff --git a/Runtime/Export/WSA/WSATiles.txt b/Runtime/Export/WSA/WSATiles.txt new file mode 100644 index 0000000..71d7ca4 --- /dev/null +++ b/Runtime/Export/WSA/WSATiles.txt @@ -0,0 +1,848 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Math/Rect.h" +#include "Runtime/Math/Vector2.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#if UNITY_METRO + #include "PlatformDependent/MetroPlayer/MetroTiles.h" + typedef Windows::UI::Notifications::TileTemplateType TileTemplate; + typedef Windows::UI::Notifications::ToastTemplateType ToastTemplate; +#else + typedef int TileTemplate; + typedef int ToastTemplate; +#endif + +CSRAW +using UnityEngine; + +namespace UnityEngine.WSA +{ + +CONDITIONAL UNITY_METRO_API +ENUM TileTemplate + TileSquare150x150Image = 0, + TileSquare150x150Block = 1, + TileSquare150x150Text01 = 2, + TileSquare150x150Text02 = 3, + TileSquare150x150Text03 = 4, + TileSquare150x150Text04 = 5, + TileSquare150x150PeekImageAndText01 = 6, + TileSquare150x150PeekImageAndText02 = 7, + TileSquare150x150PeekImageAndText03 = 8, + TileSquare150x150PeekImageAndText04 = 9, + TileWide310x150Image = 10, + TileWide310x150ImageCollection = 11, + TileWide310x150ImageAndText01 = 12, + TileWide310x150ImageAndText02 = 13, + TileWide310x150BlockAndText01 = 14, + TileWide310x150BlockAndText02 = 15, + TileWide310x150PeekImageCollection01 = 16, + TileWide310x150PeekImageCollection02 = 17, + TileWide310x150PeekImageCollection03 = 18, + TileWide310x150PeekImageCollection04 = 19, + TileWide310x150PeekImageCollection05 = 20, + TileWide310x150PeekImageCollection06 = 21, + TileWide310x150PeekImageAndText01 = 22, + TileWide310x150PeekImageAndText02 = 23, + TileWide310x150PeekImage01 = 24, + TileWide310x150PeekImage02 = 25, + TileWide310x150PeekImage03 = 26, + TileWide310x150PeekImage04 = 27, + TileWide310x150PeekImage05 = 28, + TileWide310x150PeekImage06 = 29, + TileWide310x150SmallImageAndText01 = 30, + TileWide310x150SmallImageAndText02 = 31, + TileWide310x150SmallImageAndText03 = 32, + TileWide310x150SmallImageAndText04 = 33, + TileWide310x150SmallImageAndText05 = 34, + TileWide310x150Text01 = 35, + TileWide310x150Text02 = 36, + TileWide310x150Text03 = 37, + TileWide310x150Text04 = 38, + TileWide310x150Text05 = 39, + TileWide310x150Text06 = 40, + TileWide310x150Text07 = 41, + TileWide310x150Text08 = 42, + TileWide310x150Text09 = 43, + TileWide310x150Text10 = 44, + TileWide310x150Text11 = 45, + TileSquare310x310BlockAndText01 = 46, + TileSquare310x310BlockAndText02 = 47, + TileSquare310x310Image = 48, + TileSquare310x310ImageAndText01 = 49, + TileSquare310x310ImageAndText02 = 50, + TileSquare310x310ImageAndTextOverlay01 = 51, + TileSquare310x310ImageAndTextOverlay02 = 52, + TileSquare310x310ImageAndTextOverlay03 = 53, + TileSquare310x310ImageCollectionAndText01 = 54, + TileSquare310x310ImageCollectionAndText02 = 55, + TileSquare310x310ImageCollection = 56, + TileSquare310x310SmallImagesAndTextList01 = 57, + TileSquare310x310SmallImagesAndTextList02 = 58, + TileSquare310x310SmallImagesAndTextList03 = 59, + TileSquare310x310SmallImagesAndTextList04 = 60, + TileSquare310x310Text01 = 61, + TileSquare310x310Text02 = 62, + TileSquare310x310Text03 = 63, + TileSquare310x310Text04 = 64, + TileSquare310x310Text05 = 65, + TileSquare310x310Text06 = 66, + TileSquare310x310Text07 = 67, + TileSquare310x310Text08 = 68, + TileSquare310x310TextList01 = 69, + TileSquare310x310TextList02 = 70, + TileSquare310x310TextList03 = 71, + TileSquare310x310SmallImageAndText01 = 72, + TileSquare310x310SmallImagesAndTextList05 = 73, + TileSquare310x310Text09 = 74, +END + + +CONDITIONAL UNITY_METRO_API +ENUM ToastTemplate + ToastImageAndText01 = 0, + ToastImageAndText02 = 1, + ToastImageAndText03 = 2, + ToastImageAndText04 = 3, + ToastText01 = 4, + ToastText02 = 5, + ToastText03 = 6, + ToastText04 = 7, +END + + +CONDITIONAL UNITY_METRO_API +ENUM TileForegroundText +{ + Default = -1, + Dark = 0, + Light = 1 +} + +#if UNITY_METRO_API +public struct SecondaryTileData +{ + public string arguments; + private Color32 background; + public Color32 backgroundColor + { + get { + return background; + } + set { + background = value; + backgroundColorSet = true; + } + } + public bool backgroundColorSet; + public string displayName; + public TileForegroundText foregroundText; + public string lockScreenBadgeLogo; + public bool lockScreenDisplayBadgeAndTileText; + public string phoneticName; + public bool roamingEnabled; + public bool showNameOnSquare150x150Logo; + public bool showNameOnSquare310x310Logo; + public bool showNameOnWide310x150Logo; + public string square150x150Logo; + public string square30x30Logo; + public string square310x310Logo; + public string square70x70Logo; + public string tileId; + public string wide310x150Logo; + + public SecondaryTileData(string id, string displayName) + { + arguments = ""; + background = new UnityEngine.Color32(0, 0, 0, 0); + backgroundColorSet = false; + this.displayName = displayName; + foregroundText = TileForegroundText.Default; + lockScreenBadgeLogo = ""; + lockScreenDisplayBadgeAndTileText = false; + phoneticName = ""; + roamingEnabled = true; // this is default in Win 8.1 + showNameOnSquare150x150Logo = true; + showNameOnSquare310x310Logo = false; + showNameOnWide310x150Logo = false; + square150x150Logo = ""; + square30x30Logo = ""; + square310x310Logo = ""; + square70x70Logo = ""; + tileId = id; + wide310x150Logo = ""; + } +} +#endif + +CONDITIONAL UNITY_METRO_API +CLASS Tile + + CSRAW private string m_TileId; + + CSRAW private static Tile s_MainTile; + + CSRAW private Tile(string tileId) + { + m_TileId = tileId; + } + + CSRAW public static Tile main + { + get { + if (s_MainTile == null) + s_MainTile = new Tile(""); + return s_MainTile; + } + } + + CUSTOM public static string GetTemplate(TileTemplate templ) + { + #if UNITY_METRO + return scripting_string_new(metro::Tiles::GetTemplate(templ).c_str()); + #else + return scripting_string_new(""); + #endif + } + + CSRAW public void Update(string xml) + { + Update(m_TileId, xml); + } + + CUSTOM private static void Update(string tileId, string xml) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->Update(xml); + #endif + } + + CSRAW public void Update(string medium, string wide, string large, string text) + { + UpdateImageAndText(m_TileId, medium, wide, large, text); + } + + CUSTOM private static void UpdateImageAndText(string tileId, string medium, string wide, string large, string text) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->Update(medium, wide, large, text); + #endif + } + + CSRAW public void PeriodicUpdate(string uri, float interval) + { + PeriodicUpdate(m_TileId, uri, interval); + } + + CUSTOM private static void PeriodicUpdate(string tileId, string uri, float interval) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->PeriodicUpdate(uri, interval); + #endif + } + + CSRAW public void StopPeriodicUpdate() + { + StopPeriodicUpdate(m_TileId); + } + + CUSTOM private static void StopPeriodicUpdate(string tileId) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->StopPeriodicUpdate(); + #endif + } + + CSRAW public void UpdateBadgeImage(string image) + { + UpdateBadgeImage(m_TileId, image); + } + + CUSTOM private static void UpdateBadgeImage(string tileId, string image) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->UpdateBadgeImage(image); + #endif + } + + CSRAW public void UpdateBadgeNumber(float number) + { + UpdateBadgeNumber(m_TileId, number); + } + + CUSTOM private static void UpdateBadgeNumber(string tileId, float number) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->UpdateBadgeNumber(number); + #endif + } + + CSRAW public void RemoveBadge() + { + RemoveBadge(m_TileId); + } + + CUSTOM private static void RemoveBadge(string tileId) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->RemoveBadge(); + #endif + } + + CSRAW public void PeriodicBadgeUpdate(string uri, float interval) + { + PeriodicBadgeUpdate(m_TileId, uri, interval); + } + + CUSTOM private static void PeriodicBadgeUpdate(string tileId, string uri, float interval) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->PeriodicBadgeUpdate(uri, interval); + #endif + } + + CSRAW public void StopPeriodicBadgeUpdate() + { + StopPeriodicBadgeUpdate(m_TileId); + } + + CUSTOM private static void StopPeriodicBadgeUpdate(string tileId) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + if (tile) + tile->StopPeriodicBadgeUpdate(); + #endif + } + + CSRAW public string id + { + get { + return m_TileId; + } + } + + + CSRAW public bool hasUserConsent + { + get { + return HasUserConsent(m_TileId); + } + } + + CUSTOM private static bool HasUserConsent(string tileId) + { + #if UNITY_METRO + metro::Tile::Ptr tile = metro::Tiles::Instance(tileId); + return tile ? tile->HasUserConsent() : true; // No tile means user removed/rejected + #else + return false; + #endif + } + + CSRAW public bool exists + { + get { + return Exists(m_TileId); + } + } + + CUSTOM public static bool Exists(string tileId) + { + #if UNITY_METRO + return metro::Tiles::Instance(tileId) != NULL; + #else + return false; + #endif + } + + CSRAW private static string[] MakeSecondaryTileSargs(SecondaryTileData data) + { + string[] sargs = new string[10]; + sargs[0] = data.arguments; + sargs[1] = data.displayName; + sargs[2] = data.lockScreenBadgeLogo; + sargs[3] = data.phoneticName; + sargs[4] = data.square150x150Logo; + sargs[5] = data.square30x30Logo; + sargs[6] = data.square310x310Logo; + sargs[7] = data.square70x70Logo; + sargs[8] = data.tileId; + sargs[9] = data.wide310x150Logo; + return sargs; + } + + CSRAW private static bool[] MakeSecondaryTileBargs(SecondaryTileData data) + { + bool[] bargs = new bool[6]; + bargs[0] = data.backgroundColorSet; + bargs[1] = data.lockScreenDisplayBadgeAndTileText; + bargs[2] = data.roamingEnabled; + bargs[3] = data.showNameOnSquare150x150Logo; + bargs[4] = data.showNameOnSquare310x310Logo; + bargs[5] = data.showNameOnWide310x150Logo; + return bargs; + } + + CSRAW public static Tile CreateOrUpdateSecondary(SecondaryTileData data) + { + string[] sargs = MakeSecondaryTileSargs(data); + bool[] bargs = MakeSecondaryTileBargs(data); + Color32 backgroundColor = data.backgroundColor; + + string tileId = CreateOrUpdateSecondaryTile( + sargs, + bargs, + ref backgroundColor, + (int) data.foregroundText + ); + if (string.IsNullOrEmpty(tileId)) + return null; + return new Tile(tileId); + } + + // On Win 8.0 there is limitation on argument count, so we pass them as arrays + CUSTOM private static string CreateOrUpdateSecondaryTile( + string[] sargs, + bool[] bargs, + ref Color32 backgroundColor, + int foregroundText + ) + { + #if UNITY_METRO + std::string arguments = GetStringFromArray(sargs, 0); + std::string displayName = GetStringFromArray(sargs, 1); + std::string lockScreenBadgeLogo = GetStringFromArray(sargs, 2); + std::string phoneticName = GetStringFromArray(sargs, 3); + std::string square150x150Logo = GetStringFromArray(sargs, 4); + std::string square30x30Logo = GetStringFromArray(sargs, 5); + std::string square310x310Logo = GetStringFromArray(sargs, 6); + std::string square70x70Logo = GetStringFromArray(sargs, 7); + std::string tileId = GetStringFromArray(sargs, 8); + std::string wide310x150Logo = GetStringFromArray(sargs, 9); + + bool backgroundColorSet = GetBoolFromArray(bargs, 0); + bool lockScreenDisplayBadgeAndTileText = GetBoolFromArray(bargs, 1); + bool roamingEnabled = GetBoolFromArray(bargs, 2); + bool showNameOnSquare150x150Logo = GetBoolFromArray(bargs, 3); + bool showNameOnSquare310x310Logo = GetBoolFromArray(bargs, 4); + bool showNameOnWide310x150Logo = GetBoolFromArray(bargs, 5); + + + return scripting_string_new(metro::Tiles::CreateOrUpdateSecondary( + arguments, + backgroundColor, + backgroundColorSet, + displayName, + foregroundText, + lockScreenBadgeLogo, + lockScreenDisplayBadgeAndTileText, + phoneticName, + roamingEnabled, + showNameOnSquare150x150Logo, + showNameOnSquare310x310Logo, + showNameOnWide310x150Logo, + square150x150Logo, + square30x30Logo, + square310x310Logo, + square70x70Logo, + tileId, + wide310x150Logo + )->GetId()); + #else + return scripting_string_new(""); + #endif + } + + CSRAW public static Tile CreateOrUpdateSecondary(SecondaryTileData data, Vector2 pos) + { + string[] sargs = MakeSecondaryTileSargs(data); + bool[] bargs = MakeSecondaryTileBargs(data); + Color32 backgroundColor = data.backgroundColor; + + string tileId = CreateOrUpdateSecondaryTilePoint( + sargs, + bargs, + ref backgroundColor, + (int) data.foregroundText, + pos + ); + if (string.IsNullOrEmpty(tileId)) + return null; + return new Tile(tileId); + } + + CUSTOM private static string CreateOrUpdateSecondaryTilePoint( + string[] sargs, + bool[] bargs, + ref Color32 backgroundColor, + int foregroundText, + Vector2 pos + ) + { + #if UNITY_METRO + std::string arguments = GetStringFromArray(sargs, 0); + std::string displayName = GetStringFromArray(sargs, 1); + std::string lockScreenBadgeLogo = GetStringFromArray(sargs, 2); + std::string phoneticName = GetStringFromArray(sargs, 3); + std::string square150x150Logo = GetStringFromArray(sargs, 4); + std::string square30x30Logo = GetStringFromArray(sargs, 5); + std::string square310x310Logo = GetStringFromArray(sargs, 6); + std::string square70x70Logo = GetStringFromArray(sargs, 7); + std::string tileId = GetStringFromArray(sargs, 8); + std::string wide310x150Logo = GetStringFromArray(sargs, 9); + + bool backgroundColorSet = GetBoolFromArray(bargs, 0); + bool lockScreenDisplayBadgeAndTileText = GetBoolFromArray(bargs, 1); + bool roamingEnabled = GetBoolFromArray(bargs, 2); + bool showNameOnSquare150x150Logo = GetBoolFromArray(bargs, 3); + bool showNameOnSquare310x310Logo = GetBoolFromArray(bargs, 4); + bool showNameOnWide310x150Logo = GetBoolFromArray(bargs, 5); + + return scripting_string_new(metro::Tiles::CreateOrUpdateSecondary( + arguments, + backgroundColor, + backgroundColorSet, + displayName, + foregroundText, + lockScreenBadgeLogo, + lockScreenDisplayBadgeAndTileText, + phoneticName, + roamingEnabled, + showNameOnSquare150x150Logo, + showNameOnSquare310x310Logo, + showNameOnWide310x150Logo, + square150x150Logo, + square30x30Logo, + square310x310Logo, + square70x70Logo, + tileId, + wide310x150Logo, + pos + )->GetId()); + #else + return scripting_string_new(""); + #endif + } + + CSRAW public static Tile CreateOrUpdateSecondary(SecondaryTileData data, Rect area) + { + string[] sargs = MakeSecondaryTileSargs(data); + bool[] bargs = MakeSecondaryTileBargs(data); + Color32 backgroundColor = data.backgroundColor; + + string tileId = CreateOrUpdateSecondaryTileArea( + sargs, + bargs, + ref backgroundColor, + (int) data.foregroundText, + area + ); + if (string.IsNullOrEmpty(tileId)) + return null; + return new Tile(tileId); + } + + CUSTOM private static string CreateOrUpdateSecondaryTileArea( + string[] sargs, + bool[] bargs, + ref Color32 backgroundColor, + int foregroundText, + Rect area + ) + { + #if UNITY_METRO + std::string arguments = GetStringFromArray(sargs, 0); + std::string displayName = GetStringFromArray(sargs, 1); + std::string lockScreenBadgeLogo = GetStringFromArray(sargs, 2); + std::string phoneticName = GetStringFromArray(sargs, 3); + std::string square150x150Logo = GetStringFromArray(sargs, 4); + std::string square30x30Logo = GetStringFromArray(sargs, 5); + std::string square310x310Logo = GetStringFromArray(sargs, 6); + std::string square70x70Logo = GetStringFromArray(sargs, 7); + std::string tileId = GetStringFromArray(sargs, 8); + std::string wide310x150Logo = GetStringFromArray(sargs, 9); + + bool backgroundColorSet = GetBoolFromArray(bargs, 0); + bool lockScreenDisplayBadgeAndTileText = GetBoolFromArray(bargs, 1); + bool roamingEnabled = GetBoolFromArray(bargs, 2); + bool showNameOnSquare150x150Logo = GetBoolFromArray(bargs, 3); + bool showNameOnSquare310x310Logo = GetBoolFromArray(bargs, 4); + bool showNameOnWide310x150Logo = GetBoolFromArray(bargs, 5); + + return scripting_string_new(metro::Tiles::CreateOrUpdateSecondary( + arguments, + backgroundColor, + backgroundColorSet, + displayName, + foregroundText, + lockScreenBadgeLogo, + lockScreenDisplayBadgeAndTileText, + phoneticName, + roamingEnabled, + showNameOnSquare150x150Logo, + showNameOnSquare310x310Logo, + showNameOnWide310x150Logo, + square150x150Logo, + square30x30Logo, + square310x310Logo, + square70x70Logo, + tileId, + wide310x150Logo, + area + )->GetId()); + #else + return scripting_string_new(""); + #endif + } + + CSRAW public static Tile GetSecondary(string tileId) + { + if (Exists(tileId)) + return new Tile(tileId); + return null; + } + + CSRAW public static Tile[] GetSecondaries() + { + string[] ids = GetAllSecondaryTiles(); + Tile[] tiles = new Tile[ids.Length]; + for (int i = 0; i < ids.Length; ++i) + tiles[i] = new Tile(ids[i]); + return tiles; + } + + CUSTOM private static string[] GetAllSecondaryTiles() + { + #if UNITY_METRO + return Scripting::StringVectorToMono(metro::Tiles::GetSecondaries()); + #else + return ScriptingArrayPtr(); + #endif + } + + CSRAW public void Delete() + { + DeleteSecondary(m_TileId); + } + + CUSTOM public static void DeleteSecondary(string tileId) + { + #if UNITY_METRO + metro::Tiles::Delete(tileId); + #endif + } + + CSRAW public void Delete(Vector2 pos) + { + DeleteSecondaryPos(m_TileId, pos); + } + + CSRAW public static void DeleteSecondary(string tileId, Vector2 pos) + { + DeleteSecondaryPos(tileId, pos); + } + + CUSTOM private static void DeleteSecondaryPos(string tileId, Vector2 pos) + { + #if UNITY_METRO + metro::Tiles::Delete(tileId, pos); + #endif + } + + CSRAW public void Delete(Rect area) + { + DeleteSecondaryArea(m_TileId, area); + } + + CSRAW public static void DeleteSecondary(string tileId, Rect area) + { + DeleteSecondary(tileId, area); + } + + CUSTOM private static void DeleteSecondaryArea(string tileId, Rect area) + { + #if UNITY_METRO + metro::Tiles::Delete(tileId, area); + #endif + } + +END + + +CONDITIONAL UNITY_METRO_API +CLASS Toast + CSRAW private int m_ToastId; + + CSRAW private Toast(int id) + { + m_ToastId = id; + } + + CUSTOM public static string GetTemplate(ToastTemplate templ) + { + #if UNITY_METRO + return scripting_string_new(metro::Toasts::GetTemplate(templ)); + #else + return scripting_string_new(""); + #endif + } + + CSRAW public static Toast Create(string xml) + { + int id = CreateToastXml(xml); + if (id < 0) + return null; + return new Toast(id); + } + + CUSTOM private static int CreateToastXml(string xml) + { + #if UNITY_METRO + return metro::Toasts::Create(xml); + #else + return 0; + #endif + } + + CSRAW public static Toast Create(string image, string text) + { + int id = CreateToastImageAndText(image, text); + if (id < 0) + return null; + return new Toast(id); + } + + CUSTOM private static int CreateToastImageAndText(string image, string text) + { + #if UNITY_METRO + return metro::Toasts::Create(image, text); + #else + return 0; + #endif + } + + CSRAW public string arguments + { + get { + return GetArguments(m_ToastId); + } + set { + SetArguments(m_ToastId, value); + } + } + + CUSTOM private static string GetArguments(int id) + { + #if UNITY_METRO + metro::Toast::Ptr toast = metro::Toasts::Instance(id); + if (toast) + return scripting_string_new(toast->GetArguments()); + return scripting_string_new(""); + #else + return scripting_string_new(""); + #endif + } + + CUSTOM private static void SetArguments(int id, string args) + { + #if UNITY_METRO + metro::Toast::Ptr toast = metro::Toasts::Instance(id); + if (toast) + toast->SetArguments(args); + #endif + } + + CSRAW public void Show() + { + Show(m_ToastId); + } + + CUSTOM private static void Show(int id) + { + #if UNITY_METRO + metro::Toast::Ptr toast = metro::Toasts::Instance(id); + if (toast) + toast->Show(); + #endif + } + + CSRAW public void Hide() + { + Hide(m_ToastId); + } + + CUSTOM private static void Hide(int id) + { + #if UNITY_METRO + metro::Toast::Ptr toast = metro::Toasts::Instance(id); + if (toast) + toast->Hide(); + #endif + } + + CSRAW public bool activated + { + get { + return GetActivated(m_ToastId); + } + } + + CUSTOM private static bool GetActivated(int id) + { + #if UNITY_METRO + metro::Toast::Ptr toast = metro::Toasts::Instance(id); + return toast ? toast->GetActivated() : false; + #else + return false; + #endif + } + + CSRAW public bool dismissed + { + get { + return GetDismissed(m_ToastId, false); + } + } + + CSRAW public bool dismissedByUser + { + get { + return GetDismissed(m_ToastId, true); + } + } + + CUSTOM private static bool GetDismissed(int id, bool byUser) + { + #if UNITY_METRO + metro::Toast::Ptr toast = metro::Toasts::Instance(id); + return toast ? toast->GetDismissed(byUser) : false; + #else + return false; + #endif + } +END + +CSRAW +} diff --git a/Runtime/Export/WWW.cpp b/Runtime/Export/WWW.cpp new file mode 100644 index 0000000..facc72b --- /dev/null +++ b/Runtime/Export/WWW.cpp @@ -0,0 +1,1575 @@ +#include "UnityPrefix.h" +#include "WWW.h" +#include "Runtime/Utilities/LogAssert.h" +#include "Runtime/Threads/Thread.h" +#include "Configuration/UnityConfigureVersion.h" +#include "PlatformDependent/CommonWebPlugin/UnityWebStream.h" +#include "Runtime/Misc/ReproductionLog.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/Backend/ScriptingInvocation.h" +#include "Runtime/Misc/PlayerSettings.h" +#include "Runtime/Utilities/PathNameUtility.h" +#include "Runtime/Scripting/Backend/ScriptingMethodRegistry.h" +#include "External/Curl/include/minimalcurl.h" + +#if UNITY_EDITOR +#include "Editor/Src/EditorSettings.h" +#include "Editor/Src/EditorUserBuildSettings.h" +#endif + +#if UNITY_IPHONE +#include <CFNetwork/CFNetwork.h> +#include "PlatformDependent/iPhonePlayer/iPhoneWWW.h" +#elif UNITY_ANDROID +#include "PlatformDependent/AndroidPlayer/AndroidWWW.h" +#elif UNITY_PS3 +#include "PlatformDependent/PS3Player/PS3WWW.h" +#elif UNITY_FLASH +#include "PlatformDependent/FlashSupport/cpp/WWWFlash.h" +#elif UNITY_WINRT +#include "PlatformDependent/MetroPlayer/WWWMetro.h" +#elif UNITY_XENON +#include "PlatformDependent/Xbox360/Source/XenonWWW.h" +#elif UNITY_LINUX +#include "PlatformDependent/Linux/WWW.h" +#endif + +#if UNITY_WIN +#include <malloc.h> // alloca +#if !UNITY_WP8 +#include "Winhttp.h" +#endif +#include "PlatformDependent\Win\WinUnicode.h" +#endif +#ifdef __MWERKS__ +#include <alloca.h> +#endif +#if UNITY_OSX +#include "PlatformDependent/OSX/HttpProxy.h" +#endif + +#include <algorithm> + +#if ENABLE_WWW + +#if WWW_USE_CURL +static void SetCurlOptProxy (CURL* curl, const std::string& proxyUtf8, std::string::size_type offset) +{ + std::string::size_type end = proxyUtf8.find(";", offset); + std::string proxyConverted = proxyUtf8.substr(offset, end-offset); + curl_easy_setopt(curl, CURLOPT_PROXY, proxyConverted.c_str()); +} + +void SetupCurlProxyServerBasedOnEnvironmentVariable(CURL* curl, const char* url) +{ + const char* proxy = getenv("UNITY_PROXYSERVER"); + if (proxy) + { + printf_console("Setting up proxyserver from UNITY_PROXYSERVER environment variable. Setting to: %s\n",proxy); + curl_easy_setopt(curl, CURLOPT_PROXY, proxy); + } +#if UNITY_OSX || UNITY_LINUX + else + { + string proxy; + string auth; + if (GetProxyForURL(url, proxy, auth)) + { + curl_easy_setopt(curl, CURLOPT_PROXY, proxy.c_str()); + if (!auth.empty()) + curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, auth.c_str()); + } + } +#elif UNITY_WIN + else + { + WINHTTP_CURRENT_USER_IE_PROXY_CONFIG config; + if (WinHttpGetIEProxyConfigForCurrentUser(&config) && config.lpszProxy != NULL) + { + std::string proxyUtf8; + ConvertWideToUTF8String( config.lpszProxy, proxyUtf8 ); + std::string::size_type start = proxyUtf8.find("http="); + if (start != string::npos) + { + // handle http proxy with http= prefix + SetCurlOptProxy(curl, proxyUtf8, start+5); + } + else + { + // case #534876 + // proxy might be set, but without the http= prefix. + // Sufficient to check that no "=" characters are found in the string + if (proxyUtf8.find("=") == std::string::npos ) + SetCurlOptProxy(curl, proxyUtf8, 0); + } + } + } +#else +#pragma message("WARNING: This platform has no system proxy support") +#endif +} + +#endif // WWW_USE_CURL + +/* + WWW cleanup procedure> + + WWW c# has pointer to the www class. When the WWW class is garbage collected. It tells the WWW class to kill itself. (RequestDestroy) + RequestDestroy will + * When the download is complete, the WWW c++ class is deleted immediately. + * When the download thread is still running, set a flag abortDownload in buffer which causes download to stop asap + +When the thread is finished, we check the abortDownload and based on that delete the www class +(because RequestDestroy was called and no one is interested in it anymore) + +Or just keep it around, for any WWW c# access. + +*/ + +const char* kWWWErrCustomHeadersWithGET="Error when creating request. GET request with custom headers is not supported."; +const char* kWWWErrZeroPostData="Error when creating request. POST request with a zero-sized post buffer is not supported."; +const char* kWWWErrNULLPostDataWithPositiveLength="Internal error when creating request. Post data is NULL but length is larger than 0"; +const char* kWWWErrCancelled="WWW request was cancelled"; +const char* kWWWErrPostDataWithNonHTTPSchema="Error when creating request. Non HTTP schemas with post data are not supported."; +const char* kWWWErrHeadersWithNonHTTPSchema="Error when creating request. Non HTTP schemas with custom headers are not supported."; + + +double CalculateEta (int downloadedBytes, int totalBytes, double startTime) +{ + double curTime = GetTimeSinceStartup(); + // bytes left (total bytes can be smaller for streamed files, which are complete when the stream can begin) + int bytesLeft = std::max(totalBytes - downloadedBytes, 0); + double bytesPerSecond = downloadedBytes / std::max((curTime - startTime), 0.1); + double timeLeft = bytesLeft / bytesPerSecond; + return timeLeft; +} + +const char* GetCachedWWWError(const WWW& www, std::string& err) +{ + if (!err.empty()) + { + return err.c_str(); + } + + UnityWebStream* stream = www.GetUnityWebStream(); + if( stream && stream->IsErrorFlagSet() ) + { + // Constructs the error string without temporaries + err = stream->GetError (); + err += " URL: "; + err += www.GetUrl(); + return err.c_str(); + } + + return 0; +} + + +WWW::~WWW () +{ + if (m_UnityWebStream != NULL) + m_UnityWebStream->Release(); + + #if SUPPORT_REPRODUCE_LOG + CleanupWWW(this); + #endif +} + +#if SUPPORT_THREADS +void WWW::SetThreadPriority (ThreadPriority p) +{ + m_ThreadPriority = p; + if(m_UnityWebStream) + m_UnityWebStream->SetDecompressionPriority(m_ThreadPriority); +} +#endif + +WWW::SecurityPolicy WWW::GetSecurityPolicy() const +{ + return kSecurityPolicyAllowAccess; +} + +std::string WWW::GetResponseHeaders() //returning a copy instead of a reference for thread safety +{ + // JVD: std::string does not have atomic copy c-tor, so returning by value does not help to improve thread-safety + return m_ResponseHeaders; +} + +bool WWW::SetErrorFromResponseHeaders () +{ + std::string headers = GetResponseHeaders(); + + if ( !BeginsWith(headers, "HTTP") ) + return false; // Not a valid response header + + // only interested in first line. + headers = headers.substr(0, headers.find ("\n")); + + // get result code + size_t resultCodePos = headers.find (' '); + if (resultCodePos != string::npos) + { + headers = headers.substr(resultCodePos+1); + int status = 0; + if (sscanf (headers.c_str(), "%d", &status)) + { + if (status >= 400) + { + SetError (headers); + return true; + } + } + } + + return false; +} + +UnityWebStream* WWW::GetUnityWebStream() const +{ + return m_UnityWebStream; +} + +bool WWW::IsCached () const +{ + if (m_UnityWebStream) + return m_UnityWebStream->IsCached(); + else + return m_Cached; +} + +bool WWW::IsDone() const +{ + /* + There is an issue with how IsReadyToPlay is updated that causes small assetbundles to fail downloading. + This causes AssetStore previews to fail in the Editor. + TODO: Figure out why IsReadyToPlay is never set to true. + */ + return m_UnityWebStream ? m_UnityWebStream->IsFinished(): IsDownloadingDone(); +} + +void WWW::FeedUnityWebStream(bool isDone) +{ + // Check if this actually is a UnityWebStream file + if (!m_DidParseUnityWebStream) + { + UnityWebStreamHeader header; + + // Safely parse stream header + int result; + { + WWW::AutoLock lock(*this); + const UInt8* partialData = GetPartialData(); + result = ParseStreamHeader (header, partialData, partialData + GetPartialSize()); + } + + // Is Unity Web file + if (result == 0) + { + if(m_Cached) + m_UnityWebStream = UNITY_NEW_AS_ROOT(UnityWebStream(GetUrl(), m_CacheVersion, m_RequestedCRC), kMemFile, "WebStream", GetUrl()); + else + m_UnityWebStream = UNITY_NEW_AS_ROOT(UnityWebStream(NULL, 0, m_RequestedCRC), kMemFile, "WebStream", GetUrl()); +#if SUPPORT_THREADS + m_UnityWebStream->SetDecompressionPriority(m_ThreadPriority); +#endif + m_UnityWebStream->Retain(); + m_DidParseUnityWebStream = true; + } + // Is not a Unity Web file + else if (result == 2) + { + m_DidParseUnityWebStream = true; + } + } + + // Feed it the data that has arrived +#if !UNITY_FLASH + if (m_UnityWebStream) + { + WWW::AutoLock lock(*this); + + m_UnityWebStream->FeedDownloadData(GetPartialData() + m_StreamingPosition, GetPartialSize() - m_StreamingPosition, isDone); + m_StreamingPosition = GetPartialSize(); + } +#else + if(m_UnityWebStream && isDone){ + //RH : TODO : Flash gets the whole stream in one go for now, but we can still chunk this if needs be (if we decide to use swf compression instead). + m_UnityWebStream->FeedDownloadData(GetData(), GetSize(), isDone); + } +#endif +} + +UInt32 WWW::GetEstimatedDownloadSize() const +{ + return m_UnityWebStream && m_UnityWebStream->DidParseHeader() ? + m_UnityWebStream->GetHeader().completeFileSize: 0u; +} + +void WWW::Retain() +{ + m_RefCount.Retain(); +} + +void WWW::Release() +{ + if ( m_RefCount.Release() ) { + delete this; + } +} + +#if WWW_USE_BROWSER +#include "PlatformDependent/CommonWebPlugin/Download.h" +Download* StartDownloadBinding (const char* url, void* userData, DownloadProgressFunction* callback, const void* headersData, size_t headersLength, const void* postData, size_t postLength ); + +// Requires that m_Download exists +int WWWBrowser::GetTotalBytesUntilLoadable() const +{ + Assert(m_Download); + + if (GetUnityWebStream()) + { + int res = GetUnityWebStream()->GetTotalBytesUntilLoadable(); + if (res != -1) + return res; + } + + return m_Download->GetTotalBytes(); +} + +// When all data was in browser's cache, the download might already be finished +// (happens on IE6/IE7 at least). In this case our progress callback will not be +// ever called. So check download here and call progress callback manually. +// Case 15160, 15074. + +void WWWBrowser::ForceProgressDownload () +{ + if( m_Download != NULL && (m_Download->GetStatus() == Download::kCompleted || m_Download->GetStatus() == Download::kFailed) ) + { + WWWBrowser::ProgressDownload( m_Download ); + } +} + +extern int GetPluginVersion(); + +int WWWBrowser::ProgressDownload(Download* download) +{ + if (download->GetUserData () == NULL) + return 0; + + WWWBrowser& www = *reinterpret_cast<WWWBrowser*>(download->GetUserData ()); + + AssertIf(www.m_LockedPartialData != 0); + if (www.m_Download == NULL) + return 0; + + AssertIf(www.m_Download != download); + + // get the status before changing it later! + int downloadStatus = download->GetStatus(); + + // Detect if we are loading a unity web stream and feed it the data for live decompression + if (downloadStatus == Download::kLoading || downloadStatus == Download::kCompleted) + www.FeedUnityWebStream(downloadStatus == Download::kCompleted); + + if( downloadStatus == Download::kLoading ) + www.m_Eta = CalculateEta(download->GetDownloadedBytes(), www.GetTotalBytesUntilLoadable(), www.m_StartDownloadTime); + + if( downloadStatus <= Download::kLoading ) + return 0; + + // Mark for destruction! + www.m_Download->SetStatus(Download::kDestroyAfterCallback); + + if (GetPluginVersion() >= 5) + { + if(const char* headers = download->GetResponseHeaders()) + { + www.m_ResponseHeaders.assign(headers); + www.SetErrorFromResponseHeaders (); + } + else + { + www.m_ResponseHeaders.clear(); + } + } + + // Error while downloading + if( downloadStatus != Download::kCompleted ) + { + www.m_Error = "Failed downloading " + www.m_Url; + download->SetUserData (NULL); + www.m_Download = NULL; + return 0; + } + + #if SUPPORT_REPRODUCE_LOG + CompleteWWWReproduce(&www, www.GetUrl(), download->GetDownloadedData(), download->GetDownloadedBytes()); + #endif + + if (www.GetUnityWebStream() == NULL) + { + // Move over the data. We can't just reference the data from Download, because it is allocated + // from a different DLL (on Windows each DLL has separate heaps). + std::size_t dsize = download->GetDownloadedBytes(); + const UInt8* dfirst = download->GetDownloadedData(); + + www.m_Buffer.resize(dsize); + std::copy(dfirst, dfirst + dsize, www.m_Buffer.begin()); + } + // Don't copy data for unitywebstream + else + { + www.m_Buffer.clear(); + } + www.m_Eta = 0.0F; + download->SetUserData (NULL); + www.m_Download = NULL; + + return 0; +} + +WWWBrowser::WWWBrowser (const char* postDataPtr, int postDataLength, const WWWHeaders& i_Headers, bool cached, int cacheVersion , UInt32 crc) + : WWW(cached, cacheVersion, crc) + + , m_Download(NULL) + + , m_Buffer() // Empty +{ + m_Eta = std::numeric_limits<double>::infinity(); + m_StartDownloadTime = GetTimeSinceStartup(); + m_LockedPartialData = 0; + + WWWHeaders headers = i_Headers; // Copy headers as we want to modify them before generating data + + if( postDataPtr == NULL && postDataLength > 0 ) { + m_Error = kWWWErrNULLPostDataWithPositiveLength; + return; + } + if( postDataLength < 0 && !headers.empty() ) { + m_Error = kWWWErrCustomHeadersWithGET; + return; + } + if( postDataLength == 0 && postDataPtr != NULL) { + m_Error = kWWWErrZeroPostData; + return; + } + + // Pepper adds it's own Content-Length header on post requests. Adding one here will cause an error. +#if !UNITY_PEPPER + if( postDataLength > -1 && postDataPtr != NULL ) { + // Override the Content-Length header when we have post data + headers["Content-Length"] = IntToString( postDataLength ); + } + else +#endif + headers.erase("Content-Length"); + + // Put all headers into single headers string + m_HeadersString.clear(); + for( WWWHeaders::iterator i = headers.begin(); i != headers.end(); ++i ) + m_HeadersString += i->first + ": " + i->second + +#if !UNITY_PEPPER + "\r\n" +#else + // NaCl uses CORS validation to decide if it allows cross domain requests. + // Starting with Chrome 17, it will no longer allow any Unity requests with custom headers. + // Google explained that the validation would fail because we use \r which is an illegal + // character in the http headers string. We should probably also change it for non NaCl cases, + // but I don't want to risk anything at this rc stage. + "\n" +#endif + ; + if( postDataLength >= 0 && postDataPtr != NULL && !m_HeadersString.empty() ) + { + m_PostLength = postDataLength; + + // Store a terminating byte after last byte in buffer just in case somebody thinks it's a string + m_PostData = new char[ m_PostLength + 1 ]; + m_PostData[m_PostLength] = 0; + if( postDataLength > 0 ) + memcpy( m_PostData, postDataPtr, postDataLength ); + } + else + { + m_PostLength = -1; + m_PostData = NULL; + } + + m_Cached = cached; + m_CacheVersion = cacheVersion; +} + +void WWWBrowser::BlockUntilDone () +{ + if (GetUnityWebStream()) + GetUnityWebStream()->WaitForThreadDecompression(); +} + +WWWBrowser::~WWWBrowser () +{ + #if UNITY_LINUX + #warning FIXME LINUX +// if (m_Download != NULL) { +// delete m_Download; +// } + #else + if (m_Download != NULL) + { + m_Download->SetUserData (NULL); + m_Download->SetStatus(Download::kCancelAndDestroyAfterCallback); + m_Download = NULL; + } + #endif + + delete[] m_PostData; +} + +void WWWBrowser::Cancel () +{ + m_Error = kWWWErrCancelled; + if (m_Download != NULL) + { + m_Download->SetUserData (NULL); + m_Download->SetStatus(Download::kCancelAndDestroyAfterCallback); + m_Download = NULL; + } +} + +float WWWBrowser::GetProgress() const +{ + if (m_Download != NULL) + { + return GetDownloadProgress(m_Download->GetDownloadedBytes(), GetTotalBytesUntilLoadable()); + } + else + return 1.0F; +} + +float WWWBrowser::GetUploadProgress() const +{ + // @TODO: Implement this properly - currently we return 0.5 until download progress is > 0 + if ( m_Download == NULL) + return 1.0F; + return ( m_Download->GetDownloadedBytes() )?1.0F:0.5F; +} + +const char* WWWBrowser::GetError() +{ + return GetCachedWWWError(*this, m_Error); +} + +void WWWBrowser::SetError (const std::string& error) +{ + m_Error = error; +} + +const UInt8* WWWBrowser::GetPartialData() const +{ + AssertIf (m_LockedPartialData == 0); + + if (!m_Buffer.empty()) + return m_Buffer.data(); + else if (m_Download && (m_Download->GetStatus() == Download::kLoading || m_Download->GetStatus() == Download::kCompleted)) + { + return m_Download->GetDownloadedData (); + } + else + return NULL; +} + +size_t WWWBrowser::GetPartialSize() const +{ + AssertIf (m_LockedPartialData == 0); + + if (m_Buffer.empty() && m_Download != NULL) + return m_Download->GetDownloadedBytes (); + + return m_Buffer.size(); +} + +void WWWBrowser::LockPartialData() +{ +// ErrorString("Someone needs to think about and implement proper locking for this"); + m_LockedPartialData++; +} + +void WWWBrowser::UnlockPartialData() +{ + AssertIf(m_LockedPartialData == 0); + m_LockedPartialData--; +// ErrorString("Someone needs to think about and implement proper locking for this"); +} + +double WWWBrowser::GetETA() const +{ + return m_Eta; +} + +const UInt8* WWWBrowser::GetData() +{ + return m_Buffer.data(); +} + +size_t WWWBrowser::GetSize() +{ + return m_Buffer.size(); +} + +bool WWWBrowser::IsDownloadingDone() const +{ + return m_Download == NULL; +} + +bool WWWBrowser::HasDownloadedOrMayBlock () +{ + if (GetError () != NULL) + { + ErrorString(Format("You are trying to load data from a www stream which had the following error when downloading.\n%s", GetError())); + return false; + } + + if (IsDone()) + return true; + else + { + ErrorString("You are trying to load data from a www stream which has not completed the download yet.\nYou need to yield the download or wait until isDone returns true."); + return false; + } +} + +const char* WWWBrowser::GetUrl() const +{ + return m_Url.c_str(); +} + +WWWBrowser* WWWBrowser::CreateBrowser (const char* url, const char* postDataPtr, int postDataLength, const WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc ) +{ + WWWBrowser* www = new WWWBrowser (postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + if (www->GetError() != NULL) + return www; + + const char* actualUrl = url; + int actualPostLength = www->m_PostLength; + + #if SUPPORT_REPRODUCE_LOG + string remappedurl; + CreateWWWReproduce(www, url, remappedurl, actualPostLength); + actualUrl = remappedurl.c_str(); + #endif + + Download* download = StartDownloadBinding(actualUrl, www, WWWBrowser::ProgressDownload, www->m_HeadersString.c_str(), www->m_HeadersString.size(), www->m_PostData, actualPostLength ); + if (download) + { + www->m_Download = download; + www->m_Url = url; + + #if SUPPORT_REPRODUCE_LOG + // Cant show the WWW as completed right away. Need to wait until next frame. + if (RunningReproduction()) + { + return www; + } + #endif + + // When all data was in browser's cache, the download might already be finished + // (happens on IE6/IE7 at least). In this case our progress callback will not be + // ever called. So check download here and call progress callback manually. + // Case 15160, 15074. + www->ForceProgressDownload(); + + return www; + } + else + { + printf_console("Failed browser download\n"); + delete www; + return NULL; + } +} + +#endif // WWW_USE_BROWSER + +// This function creates a WWW backend without cross domain checking; it's good to have it separated from WWW::Create, because this way it's simpler to debug +// crossdomain checking routines, because they don't have to recursively call WWW::Create when download starts. +static WWW* CreatePlatformWWWBackend (const char* url, const char* postDataPtr, int postDataLength, const WWW::WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc ); + +WWW* WWW::Create (const char* url, const char* postDataPtr, int postDataLength, const WWWHeaders& headers, bool crossDomainChecked, bool cached, int cacheVersion, UInt32 crc ) +{ +#if ENABLE_WEBPLAYER_SECURITY + +#if SUPPORT_REPRODUCE_LOG + if (RunningReproduction()) crossDomainChecked = false; +#endif + +#if UNITY_EDITOR + if (GetBuildTargetGroup( GetEditorUserBuildSettings().GetActiveBuildTarget ()) != kPlatformWebPlayer) + crossDomainChecked = false; +#endif + + if (crossDomainChecked) + { + return new WWWCrossDomainChecked(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + } + +#endif // ENABLE_WEBPLAYER_SECURITY + return CreatePlatformWWWBackend(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); +} + +static WWW* CreatePlatformWWWBackend (const char* url, const char* postDataPtr, int postDataLength, const WWW::WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc ) +{ + #if WWW_USE_BROWSER + return WWWBrowser::CreateBrowser(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif UNITY_IPHONE + return new iPhoneWWW(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif UNITY_ANDROID + return new AndroidWWW(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif UNITY_FLASH + return new WWWFlash(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif UNITY_XENON + return new XenonWWW(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif UNITY_PS3 + return new PS3WWW(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif UNITY_WINRT + return new WWWMetro(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #elif WWW_USE_CURL + return new WWWCurl(url, postDataPtr, postDataLength, headers, cached, cacheVersion, crc); + #else + #error Unknown WWW backend + #endif +} + + +#if WWW_USE_CURL + +// Forward read callbacks from CURL to AppendBytes: +size_t WWWCurl::WriteCallback(void * data, size_t size, size_t elements, WWWCurl * myData) +{ + if (myData->abortDownload) + return -1; + + size_t res = myData->AppendBytes(data,size*elements); + + myData->FeedUnityWebStream(false); + + return res; +} + +//If the server reports a Content-Length header, allocate the whole block of memory in advance. +size_t WWWCurl::HeaderCallback(void * data, size_t size, size_t elements, WWWCurl * myData) +{ + if (myData->abortDownload) + return -1; + + size_t len = size*elements; + + char *str = (char*)alloca(len+1); + + memcpy(str, data, size*elements); + str[size*elements] = '\0'; + + size_t totalSize = 0; + if(sscanf(str,"Content-Length:%d",&totalSize)) + { + if(totalSize > myData->alloc_size) { + Mutex::AutoLock lock(myData->mutex); + myData->totalSize = totalSize; + myData->alloc_size = totalSize; + myData->data = (UInt8*)realloc((void*)myData->data, totalSize); + } + } + // Set response headers + { + Mutex::AutoLock lock(myData->mutex); + myData->m_ResponseHeaders.append(str); + myData->m_ResponseHeaders.append("\r\n"); + } + myData->SetErrorFromResponseHeaders (); + return size*elements; +} + +// Forward read callbacks from CURL to PostBytes: +size_t WWWCurl::ReadCallback(void * data, size_t size, size_t elements, WWWCurl * myData) +{ + if (myData->abortDownload) + return -1; + + size_t res = myData->PostBytes(data,size*elements); + return res; +} + +int WWWCurl::ProgressCallback (WWWCurl *myData, + double dltotal, + double dlnow, + double ultotal, + double ulnow) +{ + if (myData->abortDownload) + return -1; + + if( dltotal > 0 ) { + myData->totalSize = dltotal; + myData->progress = dlnow / dltotal; + myData->eta = CalculateEta (RoundfToInt(dlnow), RoundfToInt(dltotal), myData->startTime); + myData->uploadProgress = 1.0; + } + else if( ultotal > 0 ) { + myData->uploadProgress = ulnow / ultotal; + } + return 0; +} + +UInt32 WWWCurl::GetEstimatedDownloadSize() const +{ + if (totalSize > 0) + return totalSize; + else + return WWW::GetEstimatedDownloadSize(); +} + +curl_slist* WWWCurl::GetHeaderSList () { + // Remove any previously generated headers + if(curlHeaders != NULL) + curl_slist_free_all(curlHeaders); + + // Now begin with an empty slist + curlHeaders=NULL; + + for(WWWHeaders::iterator i = requestHeaders.begin(); i != requestHeaders.end(); i++) + curlHeaders = curl_slist_append(curlHeaders, (i->first + ": " + i->second).c_str() ); + + return curlHeaders; +} + +CURLcode WWWCurl::GetURL( const char* url) { + CURL* curl = curl_easy_init(); + CURLcode res = 1; + if(curl) { + + curl_easy_setopt(curl, CURLOPT_URL, url); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, this); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); // We don't install CA certs with unity, so disable SSL cert validation + curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); // Needs to be set when running cur in multible threads + + // @TODO: Enable cookies using something like this: + // (or preferably something that does not require storing files on disk. expose cookies through Application.cookies[xx] or simmilar) + // curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookie_file); + // curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cookie_file); + + // If we have post data, the request should be a POST request + if(postData != NULL && postLength > -1) { + postPosition=0; + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postLength); + curl_easy_setopt(curl, CURLOPT_READDATA, this); + curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadCallback); + requestHeaders["Content-Length"]=Format("%d",postLength); + } + + curl_slist* headers = GetHeaderSList (); + if(headers != NULL) + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); + curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); + curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, ProgressCallback); +// curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 16000); + + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer); + curl_easy_setopt(curl, CURLOPT_USERAGENT, "UnityPlayer/" UNITY_VERSION " (http://unity3d.com)"); +// curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5); + + curl_easy_setopt(curl, CURLOPT_HEADERDATA, this); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback); + + SetupCurlProxyServerBasedOnEnvironmentVariable(curl, url); + + // curl_easy_setopt(curl, CURLOPT_HEADER, 1L); // TODO + + res = curl_easy_perform(curl); + + curl_easy_cleanup(curl); + } + + progress = 1.0F; + uploadProgress = 1.0F; + eta = 0.0F; + + return res; +} + +void WWWCurl::SetThreadPriority( ThreadPriority priority ) +{ + WWW::SetThreadPriority(priority); + thread.SetPriority(priority); +} + +size_t WWWCurl::AppendBytes(void * moreData, size_t bytes) +{ + if(size+bytes > alloc_size) + { + Mutex::AutoLock lock(mutex); + const UInt32 estimatedDownloadSize = GetEstimatedDownloadSize(); + if (alloc_size+bytes <= estimatedDownloadSize) + alloc_size = estimatedDownloadSize; + else + alloc_size = (alloc_size * 1.5) + bytes; + data = (UInt8*)realloc((void*)data, alloc_size); + if (!data) + { + ErrorString("WWW: out of memory"); + return 0; // this will stop the transfer - not all data is loaded + } + } + if (!moreData){ + return 0; + } + memcpy(data+size,moreData,bytes); + size += bytes; + return bytes; +} + +std::string WWWCurl::GetResponseHeaders() +{ + Mutex::AutoLock lock(mutex); + return m_ResponseHeaders; +} + +size_t WWWCurl::PostBytes(void * moreData, size_t bytes) { + if(bytes > postLength-postPosition) + bytes = postLength-postPosition; + + if(bytes <= 0) return 0; // end of file + + memcpy(moreData,postData+postPosition,bytes); + postPosition += bytes; + return bytes; +} + +// A C wrapper for the pthread entry point +void* WWWCurl::WWW_ThreadEntryPoint(void* data) +{ + WWWCurl& www = *(WWWCurl*)data; + + www.result = www.GetURL(www.url); + + if (!www.abortDownload && www.GetError() == NULL) + { + www.FeedUnityWebStream(true); + } + + return data; +} +WWWCurl::WWWCurl( const char* in_url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool cached, int cacheVersion, UInt32 crc ) + : WWW(cached, cacheVersion, crc) +{ + DoInit(in_url, in_postData, in_postLength, in_headers); +} + +void WWWCurl::StartThread() +{ + thread.Run(&WWW_ThreadEntryPoint, (void*) this); +} + +void WWWCurl::BlockUntilDone() +{ + thread.WaitForExit(); + + if (GetUnityWebStream()) + GetUnityWebStream()->WaitForThreadDecompression(); +} + +bool WWWCurl::IsDownloadingDone() const +{ + return !thread.IsRunning(); +} + +const UInt8* WWWCurl::GetData() +{ + BlockUntilDone(); + return data; +} + +const UInt8* WWWCurl::GetPartialData() const +{ + return data; +} + +void WWWCurl::LockPartialData() +{ + mutex.Lock(); +} + +void WWWCurl::UnlockPartialData() +{ + mutex.Unlock(); +} + +const char* WWWCurl::GetError() +{ + if (strlen (errorBuffer)) + return errorBuffer; + + std::string fullError; + const char* err = GetCachedWWWError(*this, fullError); + SetError(fullError); // Nothing will be set if empty + return err; +} + +void WWWCurl::SetError (const std::string& error) +{ + strncpy (errorBuffer, error.c_str(), CURL_ERROR_SIZE); +} + + +size_t WWWCurl::GetSize() +{ + BlockUntilDone(); + return size; +} + +size_t WWWCurl::GetPartialSize() const +{ + return size; +} + + +const char* WWWCurl::GetUrl() const +{ + return url; +} + +float WWWCurl::GetProgress() const +{ + return progress; +} + +float WWWCurl::GetUploadProgress() const +{ + return uploadProgress; +} + +double WWWCurl::GetETA() const +{ + if(IsDone()) + return 0.0; + else + return eta; +} + + +bool WWWCurl::HasDownloadedOrMayBlock () +{ + if (GetError () != NULL) + { + ErrorString(Format("You are trying to load data from a www stream which had the following error when downloading.\n%s", GetError())); + return false; + } + + if (IsDone()) + return true; + else + { + // File based curl's may block + if( BeginsWithCaseInsensitive(url, "file://") ) + return true; + + ErrorString("You are trying to load data from a www stream which has not completed the download yet.\nYou need to yield the download or wait until isDone returns true."); + return false; + } +} + + +void WWWCurl::DoInit( const char* in_url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers ) +{ + alloc_size=0; + size=0; + postData=NULL; + postLength=-1; + postPosition=0; + data=NULL; + errorBuffer=(char*)calloc(CURL_ERROR_SIZE,sizeof(char)); + AssertIf(!errorBuffer); + errorBuffer[0] = 0; + abortDownload = false; + progress = 0; + totalSize = 0; + uploadProgress = 0; + startTime = GetTimeSinceStartup(); + curlHeaders=NULL; + eta = std::numeric_limits<double>::infinity(); + + url = (char*)malloc(strlen(in_url)+1); + AssertIf(!url); + strcpy(url, in_url); + + if( in_postData == NULL && in_postLength > 0 ) { + result=-1; + if (errorBuffer) free (errorBuffer); + errorBuffer=(char*)malloc(strlen(kWWWErrNULLPostDataWithPositiveLength)+1); + strcpy(errorBuffer, kWWWErrNULLPostDataWithPositiveLength); + progress = 1.0F; + return; + } + if( in_postLength == 0 && in_postData != NULL) { + result=-1; + if (errorBuffer) free (errorBuffer); + errorBuffer=(char*)malloc(strlen(kWWWErrZeroPostData)+1); + if(errorBuffer) + strcpy(errorBuffer, kWWWErrZeroPostData); + progress = 1.0F; + return; + } + + + requestHeaders = in_headers; + + if(in_postData != NULL && in_postLength > -1) { + postLength=in_postLength; + postData = new char[in_postLength]; + memcpy((void *)postData, (const void*)in_postData, in_postLength); + } + + result = 0; + + StartThread(); +} + +WWWCurl::~WWWCurl() +{ + abortDownload = true; + thread.WaitForExit(); + + // Abort decompressionthreads that the curl thread might have spawned + if (GetUnityWebStream()) + GetUnityWebStream()->AbortThreadDecompression (); + + free(data); + free(errorBuffer); + if(postData != NULL) delete[](postData); + if(curlHeaders != NULL) + curl_slist_free_all(curlHeaders); + + free(url); +} + +void WWWCurl::Cancel () +{ + strcpy(errorBuffer, kWWWErrCancelled); + if (thread.IsRunning ()) + { + abortDownload = true; + } +} + + +#endif // WWW_USE_CURL + +WWWDelayCall::WWWDelayCall(WWW* www, DelayedCall* func, Object* o, void* userData, CleanupUserData* cleanup){ + m_wait_for=www; + m_wait_for->Retain(); + m_func=func; + m_o=o; + m_userData=userData; + m_cleanup=cleanup; +} + +WWWDelayCall::~WWWDelayCall() { + m_wait_for->Release(); + if (m_cleanup != NULL) { + m_cleanup(m_userData); + } +} + +void WWWDelayCall::Cleanup(void* userData) { + AssertIf(userData == NULL); + WWWDelayCall* delayCall = (WWWDelayCall*) userData; + delete delayCall; +} + +void WWWDelayCall::Callback(Object* o, void* userData) { + WWWDelayCall* delayCall = (WWWDelayCall*) userData; + AssertIf(delayCall->m_o != o); + + if(delayCall->m_wait_for == NULL || delayCall->m_wait_for->IsDone()) { + delayCall->m_func(o, delayCall->m_userData); + GetDelayedCallManager ().CancelCallDelayed(o,WWWDelayCall::Callback, WWWDelayCall::MatchForCancel, userData); + } +} + +bool WWWDelayCall::MatchForCancel(void* callBackUserData, void* cancelUserData) { + return callBackUserData == cancelUserData; +} + +void WWW::CallWhenDone(DelayedCall* func, Object* o, void* userData, CleanupUserData* cleanup) { + WWWDelayCall* delayCall = new WWWDelayCall(this, func, o, userData, cleanup); + CallDelayed(WWWDelayCall::Callback, o, 0.0F, (void*)delayCall, -1.0F, WWWDelayCall::Cleanup, DelayedCallManager::kRunDynamicFrameRate | DelayedCallManager::kWaitForNextFrame); +} + +#if ENABLE_WEBPLAYER_SECURITY + +#include "Runtime/Utilities/ArrayUtility.h" + +void ProcessCrossDomainRequestsFromNonMainThread() +{ + MonoMethod* monoMethod = mono_unity_find_method("CrossDomainPolicyParser.dll","UnityEngine","UnityCrossDomainHelper","ProcessRequestsFromOtherThreads"); + ScriptingMethodPtr method = GetScriptingManager().GetScriptingMethodRegistry().GetMethod(monoMethod); + if (!method) + { + Assert("Unable to find ProcessRequestsFromOtherThreads"); + return; + } + + ScriptingInvocation(method).Invoke(); +} + + +class WWWCrossDomainCheckedImpl : public WWW +{ +private: + std::string m_URL; + const char* m_Error; + ScriptingMethodPtr m_ScriptingMethod; + + // Serves only as a cache, nothing more + mutable SecurityPolicy m_CachedSecPolicy; + +public: + WWWCrossDomainCheckedImpl (const char* url, bool cached, int cacheVersion, UInt32 crc); + ~WWWCrossDomainCheckedImpl () {} + + virtual SecurityPolicy GetSecurityPolicy() const; + virtual const UInt8* GetData() { return 0; } + virtual const UInt8* GetPartialData() const { return 0; } + virtual size_t GetSize() { return 0u; } + virtual size_t GetPartialSize() const { return 0u; } + virtual UnityWebStream* GetUnityWebStream () const { return 0; } + + virtual double GetETA() const { return std::numeric_limits<double>::infinity(); } + + virtual void LockPartialData() {} + virtual void UnlockPartialData() {} + + // Returns true when the download is complete or failed. + virtual void Cancel() { m_ScriptingMethod = 0; } + virtual bool IsDownloadingDone() const; + virtual float GetProgress() const { return 0.0f; } + virtual float GetUploadProgress() const { return 0.0f; } + virtual const char* GetError() { return m_Error; } + virtual const char* GetUrl() const { return m_URL.c_str(); } + virtual bool HasDownloadedOrMayBlock () { return true; } + virtual void BlockUntilDone () { while ( !IsDownloadingDone() ) { /*Wait*/ } } + + virtual WWWType GetType () const { return kWWWTypeCrossDomainChecked; } + + bool HasNoErrors() const { return m_Error == 0; } + + const std::string& GetUrlString() const { return m_URL; } + void SetErrorStringPtr (const char* error) { m_Error = error; } +}; + + +inline static ScriptingMethodPtr GetCrossDomainPolicyParserScriptingMethod() +{ + MonoMethod* monoMethod = mono_unity_find_method("CrossDomainPolicyParser.dll","UnityEngine","UnityCrossDomainHelper","GetSecurityPolicy"); + return GetScriptingManager().GetScriptingMethodRegistry().GetMethod(monoMethod); +} + +WWWCrossDomainCheckedImpl::WWWCrossDomainCheckedImpl (const char* url, bool cached, int cacheVersion, UInt32 crc) + : WWW(cached, cacheVersion, crc) + , m_URL(url) + , m_Error(0) // Null error string + , m_ScriptingMethod(GetCrossDomainPolicyParserScriptingMethod()) + , m_CachedSecPolicy(kSecurityPolicyDontKnowYet) +{ + if (!m_ScriptingMethod) + { + m_CachedSecPolicy = kSecurityPolicyDenyAccess; + AssertString("Unable to find GetSecurityPolicy"); + } +} + +WWW::SecurityPolicy WWWCrossDomainCheckedImpl::GetSecurityPolicy() const +{ + if( kSecurityPolicyDontKnowYet != m_CachedSecPolicy ) + return m_CachedSecPolicy; + + if( !m_ScriptingMethod ) + return kSecurityPolicyDenyAccess; + + ScriptingInvocation invocation(m_ScriptingMethod); + invocation.AddString(m_URL.c_str()); + MonoObject* result = invocation.Invoke(); + + // Cache the security policy so that we don't need to invoke Mono repeatedly once we know the status + m_CachedSecPolicy = result ? *reinterpret_cast<SecurityPolicy*>(mono_object_unbox (result)): + kSecurityPolicyDenyAccess; + + return m_CachedSecPolicy; +} + +bool WWWCrossDomainCheckedImpl::IsDownloadingDone() const +{ + return GetSecurityPolicy() != kSecurityPolicyDontKnowYet; +} + +WWWCrossDomainChecked::WWWCrossDomainChecked (const char* url, const char* postData, int postDataLength, const WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc) + : WWW (cached, cacheVersion, crc), + m_PostData(0), + m_PostDataLength(postDataLength), + m_Headers(headers), + m_CrossChecker(new WWWCrossDomainCheckedImpl(url, cached, cacheVersion, crc)) +{ + if( postDataLength > 0 && postData != 0 ) + { + m_PostDataDataCopy.assign(postData, postData + postDataLength); + m_PostData = m_PostDataDataCopy.c_str(); + } + + // m_WWW is guaranteed to be initialized thoughout the lifetime of this object. At first it points to + // m_CrossChecker, which contains the stubs of all the required WWW member functions. This allows the + // trivial forwarders to be, indeed, trivial. For example, GetETA() or UnlockPartialData() do not require + // any additional checks whether the crossdomain checking has finished, or not. + m_WWW = m_CrossChecker; + m_WWW->Retain(); +} + +WWWCrossDomainChecked::~WWWCrossDomainChecked () +{ + m_WWW->Release(); // It's a no-op for the crossdomain checker, + // but will destroy an initialized WWW backend + m_CrossChecker->Release(); +} + +bool WWWCrossDomainChecked::RequestLooksSafeEnoughToMakeWithoutPolicyAccess() const +{ + /// We do this in order to completely prevent downloads that have failed the cross domain check. + /// As a result, if you download a png with a .txt extension it will not even download it thus you can't use it as a texture. + /// Using ".png" with a failing cross domain check is actually legal. + /// As long as you don't use .bytes on it, but instead just use it as a texture. It results in no security risk. + /// + /// In theory this check could be removed but it might be confusing for admins looking at unity seeing that secret.pdf actually gets downloaded. + /// Even though the script code can't actually access the data. + + //if it has post headers, we'll deny. + if (m_PostData != 0) return false; + + static const char* allowed_extensions[] = { + "png", "jpg", "jpeg", "tga", "tiff", // if it looks like a texture, we'll allow it + "wav", "mp3", "ogg", "xm", "mod", "s3m", "it" // if it looks like an audiofile, we'll allow it + }; + + const char** iter_first = allowed_extensions; + const char** iter_last = allowed_extensions + ARRAY_SIZE(allowed_extensions); + return std::find( iter_first, iter_last, ToLower(GetPathNameExtension (m_CrossChecker->GetUrlString())) ) != iter_last; +} + +bool WWWCrossDomainChecked::CanCreateDownloader() const +{ + // At this point we must have our security policy + Assert( m_CrossChecker->IsDownloadingDone() ); + + return m_WWW == m_CrossChecker && // Still no WWW backend + m_CrossChecker->HasNoErrors(); // There are no crossdomain checker errors +} + +void WWWCrossDomainChecked::StartEmbeddedDownload() +{ + if( CanCreateDownloader() ) + { + // Download hasn't begun yet, so we check what kind of security policy + // we have, or what type of content we want to download + if( GetSecurityPolicy() == kSecurityPolicyAllowAccess || RequestLooksSafeEnoughToMakeWithoutPolicyAccess() ) + { + m_WWW->Release(); // Release previously hold counter on m_CrossChecker + + m_WWW = CreatePlatformWWWBackend(m_CrossChecker->GetUrl(), m_PostData, m_PostDataLength, m_Headers, + m_Cached, m_CacheVersion, m_RequestedCRC); + + #if SUPPORT_THREADS + m_WWW->SetThreadPriority(GetThreadPriority()); + #endif + } + else + { + m_CrossChecker->SetErrorStringPtr("Rejected because no crossdomain.xml policy file was found"); + } + } +} + +void WWWCrossDomainChecked::BlockedStartEmbeddedDownload() +{ + // First we block on cross checker. + m_CrossChecker->BlockUntilDone(); + + // Now the cross domain checker has finished, we want to block + // on the donwloader until it's done. + StartEmbeddedDownload(); +} + +void WWWCrossDomainChecked::LockPartialData() +{ + // The crosschecker might have done its job, so we would like to + // start the real download and then lock the downloader's partial data. + if( m_CrossChecker->IsDownloadingDone() ) + { + StartEmbeddedDownload(); + } + + // If embedded download has started, then this locks WWW backend, otherwise this + // tries to lock m_CrossChecker, which is no-op. + m_WWW->LockPartialData(); +} + +void WWWCrossDomainChecked::BlockUntilDone () +{ + BlockedStartEmbeddedDownload(); + m_WWW->BlockUntilDone(); +} + +const UInt8* WWWCrossDomainChecked::GetData() +{ + BlockedStartEmbeddedDownload(); + return m_WWW->GetData(); +} +std::size_t WWWCrossDomainChecked::GetSize() +{ + BlockedStartEmbeddedDownload(); + return m_WWW->GetSize(); +} + +bool WWWCrossDomainChecked::HasDownloadedOrMayBlock () +{ + if (GetError () != NULL) + { + ErrorString(Format("You are trying to load data from a www stream which had the following error when downloading.\n%s", GetError())); + return false; + } + return m_WWW->HasDownloadedOrMayBlock(); +} + +WWW::SecurityPolicy WWWCrossDomainChecked::GetSecurityPolicy() const +{ + return m_CrossChecker->GetSecurityPolicy(); +} + +const char* WWWCrossDomainChecked::GetUrl() const +{ + return m_CrossChecker->GetUrl(); +} + +// Trivial forwarders to the currently running WWW backend: +// m_WWW can either be CrossDomainChecker or the backend that is created in CreatePlatformWWWBackend. +bool WWWCrossDomainChecked::IsDownloadingDone() const +{ + if( !m_CrossChecker->IsDownloadingDone() ) + { + // Can't be done, because crossdomain check is not finished + return false; + } + + if( CanCreateDownloader() ) // There is still no WWW backend + { + // Dummy PartialDataLock/PartialDataUnlock sequence; this may create + // a WWW backend if content downloading is allowed. + WWW::AutoLock lock(*const_cast<WWWCrossDomainChecked*>(this)); + } + + return m_WWW->IsDone(); +} + +const char* WWWCrossDomainChecked::GetError() +{ + return m_WWW->GetError(); +} + +void WWWCrossDomainChecked::Cancel() +{ + return m_WWW->Cancel(); +} + +void WWWCrossDomainChecked::SetThreadPriority( ThreadPriority priority ) +{ + WWW::SetThreadPriority(priority); + return m_WWW->SetThreadPriority(priority); +} + +// PartialData functions will forward to the m_CrossDomainChecker if locking +// was not acquired. Those functions are dummy and, naturally, do nothing. +// If crossdomain checking has succeeded and permissions were sufficient to start +// a download, then these partial data items will properly redirect to a WWW backend's +// apropriate functions. + +const UInt8* WWWCrossDomainChecked::GetPartialData() const +{ + return m_WWW->GetPartialData(); +} + +std::size_t WWWCrossDomainChecked::GetPartialSize() const +{ + return m_WWW->GetPartialSize(); +} + +void WWWCrossDomainChecked::UnlockPartialData() +{ + return m_WWW->UnlockPartialData(); +} + +std::string WWWCrossDomainChecked::GetResponseHeaders() +{ + return m_WWW->GetResponseHeaders(); +} + +float WWWCrossDomainChecked::GetProgress () const +{ + // WWWCrossDomainChecked requires polling IsDone on the WWW to do it's job. + // Usually users would query isDone from script code, or yield the www, but + // they might only use .progress or .audioClip.isReadyToPlay, which would never + // call isDone, so we call it here. + IsDone(); + return m_WWW->GetProgress(); +} + +double WWWCrossDomainChecked::GetETA () const +{ + return m_WWW->GetETA(); +} + +UnityWebStream* WWWCrossDomainChecked::GetUnityWebStream() const +{ + return m_WWW->GetUnityWebStream(); +} + +bool WWWCrossDomainChecked::IsCached () const +{ + return m_WWW->IsCached(); +} + +#endif // ENABLE_WEBPLAYER_SECURITY + +// Decodes % Escaped URL string +std::string DecodeEscapedURL(const std::string& url) +{ + std::string urlCopy; + urlCopy.reserve(url.length()); + + int newLength = 0; + for (unsigned int i = 0u; i < url.length(); i++) + { + if (url[i] != '%') + { + urlCopy += url[i]; + } + else if (i + 2 < url.length()) + { + char hex[2] = { url[i + 1], url[i + 2] }; + using namespace std;//Flash fix. + urlCopy += static_cast<char>(strtol(hex, NULL, 16)); + i += 2; + } + } + + return urlCopy; +} +#endif //ENABLE_WWW diff --git a/Runtime/Export/WWW.cs b/Runtime/Export/WWW.cs new file mode 100644 index 0000000..37652bc --- /dev/null +++ b/Runtime/Export/WWW.cs @@ -0,0 +1,168 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; + +namespace UnityEngine +{ +#if ENABLE_WWW + partial class WWW + { +#if UNITY_WEBPLAYER || UNITY_EDITOR + static readonly char[] forbiddenCharacters = { + (char)0, (char)1, (char)2, (char)3, (char)4, (char)5, + (char)6, (char)7, (char)8, (char)9, (char)10, + (char)11, (char)12, (char)13, (char)14, (char)15, + (char)16, (char)17, (char)18, (char)19, (char)20, + (char)21, (char)22, (char)23, (char)24, (char)25, + (char)26, (char)27, (char)28, (char)29, (char)30, + (char)31, (char)127 + }; + + // From http://www.w3.org/TR/XMLHttpRequest/#the-setrequestheader()-method + static readonly string[] forbiddenHeaderKeys = + { + "Accept-Charset", + "Accept-Encoding", + "Access-Control-Request-Headers", + "Access-Control-Request-Method", + "Connection", + "Content-Length", + "Cookie", + "Cookie2", + "Date", + "DNT", + "Expect", + "Host", + "Keep-Alive", + "Origin", + "Referer", + "TE", + "Trailer", + "Transfer-Encoding", + "Upgrade", + "User-Agent", + "Via", + "X-Unity-Version", + }; + + // Ensure headers do not contain invalid characters (ASCII 0-31, 127) + // This prevents XSS and header-spoofing vulnerabilities. + private static void CheckSecurityOnHeaders(string[] headers) + { + bool failNoisy = Application.GetBuildUnityVersion() >= Application.GetNumericUnityVersion("4.3.0b1"); + + // On non-webplayer platforms, we permit the platform itself to define the restrictions. + for(int i = 0; i < headers.Length; i+=2) + { + // headers[i] is the header name + // headers[i+1] is the header body + + foreach(string forbiddenHeaderKey in forbiddenHeaderKeys) + { + if(string.Equals(headers[i], forbiddenHeaderKey, StringComparison.CurrentCultureIgnoreCase)) + { + if(failNoisy) + { + throw new ArgumentException("Cannot overwrite header: " + headers[i]); + } + else + { + Debug.LogError("Illegal header overwrite, this will fail in 4.3 and above: " + headers[i]); + } + } + } + + if(headers[i].StartsWith("Sec-") || headers[i].StartsWith("Proxy-")) + { + if(failNoisy) + { + throw new ArgumentException("Cannot overwrite header: " + headers[i]); + } + else + { + Debug.LogError("Illegal header overwrite, this will fail in 4.3 and above: " + headers[i]); + } + } + + if(headers[i].IndexOfAny(forbiddenCharacters) > -1 || + headers[i+1].IndexOfAny(forbiddenCharacters) > -1) + { + if(failNoisy) + { + throw new ArgumentException("Cannot include control characters " + + "in a HTTP header, either as key or value."); + } + else + { + Debug.LogError("Illegal control characters in header, this will fail in 4.3 and above"); + } + } + } + } +#endif + +#if !UNITY_METRO_API && !UNITY_WP8_API + private static string[] FlattenedHeadersFrom(Hashtable headers) + { + if (headers == null) return null; + + var flattenedHeaders = new string[headers.Count * 2]; + var i = 0; + foreach (DictionaryEntry entry in headers) + { + flattenedHeaders[i++] = entry.Key.ToString(); + flattenedHeaders[i++] = entry.Value.ToString(); + } + + return flattenedHeaders; + } +#else + private static string[] FlattenedHeadersFrom(Dictionary<string, string> headers) + { + if (headers == null) return null; + + var flattenedHeaders = new string[headers.Count * 2]; + var i = 0; + foreach (KeyValuePair<string, string> entry in headers) + { + flattenedHeaders[i++] = entry.Key.ToString(); + flattenedHeaders[i++] = entry.Value.ToString(); + } + + return flattenedHeaders; + } +#endif +#if ENABLE_GENERICS && !UNITY_WEBGL + internal static Dictionary<string, string> ParseHTTPHeaderString(string input) + { + if (input == null) throw new ArgumentException("input was null to ParseHTTPHeaderString"); + var result = new Dictionary<string, string>(); + var reader = new StringReader(input); + + int count = 0; + while (true) + { + var line = reader.ReadLine(); + if (line == null) break; + + // The first line in the response header is the HTTP status line, according to the + // HTTP 1.1 specification (http://tools.ietf.org/html/rfc2616#section-6). Lets save it. + if (count++ == 0 && line.StartsWith("HTTP")) + { + result["STATUS"] = line; + continue; + } + + var index = line.IndexOf(": "); + if (index == -1) continue; + var key = line.Substring(0, index).ToUpper(); + var value = line.Substring(index + 2); + result[key] = value; + } + return result; + } +#endif + } +#endif +}
\ No newline at end of file diff --git a/Runtime/Export/WWW.h b/Runtime/Export/WWW.h new file mode 100644 index 0000000..9bc48c5 --- /dev/null +++ b/Runtime/Export/WWW.h @@ -0,0 +1,420 @@ +#ifndef WWW_H +#define WWW_H + +#if ENABLE_WWW + +#if (WEBPLUG || UNITY_IPHONE || UNITY_ANDROID || UNITY_FLASH || UNITY_XENON || UNITY_PS3 || UNITY_WINRT) +#define WWW_USE_CURL 0 +#else +#define WWW_USE_CURL 1 +#endif + +#define WWW_USE_BROWSER WEBPLUG && !WWW_USE_CURL + +#if WWW_USE_CURL +#include "External/Curl/include/minimalcurl.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include "Runtime/Threads/Mutex.h" +#include "Runtime/Threads/Thread.h" +#include "Runtime/Threads/AtomicRefCounter.h" +#include "Runtime/GameCode/CallDelayed.h" +#include "Runtime/Utilities/LogAssert.h" +#include "Runtime/Input/TimeManager.h" +#include "Runtime/Utilities/NonCopyable.h" + +/// The time since startup +double GetTimeSinceStartup (); + +class Thread; +class Download; +class UnityWebStream; +class AsyncCachedUnityWebStream; +class AssetBundle; +class AudioClip; + +#include <map> + +enum WWWType { + kWWWTypeCurl, + kWWWTypeBrowser, + kWWWTypeCached, + kWWWTypeCrossDomainChecked, + kWWWFlash +}; + +class WWW : private NonCopyable +{ +private: + UnityWebStream* m_UnityWebStream; + bool m_DidParseUnityWebStream; + int m_StreamingPosition; + + #if SUPPORT_REPRODUCE_LOG + int m_ReproRemapCount; + #endif + + AudioClip* m_AudioClip; + +protected: + bool m_Cached; + int m_CacheVersion; + UInt32 m_RequestedCRC; + friend class WWWCached; + + ThreadPriority m_ThreadPriority; + string m_ResponseHeaders; + void FeedUnityWebStream (bool isCompleted); + bool SetErrorFromResponseHeaders (); // Returns true when error is set, otherwise returns false + UInt32 GetEstimatedDownloadSize() const; + +public: + + class AutoLock + { + public: + AutoLock( WWW& www ) + : m_WWW(&www) + { + www.LockPartialData(); + } + + ~AutoLock() + { + m_WWW->UnlockPartialData(); + } + + private: + AutoLock(const AutoLock&); + AutoLock& operator=(const AutoLock&); + + private: + WWW* m_WWW; + }; + + enum SecurityPolicy + { + kSecurityPolicyDontKnowYet=0, + kSecurityPolicyAllowAccess=1, + kSecurityPolicyDenyAccess=2 + }; + + WWW (bool cached, int cacheVersion, UInt32 crc) + // Private members (initialized by the order of their definition) + : m_UnityWebStream(NULL) + , m_DidParseUnityWebStream(false) + , m_StreamingPosition(0) + #if SUPPORT_REPRODUCE_LOG + , m_ReproRemapCount(0) + #endif + , m_AudioClip(NULL) + + // Protected members + , m_Cached(cached) + , m_CacheVersion(cacheVersion) + , m_RequestedCRC(crc) + , m_ThreadPriority(kNormalPriority) + , m_ResponseHeaders() // Initially empty + + // Private thread-safe reference counter + , m_RefCount() + {} + + typedef std::map<std::string,std::string> WWWHeaders; + + static WWW* Create (const char* url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool crossDomainChecked = true, bool cached = false, int cacheVersion = 0, UInt32 crc = 0); + + virtual const UInt8* GetData() = 0; + virtual const UInt8* GetPartialData() const = 0; + virtual size_t GetSize() = 0; + virtual size_t GetPartialSize() const = 0; + + virtual double GetETA() const = 0; //seconds remaining until we're done. + + virtual void LockPartialData() = 0; + virtual void UnlockPartialData() = 0; + + // Returns true when the download is complete or failed. + virtual void Cancel() = 0; + bool IsDone() const; + virtual float GetProgress() const = 0; + virtual float GetUploadProgress() const = 0; + virtual const char* GetError() = 0; + virtual void SetError (const std::string& error) {} + virtual const char* GetUrl() const = 0; + virtual std::string GetResponseHeaders(); + virtual bool HasDownloadedOrMayBlock () = 0; + virtual void BlockUntilDone () = 0; + virtual SecurityPolicy GetSecurityPolicy() const; + + virtual WWWType GetType () const = 0; + + virtual UnityWebStream* GetUnityWebStream () const; + + virtual bool IsCached () const; + + void CallWhenDone(DelayedCall* func, Object* o, void* userData, CleanupUserData* cleanup); +#if SUPPORT_THREADS + ThreadPriority GetThreadPriority() const { return m_ThreadPriority; } + virtual void SetThreadPriority( ThreadPriority priority ); +#endif + + #if SUPPORT_REPRODUCE_LOG + int* GetReproRemapCount () { return &m_ReproRemapCount; } + #endif + + AudioClip* GetAudioClip() const { return m_AudioClip; } + void SetAudioClip(AudioClip* clip) { m_AudioClip = clip; } + +protected: + virtual ~WWW (); + +#if ENABLE_WEBPLAYER_SECURITY + friend class WWWCrossDomainChecked; +#endif + virtual bool IsDownloadingDone() const = 0; + +public: + /// These functions must be thread safe as they are called from the garbage collector thread + void Retain(); + void Release(); + +private: + AtomicRefCounter m_RefCount; +}; + +#if WWW_USE_BROWSER +class WWWBrowser : public WWW +{ + Download* m_Download; + std::vector<UInt8> m_Buffer; + double m_Eta; + double m_StartDownloadTime; + std::string m_Url; + std::string m_Error; + std::string m_HeadersString; + char* m_PostData; + size_t m_PostLength; + + int m_LockedPartialData; + + int GetTotalBytesUntilLoadable() const; + +public: + + WWWBrowser (const char* postDataPtr, int postDataLength, const WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc); + + virtual const UInt8* GetData(); + virtual size_t GetSize(); + + virtual bool IsDownloadingDone() const; + + virtual float GetProgress() const; + virtual float GetUploadProgress() const; + + virtual const char* GetError(); + virtual void SetError (const std::string& error); + + virtual const char* GetUrl() const; + + virtual const UInt8* GetPartialData() const; + virtual size_t GetPartialSize() const; + virtual void LockPartialData(); + virtual void UnlockPartialData(); + virtual double GetETA() const; //seconds remaining until we're done. + + virtual bool HasDownloadedOrMayBlock (); + virtual void BlockUntilDone (); + virtual void Cancel (); + + void ForceProgressDownload (); + + virtual WWWType GetType () const { return kWWWTypeBrowser; } + static int ProgressDownload(Download* download); + +public: + static WWWBrowser* CreateBrowser (const char* url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool cached, int cacheVersion, UInt32 crc); + +protected: + virtual ~WWWBrowser (); +}; +#endif // WWW_USE_BROWSER + + +#if WWW_USE_CURL + +class WWWCurl : public WWW +{ + private: + size_t alloc_size; + curl_slist* curlHeaders; + curl_slist* GetHeaderSList () ; + + Mutex mutex; + size_t size; + UInt8* data; + char* errorBuffer; + bool abortDownload; + float progress; + float uploadProgress; + unsigned totalSize; + double eta; + double startTime; + + char* postData; + int postLength; // -1 for GET requests + int postPosition; + + WWWHeaders requestHeaders; + + size_t AppendBytes(void * moreData, size_t bytes); + size_t PostBytes(void * moreData, size_t bytes); + + CURLcode GetURL( const char* url ); + + Thread thread; + char* url; + + int result; + + void DoInit( const char* in_url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers); + void Cleanup(); + + static size_t WriteCallback(void * data, size_t size, size_t elements, WWWCurl * myData); + static size_t ReadCallback(void * data, size_t size, size_t elements, WWWCurl * myData); + static size_t HeaderCallback(void * data, size_t size, size_t elements, WWWCurl * myData); + static int ProgressCallback (WWWCurl *myData, double dltotal, double dlnow, double ultotal, double ulnow); + + public: + + WWWCurl( const char* in_url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool cached, int cacheVersion, UInt32 crc ); + + virtual bool IsDownloadingDone() const; + virtual const UInt8* GetData(); + virtual const char* GetError(); + virtual void SetError (const std::string& error); + virtual const char* GetUrl() const; + virtual size_t GetSize(); + virtual const UInt8* GetPartialData() const; + virtual size_t GetPartialSize() const; + virtual float GetProgress() const; + virtual float GetUploadProgress() const; + virtual double GetETA() const; + + virtual void LockPartialData(); + virtual void UnlockPartialData(); + virtual bool HasDownloadedOrMayBlock (); + + virtual void Cancel (); + virtual void SetThreadPriority( ThreadPriority priority ); + void BlockUntilDone(); + + virtual WWWType GetType () const { return kWWWTypeCurl; } + virtual std::string GetResponseHeaders(); + + protected: + ~WWWCurl(); + + private: + void StartThread(); + static void* WWW_ThreadEntryPoint(void* data); + UInt32 GetEstimatedDownloadSize() const; +}; +#endif // WWW_USE_CURL + +class WWWDelayCall { + private: + WWW* m_wait_for; + DelayedCall* m_func; + Object* m_o; + void * m_userData; + CleanupUserData* m_cleanup; + public: + WWWDelayCall(WWW* www, DelayedCall* func, Object* o, void* userData, CleanupUserData* cleanup); + ~WWWDelayCall(); + static void Callback(Object* o, void* userData); + static void Cleanup(void* userData); + static bool MatchForCancel(void* callBackUserData, void* cancelUserData); +}; + +#if ENABLE_WEBPLAYER_SECURITY + +void ProcessCrossDomainRequestsFromNonMainThread(); + +class WWWCrossDomainCheckedImpl; +class WWWCrossDomainChecked : public WWW +{ +private: + const char* m_PostData; + int m_PostDataLength; + std::string m_PostDataDataCopy; + WWWHeaders m_Headers; + + WWWCrossDomainCheckedImpl* m_CrossChecker; + WWW* m_WWW; + + bool CanCreateDownloader() const; + bool RequestLooksSafeEnoughToMakeWithoutPolicyAccess() const; + void StartEmbeddedDownload(); + void BlockedStartEmbeddedDownload(); + +public: + WWWCrossDomainChecked (const char* url, const char* postData, int postDataLength, const WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc); + + virtual SecurityPolicy GetSecurityPolicy() const; + virtual UnityWebStream* GetUnityWebStream() const; + virtual const UInt8* GetData(); + virtual const UInt8* GetPartialData() const; + virtual size_t GetSize(); + virtual size_t GetPartialSize() const; + + virtual double GetETA() const; + + virtual bool IsCached () const; + + virtual void LockPartialData(); + virtual void UnlockPartialData(); + + // Returns true when the download is complete or failed. + virtual void Cancel(); + virtual bool IsDownloadingDone() const; + virtual float GetProgress() const; + virtual float GetUploadProgress() const { return 0.f; } + virtual const char* GetError(); + virtual const char* GetUrl() const; + virtual std::string GetResponseHeaders(); + virtual bool HasDownloadedOrMayBlock (); + virtual void BlockUntilDone (); + + virtual void SetThreadPriority( ThreadPriority priority ); + + virtual WWWType GetType () const { return kWWWTypeCrossDomainChecked; } + +protected: + ~WWWCrossDomainChecked (); +}; +#endif //ENABLE_WEBPLAYER_SECURITY + +// Constant error strings +extern const char* kWWWErrCustomHeadersWithGET; +extern const char* kWWWErrZeroPostData; +extern const char* kWWWErrNULLPostDataWithPositiveLength; +extern const char* kWWWErrCancelled; +extern const char* kWWWErrPostDataWithNonHTTPSchema; +extern const char* kWWWErrHeadersWithNonHTTPSchema; + +double CalculateEta (int downloadedBytes, int totalBytes, double startTime); + +const char* GetCachedWWWError(const WWW& www, std::string& err); + +#if !UNITY_FLASH + +std::string DecodeEscapedURL(const std::string& url); + +#endif + +#endif // ENABLE_WWW + +#endif // WWW_H diff --git a/Runtime/Export/WinRT/AppTrial.txt b/Runtime/Export/WinRT/AppTrial.txt new file mode 100644 index 0000000..37ec8f6 --- /dev/null +++ b/Runtime/Export/WinRT/AppTrial.txt @@ -0,0 +1,56 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#if UNITY_WINRT +#include "PlatformDependent\WinRT\ApplicationTrial.h" +#endif + +using namespace Unity; + +CSRAW + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine.Windows +{ +CONDITIONAL UNITY_WINRT_API +CLASS LicenseInformation + + /// Returns whether the user is using App trial version (rather than full version) + CUSTOM_PROP static bool isOnAppTrial + { + #if UNITY_WINRT + return ::IsOnAppTrial (); + #else + return false; + #endif + } + + /// Windows Phone 8: + /// Redirects user to app page in the Store + /// Returns an empty string + /// Call isOnAppTrial to find out whether the user bought the app + /// + /// Windows Store apps: + /// Pops up a dialog for a user asking whether he wants to buy an app + /// If use buys an app, returns a valid purchase receipt string + CUSTOM public static string PurchaseApp () + { + #if UNITY_WINRT + return ::PurchaseApp (); + #else + return SCRIPTING_NULL; + #endif + } + +CSRAW +END + +CSRAW +}
\ No newline at end of file diff --git a/Runtime/Export/Windows/WindowsCrypto.txt b/Runtime/Export/Windows/WindowsCrypto.txt new file mode 100644 index 0000000..56daa50 --- /dev/null +++ b/Runtime/Export/Windows/WindowsCrypto.txt @@ -0,0 +1,46 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Utilities/File.h" +#include "Runtime/Utilities/HashFunctions.h" + + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine.Windows +{ +CONDITIONAL UNITY_WINRT_API +CLASS Crypto + CUSTOM public static byte[] ComputeMD5Hash(byte[] buffer) + { + UInt8* first = Scripting::GetScriptingArrayStart<UInt8> (buffer); + int size = GetScriptingArraySize(buffer); + UInt8 outHash[16]; + ComputeMD5Hash(first, size, outHash); + return CreateScriptingArray<UInt8>(outHash, sizeof(outHash), GetMonoManager().GetCommonClasses().byte); + } + + CUSTOM public static byte[] ComputeSHA1Hash(byte[] buffer) + { + UInt8* first = Scripting::GetScriptingArrayStart<UInt8> (buffer); + int size = GetScriptingArraySize(buffer); + UInt8 outHash[20]; + ComputeSHA1Hash(first, size, outHash); + return CreateScriptingArray<UInt8>(outHash, sizeof(outHash), GetMonoManager().GetCommonClasses().byte); + } +CSRAW +END + +CSRAW +} diff --git a/Runtime/Export/Windows/WindowsDirectory.txt b/Runtime/Export/Windows/WindowsDirectory.txt new file mode 100644 index 0000000..b034279 --- /dev/null +++ b/Runtime/Export/Windows/WindowsDirectory.txt @@ -0,0 +1,86 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Utilities/File.h" + +#if UNITY_EDITOR +#include "Editor/Src/ProjectWizardUtility.h" +#endif + +#if UNITY_METRO +#include "PlatformDependent/MetroPlayer/MetroUtils.h" +#endif + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine.Windows +{ +CONDITIONAL UNITY_WINRT_API +CLASS Directory + CUSTOM_PROP public static string temporaryFolder + { + #if UNITY_METRO + return scripting_string_new(ConvertStringToUtf8(Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data())); + #else + #if UNITY_WP8 + string path = ConvertStringToUtf8(Platform::String::Concat(Windows::Storage::ApplicationData::Current->LocalFolder->Path, L"\\Temp")->Data()); + #else + string path = GetProjectPath() + "/TempState"; + #endif + if (IsDirectoryCreated(path) == false) CreateDirectory(path); + return scripting_string_new(path); + #endif + } + CUSTOM_PROP public static string localFolder + { + #if UNITY_WINRT + return scripting_string_new(ConvertStringToUtf8(Windows::Storage::ApplicationData::Current->LocalFolder->Path->Data())); + #else + string path = GetProjectPath() + "/LocalState"; + if (IsDirectoryCreated(path) == false) CreateDirectory(path); + return scripting_string_new(path); + #endif + } + CUSTOM_PROP public static string roamingFolder + { + #if UNITY_METRO + return scripting_string_new(ConvertStringToUtf8(Windows::Storage::ApplicationData::Current->RoamingFolder->Path->Data())); + #else + #if UNITY_WP8 + string path = ConvertStringToUtf8(Platform::String::Concat(Windows::Storage::ApplicationData::Current->LocalFolder->Path, L"\\Roaming")->Data()); + #else + string path = GetProjectPath() + "/RoamingState"; + #endif + if (IsDirectoryCreated(path) == false) CreateDirectory(path); + return scripting_string_new(path); + #endif + } + CUSTOM public static void CreateDirectory(string path) + { + CreateDirectory(path.AsUTF8()); + } + CUSTOM public static bool Exists(string path) + { + return IsDirectoryCreated(path.AsUTF8()); + } + CUSTOM public static void Delete(string path) + { + if (IsDirectoryCreated(path.AsUTF8())) + DeleteFileOrDirectory(path.AsUTF8()); + } +CSRAW +END + +CSRAW +} diff --git a/Runtime/Export/Windows/WindowsFile.txt b/Runtime/Export/Windows/WindowsFile.txt new file mode 100644 index 0000000..9c63bd6 --- /dev/null +++ b/Runtime/Export/Windows/WindowsFile.txt @@ -0,0 +1,69 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Scripting/ScriptingExportUtility.h" +#include "Runtime/Utilities/File.h" + +using namespace Unity; + +using namespace std; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngineInternal; + +namespace UnityEngine.Windows +{ +CONDITIONAL UNITY_WINRT_API +CLASS File + CUSTOM public static byte[] ReadAllBytes(string path) + { + File file; + if (file.Open(path.AsUTF8(), File::kReadPermission)) + { + std::vector<UInt8> buffer; + buffer.resize(file.GetFileLength()); + file.Read(&buffer[0], buffer.size()); + file.Close(); + return CreateScriptingArray<UInt8>(&buffer[0], buffer.size(), GetMonoManager().GetCommonClasses().byte); + } + else + { + ErrorStringMsg("File.ReadAllBytes - failed to open %s for reading", path.AsUTF8().c_str()); + } + return SCRIPTING_NULL; + } + + CUSTOM public static void WriteAllBytes(string path, byte[] bytes) + { + File file; + if (file.Open(path.AsUTF8(), File::kWritePermission)) + { + int size = GetScriptingArraySize(bytes); + UInt8* rawBytes = Scripting::GetScriptingArrayStart<UInt8>(bytes); + file.Write(rawBytes, size); + file.Close(); + } + else + { + ErrorStringMsg("File.WriteAllBytes - failed to open %s for writing", path.AsUTF8().c_str()); + } + } + CUSTOM public static bool Exists(string path) + { + return IsFileCreated(path.AsUTF8()); + } + CUSTOM public static void Delete(string path) + { + if (IsFileCreated(path.AsUTF8())) + DeleteFileOrDirectory(path.AsUTF8()); + } +CSRAW +END + +CSRAW +} diff --git a/Runtime/Export/XboxKeyboard.txt b/Runtime/Export/XboxKeyboard.txt new file mode 100644 index 0000000..c734c66 --- /dev/null +++ b/Runtime/Export/XboxKeyboard.txt @@ -0,0 +1,51 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Utilities/Utility.h" + +#if UNITY_XENON +#include "PlatformDependent/Xbox360/Source/Services/Keyboard.h" +#endif + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace UnityEngine +{ + // Xbox Guide's keyboard-style input interface + CONDITIONAL UNITY_XENON_API + CLASS X360Keyboard + + CSRAW + internal X360Keyboard() {} + + // Keyboard input result + public delegate void DelegateResult(bool textValid, string text); + public static DelegateResult OnResult; + + CSRAW private static void TriggerOnResult(bool textValid, string text) + { + if (OnResult != null) + OnResult(textValid, text); + } + + // Shows the onscreen keyboard. + CUSTOM public static bool Show(UInt32 userIndex, UInt32 characterLimit, string defaultText, string titleText, string descriptionText) + { + #if UNITY_XENON + return xenon::Keyboard::Show(userIndex, characterLimit, MonoStringToWideCpp(defaultText.str), MonoStringToWideCpp(titleText.str), MonoStringToWideCpp(descriptionText.str)); + #else + return false; + #endif + } + + END + +CSRAW +} // namespace diff --git a/Runtime/Export/XboxServices.cs b/Runtime/Export/XboxServices.cs new file mode 100644 index 0000000..23cddf6 --- /dev/null +++ b/Runtime/Export/XboxServices.cs @@ -0,0 +1,794 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using UnityEngine; + +namespace UnityEngine +{ + #if UNITY_XENON_API && ENABLE_XENON_SOCIALAPI + // TODO: We have no concept of achievement types like xbox has, not exposed + // TODO: No concept of user privilege levels, not exposed + // NOTE: There doesn't seem to be any way to explicitly set your own state (online/offline/away/busy/playing) + public class XboxLive : ISocial + { + private static LocalUser s_LocalUser; + private Action<AchievementDescription[]> m_AchievementDescriptionCallback; + private Action<bool> m_AchievementReportingCallback; + + private static GameObject s_SessionObject; + private static GameObject s_LeaderboardRoutine; + + internal const uint kDefaultUserIndex = 0; + + public static bool onlineMode { get; set; } + + public XboxLive() + { + if (X360Core.IsUserSignedIn(0, true)) + { + Debug.Log("User already signed in, in online mode"); + onlineMode = true; + } + + // DEBUG: Log when these callbacks are triggered but have not been set elsewhere + X360Achievements.OnAchievementsEnumerated = () => { Debug.Log("OnAchievementsEnumerated called"); }; + X360Achievements.OnUserAchievementsUpdated = (id) => { Debug.Log("OnUserAchievementsUpdated called for user " + id); }; + X360Achievements.OnAward = + (uid, aid, status) => { Debug.Log("OnAward called for user=" + uid + " achievement=" + aid + " status=" + status); }; + } + + public void ShowAchievementsUI() + { + X360Achievements.ShowUI(kDefaultUserIndex); + } + + // TODO: These should include an action which is triggered (OnSystemUIVisibilityChange) when the UI state changes (UI is dismissed) + public void ShowAchievementsUI(uint userIndex) + { + X360Achievements.ShowUI(userIndex); + } + + public void ShowLeaderboardUI() + { + Debug.Log("Not implemented"); + } + + public void ShowFriendsUI(uint userIndex) + { + X360Friends.ShowFriendsUI(userIndex); + } + + // NOTE: localUser.underage is not implemented on Xbox Live + public LocalUser localUser + { + get + { + if (s_LocalUser == null) + s_LocalUser = new LocalUser(); + GetLocalUser(kDefaultUserIndex, ref s_LocalUser); + return s_LocalUser; + } + } + + // TODO: Cache user so he's not recreated every time + // TODO: Maybe set this up as a generic list, the list is populated as users are logged in and valid, no need to create on access, no need for seperate GetCount() type functions + public LocalUser this[uint index] + { + get + { + LocalUser user = new LocalUser(); + GetLocalUser(index, ref user); + return user; + } + } + + private void GetLocalUser(uint index, ref LocalUser user) + { + user.m_Authenticated = X360Core.IsUserSignedIn(index, onlineMode); + if (!user.m_Authenticated) + { + //Debug.Log("Must be logged in before getting local user details"); + return; + } + user.m_UserName = X360Core.GetUserName(index); + user.m_UserId = X360Core.GetUserOnlinePlayerId(index).Raw.ToString(); + user.m_Friends = GetFriendsList(index); + user.m_Image = X360Core.GetUserGamerPicture(index, true); + } + + public void Authenticate(Action<bool> callback) + { + // Request online login of exactly 1 user + X360Core.RequestSignIn(1, 1, onlineMode); + X360Core.OnUserStateChange = delegate() { callback(true); }; + } + + // Request sign-in for min users up to max user count + public void Authenticate(uint minUsers, uint maxUsers, Action<bool> callback) + { + X360Core.RequestSignIn(minUsers, maxUsers, onlineMode); + // Xbox core doesn't report success/failure of sign-in attempts + // so lets just wrap it in another delegate which always reports true + // I assume this means all users have signed in + X360Core.OnUserStateChange = delegate() { callback(true); }; + } + + // This is kind of pointless here as the friends list is not loaded seperately + public void LoadFriends(Action<bool> callback) + { + /*if (X360Friends.IsInitialized(0)) + { + Debug.Log("Not initialized yet... "); + X360Friends.OnFriendsUpdated = delegate(uint index) { callback(true); }; + return; + }*/ + callback(true); + Debug.Log("Friends list is always populated in the local user automatically"); + } + + private UserProfile[] GetFriendsList(uint index) + { + var friends = new List<UserProfile>(); + for (uint i = 0; i < X360Friends.GetFriendCount(index); i++) + { + UserProfile friend = new UserProfile(); + friend.m_UserName = X360Friends.GetFriendName(index, i); + friend.m_UserId = X360Friends.GetFriendPlayerId(index, i).Raw.ToString(); + friend.m_IsFriend = true; + X360FriendState state = X360Friends.GetFriendState(index, i); + friend.m_State = ConvertState(state); + friend.m_Image = X360Core.GetPlayerGamerPicture(index, X360Friends.GetFriendPlayerId(index, i), false); + friends.Add(friend); + } + return friends.ToArray(); + } + + private UserState ConvertState(X360FriendState state) + { + if (state.IsOnline) return UserState.Online; + if (state.IsOnlineAndAway) return UserState.OnlineAndAway; + if (state.IsOnlineAndBusy) return UserState.OnlineAndBusy; + if (state.IsPlaying) return UserState.Playing; + return UserState.Offline; + } + + // Achievements are set up with the Xbox 360 and LIVE Authoring Submission Tool (XLAST) + // The points (or gamescore) of each one depends on the title type (retail/arcade). + // They are actually loaded automatically at startup, so this doesn't actually load + // anything. + public void LoadAchievementDescriptions(Action<AchievementDescription[]> callback) + { + if (!X360Achievements.IsEnumerated()) + { + m_AchievementDescriptionCallback = callback; + X360Achievements.OnAchievementsEnumerated = CallbackAchivementDescriptionLoader; + } + else if (X360Achievements.GetCount() == 0) + { + Debug.Log("No achievement descriptions found"); + callback(new AchievementDescription[0]); + } + else + { + callback(PopulateAchievementDescriptions()); + } + } + + private void CallbackAchivementDescriptionLoader() + { + if (m_AchievementDescriptionCallback != null) + m_AchievementDescriptionCallback(PopulateAchievementDescriptions()); + } + + private AchievementDescription[] PopulateAchievementDescriptions() + { + var achievements = new List<AchievementDescription>(); + for (uint i = 0; i < X360Achievements.GetCount(); ++i) + { + // TODO: Should the points maybe just be an uint like xbox uses? Not like you get negative points ever. + X360Achievement xboxAchoo = new X360Achievement(i); + AchievementDescription achievement = new AchievementDescription( + xboxAchoo.Id.ToString(), + xboxAchoo.Label, + xboxAchoo.Picture, + xboxAchoo.Description, + xboxAchoo.Unachieved, + xboxAchoo.ShowUnachieved, + (int)xboxAchoo.Cred); + achievements.Add(achievement); + } + return achievements.ToArray(); + } + + // Apparently xbox has no concept of unhiding achievements by reporting 0 progress + // TODO: This is printed in the log: + // '[XUI] Warning: XuiControlPlayOptionalVisual: no fallback for control: PopupControl. Trying to play: "Normal"->"EndNormal"' + public void ReportProgress(string id, double progress, Action<bool> callback) + { + uint numericId; + if (!XboxLiveUtil.TryExtractId(id, out numericId)) return; + + ReportProgress(numericId, progress, callback); + } + + public void ReportProgress(uint id, double progress, Action<bool> callback) + { + m_AchievementReportingCallback = callback; + X360Achievements.OnAward = CallbackAchivementReported; + X360Achievements.AwardUser(kDefaultUserIndex, id); + } + + private void CallbackAchivementReported(uint userIndex, uint achievementId, X360AchievementStatus status) + { + // TODO: Check if the desired achievement ID actually got updated. + // TODO: We should have enums here instead of bools + if (m_AchievementReportingCallback != null) + { + if (status == X360AchievementStatus.AlreadyAwarded || status == X360AchievementStatus.Succeeded) + m_AchievementReportingCallback(true); + else + m_AchievementReportingCallback(false); + } + } + + public void LoadAchievements(Action<Achievement[]> callback) + { + // TODO: This should really be communicated back with an enum, but since users can re-enumerate + // it's kind of useless. We should allow that or automatically handle it. + if (!X360Achievements.IsEnumerated()) + { + Debug.Log("Achievements not yet enumerated"); + callback(new Achievement[0]); + } + if (X360Achievements.GetCount() == 0) + { + Debug.Log("No achievements found or achieved"); + callback(new Achievement[0]); + } + else + { + callback(PopulateAchievements(kDefaultUserIndex)); + } + } + + private Achievement[] PopulateAchievements(uint index) + { + var achievements = new List<Achievement>(); + for (uint i = 0; i < X360Achievements.GetCount(); ++i) + { + X360Achievement xboxAchoo = new X360Achievement(i); + if (X360Achievements.IsUnlocked(index, xboxAchoo.Id, true)) + { + Achievement achievement = new Achievement( + xboxAchoo.Id.ToString(), + 100.0, + true, + false, + X360Achievements.GetUnlockTime(index, xboxAchoo.Id)); + achievements.Add(achievement); + } + } + return achievements.ToArray(); + } + + // Got this: + // WRN[XGI]: Mismatched types for property 0x10000001. XUSER_PROPERTY.value.type = 2 but property type is 1. Skipping write. Pass the correct type or 0. + public void ReportScore(long score, string board, Action<bool> callback) + { + uint boardId; + if (!XboxLiveUtil.TryExtractId(board, out boardId)) return; + + // There must be a Score property assigned to this leaderboard and it must expect a 64 bit value + uint propertyId; + if (XboxLiveUtil.TryExtractId("PROPERTY_SCORE", out propertyId)) + { + Debug.Log("Found Score property: " + propertyId); + var properties = new X360UserProperty[1]; + properties[0].Id = propertyId; + properties[0].Value.Type = X360UserDataType.Int64; + properties[0].Value.ValueInt64 = score; + ReportScore(boardId, properties, callback); + } + else + Debug.LogError("Failed to report score to " + board); + } + + // TODO: The API is set up so you have one leaderboard object, and muliple ones if you need to report/read + // to/from multiple leaderboards. Xbox has the X360StatsViewProperties value which allows you to report + // scores etc to multiple leaderboard views at a time. Here we always have one such property. + public void ReportScore(uint boardId, X360UserProperty[] props, Action<bool> callback) + { + if (X360Core.GetTotalOnlineUsers() == 0) + { + Debug.Log("ERROR: Leaderboards can only be used when the user is logged in online (online=" + X360Core.GetTotalOnlineUsers() + " signed-in=" + X360Core.GetTotalSignedInUsers() + ")"); + callback(false); + return; + } + + LeaderboardRoutine routine = GetRoutine(); + XboxScore xboxScore = new XboxScore(); + xboxScore.boardId = boardId; + xboxScore.properties = props; + routine.ReportScore(xboxScore, callback); + } + + public void LoadScores(string category, Action<Score[]> callback) + { + uint categoryId; + if (!XboxLiveUtil.TryExtractId(category, out categoryId)) return; + + // This will find all columns assigned to this leaderboard, if specific columns are desired + // you need to use the xbox specific LoadScores call which has the columns parameter + ushort[] columnIds; + if (XboxLiveUtil.TryExtractId("STATS_COLUMN_" + category.ToUpper(), out columnIds)) + LoadScores(categoryId, columnIds, callback); + else + Debug.LogError("Failed to load scores from " + category); + } + + // We convert X360StatsRow + X360StatsColumn objects to Score objects. + // NOTE: Each row contains user info + all the columns for him. Here we will only support the user info + 1 single column (value/score/points) + // NOTE: We only support getting long (64bit) values, not floats etc. + // NOTE: The date field in the Score class is not populated, not supported here unless we support it as a custom column in the leaderboard config. + // TODO: Fix formattedValue field, it should be possible to populate based on the localized string accociated with a column + // TODO: Unused row fields: Rating + Gamertag + // NOTE: Arbitrated leaderboards + the TrueSkill system complicates matters here. An + // arbitrated session must be started to be able to report scores on an arbitrated leaderboard. + // When using TrueSkill, every player must report all scores (also for other players) and the server + // verifies they are correct. + public void LoadScores(uint boardId, ushort[] columnIds, Action<Score[]> callback) + { + LeaderboardRoutine routine = GetRoutine(); + routine.LoadScores(boardId, columnIds, callback); + } + + private LeaderboardRoutine GetRoutine() + { + LeaderboardRoutine routine; + if (s_LeaderboardRoutine == null) + { + s_LeaderboardRoutine = new GameObject(); + routine = s_LeaderboardRoutine.AddComponent<LeaderboardRoutine>(); + } + else + routine = s_LeaderboardRoutine.GetComponent<LeaderboardRoutine>(); + return routine; + } + + internal static XboxLiveSession GetSession() + { + XboxLiveSession session; + if (s_SessionObject == null) + { + Debug.Log("Creating new session object"); + s_SessionObject = new GameObject(); + session = s_SessionObject.AddComponent<XboxLiveSession>(); + } + else + { + Debug.Log("Reusing old session"); + session = s_SessionObject.GetComponent<XboxLiveSession>(); + } + return session; + } + + public void LoadScores(Leaderboard board, Action<bool> callback) + { + board.m_Loading = true; + var routine = GetRoutine(); + routine.LoadScores((XboxLeaderboard) board, callback); + } + + public bool GetLoading(Leaderboard board) + { + return board.m_Loading; + } + + public static void OpenSession(Action<bool> callback) + { + XboxLiveSession session = GetSession(); + + if (session.running) + { + callback(true); + return; + } + + session.SetupSession(callback); + } + + public static void CloseSession(Action<bool> callback) + { + if (s_SessionObject == null) + { + callback(true); + return; + } + + var routine = s_SessionObject.GetComponent<XboxLiveSession>(); + routine.Cleanup(callback); + } + } + + class LeaderboardRoutine : MonoBehaviour + { + private Action<Score[]> m_ScoresCallback; + private Action<bool> m_LeaderboardCallback; + // If it's possible with the Xbox SDK to do parallel leaderboard queries, then expand this into a boardID=>board hashtable + private XboxLeaderboard m_CurrentBoard; + + public void ReportScore(XboxScore score, Action<bool> callback) + { + StartCoroutine(DoReportScore(score, callback)); + } + + // TODO: Public/private slots needs to be exposed somehow, but this is only relevant for multiplayer games + // TODO: No callbacks are accociated with writes (as they happen later)? + // TODO: Deal with this error: WRN[XGI]: Invalid leaderboard id: 0x00000000 + public IEnumerator DoReportScore(XboxScore score, Action<bool> callback) + { + /*yield return StartCoroutine(SetupSession()); + Debug.Log("Session setup done"); + if (m_Session == null) + { + callback(false); + yield break; + }*/ + XboxLiveSession session = XboxLive.GetSession(); + if (!session.running) + { + Debug.Log("Must open a session first"); + callback(false); + yield break; + } + + var viewProp = new X360StatsViewProperties[1]; + viewProp[0] = new X360StatsViewProperties { ViewId = score.boardId, Properties = score.properties }; + X360PlayerId onlineId = X360Core.GetUserOnlinePlayerId(XboxLive.kDefaultUserIndex); + if (!session.activeSession.WriteStats(onlineId, viewProp)) + { + Debug.LogError("Failed to send leaderboard data to server"); + //yield return StartCoroutine(TearDownSession()); + callback(false); + } + + // DEBUG: Maybe also skip this yield + yield return new WaitForSeconds(0.1F); + Debug.Log(DateTime.Now + ": Waiting for session to become available."); + yield return !session.activeSession.IsIdle(); + + //Debug.Log("Flush stats"); + //m_Session.FlushStats(); + //yield return new WaitForSeconds(0.1F); + //Debug.Log(DateTime.Now + ": Waiting for session to become available."); + //yield return !m_Session.IsIdle(); + + // TODO: Was it actually a success? + callback(true); + } + + public void LoadScores(uint categoryId, ushort[] columnIds, Action<Score[]> callback) + { + m_ScoresCallback = callback; + XboxLeaderboard board = new XboxLeaderboard(); + board.boardId = categoryId; + board.columnIds = columnIds; + board.playerScope = PlayerScope.FriendsOnly; + StartCoroutine(DoLoadScores(board)); + } + + public void LoadScores(XboxLeaderboard leaderboard, Action<bool> callback) + { + m_LeaderboardCallback = callback; + m_CurrentBoard = leaderboard; + + string categoryString = ""; + if (!XboxLiveUtil.TryExtractString(leaderboard.boardId, "STATS_VIEW_", out categoryString)) + Debug.Log("Failed to set leaderboard category name"); + else + m_CurrentBoard.category = categoryString; + StartCoroutine(DoLoadScores(leaderboard)); + } + + public IEnumerator DoLoadScores(XboxLeaderboard board) + { + XboxLiveSession session = XboxLive.GetSession(); + if (!session.running) + { + Debug.Log("Must open a session first"); + yield break; + } + + /*yield return StartCoroutine(SetupSession()); + if (m_Session == null) + { + Debug.Log("Session setup failed"); + FinishCallbacks(false, new Score[0]); + yield break; + }*/ + + if (board.timeScope != TimeScope.AllTime) + Debug.Log("Time scope filtering is not supported, scores from any time are always used."); + + // TODO: Figure out what should be supported, ReadPlayerStats only returns to score + // of the local player, this should go into Leaderboard.localPlayerScore + if (board.playerScope == PlayerScope.FriendsOnly) + Debug.Log("Friends only support not implemented yet, loading from all players"); + X360Stats.ReadLeaderboardByIndex( + board.boardId, + board.columnIds, + (uint) board.range.from, + (uint) board.range.count, + ProcessLeaderboardResult); + + // TODO: If the scores returned do not contain the local player score we need to fetch it + // seperately so the localPlayerScore property can be populated. + //X360Stats.ReadPlayerStats(board.boardId, board.columnIds, m_OnlineID, PopulateLocalPlayerScore); + + Debug.Log(DateTime.Now + ": Waiting for session to become available."); + yield return !session.activeSession.IsIdle(); + if (session.activeSession.LastFunctionFailed()) + { + Debug.Log("Failed to read leaderboard info"); + //m_Session = null; + yield break; + } + } + + private void FinishCallbacks(bool result, Score[] scores) + { + if (m_CurrentBoard != null) + { + m_CurrentBoard.m_Scores = scores; + m_CurrentBoard.m_Loading = false; + if (m_LeaderboardCallback != null) + { + m_LeaderboardCallback(result); + m_LeaderboardCallback = null; + } + m_CurrentBoard = null; + } + else if (m_ScoresCallback != null) + { + m_ScoresCallback(scores); + m_ScoresCallback = null; + } + } + + // TODO: This currently assumes one and only one value (column) per score element + private void ProcessLeaderboardResult(UInt32 viewId, UInt32 totalRows, X360StatsRow[] rows) + { + Debug.Log("Received " + rows.Length + " out of " + totalRows + " rows for id " + viewId); + m_CurrentBoard.m_MaxRange = totalRows; + var scores = new List<Score>(); + foreach (X360StatsRow row in rows) + { + string playerId = row.Xuid.ToString(); + long value = -1; + if (row.Columns.Length >= 1) + value = row.Columns[0].Value.ValueInt64; + DateTime date = DateTime.Now; + int rank = (int)row.Rank; + + Score score = new Score(viewId.ToString(), value, playerId, date, value.ToString(), rank); + scores.Add(score); + } + FinishCallbacks(true, scores.ToArray()); + } + } + + public class XboxScore : Score + { + public X360UserProperty[] properties { get; set; } + public uint boardId { get; set; } + } + + public class XboxLeaderboard : Leaderboard + { + public uint boardId { get; set; } + public ushort[] columnIds { get; set; } + + public XboxLeaderboard() + { + boardId = 0; + columnIds = new ushort[0]; + } + + public override string ToString() + { + return base.ToString() + " BoardID: '" + boardId + "' ColumnIds: '" + columnIds.Length + "'"; + } + } + + + internal class XboxLiveSession : MonoBehaviour + { + private X360Session m_Session; + private bool m_SessionRunning; + private X360PlayerId m_OnlineID; + private bool m_HazError; + + internal bool running { get { return m_SessionRunning; } } + internal X360Session activeSession { get { return m_Session; } } + + XboxLiveSession() + { + Debug.Log("XboxLiveSession GO created"); + // Get the online ID, sanity checks is performed earlier to ensure that the user is actually online + m_OnlineID = X360Core.GetUserOnlinePlayerId(XboxLive.kDefaultUserIndex); + } + + public void Cleanup(Action<bool> callback) + { + StartCoroutine(TearDownSession(callback)); + } + + internal void SetupSession(System.Action<bool> callback = null) + { + StartCoroutine(DoSetupSession(callback)); + } + + // TODO: These sessions calls should all be returning success boolean... + // TODO: Deal with this error: WRN[XGI]: User at index 0 is already a member of a presence session. + private IEnumerator DoSetupSession(System.Action<bool> callback) + { + if (m_SessionRunning) + { + Debug.Log("Skip session creation as we already have one running"); + yield break; + } + + m_HazError = false; + + if (m_Session == null || m_Session.IsDead()) + { + Debug.Log(DateTime.Now + ": Creating session."); + m_Session = X360Session.CreateSinglePlayerSessionWithStats(XboxLive.kDefaultUserIndex, 4, 0); + if (m_Session == null) yield break; + } + yield return StartCoroutine(ValidateOperation("Session creation failed", callback)); + if (m_HazError) yield break; + + Debug.Log(DateTime.Now + ": Session is ready. Joining."); + if (!m_Session.Join(m_OnlineID, false)) + { + Debug.LogError("Failed to join session"); + m_Session = null; + yield break; + } + yield return StartCoroutine(ValidateOperation("Session joining failed", callback)); + if (m_HazError) yield break; + + Debug.Log(DateTime.Now + ": Session is ready. Starting."); + m_Session.Start(); + yield return StartCoroutine(ValidateOperation("Session failed to start", callback)); + if (m_HazError) yield break; + + Debug.Log("Session now running"); + m_SessionRunning = true; + if (callback != null) callback(true); + } + + // We do not delete the running session completely but only end it's operation. It will + // be reused if OpenSession is called again. + private IEnumerator TearDownSession(Action<bool> callback = null) + { + if (m_Session == null || m_Session.IsDead()) + { + if (callback != null) callback(true); + yield break; + } + m_HazError = false; + + Debug.Log("Leaving running session."); + m_Session.Leave(m_OnlineID, false); + yield return StartCoroutine(ValidateOperation("Failed to leave session", callback)); + if (m_HazError) yield break; + + Debug.Log("End running session"); + m_Session.End(); + yield return StartCoroutine(ValidateOperation("Failed to end session", callback)); + if (m_HazError) yield break; + + //Debug.Log("Deleting running session."); + //m_Session.Delete(); + //yield return StartCoroutine(ValidateOperation("Failed to delete session", callback)); + //if (m_HazError) yield break; + + m_SessionRunning = false; + Debug.Log("Successfully tore down session."); + if (callback != null) callback(true); + } + + private IEnumerator ValidateOperation(string error, Action<bool> callback) + { + //Debug.Log(DateTime.Now + ": Waiting for session to become available."); + yield return !m_Session.IsIdle(); + if (m_Session.LastFunctionFailed()) + { + Debug.Log(error); + m_Session = null; + if (callback != null) callback(false); + m_HazError = true; + yield break; + } + } + } + + + static internal class XboxLiveUtil + { + // TODO: Also look out for javascript/boo assemblies + internal static Assembly s_UserScriptingAssembly = Assembly.Load(new AssemblyName("Assembly-CSharp")); + + static internal bool TryExtractId(string id, out ushort[] shorts) + { + List<ushort> foundShorts = new List<ushort>(); + bool success = false; + foreach (FieldInfo info in GetSpaConfigFields()) + { + //Debug.Log("Haz " + info); + if (info.Name.Contains(id.ToUpper())) + { + // The reflected enum contains uint values, so it must first be cast to that type + ushort value = (ushort)(uint)info.GetValue(info.GetType()); + foundShorts.Add(value); + success = true; + //Debug.Log("Found desired ID: " + value); + } + } + shorts = foundShorts.ToArray(); + if (!success) Debug.Log("Failed to find " + id + " in SPAConfig enum"); + return success; + } + + static internal bool TryExtractId(string id, out uint numericId) + { + if (uint.TryParse(id, out numericId)) return true; + + foreach (FieldInfo info in GetSpaConfigFields()) + { + //Debug.Log("Haz " + info); + if (info.Name.Contains(id.ToUpper())) + { + numericId = (uint)info.GetValue(info.GetType()); + //Debug.Log("Found desired ID: " + numericId); + return true; + } + } + + Debug.Log("Failed to find " + id + " in SPAConfig enum"); + return false; + } + + static internal bool TryExtractString(uint numericId, string pattern, out string outputString) + { + outputString = ""; + foreach (FieldInfo info in GetSpaConfigFields()) + { + if (info.Name.Contains(pattern) && (uint)info.GetValue(info.GetType()) == numericId) + { + outputString = info.Name; + return true; + } + } + + Debug.Log("Failed to find " + pattern + " field in SPAConfig enum which matched " + numericId); + return false; + } + + static internal FieldInfo[] GetSpaConfigFields() + { + if (s_UserScriptingAssembly == null) return new FieldInfo[0]; + object spaObject = s_UserScriptingAssembly.CreateInstance("spaconfig", true); + if (spaObject == null) return new FieldInfo[0]; + Type spaType = spaObject.GetType(); + FieldInfo[] spaFields = spaType.GetFields(); + return spaFields; + } + } + +#endif +} diff --git a/Runtime/Export/XboxVideoMode.txt b/Runtime/Export/XboxVideoMode.txt new file mode 100644 index 0000000..1314041 --- /dev/null +++ b/Runtime/Export/XboxVideoMode.txt @@ -0,0 +1,85 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Scripting/ScriptingUtility.h" +#include "Runtime/Mono/MonoManager.h" +#include "Runtime/Mono/MonoBehaviour.h" +#include "Runtime/Utilities/Utility.h" + +#if UNITY_XENON +#include "PlatformDependent/Xbox360/Source/Services/VideoMode.h" +#endif + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace UnityEngine +{ + // Xbox Video mode + CONDITIONAL UNITY_XENON_API + CLASS X360VideoMode + + CSRAW + internal X360VideoMode() {} + + CUSTOM public static UInt32 GetDisplayHeight() + { + #if UNITY_XENON + return xenon::VideoMode::GetDisplayHeight(); + #else + return 720; + #endif + } + + CUSTOM public static UInt32 GetDisplayWidth() + { + #if UNITY_XENON + return xenon::VideoMode::GetDisplayWidth(); + #else + return 1280; + #endif + } + + CUSTOM public static bool IsWideScreen() + { + #if UNITY_XENON + return xenon::VideoMode::IsWideScreen(); + #else + return true; + #endif + } + + CUSTOM public static bool IsInterlaced() + { + #if UNITY_XENON + return xenon::VideoMode::IsInterlaced(); + #else + return false; + #endif + } + + CUSTOM public static bool IsHiDef() + { + #if UNITY_XENON + return xenon::VideoMode::IsHiDef(); + #else + return true; + #endif + } + + CUSTOM public static float GetRefreshRate() + { + #if UNITY_XENON + return xenon::VideoMode::GetRefreshRate(); + #else + return 60.0f; + #endif + } + + END + +CSRAW +} // namespace diff --git a/Runtime/Export/common_include b/Runtime/Export/common_include new file mode 100644 index 0000000..ef5de8b --- /dev/null +++ b/Runtime/Export/common_include @@ -0,0 +1,617 @@ +TYPEMAP + +Face=>Face +MeshData=>ScriptingObjectPtr +SelectMenuItemFunction=>ScriptingObjectPtr +MaterialProperty=>ScriptingObjectPtr +Vector3=>Vector3f +Vector2=>Vector2f +Bounds=>AABB +Quaternion=>Quaternionf +Matrix4x4=>Matrix4x4f +Rect=>Rectf +Color=>ColorRGBAf +Color32=>ColorRGBA32 +Vector4=>Vector4f +Particle=>SimpleParticle +MaterialPropertyBlock=>ScriptingObjectWithIntPtrField<MaterialPropertyBlock> +ComputeBuffer=>ScriptingObjectWithIntPtrField<ComputeBuffer> +ComputeBufferType=>UInt32 +object=>ScriptingObjectPtr +Type=>ScriptingObjectPtr +Transform=>ReadOnlyScriptingObjectOfType<Transform> +EventType=>int +KeyCode=>int +EventModifiers=>int +bool=>ScriptingBool +uint=>UInt32 +long=>SInt64 +ulong=>UInt64 +ushort=>UInt16 +byte=>UInt8 +Byte=>UInt8 +sbyte=>SInt8 +char=>UInt16 +Char=>UInt16 +Int16=>short +Int32=>int +Int64=>SInt64 +Exception=>ScriptingExceptionPtr +RenderBuffer=>ScriptingRenderBuffer +string=>ICallString +IDictionary=>ScriptingObjectPtr +TimeZoneInfo=>ScriptingObjectPtr +RaycastHit=>RaycastHit +NavMeshPath=>ScriptingObjectPtr +WheelHit=>MonoWheelHit +Coroutine=>ScriptingObjectWithIntPtrField<Coroutine> +LineHandle=>LineRenderer::LineHandle +Keyframe=>KeyframeTpl<float> +WWW=>ScriptingObjectWithIntPtrField<WWW> +WebView=>ScriptingObjectPtr +WebScriptObject=>ScriptingObjectPtr +Hashtable=>ScriptingObjectPtr +IntPtr=>void* +NetworkPlayer=>int +ContainerWindow=>ScriptingObjectPtr +GUIView=>ScriptingObjectPtr +SerializedObject=>ScriptingObjectPtr +SerializedProperty=>ScriptingObjectPtr +ActiveEditorTracker=>ScriptingObjectPtr +GameObjectAndHierarchyChangeTracker=>ScriptingObjectPtr +EditorBuildSettingsScene=>ScriptingObjectPtr +HierarchyProperty=>ScriptingObjectPtr +ProfilerProperty=>ScriptingObjectPtr +ProfilerFrameDataIterator=>ScriptingObjectPtr +VisibilityNode[]=>ScriptingArrayPtr +SceneNode[]=>ScriptingArrayPtr +uint[]=>ScriptingArrayPtr +AudioSpeakerMode=>FMOD_SPEAKERMODE +AudioType=>FMOD_SOUND_TYPE +AudioFormat=>int +FindAllIterator=>ScriptingObjectPtr +FFTWindow=>FMOD_DSP_FFT_WINDOW +AudioReverbPreset=>int +AudioRolloffMode=>RolloffMode +CollisionDetectionMode=>int +MeshTopology=>GfxPrimitiveType +RequestProgressCallback=>ScriptingObjectPtr +RequestDoneCallback=>ScriptingObjectPtr +AsyncHTTPClient=>ScriptingObjectPtr +DownloadDoneCallback=>ScriptingObjectPtr + +ProfilerMode=>int +BuildAssetDependencyMode=>int +ShaderPropertyType=>int +ShaderPropertyTexDim=>int +TextClipping=>int +DragAndDropVisualMode=>int +WrapMode=>int +BuildTarget=>BuildTargetPlatform +BuildTargetGroup=>BuildTargetPlatformGroup +NetworkDiffType=>int +MetaFlags=>int +SerializedPropertyType=>int +NetworkPeerType=>int +RPCMode=>int +NetworkRPCReliability=>int +NetworkStateReliability=>int +NetworkReliability=>int +NetworkStateSynchronization=>int +NetworkPriority=>int +CubemapFace=>int +ImagePosition=>int +TextAlignment=>int +TextAnchor=>int +QueueMode=>int +SendMessageOptions=>int +CameraClearFlags=>int +DownloadResolution=>int +NameConflictResolution=>int +Changeset=>MonoChangeset +AssetsItem=>MonoAssetsItem +DeletedAsset=>MonoDeletedAsset +LightShadows=>int +ForceMode=>int +TexGenMode=>int +CameraRenderMode=>int +AnisotropicFiltering=>int +BlendWeights=>int +PhysicMaterialCombine=>int +DynamicsMaterialCombine=>int +AnimationPlayMode=>int +AnimationCullingType=>Animation::CullingType +AnimatorCullingMode=>Animator::CullingMode +PlayMode=>int +RuntimePlatform=>int +CollisionFlags=>int +PlaybackMode=>int +LightRenderMode=>int +LightAttenuationType=>int +AnimationBlendMode=>int +PrimitiveType=>int +TextureWrapMode=>int +NPOTSupport=>int +NPOTSupport=>int +EditorCurveValueType=>UnityEngine::Animation::EditorCurveValueType +QualityLevel=>int +CapStyle=>int +HideFlags=>int +AudioVelocityUpdateMode=>int +FilterMode=>int +ImportAssetOptions=>int +SelectionMode=>int +SkinQuality=>int +JointProjectionMode=>int +ConfigurableJointMotion=>int +RotationDriveMode=>int +NetworkConnectionError=>int +NetworkLogLevel=>int +ConnectionTesterStatus=>int +ModelImporterAnimationCompression=>int +NETVersion=>int +ModelImporterMeshCompression=>int +AssetStatus=>int +StaticOcclusionCullingQuality=>int +StaticOcclusionCulling.Quality=>int +ModelImporterGenerateMaterials=>int +ModelImporterClipAnimation=>ScriptingObjectPtr +ModelImporterMaterialName=>ModelImporter::MaterialName +ModelImporterMaterialSearch=>ModelImporter::MaterialSearch +ModelImporterGenerateAnimations=>ModelImporter::LegacyGenerateAnimations +ModelImporterTangentSpaceMode=>int +TextureImporter=>ReadOnlyScriptingObjectOfType<TextureImporter> +TextureImporterSettings=>ScriptingObjectPtr +TextureImportInstructions=>ScriptingObjectPtr +TextureImporterFormat=>int +TextureImporterMipFilter=>int +TextureImporterGenerateCubemap=>int +TextureImporterNPOTScale=>int +TextureImporterNormalFilter=>int +TextureImporterType=>int +LogEntry=>ScriptingObjectPtr +AudioImporterFormat=>int +AudioImporterChannels=>int +FontTextureCase=>int +System.Type=>ScriptingObjectPtr +System.Array=>ScriptingArrayPtr +DepthTextureMode=>int +LightmapBakeQuality=>int +LightmappingMode=>int +LightProbeInterpMode=>int +LightmapsMode=>int +LightmapFormat=>TextureUsageMode +DeviceOrientation=>unsigned +RigidbodyConstraints=>int +CharacterInfo=>ScriptingCharacterInfo +AudioClip=>ReadOnlyScriptingObjectOfType<AudioClip> +TreeData=>ReadOnlyScriptingObjectOfType<MonoBehaviour> +Material=>ReadOnlyScriptingObjectOfType<Material> +LodMesh=>ReadOnlyScriptingObjectOfType<Mesh> +LodMeshFilter=>ReadOnlyScriptingObjectOfType<MeshFilter> +LODGroup=>ReadOnlyScriptingObjectOfType<LODGroup> +Mesh=>ReadOnlyScriptingObjectOfType<Mesh> +SkinnedMeshRenderer=>ReadOnlyScriptingObjectOfType<SkinnedMeshRenderer> +MeshFilter=>ReadOnlyScriptingObjectOfType<MeshFilter> +MeshRenderer=>ReadOnlyScriptingObjectOfType<MeshRenderer> +SkinnedMeshRenderer=>ReadOnlyScriptingObjectOfType<SkinnedMeshRenderer> +Texture=>ReadOnlyScriptingObjectOfType<Texture> +MovieTexture=>ReadOnlyScriptingObjectOfType<MovieTexture> +FileTexture=>ReadOnlyScriptingObjectOfType<Texture2D> +Texture2D=>ReadOnlyScriptingObjectOfType<Texture2D> +Cubemap=>ReadOnlyScriptingObjectOfType<Cubemap> +Texture3D=>ReadOnlyScriptingObjectOfType<Texture3D> +HTMLTexture=>ReadOnlyScriptingObjectOfType<HTMLTexture> +TextAsset=>ReadOnlyScriptingObjectOfType<TextAsset> +MonoScript=>ReadOnlyScriptingObjectOfType<MonoScript> +Shader=>ReadOnlyScriptingObjectOfType<Shader> +PhysicMaterial=>ReadOnlyScriptingObjectOfType<PhysicMaterial> +PhysicsMaterial2D=>ReadOnlyScriptingObjectOfType<PhysicsMaterial2D> +Font=>ReadOnlyScriptingObjectOfType<Font> +GUITexture=>ReadOnlyScriptingObjectOfType<GUITexture> +Heightmap=>ReadOnlyScriptingObjectOfType<Heightmap> +ModelImporterAnimation=>ScriptingObjectPtr +ApplyToCacheArguments=>MonoApplyToCacheArguments +InternalEmitParticleArguments=>MonoInternalEmitParticleArguments +WebCamDevice=>MonoWebCamDevice +WebCamFlags=>WebCamFlags +Sprite=>ReadOnlyScriptingObjectOfType<Sprite> +SpriteSheetMetaData=>ScriptingObjectPtr +SpriteImportMode=>TextureImporter::SpriteMode +AtlasSettings=>SpritePacker::SpriteAtlasSettings +Packer.Execution=>SpritePacker::SpritePackerExecution +PackerJob=>void* +InternalDrawTextureArguments=>MonoInternalDrawTextureArguments +Internal_DrawMeshTRArguments=>MonoInternal_DrawMeshTRArguments +Internal_DrawArguments=>MonoInternal_DrawArguments +Internal_DrawMeshMatrixArguments=>MonoInternal_DrawMeshMatrixArguments +Internal_DrawWithTextSelectionArguments=>MonoInternal_DrawWithTextSelectionArguments +RenderArguments=>MonoRenderArguments +iPhoneKeyboard_InternalConstructorHelperArguments=>MonoiPhoneKeyboard_InternalConstructorHelperArguments +TouchScreenKeyboard_InternalConstructorHelperArguments=>MonoTouchScreenKeyboard_InternalConstructorHelperArguments +ParticleSystem.Particle=>ParticleSystemParticle +ParticleSystem.CollisionEvent=>MonoParticleCollisionEvent +TerrainConstructionParameters=>MonoTerrainConstructionParameters +UnityEngine.Object=>ReadOnlyScriptingObjectOfType<Object> +Object=>ReadOnlyScriptingObjectOfType<Object> +GameObject=>ReadOnlyScriptingObjectOfType<GameObject> +Component=>ReadOnlyScriptingObjectOfType<Unity::Component> + +[Writable]Material=>ScriptingObjectOfType<Material> +[Writable]GameObject=>ScriptingObjectOfType<GameObject> +[Writable]PhysicMaterial=>ScriptingObjectOfType<PhysicMaterial> +[Writable]PhysicsMaterial2D=>ScriptingObjectOfType<PhysicsMaterial2D> +[Writable]AnimationClip=>ScriptingObjectOfType<AnimationClip> +[Writable]Object=>ScriptingObjectOfType<Object> +[Writable]ScriptableObject=>ScriptingObjectOfType<MonoBehaviour> +[Writable]RenderTexture=>ScriptingObjectOfType<RenderTexture> +[Writable]Texture2D=>ScriptingObjectOfType<Texture2D> +[Writable]Texture3D=>ScriptingObjectOfType<Texture3D> +[Writable]Cubemap=>ScriptingObjectOfType<Cubemap> +[Writable]Mesh=>ScriptingObjectOfType<Mesh> +[Writable]TerrainData=>ScriptingObjectOfType<TerrainData> +[Writable]WebCamTexture=>ScriptingObjectOfType<WebCamTexture> +[Writable]Font=>ScriptingObjectOfType<Font> + +WebCamTexture=>ReadOnlyScriptingObjectOfType<WebCamTexture> +TerrainData=>ReadOnlyScriptingObjectOfType<TerrainData> +AssetBundle=>ReadOnlyScriptingObjectOfType<AssetBundle> +Editor=>ReadOnlyScriptingObjectOfType<MonoBehaviour> +EditorWindow=>ReadOnlyScriptingObjectOfType<MonoBehaviour> +Rigidbody=>ReadOnlyScriptingObjectOfType<Rigidbody> +PrimitiveCollider=>ReadOnlyScriptingObjectOfType<PrimitiveCollider> +Collider=>ScriptingObjectOfType<Collider> +BoxCollider=>ReadOnlyScriptingObjectOfType<BoxCollider> +SphereCollider=>ReadOnlyScriptingObjectOfType<SphereCollider> +CapsuleCollider=>ReadOnlyScriptingObjectOfType<CapsuleCollider> +MeshCollider=>ReadOnlyScriptingObjectOfType<MeshCollider> +RaycastCollider=>ReadOnlyScriptingObjectOfType<RaycastCollider> +WheelCollider=>ReadOnlyScriptingObjectOfType<WheelCollider> +Rigidbody2D=>ReadOnlyScriptingObjectOfType<Rigidbody2D> +Collider2D=>ScriptingObjectOfType<Collider2D> +CircleCollider2D=>ReadOnlyScriptingObjectOfType<CircleCollider2D> +PolygonCollider2D=>ReadOnlyScriptingObjectOfType<PolygonCollider2D> +SpriteCollider2D=>ReadOnlyScriptingObjectOfType<SpriteCollider2D> +BoxCollider2D=>ReadOnlyScriptingObjectOfType<BoxCollider2D> +EdgeCollider2D=>ReadOnlyScriptingObjectOfType<EdgeCollider2D> +RaycastHit2D=>RaycastHit2D +ShaderLayer=>ReadOnlyScriptingObjectOfType<ShaderLayer> +ConstantForce=>ReadOnlyScriptingObjectOfType<ConstantForce> +RenderTexture=>ReadOnlyScriptingObjectOfType<RenderTexture> +Camera=>ReadOnlyScriptingObjectOfType<Camera> +Light=>ReadOnlyScriptingObjectOfType<Light> +LightProbes=>ReadOnlyScriptingObjectOfType<LightProbes> +TextMesh=>ReadOnlyScriptingObjectOfType<TextMesh> +GUIText=>ReadOnlyScriptingObjectOfType<GUIText> +GUIElement=>ReadOnlyScriptingObjectOfType<GUIElement> +Renderer=>ReadOnlyScriptingObjectOfType<Renderer> +OffMeshLink=>ReadOnlyScriptingObjectOfType<OffMeshLink> +NavMesh=>ReadOnlyScriptingObjectOfType<NavMesh> +AudioSource=>ReadOnlyScriptingObjectOfType<AudioSource> +AudioLowPassFilter=>ReadOnlyScriptingObjectOfType<AudioLowPassFilter> +AssetImporter=>ReadOnlyScriptingObjectOfType<AssetImporter> +HingeJoint=>ReadOnlyScriptingObjectOfType<HingeJoint> +ParticleEmitter=>ReadOnlyScriptingObjectOfType<ParticleEmitter> +EulerRotationMotor=>ReadOnlyScriptingObjectOfType<EulerRotationMotor> +ScriptableObject=>ReadOnlyScriptingObjectOfType<MonoBehaviour> +MonoBehaviour=>ReadOnlyScriptingObjectOfType<MonoBehaviour> +CharacterController=>ReadOnlyScriptingObjectOfType<CharacterController> +OpenGLView=>ReadOnlyScriptingObjectOfType<Object> +NetworkView=>ReadOnlyScriptingObjectOfType<NetworkView> + +Rigidbody2D=>ReadOnlyScriptingObjectOfType<Rigidbody2D> + +ScriptableWizard=>ScriptingObjectPtr +OptimizedGUIBlock=>ScriptingObjectPtr +GUIStyle=>ScriptingObjectWithIntPtrField<GUIStyle> +GUISkin=>ScriptingObjectPtr +GUIStyleState=>ScriptingObjectWithIntPtrField<GUIStyleState> +WindowFunction=>ScriptingObjectPtr +RectOffset=>ScriptingObjectWithIntPtrField<RectOffset> +BitStream=>ScriptingObjectPtr +DetailRenderer=>ScriptingObjectPtr +Terrain=>ReadOnlyScriptingObjectOfType<MonoBehaviour> +GUIContent=>ScriptingObjectPtr +NetworkViewID=>NetworkViewID +Ping=>ScriptingObjectPtr +TreeDatabase=>ScriptingObjectPtr +TreeDatabasePrototype=>ScriptingObjectPtr +TreeRenderer=>ScriptingObjectPtr +ResolutionDialogSetting=>int +MacFullscreenMode=>int +FontStyle=>int +FontRenderingMode=>int +UserAuthorization=>int +IMECompositionMode=>int +ModelImporterAnimationType=>int +PropertyModification=>ScriptingObjectPtr + +ParticleSystem=>ReadOnlyScriptingObjectOfType<ParticleSystem> +ParticleSystemRenderer=>ReadOnlyScriptingObjectOfType<ParticleSystemRenderer> + +Gradient=>ScriptingObjectWithIntPtrField<GradientNEW> + +AnimationState=>ScriptingObjectWithIntPtrField<AnimationState> +Animation=>ReadOnlyScriptingObjectOfType<Animation> +AnimationClip=>ReadOnlyScriptingObjectOfType<AnimationClip> +AudioImporter=>ReadOnlyScriptingObjectOfType<AudioImporter> +MovieImporter=>ReadOnlyScriptingObjectOfType<MovieImporter> +Resolution=>ScreenManager::Resolution +AnimationCurve=>ScriptingObjectWithIntPtrField<AnimationCurve> +LightmapData=>ScriptingObjectPtr +EditorCurveBinding=>MonoEditorCurveBinding + +IEnumerator=>ScriptingObjectPtr +AnimationClipCurveData=>ScriptingObjectPtr +AnimationClipObjectReferenceCurveData=>ScriptingObjectPtr + +SupportedLanguage=>MonoSupportedLanguage + +JointMotor=>MonoJointMotor +TerrainChangedFlags=>TerrainData::ChangedFlags + +WiiRemoteData=>WiiRemoteDataCpp +WiiClassicData=>WiiClassicDataCpp +WiiNunchukData=>WiiNunchukDataCpp +WiiBalanceBoardData=>WiiBalanceBoardDataCpp +WiiMotionPlusDirData=>WiiMotionPlusDirDataCpp +WiiMotionPlusData=>WiiMotionPlusDataCpp +WiiBalanceCommand=>int +WiiBalanceError=>int +WiiBalanceTGCError=>int +WiiMotionPlusStatus=>int +WiiMotionPlusZeroDriftMode=>int +WiiPadInfo=>wii::WPadStatusInfo +WiiButton=>int +WiiSensorBarPosition=>int +WiiPlayMode=>SInt32 +WiiDevType=>UInt32 +WiiErrorStatus=>UInt32 +WiiInput.Status=>SInt32 + +WiiHomeMenu=>ScriptingObjectPtr + +WiiNand.NodeType=>UInt8 +WiiNand.Error=>int +WiiNand.CheckResult=>int +WiiNand.Access=>int +WiiNand.SeekMode=>int + +NVFile=>ScriptingObjectPtr +NVDirectory=>ScriptingObjectPtr +NVSystem=>ScriptingObjectPtr +NVBase=>ScriptingObjectPtr +NVStatus=>wii::nvmem::NodeStatus +NVBanner=>ScriptingObjectPtr +AlignedBuffer=>ScriptingObjectPtr +AlignedBuffer.Memory=>int + +AspectRatio=>int +ProgressiveMode=>int +EuRgb60=>int +SoundMode=>int +TvFormat=>int +ScanMode=>int +Language=>int +WiiConsoleSettings.Language=>int + +WiiDrive.State=>SInt32 +WiiDVDFile=>ScriptingObjectPtr +WiiFile=>ScriptingObjectPtr +WiiOS.Setting=>SInt32 +WiiVI.TimeToDim=>SInt32 +WiiVI.TvFormat=>SInt32 +WiiVI.ScanMode=>SInt32 + +WiiHomeMenu.Select=>SInt32 +WiiHomeMenu.NotSavedWarning=>SInt32 +WiiKeyboard.Result=>int +WiiKeyboard.State=>int + +WiiRFL.ErrorCode=>int +WiiRFL.Source=>SInt32 +WiiRFL.Sex=>SInt32 +WiiRFL.Age=>SInt32 +WiiRFL.Race=>SInt32 +WiiRFL.Expression=>SInt32 +WiiRFLAdditionalInfo=>WiiRFLAdditionalInfoCpp +WiiRFLId=>WiiRFLIdCpp +WiiRFLDB=>ScriptingObjectPtr +WiiRFLDB.Type=>int +WiiUtils.LoadingScreen.Placement=>int + +PrefabType=>int + +iPhoneTouch=>Touch +Compass=>ScriptingObjectPtr +CompassInfo=>HeadingInfo +LocationInfo=>LocationInfo +LocationServiceStatus=>LocationServiceStatus +iPhoneAccelerationEvent=>Acceleration +AccelerationEvent=>Acceleration +iPhoneOrientation=>unsigned +iPhoneMovieControlMode=>unsigned +iPhoneMovieScalingMode=>unsigned +FullScreenMovieControlMode=>unsigned +FullScreenMovieScalingMode=>unsigned +iPhoneKeyboardType=>unsigned +iPhoneKeyboard=>ScriptingObjectPtr +TouchScreenKeyboard=>ScriptingObjectWithIntPtrField<KeyboardOnScreen> +iPhoneBuildSettings=>iphone::iPhoneBuildSettings +WiiBuildSettings=>wii::WiiBuildSettings +iPhoneScreenOrientation=>ScreenOrientation +ScreenOrientation=>ScreenOrientation +SleepTimeout=>SleepTimeout +DeviceType=>DeviceType +NetworkReachability=>NetworkReachability +iPhoneNetworkReachability=>NetworkReachability +iPhoneGeneration=>iphone::iPhoneGeneration +GcLeaderboard=>ScriptingObjectPtr +StrippingLevel=>int +ScriptCallOptimizationLevel=>int +iOSSdkVersion=>int +iOSTargetOSVersion=>int +iOSTargetDevice=>int +iOSTargetPlatform=>int +iOSTargetResolution=>int +UIOrientation=>int +iOSStatusBarStyle=>int +iOSShowActivityIndicatorOnLoading=>int +iOSActivityIndicatorStyle=>int +AndroidTargetDevice=>int +TargetGlesGraphics=>int +AndroidSplashScreenScale=>int +ApiCompatibilityLevel=>int +AndroidSdkVersions=>int +AndroidPreferredInstallLocation=>int +AndroidShowActivityIndicatorOnLoading=>int +AndroidActivityIndicatorStyle=>int +WiiRegion=>int +WiiHio2Usage=>int +BuildOptions=>BuildPlayerOptions +Attributes=>int +MouseCursor=>int + +IDList=>ScriptingObjectPtr +Event=>ScriptingObjectWithIntPtrField<InputEvent> +AnimationEvent=>ScriptingObjectWithIntPtrField<AnimationEvent> +UndoSnapshot=>ScriptingObjectPtr +AsyncOperation=>ScriptingObjectWithIntPtrField<AsyncOperation> +AssetBundleRequest=>ScriptingObjectPtr +AssetBundleCreateRequest=>ScriptingObjectPtr +IDList=>ScriptingObjectPtr +GUIState=>ScriptingObjectPtr +Speed=>int +ShaderModel=>int +ASRefreshState=>int +SerializationMode=>int +EditorBehaviorMode=>int +SpritePackerMode=>int +ExportPackageOptions=>int + +ADSizeIdentifier=>unsigned +ADPosition=>unsigned +ADErrorCode=>unsigned +ADError=>ScriptingObjectPtr +ADBannerView=>ScriptingObjectPtr +ADInterstitialAd=>ScriptingObjectPtr +LocalNotification=>ScriptingObjectPtr +RemoteNotification=>ScriptingObjectPtr +RemoteNotificationType=>int +CalendarUnit=>unsigned +CalendarIdentifier=>CalendarIdentifier + +AssetIndex.Item=>ScriptingObjectPtr +WindZoneData=>ReadOnlyScriptingObjectOfType<WindZone> +WindZoneMode=>WindZone::WindZoneMode + +X360PlayerId=>ScriptingObjectPtr +X360SessionId=>ScriptingObjectPtr +X360PlayerPrivilegeLevel=>UInt32 +X360PlayerPrivilegeType=>UInt32 +X360Achievement=>ScriptingObjectPtr +X360AchievementType=>UInt32 +X360UserStorageStatus=>UInt32 +X360SaveGame=>ScriptingObjectPtr +X360StatsRow=>xenon::StatsRow +X360StatsColumn=>xenon::StatsColumn +X360UserProperty=>XUSER_PROPERTY +X360Avatar=>ScriptingObjectPtr +X360AvatarBatchShaderType=>UInt32 +X360AvatarModel=>ScriptingObjectPtr +X360AvatarShaderParam=>XAVATAR_SHADER_PARAM +X360AvatarBodyType=>UInt32 +X360AvatarAnimation=>ScriptingObjectPtr +X360AvatarAnimCursor=>ScriptingObjectPtr +X360AvatarPose=>ScriptingObjectPtr +X360AvatarLoadStatus=>UInt32 +X360AvatarAnimPlayMode=>UInt32 +X360AvatarStockAnim=>UInt32 +X360AvatarMapper=>ScriptingObjectPtr +X360Session=>ScriptingObjectPtr +X360GameRegion=>UInt32 + +KinectSkeletonTrackingState=>UInt32 +KinectSkeletonPosition=>UInt32 +KinectSkeletonPositionTrackingState=>UInt32 +KinectAutoIdentityPlayerState=>UInt32 +KinectHandSpecificData=>ATG::HandSpecificData +KinectHand=>UInt32 +KinectCameraType=>UInt32 +KinectCameraProperty=>UInt32 +KinectCameraPropertyF=>UInt32 +KinectCameraPropertyValue=>int +KinectImageStreamType=>UInt32 +KinectImageStreamResolution=>UInt32 +KinectImageStream=>ScriptingObjectPtr +KinectImageViewArea=>NUI_IMAGE_VIEW_AREA +KinectImageDigitalZoom=>UInt32 +KinectTiltObject=>xenon::TiltObject +KinectTiltObjects=>xenon::TiltObjects +KinectWavePlayerState=>NUI_WAVE_PLAYER_STATE +KinectSkeletonData=>xenon::SkeletonData +KinectSyncMode=>UInt32 +KinectAudioType=>UInt32 +KinectHandlesTuningParamsGlobal=>NUI_HANDLES_TUNING_PARAMS_GLOBAL +KinectSpeechLanguage=>UInt32 +KinectSpeechEvent=>UInt32 +KinectGesturePreprocess=>UInt32 +KinectGender=>UInt32 +KinectHeadOrientationData=>xenon::HeadOrientationData + +MetroApplicationShowName=>int +MetroApplicationForegroundText=>int +MetroCompilationOverrides=>int + +//SubstanceInput=>ReadOnlyScriptingObjectOfType<SubstanceInputMono> +SubstanceArchive=>ReadOnlyScriptingObjectOfType<SubstanceArchive> +ProceduralMaterial=>ReadOnlyScriptingObjectOfType<ProceduralMaterial> +ProceduralTexture=>ReadOnlyScriptingObjectOfType<ProceduralTexture> +SubstanceTextureGenerationType=>ProceduralMaterial::TextureGenerationType +SubstanceDiffuseAlphaCombinationType=>ProceduralMaterial::DiffuseAlphaCombinationType + +BoneWeight=>BoneInfluence +PS3ReturnCode=>int +AndroidJavaRunnable=>MonoObject* +AndroidJavaProxy=>MonoObject* +Asset=>ScriptingObjectPtr +Task=>ScriptingObjectPtr +ChangeSet=>ScriptingObjectPtr +Message=>ScriptingObjectPtr +Plugin=>ScriptingObjectPtr +ConfigField=>ScriptingObjectPtr +CustomCommand=>ScriptingObjectPtr +CommandContext=>int + +TransparencySortMode=>Camera::SortMode + +AppCallbackItem=>ScriptingObjectPtr + +AnimationClipSettings=>MonoObject* +MuscleClipQualityInfo=>MonoObject* +SkeletonBone=>MonoSkeletonBone +SkeletonBoneLimit=>MonoHumanLimit +HumanBone=>MonoHumanBone +HumanDescription=>MonoHumanDescription +State=>ReadOnlyScriptingObjectOfType<State> +Transition=>ReadOnlyScriptingObjectOfType<Transition> +StateMachine=>ReadOnlyScriptingObjectOfType<StateMachine> +Graph=>ReadOnlyScriptingObjectOfType<Graph> +MuscleClip=>ReadOnlyScriptingObjectOfType<MuscleClip> +BlendTree=>ReadOnlyScriptingObjectOfType<BlendTree> +AvatarMask=>ReadOnlyScriptingObjectOfType<AvatarMask> +Animator=>ReadOnlyScriptingObjectOfType<Animator> +RuntimeAnimatorController=>ReadOnlyScriptingObjectOfType<RuntimeAnimatorController> +AnimatorController=>ReadOnlyScriptingObjectOfType<AnimatorController> +HumanTemplate=>ReadOnlyScriptingObjectOfType<HumanTemplate> +Avatar=>ReadOnlyScriptingObjectOfType<Avatar> +[Writable]AnimatorOverrideController=>ScriptingObjectOfType<AnimatorOverrideController> +GraphRegistry=>ReadOnlyScriptingObjectOfType<GraphRegistry> +GraphModel=>MonoGraphModel +GraphNode=>ReadOnlyScriptingObjectOfType<GraphNode> +GraphSlot=>ReadOnlyScriptingObjectOfType<GraphSlot> +AvatarTarget=>int +AvatarIKGoal=>int +Motion=>ReadOnlyScriptingObjectOfType<Motion> +IconDrawStyle=>int + diff --git a/Runtime/Export/common_structs b/Runtime/Export/common_structs new file mode 100644 index 0000000..e39b534 --- /dev/null +++ b/Runtime/Export/common_structs @@ -0,0 +1,29 @@ +Vector3 +Vector2 +Quaternion +Matrix4x4 +Vector4 +Rect +Color +Bounds +Keyframe +Ray +Ray2D +Plane +NetworkViewID +JointMotor +JointSpring +JointLimits +SoftJointLimit +JointDrive +WheelFrictionCurve +WheelHit +RaycastHit +ContactPoint +TreeInstance +WiiNunchuk +WiiClassic +WiiPadInfo +WiiRemote +NVStatus +MatchTargetWeightMask diff --git a/Runtime/Export/docs.css b/Runtime/Export/docs.css new file mode 100644 index 0000000..087a8e8 --- /dev/null +++ b/Runtime/Export/docs.css @@ -0,0 +1,461 @@ +body { + background-color: white; + margin: 10px; +} +body, p, ul, ol, td, li { + font-family: Helvetica, Arial, sans-serif; + font-size: 12px; +} +body, p { color: #352f28; line-height: 17px;} + +table { + border: 0px; + border-collapse: collapse; + font-size: 13px; +} +td, th { + vertical-align: top; + padding: 0px; +} +em { + color:#111; +} +h1 { + clear:both; + font-size:18px; + font-weight:bold; + color:black; + margin: .7em 0px 0px 0px; + line-height: 25px; +} + +h2 { + font-size:14px; + font-weight:bold; + color:black; + margin: 1em 0px 0px 0px; +} + +h3 { + font-size:12px; + color:#171411; + font-weight:bold; + margin: 1em 0px 0px 0px; +} +h4{ margin: 1em 0px 0px 0px;} + +p { + margin:0px 0px 1.5em 0px; +} + +.doc-prop, .doc-keyword, .doc-menu { + font-weight:bold; +} + +a { + color: #145d7b; + text-decoration:none; +} + +a:hover { + text-decoration:underline; +} + +ul, li { margin-left:0px; } +a img { + border: 0px; +} + +/* Property tables */ +.prop { width:20%; visibility:hidden; height:1px;} +.function { width:80%; visibility:hidden;height:1px;} +.tableheader { visibility:hidden; } + +/* Previous & Next buttons */ +/* Previous + Next style navigation */ + +.nav { + clear: both; + margin-top: 10px; + margin-bottom: 10px; +} + +.nav .nav-prev, +.nav .nav-next { +} + +.nav .nav-prev .nav-left { + float: left; + background: url(../images/navigation/prev_left.png) top; + height: 22px; + width: 20px; +} +.nav .nav-prev .nav-right { + float: left; + background: url(../images/navigation/prev_right.png) top; + height: 22px; + width: 11px; +} +.nav .nav-next .nav-left { + float: right; + background: url(../images/navigation/next_right.png) top; + height: 22px; + width: 20px; +} +.nav .nav-next .nav-right { + float: right; + background: url(../images/navigation/next_left.png) top; + height: 22px; + width: 11px; +} +.nav .nav-prev .nav-main, +.nav .nav-next .nav-main { + height: 22px; + background: url(../images/navigation/nav_back.png) top repeat-x; + white-space: nowrap; + + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + + color: #333; +} +.nav .nav-prev .nav-main { + float: left; + text-align: left; +} +.nav .nav-next .nav-main { + float: right; + text-align: right; +} +.nav a { + text-decoration: none; +} +.nav a:hover { + text-decoration: underline; +} + + +/* Styles for the title bar */ +.titlebar { + width:100%; + background: url(../images/top/stretch.png) top; + font-weight:bold; + color:#a4abae; + vertical-align:middle; +} +.titleleft { + vertical-align: top; + width:80px; + height:64px; +} +.titleright { + background: url(../images/top/right.png); + width:9px; + height:64px; +} + +.titlemid { + background: url(../images/top/stretch.png) top; + height:64px; + width:100%; +} + +.titlemid .doctitle { + height:30px; + font-size: 15px; + padding-top:3px; + padding-left:9px; + vertical-align:middle; + width:100%; + color:#c7c7c7; + white-space: nowrap; +} + +.titlemid .docpath { + white-space: nowrap; + color:#a4abae; + margin-top:2px; + margin-left:9px; + width:100%; +} + +.titlemid .switchlink { + white-space: nowrap; + color:#a4abae; + vertical-align:middle; + text-align:right; +} + +.titlemid a { + color: #a4abae; + text-decoration:none; +} + +.titlemid a:hover { + text-decoration:underline; +} + +.switchlink { + text-align:right; + padding-right:16px; + padding-left:10px; +} + +.manual { + margin-left:74px; + margin-right:20px; +} + +.vspace { + margin-top:10px; +} + +/* Buttons the containing style (.Components) is the location of the current page + I use this to select between on and off images */ +.Components .manual { width:72px; height:36px; background: url(../images/top/manual.png) top right; margin:0px;} +.Components .reference { width:94px; height:36px; background: url(../images/top/reference_on.png) top right; } +.Components .scripting { width:82px; height:36px; background: url(../images/top/scripting.png) top right; } +.Components .manual:hover { background: url(../images/top/manual_hover.png) top right; margin:0px;} +.Components .reference:hover { background: url(../images/top/reference_onhover.png) top right; } +.Components .scripting:hover { background: url(../images/top/scripting_hover.png) top right; } + +.Manual .manual { width:72px; height:36px; background: url(../images/top/manual_on.png) top right; margin:0px;} +.Manual .reference { width:94px; height:36px; background: url(../images/top/reference.png) top right; } +.Manual .scripting { width:82px; height:36px; background: url(../images/top/scripting.png) top right; } +.Manual .manual:hover { background: url(../images/top/manual_onhover.png) top right; margin:0px;} +.Manual .reference:hover { background: url(../images/top/reference_hover.png) top right; } +.Manual .scripting:hover { background: url(../images/top/scripting_hover.png) top right; } + +.Scripting .manual { width:72px; height:36px; background: url(../images/top/manual.png) top right; margin:0px;} +.Scripting .reference { width:94px; height:36px; background: url(../images/top/reference.png) top right; } +.Scripting .scripting { width:82px; height:36px; background: url(../images/top/scripting_on.png) top right; } +.Scripting .manual:hover { background: url(../images/top/manual_hover.png) top right; margin:0px;} +.Scripting .reference:hover { background: url(../images/top/reference_hover.png) top right; } +.Scripting .scripting:hover { background: url(../images/top/scripting_onhover.png) top right; } + +.docs-navigation {display:none;} +.manual-text {display:none;} +.components-text {display:none;} +.scripting-text {display:none;} +/* scriptref styles + ======================================================*/ + +/* left navigation menu*/ +form.apisearch { + padding: 0px; + margin: 0px; +} + +ul.left-menu { + position: absolute; + left: 5px; + top: 90px; + + width: 159px; + padding: 0px 0px 0px 20px; + margin: 0px; + line-height: 15px; + list-style-type: none; +} +.left-menu-heading, .left-menu-softheading, .left-menu-subheading { + padding-top: 10px; + font-weight: bold; + color:black; + display: block; + overflow: hidden; + -o-text-overflow: ellipsis; /* Opera */ + text-overflow: ellipsis; /* IE, Safari (WebKit) */ +} +.left-menu-indent { + margin-left: 2em; /* this needs to be margin; otherwise .left-menu-current wont work */ +} +.left-menu a { + text-decoration: none; + white-space: nowrap; +} + +.left-menu a:hover { + text-decoration: underline; + color: #145d7b; +} + +.left-menu-current { + position: relative; + background-color: #e8e8e8; + padding: 0px 5px 0px 5px; + left: -5px; + -moz-border-radius: 4px; -webkit-border-radius: 4px; +} + +.left-menu-item, .left-menu-item a { + color: #352f28; + display: block; + width: 159px; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; /* Opera */ + text-overflow: ellipsis; /* IE, Safari (WebKit) */ +} +.left-menu-inherited-item, .left-menu-inherited-item a { + color: #352f28; + display: block; + width: 159px; + white-space: nowrap; + overflow: hidden; + -o-text-overflow: ellipsis; /* Opera */ + text-overflow: ellipsis; /* IE, Safari (WebKit) */ +} + + +/* class page */ +.scriprefmain { + padding-top:0px; + padding-left:185px; + padding-right:5px; +} +.scriprefmain ul { + list-style-type: none; + + } +.heading { + clear:both; + font-size:18px; + font-weight:bold; + color:black; + margin: .9em 0px 0px 0px; + display:block; + line-height: 25px; +} + +.text { + display:block; + margin-bottom: 1.5em; +} + +.script-section-softheading { + font-size:12px; + font-weight:bold; + margin: 1em 0px 0px 0px; +} + +.script-section-hardheading { + font-size:14px; + font-weight:bold; + color:black; + margin: 1em 0px 0px 0px; +} + +.class-member-list, .class-member-list-inherited { + width: 100%; + border-bottom:1px solid #888580; + border-top:1px solid #888580; + margin-bottom:2em; +} +.class-member-list-name { + width: 20%; + text-align: left; +} +.class-member-description { + display: inline; +} + +.scriprefmain ul.list { + list-style-type: disc; + margin-top: 2px; + margin-bottom: 2px; +} + +.scriprefmain .editorclass { + color: #666; + background-color: #ccc; + background-color: #f8f8f8; + padding: 2px 5px 2px 5px; + -moz-border-radius: 4px; -webkit-border-radius: 4px; +} + + +/* function page */ +.manual-entry h3 { margin-top: 0px; text-indent: -60px; margin-left:60px;} +.manual-entry h3 .hl-keyword, +.manual-entry h3 .hl-datatype, +.manual-entry h3 .classlink + { + font-weight:normal; +} + +h3.soft { margin-top:1em;} +table.parameters { + margin-top:-12px; + width:100%; +} +table.parameters thead { visibility:hidden; height:0px; display:block;} +table.parameters tbody { border-bottom:1px solid #888580; + border-top:1px solid #888580; +} +td.param-name {font-weight:bold; margin-right:10px; padding-right: 10px; width:20%;} +.code, .codelisting { + font-family: "Verdana", "Arial"; + font-size: 8pt; + padding: 7px; + background-color: #eee; + color: #222; + white-space: pre; + margin-bottom: 1.5em; + margin-top:0em; + -moz-border-radius: 5px; -webkit-border-radius: 5px; +} + +.comment { + color: #006600; +} +.hl-comment { + color: #006600; +} + + +/* Scripting overview stuff */ +.toc { + float: left; + margin-top: 1px; + margin-bottom: 1em; + vertical-align: top; + text-align: left; +} +.tocclear { + clear: both; +} +.toc p { + margin-bottom:0px; +} +.toc p.tocheader { + font-weight:bold; + background-color: white; + text-align: left; + font-size: 12px; +} + + +dd { + margin-left:0em; + margin-bottom:1em; +} + +dt { font-weight:bold; } +th { text-align:left; padding-right:20px;} + +.pre-next-link a { + width: 180px; + display: inline-block; + white-space: nowrap; + margin-bottom: -3px; +} + +.main ul { + padding-left:20px; +} + +.variable { + font-style:italic; +} + diff --git a/Runtime/Export/iOS/CocoaIntegration.cs b/Runtime/Export/iOS/CocoaIntegration.cs new file mode 100644 index 0000000..dea1431 --- /dev/null +++ b/Runtime/Export/iOS/CocoaIntegration.cs @@ -0,0 +1,89 @@ +#if UNITY_IPHONE_API + +using System; +using System.Collections; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace UnityEngine +{ +public sealed partial class iPhone +{ + [System.Runtime.InteropServices.DllImport("__Internal")] + internal static extern void UnityNSObject_RetainObject(IntPtr obj); + + [System.Runtime.InteropServices.DllImport("__Internal")] + internal static extern void UnityNSObject_ReleaseObject(IntPtr obj); + + public sealed partial class NSError + { + [System.Runtime.InteropServices.DllImport("__Internal")] + private static extern int UnityNSError_Code(IntPtr errorObj); + + [System.Runtime.InteropServices.DllImport("__Internal")] + private static extern IntPtr UnityNSError_Description(IntPtr errorObj); + + [System.Runtime.InteropServices.DllImport("__Internal")] + private static extern IntPtr UnityNSError_Reason(IntPtr errorObj); + + + private IntPtr _nativeError; + private NSError(IntPtr nativeError) + { + _nativeError = nativeError; + UnityNSObject_RetainObject(_nativeError); + } + ~NSError() + { + UnityNSObject_ReleaseObject(_nativeError); + } + + public static NSError CreateNSError(IntPtr nativeError) + { + return nativeError == IntPtr.Zero ? null : new NSError(nativeError); + } + + public int code + { + get { return UnityNSError_Code(_nativeError); } + } + public string description + { + get { return Marshal.PtrToStringAnsi(UnityNSError_Description(_nativeError)); } + } + public string reason + { + get { return Marshal.PtrToStringAnsi(UnityNSError_Reason(_nativeError)); } + } + } + + public sealed partial class NSNotification + { + [System.Runtime.InteropServices.DllImport("__Internal")] + private static extern IntPtr UnityNSNotification_Name(IntPtr notificationObj); + + private IntPtr _nativeNotification; + private NSNotification(IntPtr nativeNotification) + { + _nativeNotification = nativeNotification; + UnityNSObject_RetainObject(_nativeNotification); + } + ~NSNotification() + { + UnityNSObject_ReleaseObject(_nativeNotification); + } + + public static NSNotification CreateNSNotification(IntPtr nativeNotification) + { + return nativeNotification == IntPtr.Zero ? null : new NSNotification(nativeNotification); + } + + public string name + { + get { return Marshal.PtrToStringAnsi(UnityNSNotification_Name(_nativeNotification)); } + } + } +} +} + +#endif diff --git a/Runtime/Export/iOS/iAD.cs b/Runtime/Export/iOS/iAD.cs new file mode 100644 index 0000000..c8fc80f --- /dev/null +++ b/Runtime/Export/iOS/iAD.cs @@ -0,0 +1,187 @@ +#if UNITY_IPHONE_API + +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ +public sealed partial class ADBannerView +{ + public enum + Layout + { + // banner + Top = 0, + Bottom = 1, + + // rect + TopLeft = 0, + TopRight = 4, + TopCenter = 8, + BottomLeft = 1, + BottomRight = 5, + BottomCenter= 9, + CenterLeft = 2, + CenterRight = 6, + Center = 10, + + Manual = -1 + }; + + public enum + Type + { + Banner = 0, + MediumRect = 1 + }; + + private Layout _layout; + private IntPtr _bannerView; + + public static bool IsAvailable(Type type) + { + return Native_BannerTypeAvailable((int)type); + } + + // some naughty magic to make sure we can properly strip class + // if ctor is ever called, static func will be forcibly generated + private static bool _AlwaysFalseDummy = false; + public ADBannerView(Type type, Layout layout) + { + if(_AlwaysFalseDummy) + { + FireBannerWasClicked(); + FireBannerWasLoaded(); + } + + _bannerView = Native_CreateBanner((int)type, (int)layout); + } + ~ADBannerView() + { + Native_DestroyBanner(_bannerView); + } + + public bool loaded + { + get { return Native_BannerAdLoaded(_bannerView); } + } + public bool visible + { + get { return Native_BannerAdVisible(_bannerView); } + set { Native_ShowBanner(_bannerView, value); } + } + public Layout layout + { + // TODO: should we query native side? + get { return _layout; } + set { _layout = value; Native_LayoutBanner(_bannerView, (int)_layout); } + } + + public Vector2 position + { + get + { + Vector2 ret; Native_BannerPosition(_bannerView, out ret); + return OSToScreenCoords(ret); + } + set + { + Vector2 pos = new Vector2(value.x/Screen.width, value.y/Screen.height); + Native_MoveBanner(_bannerView, pos); + } + } + + public Vector2 size + { + get + { + Vector2 ret; Native_BannerSize(_bannerView, out ret); + return OSToScreenCoords(ret); + } + } + + public delegate void BannerWasClickedDelegate(); + public static event BannerWasClickedDelegate onBannerWasClicked = null; + + public delegate void BannerWasLoadedDelegate(); + public static event BannerWasLoadedDelegate onBannerWasLoaded = null; + + private Vector2 OSToScreenCoords(Vector2 v) + { + return new Vector2(v.x * Screen.width, v.y * Screen.height); + } + + private static void FireBannerWasClicked() + { + if(onBannerWasClicked != null) + onBannerWasClicked(); + } + + private static void FireBannerWasLoaded() + { + if(onBannerWasLoaded != null) + onBannerWasLoaded(); + } +} + +public sealed partial class ADInterstitialAd +{ + private IntPtr interstitialView; + + public static bool isAvailable + { + get { return Native_InterstitialAvailable(); } + } + + // some naughty magic to make sure we can properly strip class + // if ctor is ever called, static func will be forcibly generated + private static bool _AlwaysFalseDummy = false; + private void CtorImpl(bool autoReload) + { + if(_AlwaysFalseDummy) + FireInterstitialWasLoaded(); + + interstitialView = Native_CreateInterstitial(autoReload); + } + public ADInterstitialAd(bool autoReload) + { + CtorImpl(autoReload); + } + public ADInterstitialAd() + { + CtorImpl(false); + } + ~ADInterstitialAd() + { + Native_DestroyInterstitial(interstitialView); + } + + + public void Show() + { + Native_ShowInterstitial(interstitialView); + } + public void ReloadAd() + { + Native_ReloadInterstitial(interstitialView); + } + + public bool loaded + { + get { return Native_InterstitialAdLoaded(interstitialView); } + } + + public delegate void InterstitialWasLoadedDelegate(); + public static event InterstitialWasLoadedDelegate onInterstitialWasLoaded = null; + + private static void FireInterstitialWasLoaded() + { + if(onInterstitialWasLoaded != null) + onInterstitialWasLoaded(); + } +} +} + +#endif diff --git a/Runtime/Export/iOS/iAD.txt b/Runtime/Export/iOS/iAD.txt new file mode 100644 index 0000000..725e4e6 --- /dev/null +++ b/Runtime/Export/iOS/iAD.txt @@ -0,0 +1,91 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Math/Vector2.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +using namespace Unity; + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + +CONDITIONAL UNITY_IPHONE_API +CLASS ADBannerView + + C++RAW extern void* UnityAD_CreateBanner(int, int); + C++RAW extern void UnityAD_DestroyBanner(void*); + C++RAW extern void UnityAD_ShowBanner(void*, bool); + C++RAW extern void UnityAD_MoveBanner(void*, float, float); + C++RAW extern void UnityAD_LayoutBanner(void*, int); + C++RAW extern bool UnityAD_BannerTypeAvailable(int); + C++RAW extern void UnityAD_BannerPosition(void*, float*, float*); + C++RAW extern void UnityAD_BannerSize(void*, float*, float*); + C++RAW extern bool UnityAD_BannerAdLoaded(void*); + C++RAW extern bool UnityAD_BannerAdVisible(void*); + + + CUSTOM private static IntPtr Native_CreateBanner(int type, int layout) { return UnityAD_CreateBanner(type, layout); } + CUSTOM private static void Native_ShowBanner(IntPtr view, bool show) { UnityAD_ShowBanner(view, show); } + CUSTOM private static void Native_MoveBanner(IntPtr view, Vector2 pos) { UnityAD_MoveBanner(view, pos.x, pos.y); } + CUSTOM private static void Native_LayoutBanner(IntPtr view, int layout) { UnityAD_LayoutBanner(view, layout); } + CUSTOM private static bool Native_BannerTypeAvailable(int type) { return UnityAD_BannerTypeAvailable(type); } + CUSTOM private static void Native_BannerPosition(IntPtr view, out Vector2 pos){ UnityAD_BannerPosition(view, &pos->x, &pos->y); } + CUSTOM private static void Native_BannerSize(IntPtr view, out Vector2 pos) { UnityAD_BannerSize(view, &pos->x, &pos->y); } + CUSTOM private static bool Native_BannerAdLoaded(IntPtr view) { return UnityAD_BannerAdLoaded(view); } + CUSTOM private static bool Native_BannerAdVisible(IntPtr view) { return UnityAD_BannerAdVisible(view); } + + + THREAD_SAFE CUSTOM private static void Native_DestroyBanner(IntPtr view) { UnityAD_DestroyBanner(view); } + +END + +CONDITIONAL UNITY_IPHONE_API +CLASS ADInterstitialAd + + C++RAW extern void* UnityAD_CreateInterstitial(bool); + C++RAW extern void UnityAD_DestroyInterstitial(void*); + C++RAW extern void UnityAD_ShowInterstitial(void*); + C++RAW extern void UnityAD_ReloadInterstitial(void*); + C++RAW extern bool UnityAD_InterstitialAvailable(); + C++RAW extern bool UnityAD_InterstitialAdLoaded(void*); + + + CUSTOM private static IntPtr Native_CreateInterstitial(bool autoReload) { return UnityAD_CreateInterstitial(autoReload); } + CUSTOM private static void Native_ShowInterstitial(IntPtr view) { UnityAD_ShowInterstitial(view); } + CUSTOM private static void Native_ReloadInterstitial(IntPtr view) { UnityAD_ReloadInterstitial(view); } + CUSTOM private static bool Native_InterstitialAdLoaded(IntPtr view) { return UnityAD_InterstitialAdLoaded(view); } + CUSTOM private static bool Native_InterstitialAvailable() { return UnityAD_InterstitialAvailable(); } + + + THREAD_SAFE CUSTOM private static void Native_DestroyInterstitial(IntPtr view) { UnityAD_DestroyInterstitial(view); } +END + + +CSRAW +} + +C++RAW +#if !UNITY_IPHONE + void* UnityAD_CreateBanner(int, int) { return 0; } + void UnityAD_DestroyBanner(void*) {} + void UnityAD_ShowBanner(void*, bool) {} + void UnityAD_MoveBanner(void*, float, float) {} + void UnityAD_LayoutBanner(void*, int) {} + bool UnityAD_BannerTypeAvailable(int) { return false; } + void UnityAD_BannerPosition(void*, float*, float*) {} + void UnityAD_BannerSize(void*, float*, float*) {} + bool UnityAD_BannerAdLoaded(void*) { return false; } + bool UnityAD_BannerAdVisible(void*) { return false; } + void* UnityAD_CreateInterstitial(bool) { return 0; } + void UnityAD_DestroyInterstitial(void*) {} + void UnityAD_ShowInterstitial(void*) {} + void UnityAD_ReloadInterstitial(void*) {} + bool UnityAD_InterstitialAvailable() { return false; } + bool UnityAD_InterstitialAdLoaded(void*) { return false; } +#endif diff --git a/Runtime/Export/iPhoneInput.txt b/Runtime/Export/iPhoneInput.txt new file mode 100644 index 0000000..ecda622 --- /dev/null +++ b/Runtime/Export/iPhoneInput.txt @@ -0,0 +1,1020 @@ +C++RAW + +#include "UnityPrefix.h" +#include "Runtime/Video/MoviePlayback.h" +#include "Runtime/Math/Color.h" +#include "Runtime/Misc/SystemInfo.h" +#include "Runtime/Network/NetworkManager.h" +#include "Runtime/Input/GetInput.h" +#include "Runtime/Input/LocationService.h" +#include "Runtime/Input/OnScreenKeyboard.h" +#include "PlatformDependent/iPhonePlayer/iPhoneSettings.h" +#include "PlatformDependent/iPhonePlayer/APN.h" +#include "Runtime/Scripting/Scripting.h" +#include "Runtime/Scripting/ScriptingUtility.h" + +using namespace Unity; + + +CSRAW +using System; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +using System.Collections; + +namespace UnityEngine +{ + + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneTouchPhase enumeration is deprecated. Please use TouchPhase instead. +ENUM iPhoneTouchPhase + // A finger touched the screen. + Began = 0, + // A finger moved on the screen. + Moved = 1, + // A finger is touching the screen but hasn't moved. + Stationary = 2, + // A finger was lifted from the screen. This is the final phase of a touch. + Ended = 3, + // The system cancelled tracking for the touch, as when (for example) the user puts the device to her face or more than five touches happened simultaneously. This is the final phase of a touch. + Canceled = 4 +END + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneTouch struct is deprecated. Please use Touch instead. +STRUCT iPhoneTouch + CSRAW private int m_FingerId; + CSRAW private Vector2 m_Position; + CSRAW private Vector2 m_PositionDelta; + CSRAW private float m_TimeDelta; + CSRAW private int m_TapCount; + CSRAW private iPhoneTouchPhase m_Phase; + + // The unique index for touch. + CSRAW public int fingerId { get { return m_FingerId; } } + + // The position of the touch. + CSRAW public Vector2 position { get { return m_Position; } } + + // The position delta since last change. + CSRAW public Vector2 deltaPosition { get { return m_PositionDelta; } } + + // Amount of time passed since last change. + CSRAW public float deltaTime { get { return m_TimeDelta; } } + + // Number of taps. + CSRAW public int tapCount { get { return m_TapCount; } } + + // Describes the phase of the touch. + CSRAW public iPhoneTouchPhase phase { get { return m_Phase; } } + + + OBSOLETE warning positionDelta property is deprecated. Please use iPhoneTouch.deltaPosition instead. + CSRAW public Vector2 positionDelta { get { return m_PositionDelta; } } + + OBSOLETE warning timeDelta property is deprecated. Please use iPhoneTouch.deltaTime instead. + CSRAW public float timeDelta { get { return m_TimeDelta; } } +END + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneAccelerationEvent struct is deprecated. Please use AccelerationEvent instead. +STRUCT iPhoneAccelerationEvent + CSRAW private Vector3 m_Acceleration; + CSRAW private float m_TimeDelta; + + // Value of acceleration. + CSRAW public Vector3 acceleration { get { return m_Acceleration; } } + + // Amount of time passed since last accelerometer measurement. + CSRAW public float deltaTime { get { return m_TimeDelta; } } + + OBSOLETE warning timeDelta property is deprecated. Please use iPhoneAccelerationEvent.deltaTime instead. + CSRAW public float timeDelta { get { return m_TimeDelta; } } + +END + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneOrientation enumeration is deprecated. Please use DeviceOrientation instead. +ENUM iPhoneOrientation + // The orientation of the device cannot be determined. + Unknown = 0, + // The device is in portrait mode, with the device held upright and the home button at the bottom. + Portrait = 1, + // The device is in portrait mode but upside down, with the device held upright and the home button at the top. + PortraitUpsideDown = 2, + // The device is in landscape mode, with the device held upright and the home button on the right side. + LandscapeLeft = 3, + // The device is in landscape mode, with the device held upright and the home button on the left side. + LandscapeRight = 4, + // The device is held perpendicular to the ground with the screen facing upwards. + FaceUp = 5, + // The device is held perpendicular to the ground with the screen facing downwards. + FaceDown = 6 +END + +// The iPhoneInput class acts as the interface into the iPhone's unique Input systems. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +CLASS iPhoneInput + + OBSOLETE warning accelerationEvents property is deprecated. Please use Input.accelerationEvents instead. + CSRAW public static iPhoneAccelerationEvent[] accelerationEvents { get { + int count = accelerationEventCount; + iPhoneAccelerationEvent[] events = new iPhoneAccelerationEvent[count]; + for (int q = 0; q < count; ++q) + events[q] = GetAccelerationEvent (q); + return events; + } + } + + OBSOLETE warning touches property is deprecated. Please use Input.touches instead. + CSRAW public static iPhoneTouch[] touches { get { + int count = touchCount; + iPhoneTouch[] touches = new iPhoneTouch[count]; + for (int q = 0; q < count; ++q) + touches[q] = GetTouch (q); + return touches; + } + } + + OBSOLETE warning GetTouch method is deprecated. Please use Input.GetTouch instead. + CUSTOM static iPhoneTouch GetTouch (int index) + { +#if ENABLE_NEW_EVENT_SYSTEM + if (index >= 0 && index < GetTouchCount ()) + { + Touch* t = GetTouch(index); + + if (t != NULL) + { + return *t; + } + else + { + Scripting::RaiseMonoException ("GetTouch() failed!"); + } + } + else + { + Scripting::RaiseMonoException ("Index specified to GetTouch() is out of bounds! Must be less than Touch.touchCount."); + } + Touch dummy; + return dummy; +#else + Touch touch; + + if (index >= 0 && index < GetTouchCount ()) + { + if (!GetTouch (index, touch)) + Scripting::RaiseMonoException ("Internal error."); + } + else + Scripting::RaiseMonoException ("Index out of bounds."); + return touch; +#endif + } + + OBSOLETE warning touchCount property is deprecated. Please use Input.touchCount instead. + CUSTOM_PROP static int touchCount { return GetTouchCount (); } + + OBSOLETE warning multiTouchEnabled property is deprecated. Please use Input.multiTouchEnabled instead. + CUSTOM_PROP static bool multiTouchEnabled { return IsMultiTouchEnabled (); } { return SetMultiTouchEnabled (value); } + + OBSOLETE warning GetAccelerationEvent method is deprecated. Please use Input.GetAccelerationEvent instead. + CUSTOM static iPhoneAccelerationEvent GetAccelerationEvent (int index) + { + Acceleration acc; + if (index >= 0 && index < GetAccelerationCount ()) + GetAcceleration (index, acc); + else + Scripting::RaiseMonoException ("Index out of bounds."); + return acc; + } + + OBSOLETE warning accelerationEventCount property is deprecated. Please use Input.accelerationEventCount instead. + CUSTOM_PROP static int accelerationEventCount { return GetAccelerationCount (); } + + OBSOLETE warning acceleration property is deprecated. Please use Input.acceleration instead. + CUSTOM_PROP static Vector3 acceleration { return GetAcceleration (); } + + OBSOLETE warning orientation property is deprecated. Please use Input.deviceOrientation instead. + CUSTOM_PROP static iPhoneOrientation orientation { return GetOrientation(); } + + OBSOLETE warning lastLocation property is deprecated. Please use Input.location.lastData instead. + CUSTOM_PROP static LocationInfo lastLocation { + if (LocationService::GetLocationStatus() != kLocationServiceRunning) + printf_console ("Location service updates are not enabled. Check Handheld.locationServiceStatus before querying last location.\n"); + + return LocationService::GetLastLocation(); + } +END + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneScreenOrientation enumeration is deprecated. Please use ScreenOrientation instead. +ENUM iPhoneScreenOrientation + //*undocumented* + Unknown = 0, + // Portrait orientation. + Portrait = 1, + // Portrait orientation upside down. + PortraitUpsideDown = 2, + // Landscape orientation, home button on the right side. + LandscapeLeft = 3, + // Landscape orientation, home button on the left side. + LandscapeRight = 4, + + // Default landscape orientation, home button on the right side (equals to \LandscapeLeft\). + Landscape = 3, +END + +// Interface into iPhone specific settings. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +CLASS iPhoneSettings + OBSOLETE warning screenOrientation property is deprecated. Please use Screen.orientation instead. + CUSTOM_PROP static iPhoneScreenOrientation screenOrientation { return GetScreenManager().GetScreenOrientation(); } { GetScreenManager().RequestOrientation(value); } + OBSOLETE warning verticalOrientation property is deprecated. Please use Screen.orientation instead. + CUSTOM_PROP static bool verticalOrientation { return GetScreenManager().GetScreenOrientation() == kPortrait; } { GetScreenManager().SetScreenOrientation(value ? kPortrait : kLandscapeLeft); } + OBSOLETE warning screenCanDarken property is deprecated. Please use Screen.sleepTimeout instead. + CUSTOM_PROP static bool screenCanDarken { return IsIdleTimerEnabled(); } { SetIdleTimerEnabled(value); } + OBSOLETE warning uniqueIdentifier property is deprecated. Please use SystemInfo.deviceUniqueIdentifier instead. + CUSTOM_PROP static string uniqueIdentifier { return scripting_string_new(systeminfo::GetDeviceUniqueIdentifier()); } + OBSOLETE warning name property is deprecated. Please use SystemInfo.deviceName instead. + CUSTOM_PROP static string name { return scripting_string_new(systeminfo::GetDeviceName()); } + OBSOLETE warning model property is deprecated. Please use SystemInfo.deviceModel instead. + CUSTOM_PROP static string model { return scripting_string_new(systeminfo::GetDeviceModel()); } + OBSOLETE warning systemName property is deprecated. Please use SystemInfo.operatingSystem instead. + CUSTOM_PROP static string systemName { return scripting_string_new(systeminfo::GetDeviceSystemName()); } + OBSOLETE warning systemVersion property is deprecated. Please use SystemInfo.operatingSystem instead. + CUSTOM_PROP static string systemVersion { return scripting_string_new(systeminfo::GetDeviceSystemVersion()); } + OBSOLETE warning internetReachability property is deprecated. Please use Application.internetReachability instead. + CUSTOM_PROP static iPhoneNetworkReachability internetReachability { return GetInternetReachability(); } + OBSOLETE warning generation property is deprecated. Please use iPhone.generation instead. + CUSTOM_PROP static iPhoneGeneration generation { return iphone::GetDeviceGeneration(); } + OBSOLETE warning locationServiceStatus property is deprecated. Please use Input.location.status instead. + CUSTOM_PROP static LocationServiceStatus locationServiceStatus { return LocationService::GetLocationStatus(); } + OBSOLETE warning locationServiceEnabledByUser property is deprecated. Please use Input.location.isEnabledByUser instead. + CUSTOM_PROP static bool locationServiceEnabledByUser { return LocationService::IsServiceEnabledByUser(); } + + OBSOLETE warning StartLocationServiceUpdates method is deprecated. Please use Input.location.Start instead. + CUSTOM static void StartLocationServiceUpdates(float desiredAccuracyInMeters, float updateDistanceInMeters) { + LocationService::SetDesiredAccuracy(desiredAccuracyInMeters); + LocationService::SetDistanceFilter(updateDistanceInMeters); + LocationService::StartUpdatingLocation(); + } + OBSOLETE warning StartLocationServiceUpdates method is deprecated. Please use Input.location.Start instead. + CSRAW public static void StartLocationServiceUpdates(float desiredAccuracyInMeters) { + StartLocationServiceUpdates(desiredAccuracyInMeters, 10.0f); + } + OBSOLETE warning StartLocationServiceUpdates method is deprecated. Please use Input.location.Start instead. + CSRAW public static void StartLocationServiceUpdates() { + StartLocationServiceUpdates(10.0f, 10.0f); + } + + OBSOLETE warning StopLocationServiceUpdates method is deprecated. Please use Input.location.Stop instead. + CUSTOM static void StopLocationServiceUpdates() { + LocationService::StopUpdatingLocation(); + } +END + +// Describes the type of keyboard. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneKeyboardType enumeration is deprecated. Please use TouchScreenKeyboardType instead. +ENUM iPhoneKeyboardType + // Default keyboard for the current input method. + Default = 0, + // Keyboard displays standard ASCII characters. + ASCIICapable = 1, + // Keyboard with numbers and punctuation. + NumbersAndPunctuation = 2, + // Keyboard optimized for URL entry, features ".", "/", and ".com" prominently. + URL = 3, + // Numeric keypad designed for PIN entry, features the numbers 0 through 9 prominently. + NumberPad = 4, + // Keypad designed for entering telephone numbers, features the numbers 0 through 9 and the "*" and "#" characters prominently. + PhonePad = 5, + // Keypad designed for entering a person's name or phone number. + NamePhonePad = 6, + // Keyboard optimized for specifying email addresses, features the "@", "." and space characters prominently. + EmailAddress = 7 +END + +// Simple struct that contains all the arguments needed by iPhoneKeyboard_InternalConstructorHelper. + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +STRUCT internal iPhoneKeyboard_InternalConstructorHelperArguments + CSRAW public string text; + CSRAW public string textPlaceholder; + CSRAW public uint keyboardType; + CSRAW public uint autocorrection; + CSRAW public uint multiline; + CSRAW public uint secure; + CSRAW public uint alert; +END + +C++RAW + +struct MonoiPhoneKeyboard_InternalConstructorHelperArguments { + MonoString* text; + MonoString* textPlaceholder; + unsigned int keyboardType; + unsigned int autocorrection; + unsigned int multiline; + unsigned int secure; + unsigned int alert; +}; + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneKeyboard class is deprecated. Please use TouchScreenKeyboard instead. +CLASS iPhoneKeyboard + // We are matching the KeyboardOnScreen class here so we can directly access it. + CSRAW private IntPtr keyboardWrapper; + + C++RAW + #define GET ExtractMonoObjectData<KeyboardOnScreen*> (self) + + THREAD_SAFE + CUSTOM private void Destroy() + { + if (GET) + { + delete GET; + GET=0; + } + } + + //*undocumented* + CSRAW ~iPhoneKeyboard() + { + Destroy(); + } + + //*undocumented* + public iPhoneKeyboard(string text, iPhoneKeyboardType keyboardType, bool autocorrection, bool multiline, bool secure, bool alert, string textPlaceholder) + { + iPhoneKeyboard_InternalConstructorHelperArguments arguments = new iPhoneKeyboard_InternalConstructorHelperArguments (); + arguments.text = text; + arguments.keyboardType = Convert.ToUInt32(keyboardType); + arguments.autocorrection = Convert.ToUInt32(autocorrection); + arguments.multiline = Convert.ToUInt32(multiline); + arguments.secure = Convert.ToUInt32(secure); + arguments.alert = Convert.ToUInt32(alert); + arguments.textPlaceholder = textPlaceholder; + iPhoneKeyboard_InternalConstructorHelper (arguments); + } + + CUSTOM private void iPhoneKeyboard_InternalConstructorHelper (iPhoneKeyboard_InternalConstructorHelperArguments arguments) + { + GET = new KeyboardOnScreen(scripting_cpp_string_for(arguments.text), + arguments.keyboardType, arguments.autocorrection, arguments.multiline, arguments.secure, arguments.alert, + scripting_cpp_string_for(arguments.textPlaceholder)); + } + + //*undocumented* + CSRAW public static iPhoneKeyboard Open(string text, iPhoneKeyboardType keyboardType = iPhoneKeyboardType.Default, bool autocorrection = true, bool multiline = false, bool secure = false, bool alert = false, string textPlaceholder = "") + { + return new iPhoneKeyboard(text, keyboardType, autocorrection, multiline, secure, alert, textPlaceholder); + } + + //*undocumented* + CUSTOM_PROP public string text { + if (GET) return scripting_string_new(GET->getText()); + else return scripting_string_new(""); + } { + if (GET) GET->setText(value); + } + + //*undocumented* + CUSTOM_PROP public static bool hideInput { + return KeyboardOnScreen::isInputHidden(); + } { + KeyboardOnScreen::setInputHidden(value); + } + + //*undocumented* + CUSTOM_PROP public bool active { + if (GET) return (short)GET->isActive(); + else return false; + } { + if (GET) GET->setActive(value); + } + + //*undocumented* + CUSTOM_PROP public bool done { + if (GET) return (short)GET->isDone(); + else return false; + } + + C++RAW + #undef GET + + //*undocumented* + CUSTOM_PROP static Rect area { return KeyboardOnScreen::GetRect(); } + + //*undocumented* + CUSTOM_PROP static bool visible { return KeyboardOnScreen::IsVisible(); } +END + + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneMovieControlMode enumeration is deprecated. Please use FullScreenMovieControlMode instead. +ENUM iPhoneMovieControlMode + // Display the standard controls for controlling movie playback. This includes play/pause controls, a volume slider, and a timeline control. + Full = 0, + // Display minimal set of controls controlling movie playback. Set of controls might differ between OS versions. + Minimal = 1, + // Do not display any controls, but cancel movie playback if the user touches the screen. + CancelOnTouch = 2, + // Do not display any controls. This mode prevents the user from controlling playback. + Hidden = 3, + + OBSOLETE warning VolumeOnly is deprecated. Please use iPhoneMovieControlMode.Minimal instead. + // Display volume controls only. + VolumeOnly = 1 +END + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneMovieScalingMode enumeration is deprecated. Please use FullScreenMovieScalingMode instead. +ENUM iPhoneMovieScalingMode + // Do not scale the movie. + None = 0, + // Scale the movie until one dimension fits on the screen exactly. + AspectFit = 1, + // Scale the movie until the movie fills the entire screen. + AspectFill = 2, + // Scale the movie until both dimensions fit the screen exactly. The aspect ratio of the movie is not preserved. + Fill = 3 +END + +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +OBSOLETE warning iPhoneNetworkReachability enumeration is deprecated. Please use NetworkReachability instead. +ENUM iPhoneNetworkReachability + // Network is not reachable + NotReachable = 0, + // Network is reachable via carrier data network + ReachableViaCarrierDataNetwork = 1, + // Network is reachable via WiFi network + ReachableViaWiFiNetwork = 2 +END + +// Interface into iPhone miscellaneous functionality. +CONDITIONAL UNITY_IPHONE_API || UNITY_ANDROID_API +CLASS iPhoneUtils + + // we want to avoid obsolete warnings: + // if method is not marked as obsolete and uses obsolete types we get warning + // so prototypes for c-side calls will use ints and we manually create default-params overloads + + OBSOLETE warning PlayMovie method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CUSTOM static void PlayMovie (string path, Color bgColor, int controlMode, int scalingMode) + { + PlayFullScreenMovie (path, bgColor, (unsigned)controlMode, (unsigned)scalingMode); + } + OBSOLETE warning PlayMovie method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CSRAW public static void PlayMovie (string path, Color bgColor, iPhoneMovieControlMode controlMode, iPhoneMovieScalingMode scalingMode) + { + PlayMovie (path, bgColor, (int)controlMode, (int)scalingMode); + } + OBSOLETE warning PlayMovie method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CSRAW public static void PlayMovie (string path, Color bgColor, iPhoneMovieControlMode controlMode) + { + PlayMovie (path, bgColor, (int)controlMode, (int)iPhoneMovieScalingMode.AspectFit); + } + OBSOLETE warning PlayMovie method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CSRAW public static void PlayMovie (string path, Color bgColor) + { + PlayMovie (path, bgColor, (int)iPhoneMovieControlMode.Full, (int)iPhoneMovieScalingMode.AspectFit); + } + + OBSOLETE warning PlayMovieURL method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CUSTOM static void PlayMovieURL (string url, Color bgColor, int controlMode, int scalingMode) + { + PlayFullScreenMovie (url, bgColor, (unsigned)controlMode, (unsigned)scalingMode); + } + OBSOLETE warning PlayMovieURL method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CSRAW public static void PlayMovieURL (string url, Color bgColor, iPhoneMovieControlMode controlMode, iPhoneMovieScalingMode scalingMode) + { + PlayMovieURL (url, bgColor, (int)controlMode, (int)scalingMode); + } + OBSOLETE warning PlayMovieURL method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CSRAW public static void PlayMovieURL (string url, Color bgColor, iPhoneMovieControlMode controlMode) + { + PlayMovieURL (url, bgColor, (int)controlMode, (int)iPhoneMovieScalingMode.AspectFit); + } + OBSOLETE warning PlayMovieURL method is deprecated. Please use Handheld.PlayFullScreenMovie instead. + CSRAW public static void PlayMovieURL (string url, Color bgColor) + { + PlayMovieURL (url, bgColor, (int)iPhoneMovieControlMode.Full, (int)iPhoneMovieScalingMode.AspectFit); + } + + OBSOLETE warning Vibrate method is deprecated. Please use Handheld.Vibrate instead. + CUSTOM static void Vibrate () + { + Vibrate (); + } + OBSOLETE warning isApplicationGenuine property is deprecated. Please use Application.genuine instead. + CUSTOM_PROP static bool isApplicationGenuine + { + return IsApplicationGenuine (); + } + OBSOLETE warning isApplicationGenuineAvailable property is deprecated. Please use Application.genuineCheckAvailable instead. + CUSTOM_PROP static bool isApplicationGenuineAvailable + { + return IsApplicationGenuineAvailable(); + } +END + +// Specify calendar types. +CONDITIONAL UNITY_IPHONE_API +ENUM CalendarIdentifier + // Identifies the Gregorian calendar. + GregorianCalendar = 0, + // Identifies the Buddhist calendar. + BuddhistCalendar = 1, + // Identifies the Chinese calendar. + ChineseCalendar = 2, + // Identifies the Hebrew calendar. + HebrewCalendar = 3, + // Identifies the Islamic calendar. + IslamicCalendar = 4, + // Identifies the Islamic civil calendar. + IslamicCivilCalendar = 5, + // Identifies the Japanese calendar. + JapaneseCalendar = 6, + // Identifies the Republic of China (Taiwan) calendar. + RepublicOfChinaCalendar = 7, + // Identifies the Persian calendar. + PersianCalendar = 8, + // Identifies the Indian calendar. + IndianCalendar = 9, + // Identifies the ISO8601. + ISO8601Calendar = 10 +END + +// Specify calendrical units. +CONDITIONAL UNITY_IPHONE_API +ENUM CalendarUnit + // Specifies the era unit. + Era = 2, + // Specifies the year unit. + Year = 4, + // Specifies the month unit. + Month = 8, + // Specifies the day unit. + Day = 16, + // Specifies the hour unit. + Hour = 32, + // Specifies the minute unit. + Minute = 64, + // Specifies the second unit. + Second = 128, + // Specifies the week unit. + Week = 256, + // Specifies the weekday unit. + Weekday = 512, + // Specifies the ordinal weekday unit. + WeekdayOrdinal = 1024, + // Specifies the quarter of the calendar. + Quarter = 2048 +END + +// LocalNotification is a wrapper around the UILocalNotification class found in the Apple UIKit framework and is only available on iPhone/iPad/iPod Touch. +CONDITIONAL UNITY_IPHONE_API +CLASS LocalNotification + CSRAW private IntPtr notificationWrapper; + + C++RAW + #define GET ExtractMonoObjectData<iPhoneLocalNotification*> (self) + + //*undocumented* + CUSTOM private double GetFireDate() + { + return GET->GetFireDate(); + } + + //*undocumented* + CUSTOM private void SetFireDate(double dt) + { + GET->SetFireDate(dt); + } + + CSRAW private static long m_NSReferenceDateTicks = new DateTime( + 2001, 1, 1, 0, 0, 0, DateTimeKind.Utc).Ticks; + + // The date and time when the system should deliver the notification. + CSRAW public DateTime fireDate { get { + return new DateTime((long)(GetFireDate() * 10000000) + m_NSReferenceDateTicks); + } + + set { + SetFireDate((value.ToUniversalTime().Ticks - m_NSReferenceDateTicks) / 10000000.0); + } + } + + // The time zone of the notification's fire date. + CUSTOM_PROP public string timeZone + { + const char *timeZone = GET->GetTimeZone(); + return (timeZone ? scripting_string_new(timeZone) : 0); + } + { + GET->SetTimeZone(value.IsNull() ? 0 : value.AsUTF8().c_str()); + } + + // The calendar interval at which to reschedule the notification. + CUSTOM_PROP public CalendarUnit repeatInterval + { + return GET->GetRepeatInterval(); + } + { + GET->SetRepeatInterval(value); + } + + // The name of the file containing the sound to play when an alert is displayed. + CUSTOM_PROP public CalendarIdentifier repeatCalendar + { + return GET->GetRepeatCalendar(); + } + { + GET->SetRepeatCalendar(value); + } + + // The message displayed in the notification alert. + CUSTOM_PROP public string alertBody + { + const char *message = GET->GetAlertBody(); + return (message ? scripting_string_new(message) : 0); + } + { + GET->SetAlertBody(value.IsNull() ? 0 : value.AsUTF8().c_str()); + } + + // The title of the action button or slider. + CUSTOM_PROP public string alertAction + { + const char *action = GET->GetAlertAction(); + return (action ? scripting_string_new(action) : 0); + } + { + GET->SetAlertAction(value.IsNull() ? 0 : value.AsUTF8().c_str()); + } + + // A boolean value that controls whether the alert action is visible or not. + CUSTOM_PROP public bool hasAction + { + return GET->HasAction(); + } + { + GET->HasAction(value); + } + + // Identifies the image used as the launch image when the user taps the action button. + CUSTOM_PROP public string alertLaunchImage + { + const char *path = GET->GetAlertLaunchImage(); + return (path ? scripting_string_new(path) : 0); + } + { + GET->SetAlertLaunchImage(value.IsNull () ? 0 : value.AsUTF8().c_str()); + } + + // The number to display as the application's icon badge. + CUSTOM_PROP public int applicationIconBadgeNumber + { + return GET->GetApplicationIconBadgeNumber(); + } + { + GET->SetApplicationIconBadgeNumber(value); + } + + // The name of the sound file to play when an alert is displayed. + CUSTOM_PROP public string soundName + { + const char *path = GET->GetSoundName(); + return (path ? scripting_string_new(path) : 0); + } + { + GET->SetSoundName(value.IsNull() ? 0 : value.AsUTF8().c_str()); + } + + // The default system sound. (RO) + CUSTOM_PROP public static string defaultSoundName + { + const char *path = iPhoneLocalNotification::GetDefaultSoundName(); + return (path ? scripting_string_new(path) : 0); + } + + // A dictionary for passing custom information to the notified application. + CUSTOM_PROP public IDictionary userInfo + { + return GET->GetUserInfo(); + } + { + GET->SetUserInfo(value); + } + + THREAD_SAFE + CUSTOM private void Destroy() + { + if (GET) + { + delete GET; + GET = 0; + } + } + + //*undocumented* + CSRAW ~LocalNotification() + { + Destroy(); + } + + //*undocumented* + CUSTOM private void InitWrapper() + { + GET = new iPhoneLocalNotification; + } + + // Creates a new local notification. + CSRAW public LocalNotification() + { + InitWrapper(); + } + + C++RAW + #undef GET +END + +// RemoteNotification is only available on iPhone/iPad/iPod Touch. +CONDITIONAL UNITY_IPHONE_API +CLASS RemoteNotification + CSRAW private IntPtr notificationWrapper; + + C++RAW + #define GET ExtractMonoObjectData<iPhoneRemoteNotification*> (self) + + // The message displayed in the notification alert. (RO) + CUSTOM_PROP public string alertBody + { + const char *message = GET->GetAlertBody(); + return (message ? scripting_string_new(message) : 0); + } + + // A boolean value that controls whether the alert action is visible or not. (RO) + CUSTOM_PROP public bool hasAction + { + return GET->HasAction(); + } + + // The number to display as the application's icon badge. (RO) + CUSTOM_PROP public int applicationIconBadgeNumber + { + return GET->GetApplicationIconBadgeNumber(); + } + + // The name of the sound file to play when an alert is displayed. (RO) + CUSTOM_PROP public string soundName + { + const char *path = GET->GetSoundName(); + return (path ? scripting_string_new(path) : 0); + } + + // A dictionary for passing custom information to the notified application. (RO) + CUSTOM_PROP public IDictionary userInfo + { + return GET->GetUserInfo(); + } + + THREAD_SAFE + CUSTOM private void Destroy() + { + if (GET) + { + delete GET; + GET = 0; + } + } + + //*undocumented* + CSRAW ~RemoteNotification() + { + Destroy(); + } + + //*undocumented* + CSRAW private RemoteNotification() + { } + + C++RAW + #undef GET +END + +// Specify remote notification types. +CONDITIONAL UNITY_IPHONE_API +ENUM RemoteNotificationType + // The application accepts no notifications. + None = 0, + // The application accepts notifications that badge the application icon. + Badge = 1, + // The application accepts alert sounds as notifications. + Sound = 2, + // The application accepts alert messages as notifications. + Alert = 4 +END + +// NotificationServices is only available on iPhone/iPad/iPod Touch. +CONDITIONAL UNITY_IPHONE_API +CLASS NotificationServices + // The number of received local notifications. (RO) + CUSTOM_PROP static int localNotificationCount { return GetLocalNotificationCount(); } + + // Returns an object representing a specific local notification. (RO) + CUSTOM static LocalNotification GetLocalNotification(int index) + { + if (index >= 0 && index < GetLocalNotificationCount()) + { + MonoClass *classLocalNotification; + MonoObject *localNotification; + + classLocalNotification = GetMonoManager().GetBuiltinMonoClass("LocalNotification"); + localNotification = mono_object_new(mono_domain_get(), classLocalNotification); + + ExtractMonoObjectData<iPhoneLocalNotification*>(localNotification) = CopyLocalNotification(index); + + return localNotification; + } + + Scripting::RaiseMonoException("Index out of bounds."); + return 0; + } + + // The list of objects representing received local notifications. (RO) + CSRAW public static LocalNotification[] localNotifications { get { + int count = localNotificationCount; + LocalNotification[] notifications = new LocalNotification[count]; + for (int i = 0; i < count; ++i) + notifications[i] = GetLocalNotification(i); + return notifications; + } + } + + // Schedules a local notification. + CUSTOM public static void ScheduleLocalNotification(LocalNotification notification) + { + Scripting::RaiseIfNull(notification); + ExtractMonoObjectData<iPhoneLocalNotification*>(notification)->Schedule(); + } + + // Presents a local notification immediately. + CUSTOM public static void PresentLocalNotificationNow(LocalNotification notification) + { + Scripting::RaiseIfNull(notification); + ExtractMonoObjectData<iPhoneLocalNotification*>(notification)->PresentNow(); + } + + // Cancels the delivery of the specified scheduled local notification. + CUSTOM public static void CancelLocalNotification(LocalNotification notification) + { + Scripting::RaiseIfNull(notification); + ExtractMonoObjectData<iPhoneLocalNotification*>(notification)->Cancel(); + } + + // Cancels the delivery of all scheduled local notifications. + CUSTOM public static void CancelAllLocalNotifications() + { + iPhoneLocalNotification::CancelAll(); + } + + // All currently scheduled local notifications. + CUSTOM_PROP public static LocalNotification[] scheduledLocalNotifications + { + std::vector<iPhoneLocalNotification*> notifications = iPhoneLocalNotification::GetScheduled(); + int count = notifications.size(); + MonoClass *classLocalNotification = GetMonoManager().GetBuiltinMonoClass("LocalNotification"); + MonoArray *monoNotifications = mono_array_new(mono_domain_get(), classLocalNotification, count); + + for (int index = 0; index < count; ++index) + { + MonoObject *notif = mono_object_new(mono_domain_get(), classLocalNotification); + ExtractMonoObjectData<iPhoneLocalNotification*>(notif) = notifications[index]; + Scripting::SetScriptingArrayElement(monoNotifications, index, notif); + } + + return monoNotifications; + } + + // The number of received remote notifications. (RO) + CUSTOM_PROP static int remoteNotificationCount { return GetRemoteNotificationCount(); } + + // Returns an object representing a specific remote notification. (RO) + CUSTOM static RemoteNotification GetRemoteNotification(int index) + { + if (index >= 0 && index < GetRemoteNotificationCount()) + { + MonoClass *classRemoteNotification; + MonoObject *remoteNotification; + + classRemoteNotification = GetMonoManager().GetBuiltinMonoClass("RemoteNotification"); + remoteNotification = mono_object_new(mono_domain_get(), classRemoteNotification); + + ExtractMonoObjectData<iPhoneRemoteNotification*>(remoteNotification) = CopyRemoteNotification(index); + + return remoteNotification; + } + + Scripting::RaiseMonoException("Index out of bounds."); + return 0; + } + + // The list of objects representing received remote notifications. (RO) + CSRAW public static RemoteNotification[] remoteNotifications { get { + int count = remoteNotificationCount; + RemoteNotification[] notifications = new RemoteNotification[count]; + for (int i = 0; i < count; ++i) + notifications[i] = GetRemoteNotification(i); + return notifications; + } + } + + // Discards of all received local notifications. + CUSTOM public static void ClearLocalNotifications() + { + ClearLocalNotifications(); + } + + // Discards of all received remote notifications. + CUSTOM public static void ClearRemoteNotifications() + { + ClearRemoteNotifications(); + } + + // Register to receive remote notifications of the specified types from a provider via Apple Push Service. + CUSTOM public static void RegisterForRemoteNotificationTypes(RemoteNotificationType notificationTypes) + { + iPhoneRemoteNotification::Register(notificationTypes); + } + + // Unregister for remote notifications. + CUSTOM public static void UnregisterForRemoteNotifications() + { + iPhoneRemoteNotification::Unregister(); + } + + // The types of notifications the application accepts. + CUSTOM_PROP public static RemoteNotificationType enabledRemoteNotificationTypes + { + return iPhoneRemoteNotification::GetEnabledTypes(); + } + + // Device token received from Apple Push Service after calling @@NotificationServices.RegisterForRemoteNotificationTypes@@. (RO) + CUSTOM_PROP public static byte[] deviceToken + { + const char *deviceToken = iPhoneRemoteNotification::GetDeviceToken(); + + if (!deviceToken) + return 0; + + int count = iPhoneRemoteNotification::GetDeviceTokenLength(); + MonoArray *monoDeviceToken = mono_array_new(mono_domain_get(), mono_get_byte_class(), count); + + for (int index = 0; index < count; ++index) + { + Scripting::SetScriptingArrayElement(monoDeviceToken, index, deviceToken[index]); + } + + return monoDeviceToken; + } + + // Returns an error that might occur on registration for remote notifications via @@NotificationServices.RegisterForRemoteNotificationTypes@@. (RO) + CUSTOM_PROP public static string registrationError + { + const char *error = iPhoneRemoteNotification::GetError(); + return (error ? scripting_string_new(error) : 0); + } +END + +CONDITIONAL UNITY_IPHONE_API +CLASS internal UnhandledExceptionHandler + CSRAW private static void RegisterUECatcher() + { + AppDomain.CurrentDomain.UnhandledException += HandleUnhandledException; + } + + C++RAW + extern void CrashedCheckBellowForHintsWhy(); + THREAD_SAFE + CUSTOM private static void HandleUnhandledException(object sender, object args) + { + #if UNITY_IOS + // Let unhandled exceptions crash only when happening on main thread + if ( Thread::CurrentThreadIsMainThread() ) + { + // This function is defined in iOS trampoline + CrashedCheckBellowForHintsWhy(); + } + #endif + } +END + +CSRAW +} + diff --git a/Runtime/Export/style.css b/Runtime/Export/style.css new file mode 100644 index 0000000..af8867a --- /dev/null +++ b/Runtime/Export/style.css @@ -0,0 +1,407 @@ +html { + height: 100%; +} +body { + background-color: white; + margin: 0px; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + height: 100%; + overflow: auto; + color: #222; +} +img { + border: 0px; +} +.main { + padding-top:0px; + padding-left:185px; + padding-right:5px; +} + +a { + color: #900000; + text-decoration:underline; +} + +.classlink { + text-decoration:none; +} +.itemlink { + text-decoration:none; +} + + +td { + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; +} +th { + border-bottom: 1px solid #c9c9c9; + font-family: Arial, Helvetica, sans-serif; + font-size: 12px; + text-align: left; +} + +table.parameters { + margin: 0px 20px 0px 20px; + padding: 7px; +// border: 1px solid #ededed; + width: 87%; + border-collapse: collapse; +} + +table.parameters th { + padding-left:2px; + padding-right:2px; + margin: 0px; + border-bottom: 1px solid #666666; +} + +table.parameters td { + padding-left:2px; + padding-right:2px; + border: 0px; + margin: 0px; +} + +table.parameters th { + color: #222; +// background: #eee; +} + +tr.even-row { +// background: #edf3fe; +} +tr.even-row td{ +// border-left: 1px solid #dcdfe4; +} +tr.odd-row td { + padding-right: 20px; +// border-left: 1px solid #ededed; +} + +td.param-name { + font-weight: bold; + padding-left: 0px; +} + + +dt { + font-weight: bold; +} + +h1{ + font-size: 20px; + margin-bottom: 1px; + clear: both; +} + +.script-section-hardheading { + display: block; + width: 100%; + font-size: 20px; + font-weight: bold; + clear: both; + color: #666666; + margin-bottom: 1px; + margin-top: 20px; +} + +.script-section-softheading { + display: block; + width: 70%; + font-size: 12px; + font-weight: bold; + clear: both; + color: black; + margin-bottom: 1px; + margin-top: 10px; + border-bottom: 1px solid #c9c9c9; +} + +h3 { + font-size: 12px; + font-weight: bold; + clear: both; + margin-top: 1px; + margin-bottom: 1px; + color: black; +} +.manual-entry h3 { + padding-left: 40px; + text-indent: -40px; +} + +h3.soft { + color: #666666; + margin-top:10px; + margin-bottom:0px; + font-weight: normal; +} +p { + padding-top: 0px; + margin-top: 0px; + margin-bottom:10px; +} + + +p.details { + padding-left:20px; + padding-right:20px; +} +p.basic { +} +p.first { + margin-top: 10px; +} +.toplink { +} + +.synopsis { + font-family: "monaco", "Courier", "Courier New"; + font-size: 11px; + font-weight: normal; + padding-left:20px; + margin-bottom:10px; +} +.synopsis .doc-comment { + font: italic 12px; +} +.note { + font-weight: bold; + color: #666666; +} +.editorclass { + color: #666666; +} +.code { + font-family: "Verdana", "Arial"; + font-size: 8pt; + margin: 10px 20px 10px 30px; + padding: 7px; + background-color: #eee; + color: #222; + border: 1px solid #c9c9c9; + white-space: pre; + width: 85%; +} +.comment { + color: #006600; +} +.hl-comment { + color: #666666; + color: #006600; +} +.hl-datatype { + color: #0000a0; +} +.hl-keyword { + color: #000066; +} +.hl-operator { + font-weight: bold; + color: #444; +} +.hl-string { + color: #0000a0; +} + +.refimg { + display: block; + border: 1px solid #c9c9c9; + margin: 5px 20px 5px 30px; + padding: 1px; +} + +.toc { + width:180; + font-size:12px; + border-top-width: 1px; + border-bottom-width: 1px; + float: left; + margin-top: 1px; + margin-bottom: 10px; + vertical-align: top; + text-align: left; + font-weight:bold; +} +.tocclear { + clear: both; +} +.toc p { + margin-bottom:0px; + margin-left: 10px; +} +.toc p.tocheader { + background-color: white; + border-bottom: 1px solid #c9c9c9; + margin-left: 10px; + text-align: left; + font-size: 12px; +} +.toc a { + font-weight: normal; + text-decoration:none; +} + +.class-member-list { + width: 100%; +} +.class-member-list-name { + width: 200px; + text-align: left; +} +.class-member-list-name a { + text-decoration:none; +} +.class-member-description { + display: inline; +} +.class-member-list-inherited .class-member-list-name { + font-style: italic; +} + +/* NAVIGATION BAR STUFF */ + + +td.doctitle { + height:50px; +} +td.doctitle p { + margin-top: 0px; + margin-bottom: 0px; + padding: 0px 5px 0px 15px; + font-weight: bold; + color: #666666; +} +td.doctitle p a { + color: #666666; + text-decoration: none; +} + +td.doctitle p a:hover { + color: #cc0000; + text-decoration: underline; +} + +form.apisearch { + padding: 0px; + padding-top: 5px; + margin: 0px; +} +form.apisearch input { + width: 120px; + font-size: 12px; +} + +.doctitle .heading { + margin-bottom: 1px; + color: #333333; + font-size: 24px; + font-weight:bold; + margin-top: 5px; + margin-left: 15px; +} + +.doctitle .text { + padding: 0px 5px 0px 10px; + font-size: 12px; + font-weight: bold; + color: #333333; +} + +.titlebar { + width: 100%; + border-width:0px; + margin-bottom:20px; + padding: 0px; + border-collapse: collapse; +} + +.navbuttons { + text-align:right; + width:194px; + padding: 0px; + white-space: nowrap; +} + +.variable { + font-style: italic; +} +.parameter { + font-style: italic; +} + + +ul.left-menu { + position: absolute; + left: 5px; + top: 50px; + + width: 139px; + padding: 0px 0px 0px 20px; + margin: 0px; + + list-style-type: none; +} +.left-menu a { + text-decoration: none; + white-space: nowrap; +} +.left-menu-item, .left-menu-item a { + color: #900000; +} +.left-menu-inherited-item, .left-menu-inherited-item a { + color: #900000; + font-style: oblique; +} + +.left-menu-seperator { + height: 10px; + display: block; +} +.left-menu-heading { + padding-top: 0px; + font-weight: bold; + margin-left: -18px; + display: block; +} +.left-menu-subheading { + padding-top: 4px; + font-weight: bold; + border-bottom: 1px solid #c9c9c9; + display: block; +} +.left-menu-softheading { + padding-top: 4px; + border-bottom: 1px solid #c9c9c9; + display: block; + color: #666666; + font-style: italic; +} +.left-menu-seperator, .left-menu-heading, a.left-menu-heading { + color:black; +} + +.left-menu-current { + color: #cc0000; + font-weight: bold; + white-space: nowrap; +} + +.pre-next-link a { + width: 180px; + display: inline-block; + white-space: nowrap; + margin-bottom: -3px; + text-decoration: none; +} +div.pre-next-link { + margin-bottom: 10px; +} + +a:hover { + color: #cc0000; + text-decoration: underline; +}
\ No newline at end of file |