@@ -285,33 +285,56 @@ namespace jni
285
285
RegisterNatives (env, clazz, methods.template operator ()<Peer>(field)...);
286
286
}
287
287
288
- template < class Peer , class TagType , class Constructor , class ... Methods >
288
+ template < class Peer , class TagType , class >
289
+ struct NativePeerHelper ;
290
+
291
+ template < class Peer , class TagType , class ... Args >
292
+ struct NativePeerHelper < Peer, TagType, std::unique_ptr<Peer> (JNIEnv&, Args...) >
293
+ {
294
+ using UniquePeer = std::unique_ptr<Peer>;
295
+ using Initializer = UniquePeer (JNIEnv&, Args...);
296
+
297
+ auto MakeInitializer (const Field<TagType, jlong>& field, const char * name, Initializer* initializer) const
298
+ {
299
+ auto wrapper = [field, initializer] (JNIEnv& e, Object<TagType> obj, std::decay_t <Args>... args)
300
+ {
301
+ UniquePeer previous (reinterpret_cast <Peer*>(obj.Get (e, field)));
302
+ UniquePeer instance (initializer (e, std::move (args)...));
303
+ obj.Set (e, field, reinterpret_cast <jlong>(instance.get ()));
304
+ instance.release ();
305
+ };
306
+
307
+ return MakeNativeMethod (name, wrapper);
308
+ }
309
+
310
+ auto MakeFinalizer (const Field<TagType, jlong>& field, const char * name) const
311
+ {
312
+ auto wrapper = [field] (JNIEnv& e, Object<TagType> obj)
313
+ {
314
+ UniquePeer instance (reinterpret_cast <Peer*>(obj.Get (e, field)));
315
+ if (instance) obj.Set (e, field, jlong (0 ));
316
+ instance.reset ();
317
+ };
318
+
319
+ return MakeNativeMethod (name, wrapper);
320
+ }
321
+ };
322
+
323
+ template < class Peer , class TagType , class Initializer , class ... Methods >
289
324
void RegisterNativePeer (JNIEnv& env, const Class<TagType>& clazz, const char * fieldName,
290
- Constructor constructor ,
325
+ Initializer initialize ,
291
326
const char * initializeMethodName,
292
327
const char * finalizeMethodName,
293
328
Methods&&... methods)
294
329
{
295
330
static Field<TagType, jlong> field { env, clazz, fieldName };
296
331
297
- auto finalize = [] (JNIEnv& e, Object<TagType> obj)
298
- {
299
- std::unique_ptr<Peer> instance (reinterpret_cast <Peer*>(obj.Get (e, field)));
300
- if (instance) obj.Set (e, field, jlong (0 ));
301
- instance.reset ();
302
- };
303
-
304
- auto initialize = [constructor] (JNIEnv& e, Object<TagType> obj)
305
- {
306
- std::unique_ptr<Peer> previous (reinterpret_cast <Peer*>(obj.Get (e, field)));
307
- std::unique_ptr<Peer> instance (constructor ());
308
- obj.Set (e, field, reinterpret_cast <jlong>(instance.get ()));
309
- instance.release ();
310
- };
332
+ using InitializerMethodType = typename NativeMethodTraits<Initializer>::Type;
333
+ NativePeerHelper<Peer, TagType, InitializerMethodType> helper;
311
334
312
335
RegisterNatives (env, clazz,
313
- MakeNativeMethod ( initializeMethodName, initialize),
314
- MakeNativeMethod (finalizeMethodName, finalize ),
336
+ helper. MakeInitializer (field, initializeMethodName, initialize),
337
+ helper. MakeFinalizer (field, finalizeMethodName ),
315
338
methods.template operator ()<Peer>(field)...);
316
339
}
317
340
}
0 commit comments