forked from LeenkxTeam/LNXSDK
Update
This commit is contained in:
@ -130,57 +130,74 @@ import python.Syntax;
|
||||
}
|
||||
}
|
||||
|
||||
static inline function isSpaceChar(char:String):Bool
|
||||
return Syntax.isIn(char, " \n\r\t\x0b\x0c");
|
||||
|
||||
static inline function isHexPrefix(cur:String, next:String):Bool
|
||||
return cur == '0' && (next == 'x' || next == 'X');
|
||||
|
||||
static inline function isDecimalDigit(char:String):Bool
|
||||
return Syntax.isIn(char, "0123456789");
|
||||
|
||||
static inline function isHexadecimalDigit(char:String):Bool
|
||||
return Syntax.isIn(char, "0123456789abcdefABCDEF");
|
||||
|
||||
public static function parseInt(x:String):Null<Int> {
|
||||
if (x == null)
|
||||
return null;
|
||||
try {
|
||||
return UBuiltins.int(x);
|
||||
} catch (e:Dynamic) {
|
||||
var base = 10;
|
||||
var len = x.length;
|
||||
var foundCount = 0;
|
||||
var sign = 0;
|
||||
var firstDigitIndex = 0;
|
||||
var lastDigitIndex = -1;
|
||||
var previous = 0;
|
||||
|
||||
for(i in 0...len) {
|
||||
var c = StringTools.fastCodeAt(x, i);
|
||||
switch c {
|
||||
case _ if((c > 8 && c < 14) || c == 32):
|
||||
if(foundCount > 0) {
|
||||
return null;
|
||||
}
|
||||
continue;
|
||||
case '-'.code if(foundCount == 0):
|
||||
sign = -1;
|
||||
case '+'.code if(foundCount == 0):
|
||||
sign = 1;
|
||||
case '0'.code if(foundCount == 0 || (foundCount == 1 && sign != 0)):
|
||||
case 'x'.code | 'X'.code if(previous == '0'.code && ((foundCount == 1 && sign == 0) || (foundCount == 2 && sign != 0))):
|
||||
base = 16;
|
||||
case _ if('0'.code <= c && c <= '9'.code):
|
||||
case _ if(base == 16 && (('a'.code <= c && c <= 'z'.code) || ('A'.code <= c && c <= 'Z'.code))):
|
||||
case _:
|
||||
break;
|
||||
}
|
||||
if((foundCount == 0 && sign == 0) || (foundCount == 1 && sign != 0)) {
|
||||
firstDigitIndex = i;
|
||||
}
|
||||
foundCount++;
|
||||
lastDigitIndex = i;
|
||||
previous = c;
|
||||
}
|
||||
if(firstDigitIndex <= lastDigitIndex) {
|
||||
var digits = x.substring(firstDigitIndex, lastDigitIndex + 1);
|
||||
return try {
|
||||
(sign == -1 ? -1 : 1) * UBuiltins.int(digits, base);
|
||||
} catch(e:Dynamic) {
|
||||
null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
final len = x.length;
|
||||
var index = 0;
|
||||
|
||||
inline function hasIndex(index:Int)
|
||||
return index < len;
|
||||
|
||||
// skip whitespace
|
||||
while (hasIndex(index)) {
|
||||
if (!isSpaceChar(Syntax.arrayAccess(x, index)))
|
||||
break;
|
||||
++index;
|
||||
}
|
||||
|
||||
// handle sign
|
||||
final isNegative = hasIndex(index) && {
|
||||
final sign = Syntax.arrayAccess(x, index);
|
||||
if (sign == '-' || sign == '+') {
|
||||
++index;
|
||||
}
|
||||
sign == '-';
|
||||
}
|
||||
|
||||
// handle base
|
||||
final isHexadecimal = hasIndex(index + 1) && isHexPrefix(Syntax.arrayAccess(x, index), Syntax.arrayAccess(x, index + 1));
|
||||
if (isHexadecimal)
|
||||
index += 2; // skip prefix
|
||||
|
||||
// handle digits
|
||||
final firstInvalidIndex = {
|
||||
var cur = index;
|
||||
if (isHexadecimal) {
|
||||
while (hasIndex(cur)) {
|
||||
if (!isHexadecimalDigit(Syntax.arrayAccess(x, cur)))
|
||||
break;
|
||||
++cur;
|
||||
}
|
||||
} else {
|
||||
while (hasIndex(cur)) {
|
||||
if (!isDecimalDigit(Syntax.arrayAccess(x, cur)))
|
||||
break;
|
||||
++cur;
|
||||
}
|
||||
}
|
||||
cur;
|
||||
}
|
||||
|
||||
// no valid digits
|
||||
if (index == firstInvalidIndex)
|
||||
return null;
|
||||
|
||||
final result = python.internal.UBuiltins.int(x.substring(index, firstInvalidIndex), if (isHexadecimal) 16 else 10);
|
||||
return if (isNegative) -result else result;
|
||||
}
|
||||
|
||||
static function shortenPossibleNumber(x:String):String {
|
||||
|
||||
@ -28,20 +28,6 @@ import haxe.ds.StringMap;
|
||||
|
||||
@:coreApi
|
||||
class Sys {
|
||||
static var environ(get,default):StringMap<String>;
|
||||
static function get_environ():StringMap<String> {
|
||||
return switch environ {
|
||||
case null:
|
||||
var environ = new StringMap();
|
||||
var env = Os.environ;
|
||||
for (key in env.keys()) {
|
||||
environ.set(key, env.get(key, null));
|
||||
}
|
||||
Sys.environ = environ;
|
||||
case env: env;
|
||||
}
|
||||
}
|
||||
|
||||
public static inline function time():Float {
|
||||
return Time.time();
|
||||
}
|
||||
@ -64,15 +50,27 @@ class Sys {
|
||||
}
|
||||
|
||||
public static function getEnv(s:String):String {
|
||||
return environ.get(s);
|
||||
return Os.environ.get(s, null);
|
||||
}
|
||||
|
||||
public static function putEnv(s:String, v:String):Void {
|
||||
python.lib.Os.putenv(s, v);
|
||||
environ.set(s, v);
|
||||
public static function putEnv(s:String, v:Null<String>):Void {
|
||||
if (v == null) {
|
||||
try {
|
||||
Os.environ.remove(s);
|
||||
} catch(e:python.Exceptions.KeyError) {
|
||||
// the variable didn't exist
|
||||
}
|
||||
return;
|
||||
}
|
||||
Os.environ.set(s, v);
|
||||
}
|
||||
|
||||
public static function environment():Map<String, String> {
|
||||
final environ = new StringMap();
|
||||
final env = Os.environ;
|
||||
for (key in env.keys()) {
|
||||
environ.set(key, env.get(key, null));
|
||||
}
|
||||
return environ;
|
||||
}
|
||||
|
||||
@ -85,7 +83,7 @@ class Sys {
|
||||
}
|
||||
|
||||
public static function getCwd():String {
|
||||
return python.lib.Os.getcwd();
|
||||
return haxe.io.Path.addTrailingSlash(python.lib.Os.getcwd());
|
||||
}
|
||||
|
||||
public static function setCwd(s:String):Void {
|
||||
|
||||
@ -72,7 +72,7 @@ class IntMap<T> implements haxe.Constraints.IMap<Int, T> {
|
||||
|
||||
public function toString():String {
|
||||
var s = new StringBuf();
|
||||
s.add("{");
|
||||
s.add("[");
|
||||
var it = keys();
|
||||
for (i in it) {
|
||||
s.add(i);
|
||||
@ -81,7 +81,7 @@ class IntMap<T> implements haxe.Constraints.IMap<Int, T> {
|
||||
if (it.hasNext())
|
||||
s.add(", ");
|
||||
}
|
||||
s.add("}");
|
||||
s.add("]");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ class ObjectMap<K:{}, V> implements haxe.Constraints.IMap<K, V> {
|
||||
|
||||
public function toString():String {
|
||||
var s = new StringBuf();
|
||||
s.add("{");
|
||||
s.add("[");
|
||||
var it = keys();
|
||||
for (i in it) {
|
||||
s.add(Std.string(i));
|
||||
@ -80,7 +80,7 @@ class ObjectMap<K:{}, V> implements haxe.Constraints.IMap<K, V> {
|
||||
if (it.hasNext())
|
||||
s.add(", ");
|
||||
}
|
||||
s.add("}");
|
||||
s.add("]");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@ class StringMap<T> implements haxe.Constraints.IMap<String, T> {
|
||||
public function toString():String {
|
||||
var s = new StringBuf();
|
||||
|
||||
s.add("{");
|
||||
s.add("[");
|
||||
var it = keys();
|
||||
for (i in it) {
|
||||
s.add(i);
|
||||
@ -82,7 +82,7 @@ class StringMap<T> implements haxe.Constraints.IMap<String, T> {
|
||||
if (it.hasNext())
|
||||
s.add(", ");
|
||||
}
|
||||
s.add("}");
|
||||
s.add("]");
|
||||
return s.toString();
|
||||
}
|
||||
|
||||
|
||||
@ -126,6 +126,11 @@ private class SocketOutput extends haxe.io.Output {
|
||||
__s = new PSocket();
|
||||
}
|
||||
|
||||
function __rebuildIoStreams():Void {
|
||||
input = new SocketInput(__s);
|
||||
output = new SocketOutput(__s);
|
||||
}
|
||||
|
||||
public function close():Void {
|
||||
__s.close();
|
||||
}
|
||||
|
||||
@ -0,0 +1,34 @@
|
||||
package sys.thread;
|
||||
|
||||
@:coreApi
|
||||
class Condition {
|
||||
final cond:python.lib.threading.Condition;
|
||||
|
||||
public function new():Void {
|
||||
this.cond = new python.lib.threading.Condition();
|
||||
}
|
||||
|
||||
public function acquire():Void {
|
||||
cond.acquire();
|
||||
}
|
||||
|
||||
public function tryAcquire():Bool {
|
||||
return cond.acquire(false);
|
||||
}
|
||||
|
||||
public function release():Void {
|
||||
cond.release();
|
||||
}
|
||||
|
||||
public function wait():Void {
|
||||
cond.wait();
|
||||
}
|
||||
|
||||
public function signal():Void {
|
||||
cond.notify();
|
||||
}
|
||||
|
||||
public function broadcast():Void {
|
||||
cond.notify_all();
|
||||
}
|
||||
}
|
||||
@ -22,15 +22,17 @@
|
||||
|
||||
package sys.thread;
|
||||
|
||||
import python.lib.threading.Condition;
|
||||
|
||||
using python.internal.UBuiltins;
|
||||
|
||||
class Deque<T> {
|
||||
var deque:NativeDeque<T>;
|
||||
var lock:NativeCondition;
|
||||
var lock:Condition;
|
||||
|
||||
public function new() {
|
||||
deque = new NativeDeque<T>();
|
||||
lock = new NativeCondition();
|
||||
lock = new Condition();
|
||||
}
|
||||
|
||||
public function add(i:T) {
|
||||
@ -63,21 +65,9 @@ class Deque<T> {
|
||||
|
||||
@:pythonImport("collections", "deque")
|
||||
@:native("deque")
|
||||
extern class NativeDeque<T> {
|
||||
private extern class NativeDeque<T> {
|
||||
function new();
|
||||
function append(x:T):Void;
|
||||
function appendleft(x:T):Void;
|
||||
function popleft():T;
|
||||
}
|
||||
|
||||
@:pythonImport("threading", "Condition")
|
||||
@:native("Condition")
|
||||
private extern class NativeCondition {
|
||||
function new(?lock:Dynamic);
|
||||
function acquire(blocking:Bool = true, timeout:Float = -1):Bool;
|
||||
function release():Void;
|
||||
function wait(?timeout:Float):Bool;
|
||||
function wait_for(predicate:()->Bool, ?timeout:Float):Bool;
|
||||
function notify(n:Int = 1):Void;
|
||||
function notify_all():Void;
|
||||
}
|
||||
@ -22,12 +22,14 @@
|
||||
|
||||
package sys.thread;
|
||||
|
||||
import python.lib.threading.Semaphore;
|
||||
|
||||
@:coreApi
|
||||
class Lock {
|
||||
final semaphore:NativeSemaphore;
|
||||
final semaphore:Semaphore;
|
||||
|
||||
public inline function new() {
|
||||
semaphore = new NativeSemaphore(0);
|
||||
semaphore = new Semaphore(0);
|
||||
}
|
||||
|
||||
public inline function wait(?timeout:Float):Bool {
|
||||
@ -38,11 +40,3 @@ class Lock {
|
||||
semaphore.release();
|
||||
}
|
||||
}
|
||||
|
||||
@:pythonImport("threading", "Semaphore")
|
||||
@:native("Lock")
|
||||
private extern class NativeSemaphore {
|
||||
function new(value:Int);
|
||||
function acquire(blocking:Bool = true, ?timeout:Float):Bool;
|
||||
function release():Void;
|
||||
}
|
||||
@ -22,12 +22,14 @@
|
||||
|
||||
package sys.thread;
|
||||
|
||||
import python.lib.threading.RLock;
|
||||
|
||||
@:coreApi
|
||||
class Mutex {
|
||||
final lock:NativeRLock;
|
||||
final lock:RLock;
|
||||
|
||||
inline public function new():Void {
|
||||
lock = new NativeRLock();
|
||||
lock = new RLock();
|
||||
}
|
||||
|
||||
inline public function acquire():Void {
|
||||
@ -42,10 +44,3 @@ class Mutex {
|
||||
lock.release();
|
||||
}
|
||||
}
|
||||
|
||||
@:pythonImport("threading", "RLock")
|
||||
private extern class NativeRLock {
|
||||
function new():Void;
|
||||
function acquire(blocking:Bool):Bool;
|
||||
function release():Void;
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
package sys.thread;
|
||||
|
||||
import python.lib.threading.Semaphore as NativeSemaphore;
|
||||
|
||||
@:coreApi
|
||||
class Semaphore {
|
||||
final semaphore:NativeSemaphore;
|
||||
|
||||
public function new(value:Int):Void {
|
||||
this.semaphore = new NativeSemaphore(value);
|
||||
}
|
||||
|
||||
public function acquire():Void {
|
||||
semaphore.acquire();
|
||||
}
|
||||
|
||||
public function tryAcquire(?timeout:Float):Bool {
|
||||
return timeout == null ? semaphore.acquire(false) : semaphore.acquire(true, timeout);
|
||||
}
|
||||
|
||||
public function release():Void {
|
||||
semaphore.release();
|
||||
}
|
||||
}
|
||||
@ -22,6 +22,9 @@
|
||||
|
||||
package sys.thread;
|
||||
|
||||
import python.lib.threading.Thread as NativeThread;
|
||||
import python.lib.Threading;
|
||||
|
||||
import haxe.ds.ObjectMap;
|
||||
|
||||
private typedef ThreadImpl = HxThread;
|
||||
@ -33,8 +36,8 @@ abstract Thread(ThreadImpl) from ThreadImpl {
|
||||
return HxThread.current();
|
||||
}
|
||||
|
||||
public static inline function create(callb:Void->Void):Thread {
|
||||
return HxThread.create(callb, false);
|
||||
public static inline function create(job:Void->Void):Thread {
|
||||
return HxThread.create(job, false);
|
||||
}
|
||||
|
||||
public static inline function runWithEventLoop(job:()->Void):Void {
|
||||
@ -78,7 +81,7 @@ private class HxThread {
|
||||
static function __init__() {
|
||||
threads = new ObjectMap();
|
||||
threadsMutex = new Mutex();
|
||||
mainThread = new HxThread(PyThreadingAPI.current_thread());
|
||||
mainThread = new HxThread(Threading.current_thread());
|
||||
mainThread.events = new EventLoop();
|
||||
}
|
||||
|
||||
@ -92,8 +95,8 @@ private class HxThread {
|
||||
|
||||
public static function current():HxThread {
|
||||
threadsMutex.acquire();
|
||||
var ct = PyThreadingAPI.current_thread();
|
||||
if (ct == PyThreadingAPI.main_thread()) {
|
||||
var ct = Threading.current_thread();
|
||||
if (ct == Threading.main_thread()) {
|
||||
threadsMutex.release();
|
||||
return mainThread;
|
||||
}
|
||||
@ -121,7 +124,7 @@ private class HxThread {
|
||||
}
|
||||
dropThread(nt);
|
||||
}
|
||||
nt = new NativeThread(null, wrappedCallB);
|
||||
nt = new NativeThread({target:wrappedCallB});
|
||||
t = new HxThread(nt);
|
||||
if(withEventLoop)
|
||||
t.events = new EventLoop();
|
||||
@ -159,17 +162,3 @@ private class HxThread {
|
||||
return current().messages.pop(block);
|
||||
}
|
||||
}
|
||||
|
||||
@:pythonImport("threading", "Thread")
|
||||
@:native("Thread")
|
||||
private extern class NativeThread {
|
||||
function new(group:Dynamic, target:Void->Void);
|
||||
function start():Void;
|
||||
}
|
||||
|
||||
@:pythonImport("threading")
|
||||
@:native("threading")
|
||||
private extern class PyThreadingAPI {
|
||||
static function current_thread():NativeThread;
|
||||
static function main_thread():NativeThread;
|
||||
}
|
||||
@ -57,6 +57,12 @@ extern class Os {
|
||||
|
||||
static function putenv(name:String, value:String):Void;
|
||||
|
||||
/** Removes the value for the environment variable `name`.
|
||||
|
||||
When targeting python versions prior to 3.9, this function may not exist on some platforms.
|
||||
**/
|
||||
static function unsetenv(name:String):Void;
|
||||
|
||||
static function chdir(path:String):Void;
|
||||
|
||||
static function unlink(path:String):Void;
|
||||
|
||||
@ -30,6 +30,14 @@ extern class StartupInfo {
|
||||
var wShowWindow:Int;
|
||||
}
|
||||
|
||||
extern class CompletedProcess {
|
||||
var args:EitherType<String, Array<String>>;
|
||||
var returncode:Int;
|
||||
var stdout:Null<EitherType<Bytes,String>>;
|
||||
var stderr:Null<EitherType<Bytes,String>>;
|
||||
function check_returncode():Void;
|
||||
}
|
||||
|
||||
@:pythonImport("subprocess")
|
||||
extern class Subprocess {
|
||||
static function STARTUPINFO():StartupInfo;
|
||||
@ -49,4 +57,5 @@ extern class Subprocess {
|
||||
static var STDOUT:Int;
|
||||
|
||||
static function call(args:EitherType<String, Array<String>>, ?kwArgs:python.KwArgs<Dynamic>):Int;
|
||||
static function run(args:EitherType<String, Array<String>>, ?kwArgs:python.KwArgs<Dynamic>):CompletedProcess;
|
||||
}
|
||||
|
||||
@ -80,6 +80,11 @@ extern class Socket {
|
||||
**/
|
||||
function getsockname():python.lib.socket.Address;
|
||||
|
||||
/**
|
||||
Return the timeout for the socket or null if no timeout has been set.
|
||||
**/
|
||||
function gettimeout():Null<Float>;
|
||||
|
||||
/**
|
||||
Gives a timeout after which blocking socket operations (such as reading and writing) will abort and throw an exception.
|
||||
**/
|
||||
@ -90,14 +95,26 @@ extern class Socket {
|
||||
**/
|
||||
function waitForRead():Void;
|
||||
|
||||
/**
|
||||
Return the current blocking mode of the socket.
|
||||
**/
|
||||
@:require(python_version >= 3.7)
|
||||
function getblocking():Bool;
|
||||
|
||||
/**
|
||||
Change the blocking mode of the socket. A blocking socket is the default behavior. A non-blocking socket will abort blocking operations immediately by throwing a haxe.io.Error.Blocked value.
|
||||
**/
|
||||
function setblocking(b:Bool):Void;
|
||||
|
||||
/**
|
||||
|
||||
Return the current value of the sockopt as an Int or a Bytes buffer (if buflen is specified).
|
||||
**/
|
||||
function getsockopt(family:Int, option:Int):Int;
|
||||
|
||||
/**
|
||||
Change the value of the given socket option.
|
||||
**/
|
||||
@:overload(function(family:Int, option:Int, value:Int):Void {})
|
||||
function setsockopt(family:Int, option:Int, value:Bool):Void;
|
||||
|
||||
function fileno():Int;
|
||||
|
||||
12
Kha/Tools/windows_x64/std/python/lib/threading/Condition.hx
Normal file
12
Kha/Tools/windows_x64/std/python/lib/threading/Condition.hx
Normal file
@ -0,0 +1,12 @@
|
||||
package python.lib.threading;
|
||||
|
||||
@:pythonImport("threading", "Condition")
|
||||
extern class Condition {
|
||||
function new(?lock:haxe.extern.EitherType<Lock, RLock>):Void;
|
||||
function acquire(?blocking:Bool, ?timeout:Float):Bool;
|
||||
function release():Void;
|
||||
function wait(?timeout:Float):Bool;
|
||||
function wait_for(predicate:()->Bool, ?timeout:Float):Bool;
|
||||
function notify(n:Int = 1):Void;
|
||||
function notify_all():Void;
|
||||
}
|
||||
@ -0,0 +1,9 @@
|
||||
package python.lib.threading;
|
||||
|
||||
@:noDoc
|
||||
@:pythonImport("threading", "Semaphore")
|
||||
extern class Semaphore {
|
||||
function new(value:Int);
|
||||
function acquire(blocking:Bool = true, ?timeout:Float):Bool;
|
||||
function release(n:Int = 1):Void;
|
||||
}
|
||||
@ -25,12 +25,15 @@ package python.net;
|
||||
import python.lib.Ssl;
|
||||
import python.lib.ssl.Purpose;
|
||||
import python.lib.socket.Socket as PSocket;
|
||||
import python.lib.Socket in PSocketModule;
|
||||
import sys.net.Host;
|
||||
|
||||
class SslSocket extends sys.net.Socket {
|
||||
var hostName:String;
|
||||
var _timeout:Null<Float> = null;
|
||||
var _blocking:Null<Bool> = null;
|
||||
var _fastSend:Null<Bool> = null;
|
||||
|
||||
override function __initSocket():Void {
|
||||
function wrapSocketWithSslContext(hostName:String):Void {
|
||||
#if (python_version >= 3.4)
|
||||
var context = Ssl.create_default_context(Purpose.SERVER_AUTH);
|
||||
#else
|
||||
@ -43,16 +46,42 @@ class SslSocket extends sys.net.Socket {
|
||||
context.options |= Ssl.OP_NO_COMPRESSION;
|
||||
#end
|
||||
context.options |= Ssl.OP_NO_TLSv1 #if (python_version >= 3.4) | Ssl.OP_NO_TLSv1_1 #end; // python 3.4 | Ssl.OP_NO_TLSv1_1;
|
||||
__s = new PSocket();
|
||||
__s = context.wrap_socket(__s, false, true, true, this.hostName);
|
||||
__s = context.wrap_socket(__s, false, true, true, hostName);
|
||||
if (_timeout != null) {
|
||||
super.setTimeout(_timeout);
|
||||
}
|
||||
|
||||
if (_blocking != null) {
|
||||
super.setBlocking(_blocking);
|
||||
}
|
||||
|
||||
if (_fastSend != null) {
|
||||
super.setFastSend(_fastSend);
|
||||
}
|
||||
__rebuildIoStreams();
|
||||
}
|
||||
|
||||
public override function connect(host:Host, port:Int):Void {
|
||||
this.hostName = host.host;
|
||||
wrapSocketWithSslContext(host.host);
|
||||
super.connect(host, port);
|
||||
}
|
||||
|
||||
public override function bind(host:Host, port:Int):Void {
|
||||
throw new haxe.exceptions.NotImplementedException();
|
||||
}
|
||||
|
||||
public override function setTimeout(timeout:Float):Void {
|
||||
_timeout = timeout;
|
||||
super.setTimeout(_timeout);
|
||||
}
|
||||
|
||||
public override function setBlocking(b:Bool):Void {
|
||||
_blocking = b;
|
||||
super.setBlocking(_blocking);
|
||||
}
|
||||
|
||||
public override function setFastSend(b:Bool):Void {
|
||||
_fastSend = b;
|
||||
super.setFastSend(_fastSend);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user