forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			297 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
		
		
			
		
	
	
			297 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			Haxe
		
	
	
	
	
	
|  | /* | ||
|  |  * Copyright (C)2005-2019 Haxe Foundation | ||
|  |  * | ||
|  |  * Permission is hereby granted, free of charge, to any person obtaining a | ||
|  |  * copy of this software and associated documentation files (the "Software"), | ||
|  |  * to deal in the Software without restriction, including without limitation | ||
|  |  * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
|  |  * and/or sell copies of the Software, and to permit persons to whom the | ||
|  |  * Software is furnished to do so, subject to the following conditions: | ||
|  |  * | ||
|  |  * The above copyright notice and this permission notice shall be included in | ||
|  |  * all copies or substantial portions of the Software. | ||
|  |  * | ||
|  |  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
|  |  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
|  |  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
|  |  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
|  |  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
|  |  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
|  |  * DEALINGS IN THE SOFTWARE. | ||
|  |  */ | ||
|  | 
 | ||
|  | package cs; | ||
|  | 
 | ||
|  | import cs.system.Type; | ||
|  | 
 | ||
|  | /** | ||
|  | 	Platform-specific C# Library. Provides some platform-specific functions for the C# target, | ||
|  | 	such as conversion from haxe types to native types and vice-versa. | ||
|  | **/ | ||
|  | class Lib { | ||
|  | 	private static var decimalSeparator:String; | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Changes the current culture settings to allow a consistent cross-target behavior. | ||
|  | 		Currently the only change made is in regard to the decimal separator, which is always set to "." | ||
|  | 	**/ | ||
|  | 	public static function applyCultureChanges():Void { | ||
|  | 		var ci = new cs.system.globalization.CultureInfo(cs.system.threading.Thread.CurrentThread.CurrentCulture.Name, true); | ||
|  | 		decimalSeparator = ci.NumberFormat.NumberDecimalSeparator; | ||
|  | 		ci.NumberFormat.NumberDecimalSeparator = "."; | ||
|  | 		cs.system.threading.Thread.CurrentThread.CurrentCulture = ci; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Reverts the culture changes to the default settings. | ||
|  | 	**/ | ||
|  | 	public static function revertDefaultCulture():Void { | ||
|  | 		var ci = new cs.system.globalization.CultureInfo(cs.system.threading.Thread.CurrentThread.CurrentCulture.Name, true); | ||
|  | 		cs.system.threading.Thread.CurrentThread.CurrentCulture = ci; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns a native array from the supplied Array. This native array is unsafe to be written on, | ||
|  | 		as it may or may not be linked to the actual Array implementation. | ||
|  | 
 | ||
|  | 		If equalLengthRequired is true, the result might be a copy of an array with the correct size. | ||
|  | 	**/ | ||
|  | 	extern inline public static function nativeArray<T>(arr:Array<T>, equalLengthRequired:Bool):NativeArray<T> { | ||
|  | 		var ret = new cs.NativeArray(arr.length); | ||
|  | 		#if erase_generics | ||
|  | 		for (i in 0...arr.length) | ||
|  | 			ret[i] = arr[i]; | ||
|  | 		#else | ||
|  | 		p_nativeArray(arr, ret); | ||
|  | 		#end | ||
|  | 		return ret; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	#if !erase_generics | ||
|  | 	static function p_nativeArray<T>(arr:Array<T>, ret:cs.system.Array):Void { | ||
|  | 		var native:NativeArray<T> = untyped arr.__a; | ||
|  | 		var len = arr.length; | ||
|  | 		cs.system.Array.Copy(native, 0, ret, 0, len); | ||
|  | 	} | ||
|  | 	#end | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Provides support for the "as" keyword in C#. | ||
|  | 		If the object is not of the supplied type "T", it will return null instead of rasing an exception. | ||
|  | 
 | ||
|  | 		This function will not work with Value Types (such as Int, Float, Bool...) | ||
|  | 	**/ | ||
|  | 	@:pure | ||
|  | 	extern public static inline function as<T>(obj:Dynamic, cl:Class<T>):T { | ||
|  | 		return untyped __as__(obj); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns a Class<> equivalent to the native System.Type type. | ||
|  | 
 | ||
|  | 		Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail.
 | ||
|  | 		This may change in the future, so use this function whenever you need to perform such conversion. | ||
|  | 	**/ | ||
|  | 	public static inline function fromNativeType(t:cs.system.Type):Class<Dynamic> { | ||
|  | 		return untyped t; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns a System.Type equivalent to the Haxe Class<> type. | ||
|  | 
 | ||
|  | 		Currently Haxe's Class<> is equivalent to System.Type, but this is an implementation detail.
 | ||
|  | 		This may change in the future, so use this function whenever you need to perform such conversion. | ||
|  | 	**/ | ||
|  | 	public static inline function toNativeType(cl:Class<Dynamic>):Type { | ||
|  | 		return untyped cl; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns a System.Type equivalent to the Haxe Enum<> type. | ||
|  | 	**/ | ||
|  | 	public static inline function toNativeEnum(cl:Enum<Dynamic>):Type { | ||
|  | 		return untyped cl; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed. | ||
|  | 		[deprecated] - use `getNativeType` instead | ||
|  | 	**/ | ||
|  | 	@:deprecated('The function `nativeType` is deprecated and will be removed in later versions. Please use `getNativeType` instead') | ||
|  | 	public static inline function nativeType(obj:Dynamic):Type { | ||
|  | 		return untyped obj.GetType(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Gets the native System.Type from the supplied object. Will throw an exception in case of null being passed. | ||
|  | 	**/ | ||
|  | 	public static inline function getNativeType(obj:Dynamic):Type { | ||
|  | 		return untyped obj.GetType(); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	#if erase_generics | ||
|  | 	inline private static function mkDynamic<T>(native:NativeArray<T>):NativeArray<Dynamic> { | ||
|  | 		var ret = new cs.NativeArray<Dynamic>(native.Length); | ||
|  | 		for (i in 0...native.Length) | ||
|  | 			ret[i] = native[i]; | ||
|  | 		return ret; | ||
|  | 	} | ||
|  | 	#end | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns a Haxe Array of a native Array. | ||
|  | 		Unless `erase_generics` is defined, it won't copy the contents of the native array,
 | ||
|  | 		so unless any operation triggers an array resize, all changes made to the Haxe array | ||
|  | 		will affect the native array argument. | ||
|  | 	**/ | ||
|  | 	inline public static function array<T>(native:cs.NativeArray<T>):Array<T> { | ||
|  | 		#if erase_generics | ||
|  | 		var dyn:NativeArray<Dynamic> = mkDynamic(native); | ||
|  | 		return @:privateAccess Array.ofNative(dyn); | ||
|  | 		#else | ||
|  | 		return @:privateAccess Array.ofNative(native); | ||
|  | 		#end | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Allocates a new Haxe Array with a predetermined size | ||
|  | 	**/ | ||
|  | 	inline public static function arrayAlloc<T>(size:Int):Array<T> { | ||
|  | 		return @:privateAccess Array.alloc(size); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Rethrow an exception. This is useful when manually filtering an exception in order | ||
|  | 		to keep the previous exception stack. | ||
|  | 	**/ | ||
|  | 	extern inline public static function rethrow(e:Dynamic):Void { | ||
|  | 		throw untyped __rethrow__; | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Creates a "checked" block, which throws exceptions for overflows. | ||
|  | 
 | ||
|  | 		Usage: | ||
|  | 			cs.Lib.checked({ | ||
|  | 				var x = 1000; | ||
|  | 				while(true) | ||
|  | 				{ | ||
|  | 					x *= x; | ||
|  | 				} | ||
|  | 			}); | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 	**/ | ||
|  | 	extern public static inline function checked<V>(block:V):Void { | ||
|  | 		untyped __checked__(block); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Ensures that one thread does not enter a critical section of code while another thread | ||
|  | 		is in the critical section. If another thread attempts to enter a locked code, it | ||
|  | 		will wait, block, until the object is released. | ||
|  | 
 | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 	**/ | ||
|  | 	extern public static inline function lock<O, V>(obj:O, block:V):Void { | ||
|  | 		untyped __lock__(obj, block); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	// Unsafe code manipulation | ||
|  | 
 | ||
|  | 	#if unsafe | ||
|  | 	/** | ||
|  | 		Marks its parameters as fixed objects inside the defined block. | ||
|  | 		The first variable declarations that use cs.Lib.pointerOfArray() will be the fixed definitions. | ||
|  | 		Usage: | ||
|  | 			cs.Lib.fixed({ | ||
|  | 				var obj1 = cs.Lib.pointerOfArray(someArray); | ||
|  | 				var obj2 = cs.Lib.pointerOfArray(someArray2); | ||
|  | 				var obj3 = cs.Lib.pointerOfArray(someArray3); | ||
|  | 				//from now on, obj1, obj2 and obj3 are fixed | ||
|  | 				//we cannot change obj1, obj2 or obj3 variables like this: | ||
|  | 				//obj1++; | ||
|  | 			}); | ||
|  | 
 | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 	**/ | ||
|  | 	extern public static inline function fixed<V>(block:V):Void { | ||
|  | 		untyped __fixed__(block); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Marks the contained block as an unsafe block, meaning that it can contain unsafe code. | ||
|  | 		Usage: | ||
|  | 			cs.Lib.unsafe({ | ||
|  | 				//unsafe code is allowed inside here | ||
|  | 			}); | ||
|  | 
 | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 	**/ | ||
|  | 	extern public static inline function unsafe<V>(block:V):Void { | ||
|  | 		untyped __unsafe__(block); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Gets the pointer to the address of current local. Equivalent to the "&" operator in C# | ||
|  | 		Usage: | ||
|  | 			var x:Int = 0; | ||
|  | 			cs.Lib.unsafe({ | ||
|  | 				var addr = cs.Lib.addressOf(x); | ||
|  | 				x[0] = 42; | ||
|  | 			}); | ||
|  | 			trace(x); //42 | ||
|  | 
 | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 		Warning: This method will only work if a local variable is passed as an argument. | ||
|  | 	**/ | ||
|  | 	extern public static inline function addressOf<T>(variable:T):cs.Pointer<T> { | ||
|  | 		return untyped __addressOf__(variable); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Gets the value of the pointer address. | ||
|  | 		Usage: | ||
|  | 			var x:Int = 0; | ||
|  | 			cs.Lib.unsafe({ | ||
|  | 				var addr = cs.Lib.addressOf(x); | ||
|  | 				trace(cs.Lib.valueOf(addr)); //0 | ||
|  | 				addr[0] = 42; | ||
|  | 				trace(cs.Lib.valueOf(addr)); //42 | ||
|  | 			}); | ||
|  | 			trace(x); //42 | ||
|  | 
 | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 	**/ | ||
|  | 	extern public static inline function valueOf<T>(pointer:cs.Pointer<T>):T { | ||
|  | 		return untyped __valueOf__(pointer); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Transforms a managed native array into a Pointer. Must be inside a fixed statement | ||
|  | 		Usage: | ||
|  | 			var x:cs.NativeArray<Int> = new cs.NativeArray(1); | ||
|  | 			cs.Lib.unsafe({ | ||
|  | 				cs.Lib.fixed({ | ||
|  | 					var addr = cs.Lib.pointerOfArray(x); | ||
|  | 					trace(cs.Lib.valueOf(addr)); //0 | ||
|  | 					addr[0] = 42; | ||
|  | 					trace(cs.Lib.valueOf(addr)); //42 | ||
|  | 				}); | ||
|  | 			}); | ||
|  | 			trace(x[0]); //42 | ||
|  | 
 | ||
|  | 		This method only exists at compile-time, so it can't be called via reflection.
 | ||
|  | 	**/ | ||
|  | 	extern public static inline function pointerOfArray<T>(array:cs.NativeArray<T>):cs.Pointer<T> { | ||
|  | 		return untyped __ptr__(array); | ||
|  | 	} | ||
|  | 
 | ||
|  | 	/** | ||
|  | 		Returns the byte size of the given struct. Only works with structs and basic types. | ||
|  | 	**/ | ||
|  | 	extern public static inline function sizeof(struct:Class<Dynamic>):Int { | ||
|  | 		return untyped __sizeof__(struct); | ||
|  | 	} | ||
|  | 	#end | ||
|  | } |