ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/server/cfperl.xs
(Generate patch)

Comparing deliantra/server/server/cfperl.xs (file contents):
Revision 1.10 by root, Fri Aug 25 17:11:53 2006 UTC vs.
Revision 1.11 by root, Sat Aug 26 08:44:06 2006 UTC

99#define PUSH_PV PUSHcfapi_va(STRING, const char *) 99#define PUSH_PV PUSHcfapi_va(STRING, const char *)
100#define PUSH_IV PUSHs (sv_2mortal (newSViv (va_arg (args, int)))) 100#define PUSH_IV PUSHs (sv_2mortal (newSViv (va_arg (args, int))))
101 101
102////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 102//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
103 103
104// garbage collect some perl objects, if possible
105// all objects no longer referenced and empty are
106// eligible for destruction.
107static void
108clean_obj_cache ()
109{
110 static int count;
111
112 if (++count & 7)
113 return;
114
115 int todo = 1000;
116 do
117 {
118 I32 klen;
119 char *key;
120 HE *he = hv_iternext (obj_cache);
121
122 if (he)
123 {
124 SV *sv = hv_iterval (obj_cache, he);
125
126 // empty and unreferenced? nuke it
127 if (SvREFCNT (sv) == 1 && SvREFCNT (SvRV (sv)) == 1 && !HvFILL ((HV *)(SvRV (sv))))
128 {
129 hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD);
130 todo++;
131 }
132 }
133 else
134 break;
135 }
136 while (--todo);
137}
138
139static SV * 104static SV *
140newSVptr (void *ptr, const char *klass) 105newSVptr (void *ptr, const char *klass)
141{ 106{
142 SV *sv; 107 SV *sv;
143 108
145 return &PL_sv_undef; 110 return &PL_sv_undef;
146 111
147 sv = (SV *)newHV (); 112 sv = (SV *)newHV ();
148 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0); 113 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0);
149 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1)); 114 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1));
115}
116
117template<class extendable>
118SV *
119newSVextendable (extendable *obj, const char *klass)
120{
121 if (!obj)
122 return &PL_sv_undef;
123
124 if (!obj->self)
125 obj->self = newSVptr (obj, klass);
126
127 return newSVsv (static_cast<SV *>(obj->self));
150} 128}
151 129
152static void 130static void
153SVptr_cache_set (void *ptr, SV *sv) 131SVptr_cache_set (void *ptr, SV *sv)
154{ 132{
266 break; 244 break;
267 245
268 case DT_OBJECT: 246 case DT_OBJECT:
269 { 247 {
270 object *obj = va_arg (ap, object *); 248 object *obj = va_arg (ap, object *);
271 249 sv = newSVextendable (obj, obj->type == PLAYER ? "cf::object::player::wrap" : "cf::object::wrap");
272 if (!obj)
273 sv = &PL_sv_undef;
274 else
275 {
276 if (!obj->self)
277 switch (obj->type)
278 {
279 case MAP:
280 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::map::wrap"));
281 break;
282
283 case PLAYER:
284 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::player::wrap"));
285 break;
286
287 default:
288 obj->self = static_cast<void *>(newSVptr (obj, "cf::object::wrap"));
289 break;
290 }
291
292 sv = newSVsv (static_cast<SV *>(obj->self));
293 }
294 } 250 }
295 break; 251 break;
296 252
297 case DT_MAP: 253 case DT_MAP:
254 // va_arg (object *) when void * is passed is an XSI extension
298 sv = newSVptr (va_arg (ap, mapstruct *), "cf::map::wrap"); 255 sv = newSVextendable (va_arg (ap, mapstruct *), "cf::map::wrap");
299 break; 256 break;
300 257
301 case DT_PLAYER: 258 case DT_PLAYER:
302 sv = newSVptr (va_arg (ap, player *), "cf::player::wrap"); 259 sv = newSVextendable (va_arg (ap, player *), "cf::player::wrap");
303 break; 260 break;
304 261
305 case DT_ARCH: 262 case DT_ARCH:
306 sv = newSVptr (va_arg (ap, archetype *), "cf::arch::wrap"); 263 sv = newSVptr (va_arg (ap, archetype *), "cf::arch::wrap");
307 break; 264 break;
359 } 316 }
360 317
361 va_end (ap); 318 va_end (ap);
362 319
363 return sv; 320 return sv;
321}
322
323//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
324
325void extendable_base::clear ()
326{
327 //if (self) fprintf (stderr, "free_ob_self %p\n", this);//D
328 if (self) SvREFCNT_dec (self), self = 0;
329 if (cb) SvREFCNT_dec (cb), cb = 0;
330}
331
332void extendable_base::optimise ()
333{
334 // optional, and not used yet anyways
335// // empty and unreferenced? nuke it
336// if (SvREFCNT (sv) == 1 && SvREFCNT (SvRV (sv)) == 1 && !HvFILL ((HV *)(SvRV (sv))))
337// {
338// hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD);
339// todo++;
340// }
341
342}
343
344void extendable_base::reattach (data_type type, void *self)
345{
346 dSP;
347
348 ENTER;
349 SAVETMPS;
350 PUSHMARK (SP);
351 EXTEND (SP, 1);
352 PUSHs (sv_2mortal (newSVdt (type, self)));
353 PUTBACK;
354 call_pv ("cf::reattach", G_DISCARD | G_VOID | G_EVAL);
355 FREETMPS;
356 LEAVE;
357}
358
359void extendable_base::instantiate (data_type type, void *self)
360{
361 dSP;
362
363 ENTER;
364 SAVETMPS;
365 PUSHMARK (SP);
366 EXTEND (SP, 1);
367 PUSHs (sv_2mortal (newSVdt (type, self)));
368 PUTBACK;
369 call_pv ("cf::instantiate", G_DISCARD | G_VOID | G_EVAL);
370 FREETMPS;
371 LEAVE;
372}
373
374void extendable_base::clone (data_type type, void *self, void *dest)
375{
376 dSP;
377
378 ENTER;
379 SAVETMPS;
380 PUSHMARK (SP);
381 EXTEND (SP, 1);
382 PUSHs (sv_2mortal (newSVdt (type, self)));
383 PUSHs (sv_2mortal (newSVdt (type, dest)));
384 PUTBACK;
385 call_pv ("cf::clone", G_DISCARD | G_VOID | G_EVAL);
386 FREETMPS;
387 LEAVE;
364} 388}
365 389
366///////////////////////////////////////////////////////////////////////////// 390/////////////////////////////////////////////////////////////////////////////
367 391
368extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) 392extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
469 object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert"); 493 object_insert = (void* (*)(int*, ...)) gethook (&rtype, hooktype, "cfapi_object_insert");
470 494
471 cf_init_plugin (gethook); 495 cf_init_plugin (gethook);
472 496
473 /* Pick the global events you want to monitor from this plugin */ 497 /* Pick the global events you want to monitor from this plugin */
474 registerGlobalEvent (NULL, EVENT_CLOCK, PLUGIN_NAME, globalEventListener);
475 //registerGlobalEvent (NULL, EVENT_CRASH, PLUGIN_NAME, globalEventListener);
476 registerGlobalEvent (NULL, EVENT_FIND_UNARMED_SKILL, PLUGIN_NAME, globalEventListener);
477 registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener); 498 registerGlobalEvent (NULL, EVENT_SHOUT, PLUGIN_NAME, globalEventListener);
478 registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener); 499 registerGlobalEvent (NULL, EVENT_TELL, PLUGIN_NAME, globalEventListener);
479 registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener); 500 registerGlobalEvent (NULL, EVENT_MUZZLE, PLUGIN_NAME, globalEventListener);
480 registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener); 501 registerGlobalEvent (NULL, EVENT_KICK, PLUGIN_NAME, globalEventListener);
481 502
493 return NULL; 514 return NULL;
494 515
495 va_start (args, type); 516 va_start (args, type);
496 event_code = va_arg (args, int); 517 event_code = va_arg (args, int);
497 518
498 if (event_code == EVENT_CLOCK) 519 dSP;
520
521 ENTER;
522 SAVETMPS;
523
524 PUSHMARK (SP);
525
526 EXTEND (SP, 10);
527 PUSHs (sv_2mortal (newSViv (event_code)));
528
529 switch (event_code)
499 { 530 {
500 clean_obj_cache (); 531 case EVENT_CRASH:
532 break;
533
534 case EVENT_SHOUT:
535 case EVENT_MUZZLE:
536 case EVENT_KICK:
537 PUSH_OB;
538 PUSH_PV;
539 break;
540
541 case EVENT_TELL:
542 break;
501 } 543 }
502 else
503 {
504 dSP;
505 544
506 ENTER;
507 SAVETMPS;
508
509 PUSHMARK (SP);
510
511 EXTEND (SP, 10);
512 PUSHs (sv_2mortal (newSViv (event_code)));
513
514 switch (event_code)
515 {
516 case EVENT_CRASH:
517 break;
518
519 case EVENT_SHOUT:
520 case EVENT_MUZZLE:
521 case EVENT_KICK:
522 PUSH_OB;
523 PUSH_PV;
524 break;
525
526 case EVENT_FIND_UNARMED_SKILL:
527 PUSH_OB;
528 break;
529
530 case EVENT_TELL:
531 break;
532 }
533
534 va_end (args); 545 va_end (args);
535 546
536 PUTBACK; 547 PUTBACK;
537 int count = call_pv ("cf::inject_global_event", G_SCALAR | G_EVAL); 548 int count = call_pv ("cf::inject_global_event", G_SCALAR | G_EVAL);
538 SPAGAIN; 549 SPAGAIN;
539 550
540 if (SvTRUE (ERRSV)) 551 if (SvTRUE (ERRSV))
541 LOG (llevError, "global event '%d' callback evaluation error: %s", event_code, SvPV_nolen (ERRSV)); 552 LOG (llevError, "global event '%d' callback evaluation error: %s", event_code, SvPV_nolen (ERRSV));
542 553
543 rv = count > 0 ? POPi : 0; 554 rv = count > 0 ? POPi : 0;
544 555
545 PUTBACK; 556 PUTBACK;
546 FREETMPS; 557 FREETMPS;
547 LEAVE; 558 LEAVE;
548 }
549 559
550 return &rv; 560 return &rv;
551} 561}
552 562
553extern "C" void *cfperl_eventListener (int *type, ...) 563extern "C" void *cfperl_eventListener (int *type, ...)
685 dSP; 695 dSP;
686 696
687 PUSHMARK (SP); 697 PUSHMARK (SP);
688 PUTBACK; 698 PUTBACK;
689 call_pv ("cf::main", G_DISCARD | G_VOID); 699 call_pv ("cf::main", G_DISCARD | G_VOID);
690}
691
692void cfperl_free_ob (object *op)
693{
694 if (op->self) fprintf (stderr, "free_ob_self %p %s\n", op, op->name);//D
695 if (op->self) SvREFCNT_dec (op->self), op->self = 0;
696 if (op->cb) SvREFCNT_dec (op->cb), op->cb = 0;
697} 700}
698 701
699static event_klass klass_of[NUM_EVENT_TYPES] = { 702static event_klass klass_of[NUM_EVENT_TYPES] = {
700# define def(type,name) KLASS_ ## type, 703# define def(type,name) KLASS_ ## type,
701# include "eventinc.h" 704# include "eventinc.h"
1376 const_event (TRIGGER) 1379 const_event (TRIGGER)
1377 const_event (CLOSE) 1380 const_event (CLOSE)
1378 const_event (TIMER) 1381 const_event (TIMER)
1379 const_event (MOVE) 1382 const_event (MOVE)
1380 1383
1381 //const_event (CLOCK)
1382 const_event (CRASH)
1383 const_event (SHOUT) 1384 const_event (SHOUT)
1384 const_event (TELL) 1385 const_event (TELL)
1385 const_event (MUZZLE) 1386 const_event (MUZZLE)
1386 const_event (KICK) 1387 const_event (KICK)
1387 const_event (FIND_UNARMED_SKILL)
1388 //const_event (FREE_OB)
1389 }; 1388 };
1390 1389
1391 av = get_av ("cf::PLUGIN_EVENT", 1); 1390 av = get_av ("cf::PLUGIN_EVENT", 1);
1392 1391
1393 for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; ) 1392 for (event = event_list + sizeof (event_list) / sizeof (event_list [0]); event-- > event_list; )

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines