Skip to content

Commit a8a3ce9

Browse files
committed
Refactor: JS Module and JS Api implementation are now separated
1 parent 4360817 commit a8a3ce9

File tree

2 files changed

+315
-307
lines changed

2 files changed

+315
-307
lines changed

lib/modules/jsapi.dart

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
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

Comments
 (0)