From 40ff60f0f4fc22bb431774de6180ed3f0cd5355a Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Wed, 28 Dec 2022 20:31:24 +0800 Subject: [PATCH] up up --- plugins/flutter/example/pubspec.lock | 2 +- plugins/flutter/lib/no_web.dart | 4 +- plugins/flutter/lib/web.dart | 139 ++++++++++++++++++++++++++- plugins/flutter/pubspec.yaml | 5 +- 4 files changed, 142 insertions(+), 8 deletions(-) diff --git a/plugins/flutter/example/pubspec.lock b/plugins/flutter/example/pubspec.lock index ad2de5cc..5c0cda11 100644 --- a/plugins/flutter/example/pubspec.lock +++ b/plugins/flutter/example/pubspec.lock @@ -108,7 +108,7 @@ packages: path: ".." relative: true source: path - version: "0.5.1+3" + version: "0.5.2+1" sky_engine: dependency: transitive description: flutter diff --git a/plugins/flutter/lib/no_web.dart b/plugins/flutter/lib/no_web.dart index f8c06f6a..25d69b78 100644 --- a/plugins/flutter/lib/no_web.dart +++ b/plugins/flutter/lib/no_web.dart @@ -42,9 +42,8 @@ class _Bindings static final pkpy_vm_read_output = _lib.lookupFunction Function(ffi.Pointer vm), ffi.Pointer Function(ffi.Pointer vm)>("pkpy_vm_read_output"); } - class _Str { - static final Finalizer> finalizer = Finalizer((p) => calloc.free(p)); + static final Finalizer> finalizer = Finalizer((p) => malloc.free(p)); late final ffi.Pointer _p; _Str(String s) { @@ -54,7 +53,6 @@ class _Str { ffi.Pointer get p => _p; } - class VM { late final ffi.Pointer pointer; diff --git a/plugins/flutter/lib/web.dart b/plugins/flutter/lib/web.dart index b881cb83..9b22facb 100644 --- a/plugins/flutter/lib/web.dart +++ b/plugins/flutter/lib/web.dart @@ -1,5 +1,140 @@ +// ignore_for_file: prefer_function_declarations_over_variables, non_constant_identifier_names, no_leading_underscores_for_local_identifiers +import 'dart:convert' as cvt; import 'package:js/js.dart'; +import 'common.dart'; @JS("Module.ccall") -external int ccall(String name, String returnType, List argTypes, - List args); +external dynamic ccall(String name, String? returnType, List argTypes, List args); + +class _Bindings +{ + static final pkpy_delete = (dynamic p) => ccall("pkpy_delete", null, ["number"], [p]); + static final pkpy_new_repl = (dynamic vm) => ccall("pkpy_new_repl", "number", ["number"], [vm]); + static final pkpy_repl_input = (dynamic r, String line) => ccall("pkpy_repl_input", "number", ["number", "string"], [r, line]); + static final pkpy_new_tvm = (bool use_stdio) => ccall("pkpy_new_tvm", "number", ["boolean"], [use_stdio]); + static final pkpy_tvm_exec_async = (dynamic vm, String source) => ccall("pkpy_tvm_exec_async", "boolean", ["number", "string"], [vm, source]); + static final pkpy_tvm_get_state = (dynamic vm) => ccall("pkpy_tvm_get_state", "number", ["number"], [vm]); + static final pkpy_tvm_read_jsonrpc_request = (dynamic vm) => ccall("pkpy_tvm_read_jsonrpc_request", "string", ["number"], [vm]); + static final pkpy_tvm_reset_state = (dynamic vm) => ccall("pkpy_tvm_reset_state", null, ["number"], [vm]); + static final pkpy_tvm_terminate = (dynamic vm) => ccall("pkpy_tvm_terminate", null, ["number"], [vm]); + static final pkpy_tvm_write_jsonrpc_response = (dynamic vm, String value) => ccall("pkpy_tvm_write_jsonrpc_response", null, ["number", "string"], [vm, value]); + static final pkpy_new_vm = (bool use_stdio) => ccall("pkpy_new_vm", "number", ["boolean"], [use_stdio]); + static final pkpy_vm_add_module = (dynamic vm, String name, String source) => ccall("pkpy_vm_add_module", "boolean", ["number", "string", "string"], [vm, name, source]); + static final pkpy_vm_eval = (dynamic vm, String source) => ccall("pkpy_vm_eval", "string", ["number", "string"], [vm, source]); + static final pkpy_vm_exec = (dynamic vm, String source) => ccall("pkpy_vm_exec", "boolean", ["number", "string"], [vm, source]); + static final pkpy_vm_get_global = (dynamic vm, String name) => ccall("pkpy_vm_get_global", "string", ["number", "string"], [vm, name]); + static final pkpy_vm_read_output = (dynamic vm) => ccall("pkpy_vm_read_output", "string", ["number"], [vm]); +} + +class VM { + late final dynamic pointer; + + VM() { + if (this is ThreadedVM) { + pointer = _Bindings.pkpy_new_tvm(false); + } else { + pointer = _Bindings.pkpy_new_vm(false); + } + } + + void dispose() { + _Bindings.pkpy_delete(pointer); + } + + PyOutput read_output() { + var _o = _Bindings.pkpy_vm_read_output(pointer); + String _j = _o.toDartString(); + var ret = PyOutput.fromJson(cvt.jsonDecode(_j)); + _Bindings.pkpy_delete(_o); + return ret; + } + + /// Add a source module into a virtual machine. Return `true` if there is no complie error. + bool add_module(String name, String source) + { + var ret = _Bindings.pkpy_vm_add_module(pointer, name, source); + return ret; + } + + /// Evaluate an expression. Return a json representing the result. If there is any error, return `nullptr`. + String? eval(String source) + { + var ret = _Bindings.pkpy_vm_eval(pointer, source); + return ret; + } + + /// Run a given source on a virtual machine. Return `true` if there is no compile error. + bool exec(String source) + { + var ret = _Bindings.pkpy_vm_exec(pointer, source); + return ret; + } + + /// Get a global variable of a virtual machine. Return a json representing the result. If the variable is not found, return `nullptr`. + String? get_global(String name) + { + var ret = _Bindings.pkpy_vm_get_global(pointer, name); + return ret; + } + +} + +enum ThreadState { ready, running, suspended, finished } + +class ThreadedVM extends VM { + ThreadState get state => ThreadState.values[_Bindings.pkpy_tvm_get_state(pointer)]; + + /// Run a given source on a threaded virtual machine. The excution will be started in a new thread. Return `true` if there is no compile error. + bool exec_async(String source) + { + var ret = _Bindings.pkpy_tvm_exec_async(pointer, source); + return ret; + } + + /// Read the current JSONRPC request from shared string buffer. + String? read_jsonrpc_request() + { + var ret = _Bindings.pkpy_tvm_read_jsonrpc_request(pointer); + return ret; + } + + /// Set the state of a threaded virtual machine to `THREAD_READY`. The current state should be `THREAD_FINISHED`. + void reset_state() + { + _Bindings.pkpy_tvm_reset_state(pointer); + } + + /// Emit a KeyboardInterrupt signal to stop a running threaded virtual machine. + void terminate() + { + _Bindings.pkpy_tvm_terminate(pointer); + } + + /// Write a JSONRPC response to shared string buffer. + void write_jsonrpc_response(String value) + { + _Bindings.pkpy_tvm_write_jsonrpc_response(pointer, value); + } + +} + +class REPL { + late final dynamic pointer; + + REPL(VM vm) { + pointer = _Bindings.pkpy_new_repl(vm.pointer); + } + + void dispose() { + _Bindings.pkpy_delete(pointer); + } + + /// Input a source line to an interactive console. Return `0` if need more lines, `1` if execution happened, `2` if execution skipped (compile error or empty input). + int input(String line) + { + var ret = _Bindings.pkpy_repl_input(pointer, line); + return ret; + } + +} + diff --git a/plugins/flutter/pubspec.yaml b/plugins/flutter/pubspec.yaml index 58e9ed3b..1f87f696 100644 --- a/plugins/flutter/pubspec.yaml +++ b/plugins/flutter/pubspec.yaml @@ -1,6 +1,6 @@ name: pocketpy description: A lightweight Python interpreter for game engines. -version: 0.5.1+3 +version: 0.5.2+1 homepage: https://pocketpy.dev repository: https://github.com/blueloveth/pocketpy @@ -27,4 +27,5 @@ flutter: ios: ffiPlugin: true windows: - ffiPlugin: true \ No newline at end of file + ffiPlugin: true + web: true \ No newline at end of file