summaryrefslogtreecommitdiff
path: root/Runtime/Scripting/ScriptingObjectWithIntPtrField.h
blob: e4cbf99ae6a2c672fe994c2d92a7673eb7c43c25 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#pragma once

#include "Runtime/Scripting/ScriptingUtility.h"

#if 1 //!UNITY_WINRT
#if ENABLE_MONO
extern int* s_MonoDomainContainer;
#endif
template<class T>
struct ScriptingObjectWithIntPtrField
{
	ScriptingObjectPtr object;

	ScriptingObjectWithIntPtrField(ScriptingObjectPtr o) : object(o) {}

	T& operator * () const
	{
		return GetReference ();
	}
	
	T* operator -> () const
	{
		return &GetReference ();
	}

	operator T* () const
	{
		return GetPtr ();
	}
	
	inline T& GetReference () const
	{
		void* nativePointer = GetPtr();

		if (nativePointer == NULL)
			Scripting::RaiseNullException ("");
		
		return *reinterpret_cast<T*> (nativePointer);
	}

	typedef void ExecuteOnManagedFinalizer(void* obj);

	inline void SetPtr(T* ptr, ExecuteOnManagedFinalizer* eomf = NULL)
	{
	#if ENABLE_MONO
		Assert(ptr == NULL || GET_CURRENT_ALLOC_ROOT_HEADER() == NULL
			|| GET_CURRENT_ALLOC_ROOT_HEADER() == GET_ALLOC_HEADER(s_MonoDomainContainer, kMemMono));
		ExtractMonoObjectData<T*>(object) = ptr;
		(void)eomf;
	#elif UNITY_FLASH
		
		__asm __volatile__("obj_g0 = marshallmap.getObjectWithId(%0);"::"r"(object));
		__asm __volatile__("obj_g0.m_Ptr = %0;"::"r"(ptr));

		//We only insert this if we actually have a way to clean it...if we don't then there's no point in inserting it in the finalizer map.
		if(eomf == NULL)
			return;
			
		__asm __volatile__("finalizePtrsMap[%0] = %1;" : : "r"(ptr),"r"(eomf));
		__asm __volatile__("finalizeMap[obj_g0] = %0;"::"r"(ptr));
	#elif UNITY_WINRT
		static BridgeInterface::IMarshalling^ marshaller = s_WinRTBridge->Marshalling;
		marshaller->MarshalNativePtrIntoFirstFieldGC(object.GetHandle(), (int)ptr);
		//typedef void (__stdcall *TMarshalNativePtrIntoFirstField)(ScriptingObjectPtr, int);
		//static TMarshalNativePtrIntoFirstField call = (TMarshalNativePtrIntoFirstField)GetWinRTMarshalling()->GetMarshalNativePtrIntoFirstFieldDelegatePtr();
		//call(object, (int)ptr);
	#endif	
	}

	inline T* GetPtr() const
	{
		if (!object)
			return NULL;
		
	#if ENABLE_MONO
		return ExtractMonoObjectData<T*>(object);
	#elif UNITY_FLASH
		T* result;
		__asm __volatile__("%0 = marshallmap.getObjectWithId(%1).m_Ptr;" : "=r"(result) : "r"(object));
		return result;
	#elif UNITY_WINRT
		static BridgeInterface::IMarshalling^ marshaller = s_WinRTBridge->Marshalling;
		return (T*)marshaller->MarshalFirstFieldIntoNativePtrGC(object.GetHandle());
		//typedef int (__stdcall *TMarshalFirstFieldIntoNativePtr)(ScriptingObjectPtr);
		//static TMarshalFirstFieldIntoNativePtr call = (TMarshalFirstFieldIntoNativePtr)GetWinRTMarshalling()->GetMarshalFirstFieldIntoNativePtrDelegatePtr();
		//return (T*)call(object);
	#endif	
	}

	inline ScriptingObjectPtr GetScriptingObject()
	{
		return object;
	}
};
#else
// THIS WON'T WORK because cachedPtr doesn't derive from Object, thus we cannot extract ScriptingObjectPtr from cachedPtr
template<class T>
struct ScriptingObjectWithIntPtrField
{
	T* cachedPtr;

	ScriptingObjectWithIntPtrField(void* o) : cachedPtr((T*)o) {}

	T& operator * () const
	{
		return *cachedPtr;
	}
	
	T* operator -> () const
	{
		return cachedPtr;
	}

	operator T* () const
	{
		return cachedPtr;
	}
	
	inline T& GetReference () const
	{
		return *cachedPtr;
	}

	inline T* GetPtr() const
	{
		return cachedPtr;
	}

	typedef void ExecuteOnManagedFinalizer(void* obj);

	inline void SetPtr(T* ptr, ExecuteOnManagedFinalizer* eomf = NULL)
	{
		if (cachedPtr != NULL)
		{
			s_WinRTBridge->Marshalling->MarshalNativePtrIntoFirstField(ObjectToScriptingObjectImpl(cachedPtr), (int)ptr);
		}
	}
};
#endif