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
 | 
						|
}
 |