1+ import 'dart:convert' ;
2+ import 'dart:ffi' ;
3+ import 'dart:typed_data' ;
4+ import 'package:corecoder_develop/modules/module_jsplugins.dart' ;
5+ import 'package:corecoder_develop/util/modules_manager.dart' ;
6+ import 'package:flutter/material.dart' ;
7+ import 'package:ffi/ffi.dart' ;
8+ import 'package:flutter_jscore/flutter_jscore.dart' ;
9+ import 'package:flutter_jscore/jscore_bindings.dart' as js;
10+
11+
12+ String jsStringToDartString (Pointer resultJsString) {
13+ var resultCString = js.jSStringGetCharactersPtr (resultJsString);
14+ int resultCStringLength = js.jSStringGetLength (resultJsString);
15+ if (resultCString == nullptr) {
16+ return 'null' ;
17+ }
18+ String result = String .fromCharCodes (Uint16List .view (
19+ resultCString.cast <Uint16 >().asTypedList (resultCStringLength).buffer,
20+ 0 ,
21+ resultCStringLength));
22+ return result;
23+ }
24+
25+ String _getJsValue (Pointer _ctxPtr, Pointer jsValueRef) {
26+ if (js.jSValueIsNull (_ctxPtr, jsValueRef) == 1 ) {
27+ return 'null' ;
28+ } else if (js.jSValueIsUndefined (_ctxPtr, jsValueRef) == 1 ) {
29+ return 'undefined' ;
30+ } else if (js.jSValueIsObject (_ctxPtr, jsValueRef) == 1 ) {
31+ // Is object, convert to map
32+ return 'Object object' ;
33+ }
34+
35+ /// Last resort, cast anything to string, like "[Object object] "
36+ var resultJsString = js.jSValueToStringCopy (_ctxPtr, jsValueRef, nullptr);
37+ var resultCString = js.jSStringGetCharactersPtr (resultJsString);
38+ int resultCStringLength = js.jSStringGetLength (resultJsString);
39+ if (resultCString == nullptr) {
40+ return 'null' ;
41+ }
42+ String result = String .fromCharCodes (Uint16List .view (
43+ resultCString.cast <Uint16 >().asTypedList (resultCStringLength).buffer,
44+ 0 ,
45+ resultCStringLength));
46+ js.jSStringRelease (resultJsString);
47+ return result;
48+ }
49+
50+ /// Convert a javascript object to dart map
51+ /// [jsValueRef] The pointer to JS obj
52+ Map <String , String > jsObjectToDartMap (Pointer _ctxPtr, Pointer jsValueRef) {
53+ if (js.jSValueIsObject (_ctxPtr, jsValueRef) == 1 ) {
54+ // if is object
55+ Pointer obj = js.jSValueToObject (_ctxPtr, jsValueRef, nullptr);
56+
57+ //(JSPropertyNameArrayRef)
58+ Pointer props = js.jSObjectCopyPropertyNames (_ctxPtr, obj);
59+ int propCount = js.jSPropertyNameArrayGetCount (props);
60+ Map <String , String > result = {};
61+ // debugPrint("JS PROPC $propCount");
62+ for (var i = 0 ; i < propCount; i++ ) {
63+ Pointer /*(JSStringRef)*/ propName =
64+ js.jSPropertyNameArrayGetNameAtIndex (props, i);
65+ Pointer /*JSValueRef*/ propValue =
66+ js.jSObjectGetProperty (_ctxPtr, obj, propName, nullptr);
67+ String name = jsStringToDartString (propName);
68+ js.jSStringRelease (propName);
69+ dynamic value;
70+ int propType = js.jSValueGetType (_ctxPtr, propValue);
71+ switch (propType) {
72+ case 4 : //kJSTypeString:
73+ value = _getJsValue (_ctxPtr, propValue);
74+ break ;
75+ case 3 : //kJSTypeNumber:
76+ //TODO:not implemented
77+ break ;
78+ }
79+ // debugPrint("JS NAME $name");
80+ // debugPrint("JS VALUE($propType) $value");
81+ result[name] = value;
82+ }
83+ return result;
84+ }
85+ int type = js.jSValueGetType (_ctxPtr, jsValueRef);
86+ debugPrint ("jsObjectToDartMap error: value is not obj, type:$type " );
87+ return {};
88+ }
89+
90+
91+ class CoreCoder {
92+ static late JsModule module; // set by the parent object
93+ static late JSContext context; // set by the parent object
94+ static CoreCoder ? _instance;
95+ static CoreCoder get instance{
96+ _instance ?? = CoreCoder ();
97+ _printDartFunc = _instance! ._print;
98+ return _instance! ;
99+ }
100+
101+ void addTemplate (Pointer ctx,
102+ Pointer function,
103+ Pointer thisObject,
104+ int argumentCount,
105+ Pointer <Pointer > arguments,
106+ Pointer <Pointer > exception){
107+ if (argumentCount > 0 ) {
108+ Pointer jsValueRef = arguments[0 ];
109+ if (js.jSValueIsObject (ctx, jsValueRef) == 1 ) {
110+ /// the provided argument 0 is an object, then parse it
111+ String name, description, version, identifier;
112+ Pointer obj = js.jSValueToObject (ctx, jsValueRef, nullptr);
113+ name = _getJsValue (ctx,js.jSObjectGetProperty (ctx, obj,
114+ js.jSStringCreateWithUTF8CString ('name' .toNativeUtf8 ()), nullptr));
115+
116+ description = _getJsValue (ctx,js.jSObjectGetProperty (
117+ ctx,
118+ obj,
119+ js.jSStringCreateWithUTF8CString ('description' .toNativeUtf8 ()),
120+ nullptr));
121+
122+ version = _getJsValue (ctx,js.jSObjectGetProperty (ctx, obj,
123+ js.jSStringCreateWithUTF8CString ('version' .toNativeUtf8 ()), nullptr));
124+
125+ identifier = _getJsValue (ctx,js.jSObjectGetProperty (
126+ ctx,
127+ obj,
128+ js.jSStringCreateWithUTF8CString ('identifier' .toNativeUtf8 ()),
129+ nullptr));
130+
131+ var _options = js.jSObjectGetProperty (ctx, obj,
132+ js.jSStringCreateWithUTF8CString ('options' .toNativeUtf8 ()), nullptr);
133+ var options = jsObjectToDartMap (ctx,_options);
134+
135+ var onCreate = (Map <String , dynamic > args) async {};
136+ var _onCreate = js.jSObjectGetProperty (ctx, obj,
137+ js.jSStringCreateWithUTF8CString ('onCreate' .toNativeUtf8 ()), nullptr);
138+ if (js.jSValueIsObject (ctx, _onCreate) == 1 ) {
139+ onCreate = (Map <String , dynamic > args) async {
140+ var optionsObj = JSObject .make (
141+ context,
142+ JSClass .create (
143+ JSClassDefinition (className: "OptionsObj" )));
144+ for (var key in args.keys) {
145+ var value = args[key];
146+ if (value is String ) {
147+ optionsObj.setProperty (
148+ key,
149+ JSValue .makeString (context, value),
150+ JSPropertyAttributes .kJSPropertyAttributeReadOnly);
151+ } else if (value is int || value is double ) {
152+ optionsObj.setProperty (
153+ key,
154+ JSValue .makeNumber (context, value as double ),
155+ JSPropertyAttributes .kJSPropertyAttributeReadOnly);
156+ }
157+ }
158+ js.jSObjectCallAsFunction (
159+ ctx,
160+ _onCreate,
161+ obj,
162+ 1 ,
163+ JSValuePointer .array ([optionsObj.toValue ()]).pointer,
164+ nullptr);
165+ };
166+ }
167+
168+ module.templates.add (Template (
169+ name,
170+ description,
171+ version,
172+ options,
173+ onCreate,
174+ module.icon,
175+ identifier,
176+ ));
177+ }
178+ }
179+ }
180+
181+ static Pointer jsAddTemplate (Pointer ctx,
182+ Pointer function,
183+ Pointer thisObject,
184+ int argumentCount,
185+ Pointer <Pointer > arguments,
186+ Pointer <Pointer > exception){
187+ instance.addTemplate (ctx,function, thisObject, argumentCount, arguments, exception);
188+ return nullptr;
189+ }
190+
191+ /*static JSObjectCallAsFunctionCallbackDart? get jsAddTemplate{
192+ return _jsAddTemplate;
193+ }*/
194+
195+
196+ /// # ======== THE PRINT FUNCTION ========== # ///
197+ static Pointer flutterPrint (
198+ Pointer ctx,
199+ Pointer function,
200+ Pointer thisObject,
201+ int argumentCount,
202+ Pointer <Pointer > arguments,
203+ Pointer <Pointer > exception) {
204+ if (_printDartFunc != null ) {
205+ _printDartFunc !(
206+ ctx, function, thisObject, argumentCount, arguments, exception);
207+ }
208+ return nullptr;
209+ }
210+
211+ static JSObjectCallAsFunctionCallbackDart ?
212+ _printDartFunc; // points to non static function
213+
214+ Pointer _print (
215+ Pointer ctx,
216+ Pointer function,
217+ Pointer thisObject,
218+ int argumentCount,
219+ Pointer <Pointer > arguments,
220+ Pointer <Pointer > exception) {
221+ if (argumentCount > 0 ) {
222+ debugPrint (_getJsValue (ctx,arguments[0 ]));
223+ }
224+ return nullptr;
225+ }
226+
227+ /// # ======== THE PRINT FUNCTION - END ========== # ///
228+
229+ }
230+
231+ class FileIO {
232+ static late JsModule module; // set by the parent object
233+ static late JSContext context; // set by the parent object
234+ }
0 commit comments