… | |
… | |
108 | |
108 | |
109 | sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); |
109 | sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); |
110 | return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); |
110 | return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); |
111 | } |
111 | } |
112 | |
112 | |
113 | template<class extendable> |
113 | template<class attachable> |
114 | SV * |
114 | SV * |
115 | newSVextendable (extendable *obj, const char *klass) |
115 | newSVattachable (attachable *obj, const char *klass) |
116 | { |
116 | { |
117 | if (!obj) |
117 | if (!obj) |
118 | return &PL_sv_undef; |
118 | return &PL_sv_undef; |
119 | |
119 | |
120 | if (!obj->self) |
120 | if (!obj->self) |
… | |
… | |
227 | break; |
227 | break; |
228 | |
228 | |
229 | case DT_OBJECT: |
229 | case DT_OBJECT: |
230 | { |
230 | { |
231 | object *obj = va_arg (ap, object *); |
231 | object *obj = va_arg (ap, object *); |
232 | sv = newSVextendable (obj, obj && obj->type == PLAYER ? "cf::object::player::wrap" : "cf::object::wrap"); |
232 | sv = newSVattachable (obj, obj && obj->type == PLAYER ? "cf::object::player::wrap" : "cf::object::wrap"); |
233 | } |
233 | } |
234 | break; |
234 | break; |
235 | |
235 | |
236 | case DT_MAP: |
236 | case DT_MAP: |
237 | // va_arg (object *) when void * is passed is an XSI extension |
237 | // va_arg (object *) when void * is passed is an XSI extension |
238 | sv = newSVextendable (va_arg (ap, mapstruct *), "cf::map::wrap"); |
238 | sv = newSVattachable (va_arg (ap, mapstruct *), "cf::map::wrap"); |
239 | break; |
239 | break; |
240 | |
240 | |
241 | case DT_PLAYER: |
241 | case DT_PLAYER: |
242 | sv = newSVextendable (va_arg (ap, player *), "cf::player::wrap"); |
242 | sv = newSVattachable (va_arg (ap, player *), "cf::player::wrap"); |
243 | break; |
243 | break; |
244 | |
244 | |
245 | case DT_ARCH: |
245 | case DT_ARCH: |
246 | sv = newSVptr (va_arg (ap, archetype *), "cf::arch::wrap"); |
246 | sv = newSVptr (va_arg (ap, archetype *), "cf::arch::wrap"); |
247 | break; |
247 | break; |
… | |
… | |
304 | } |
304 | } |
305 | |
305 | |
306 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
306 | ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
307 | |
307 | |
308 | SV * |
308 | SV * |
309 | registry_of (extendable_base *ext) |
309 | registry_of (attachable_base *ext) |
310 | { |
310 | { |
311 | if (!ext->cb) |
311 | if (!ext->cb) |
312 | ext->cb = newAV (); |
312 | ext->cb = newAV (); |
313 | |
313 | |
314 | return newRV_inc ((SV *)ext->cb); |
314 | return newRV_inc ((SV *)ext->cb); |
315 | } |
315 | } |
316 | |
316 | |
317 | void extendable_base::clear () |
317 | void attachable_base::clear () |
318 | { |
318 | { |
319 | //if (self) fprintf (stderr, "free_ob_self %p %s (%p,%p)\n", this, ((object *)this)->name, self, cb);//D |
319 | //if (self) fprintf (stderr, "free_ob_self %p %s (%p,%p)\n", this, ((object *)this)->name, self, cb);//D |
320 | |
320 | |
321 | if (self) SvREFCNT_dec (self); |
321 | if (self) SvREFCNT_dec (self); |
322 | if (cb) SvREFCNT_dec (cb); |
322 | if (cb) SvREFCNT_dec (cb); |
… | |
… | |
326 | self = 0; |
326 | self = 0; |
327 | cb = 0; |
327 | cb = 0; |
328 | attach = 0; |
328 | attach = 0; |
329 | } |
329 | } |
330 | |
330 | |
331 | void extendable_base::optimise () |
331 | void attachable_base::optimise () |
332 | { |
332 | { |
333 | if (!self) |
333 | if (!self) |
334 | return; |
334 | return; |
335 | |
335 | |
336 | HV *hv = (HV *)SvRV ((SV *)self); |
336 | HV *hv = (HV *)SvRV ((SV *)self); |
… | |
… | |
384 | call_pv ("cf::object_freezer_save", G_VOID | G_DISCARD | G_EVAL); |
384 | call_pv ("cf::object_freezer_save", G_VOID | G_DISCARD | G_EVAL); |
385 | FREETMPS; |
385 | FREETMPS; |
386 | LEAVE; |
386 | LEAVE; |
387 | } |
387 | } |
388 | |
388 | |
389 | void object_freezer::put (extendable_base *ext) |
389 | void object_freezer::put (attachable_base *ext) |
390 | { |
390 | { |
391 | ext->optimise (); |
391 | ext->optimise (); |
392 | |
392 | |
393 | if (ext->self) |
393 | if (ext->self) |
394 | av_store ((AV *)av, idx, SvREFCNT_inc ((SV *)ext->self)); |
394 | av_store ((AV *)av, idx, SvREFCNT_inc ((SV *)ext->self)); |
… | |
… | |
442 | case DT_MAP: INVOKE_MAP (REATTACH, obj); break; |
442 | case DT_MAP: INVOKE_MAP (REATTACH, obj); break; |
443 | } |
443 | } |
444 | } |
444 | } |
445 | |
445 | |
446 | template<class subclass> |
446 | template<class subclass> |
447 | void reattach (extendable<subclass> *obj) |
447 | void reattach (attachable<subclass> *obj) |
448 | { |
448 | { |
449 | obj->optimise (); |
449 | obj->optimise (); |
450 | |
450 | |
451 | if (obj->self) |
451 | if (obj->self) |
452 | reattach (subclass::get_dt (), (subclass *)obj); |
452 | reattach (subclass::get_dt (), (subclass *)obj); |
453 | } |
453 | } |
454 | |
454 | |
455 | void object_thawer::get (data_type type, void *obj, extendable_base *ext) |
455 | void object_thawer::get (data_type type, void *obj, attachable_base *ext) |
456 | { |
456 | { |
457 | if (!av) |
457 | if (!av) |
458 | return; |
458 | return; |
459 | |
459 | |
460 | // we have to "re-instantiate"/reattach to an object, so nuke ext->attach |
460 | // we have to "re-instantiate"/reattach to an object, so nuke ext->attach |
… | |
… | |
485 | ///////////////////////////////////////////////////////////////////////////// |
485 | ///////////////////////////////////////////////////////////////////////////// |
486 | |
486 | |
487 | extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) |
487 | extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) |
488 | { |
488 | { |
489 | gethook = gethooksptr; |
489 | gethook = gethooksptr; |
490 | printf (PLUGIN_VERSION " init\n"); |
|
|
491 | |
490 | |
492 | return 0; |
491 | return 0; |
493 | } |
492 | } |
494 | |
493 | |
495 | static CommArray_s rtn_cmd; |
494 | static CommArray_s rtn_cmd; |
… | |
… | |
575 | |
574 | |
576 | extern "C" int cfperl_postInitPlugin () |
575 | extern "C" int cfperl_postInitPlugin () |
577 | { |
576 | { |
578 | int hooktype = 1; |
577 | int hooktype = 1; |
579 | int rtype = 0; |
578 | int rtype = 0; |
580 | |
|
|
581 | printf (PLUGIN_VERSION " post init\n"); |
|
|
582 | |
579 | |
583 | systemDirectory = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_system_directory"); |
580 | systemDirectory = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_system_directory"); |
584 | object_set_property = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_set_property"); |
581 | object_set_property = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_set_property"); |
585 | map_get_map = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_map_get_map"); |
582 | map_get_map = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_map_get_map"); |
586 | object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert"); |
583 | object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert"); |