Skip to content

Commit dcf2fb2

Browse files
authored
feat: interop.addMethod and addProtocol APIs (#24)
* addMethod and addProtocol API * fix
1 parent caf1c60 commit dcf2fb2

File tree

4 files changed

+86
-5
lines changed

4 files changed

+86
-5
lines changed

include/ClassBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ class ClassBuilder : public ObjCClass {
2020

2121
void addProtocol(ObjCProtocol *protocol);
2222
MethodDescriptor *lookupMethodDescriptor(std::string &name);
23-
void addMethod(std::string &name, MethodDescriptor *desc, napi_value key);
23+
void addMethod(std::string &name, MethodDescriptor *desc, napi_value key,
24+
napi_value func = nullptr);
2425

2526
void build();
2627

include/Interop.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ namespace objc_bridge {
99

1010
void registerInterop(napi_env env, napi_value global);
1111

12+
napi_value interop_addMethod(napi_env env, napi_callback_info info);
13+
napi_value interop_addProtocol(napi_env env, napi_callback_info info);
1214
napi_value interop_adopt(napi_env env, napi_callback_info info);
1315
napi_value interop_free(napi_env env, napi_callback_info info);
1416
napi_value interop_sizeof(napi_env env, napi_callback_info info);

src/ClassBuilder.mm

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -118,13 +118,16 @@
118118
}
119119

120120
void ClassBuilder::addMethod(std::string &name, MethodDescriptor *desc,
121-
napi_value key) {
121+
napi_value key, napi_value func) {
122122
switch (desc->kind) {
123123
case kMethodDescEncoding: {
124124
const char *encoding = desc->encoding.c_str();
125125
auto closure = new Closure(encoding, false);
126126
closure->env = env;
127-
closure->propertyName = name;
127+
if (func != nullptr)
128+
closure->func = make_ref(env, func);
129+
else
130+
closure->propertyName = name;
128131
closure->thisConstructor = constructor;
129132
class_replaceMethod(nativeClass, desc->selector, (IMP)closure->fnptr,
130133
encoding);
@@ -136,7 +139,10 @@
136139
auto closure = new Closure(bridgeState->metadata, desc->signatureOffset,
137140
false, &encoding, true);
138141
closure->env = env;
139-
closure->propertyName = name;
142+
if (func != nullptr)
143+
closure->func = make_ref(env, func);
144+
else
145+
closure->propertyName = name;
140146
closure->thisConstructor = constructor;
141147
class_replaceMethod(nativeClass, desc->selector, (IMP)closure->fnptr,
142148
encoding.c_str());

src/Interop.mm

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,24 @@ void registerInterop(napi_env env, napi_value global) {
172172
.data = nullptr,
173173
.method = interop_adopt,
174174
},
175+
{
176+
.utf8name = "addMethod",
177+
.attributes = napi_enumerable,
178+
.getter = nullptr,
179+
.setter = nullptr,
180+
.value = nullptr,
181+
.data = nullptr,
182+
.method = interop_addMethod,
183+
},
184+
{
185+
.utf8name = "addProtocol",
186+
.attributes = napi_enumerable,
187+
.getter = nullptr,
188+
.setter = nullptr,
189+
.value = nullptr,
190+
.data = nullptr,
191+
.method = interop_addProtocol,
192+
},
175193
{
176194
.utf8name = "free",
177195
.attributes = napi_enumerable,
@@ -219,11 +237,65 @@ void registerInterop(napi_env env, napi_value global) {
219237
},
220238
};
221239

222-
napi_define_properties(env, interop, 9, properties);
240+
napi_define_properties(env, interop, 11, properties);
223241

224242
napi_set_named_property(env, global, "interop", interop);
225243
}
226244

245+
napi_value interop_addMethod(napi_env env, napi_callback_info info) {
246+
napi_value argv[2];
247+
size_t argc = 2;
248+
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
249+
250+
ClassBuilder *builder = nullptr;
251+
napi_unwrap(env, argv[0], (void **)&builder);
252+
if (builder == nullptr) {
253+
napi_throw_error(env, nullptr, "Invalid class");
254+
return nullptr;
255+
}
256+
257+
napi_value name;
258+
napi_get_named_property(env, argv[1], "name", &name);
259+
260+
static char funcNameBuf[512];
261+
napi_get_value_string_utf8(env, name, funcNameBuf, 512, nullptr);
262+
std::string funcName = funcNameBuf;
263+
264+
MethodDescriptor *desc = builder->lookupMethodDescriptor(funcName);
265+
if (desc == nullptr) {
266+
napi_throw_error(env, nullptr, "Invalid method, descriptor not found");
267+
return nullptr;
268+
}
269+
270+
builder->addMethod(funcName, desc, name, argv[1]);
271+
272+
return nullptr;
273+
}
274+
275+
napi_value interop_addProtocol(napi_env env, napi_callback_info info) {
276+
napi_value argv[2];
277+
size_t argc = 2;
278+
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
279+
280+
ClassBuilder *builder = nullptr;
281+
napi_unwrap(env, argv[0], (void **)&builder);
282+
if (builder == nullptr) {
283+
napi_throw_error(env, nullptr, "Invalid class");
284+
return nullptr;
285+
}
286+
287+
ObjCProtocol *proto = nullptr;
288+
napi_unwrap(env, argv[1], (void **)&proto);
289+
if (proto == nullptr) {
290+
napi_throw_error(env, nullptr, "Invalid protocol");
291+
return nullptr;
292+
}
293+
294+
builder->addProtocol(proto);
295+
296+
return nullptr;
297+
}
298+
227299
napi_value interop_adopt(napi_env env, napi_callback_info info) {
228300
napi_value arg;
229301
size_t argc = 1;

0 commit comments

Comments
 (0)