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

Comparing deliantra/server/plugins/cfperl/cfperl.xs (file contents):
Revision 1.14 by root, Tue Feb 7 23:29:55 2006 UTC vs.
Revision 1.18 by root, Wed Feb 8 06:15:13 2006 UTC

28#include <perl.h> 28#include <perl.h>
29#include <XSUB.h> 29#include <XSUB.h>
30 30
31#undef save_long // clashes with libproto.h 31#undef save_long // clashes with libproto.h
32 32
33#define PLUGIN_NAME "cfperl" 33#define PLUGIN_NAME "perl"
34#define PLUGIN_VERSION "cfperl 0.0" 34#define PLUGIN_VERSION "cfperl 0.0"
35 35
36#ifndef __CEXTRACT__ 36#ifndef __CEXTRACT__
37#include <plugin.h> 37#include <plugin.h>
38#endif 38#endif
62 object* activator; 62 object* activator;
63 object* third; 63 object* third;
64 char message[1024]; 64 char message[1024];
65 int fix; 65 int fix;
66 int event_code; 66 int event_code;
67 char options[1024]; 67 char extension[1024]; // name field, should invoke specific perl extension
68 char options[1024]; // slaying field of event_connectors
68 int returnvalue; 69 int returnvalue;
69} CFPContext; 70} CFPContext;
70 71
71//static int current_command = -999; 72//static int current_command = -999;
72 73
79// all objects no longer referenced and empty are 80// all objects no longer referenced and empty are
80// eligible for destruction. 81// eligible for destruction.
81void 82void
82clean_obj_cache () 83clean_obj_cache ()
83{ 84{
85 static int count;
86
87 if (++count & 7)
88 return;
89
84 int todo = 10; 90 int todo = 1000;
85 do 91 do
86 { 92 {
87 I32 klen; 93 I32 klen;
88 char *key; 94 char *key;
89 HE *he = hv_iternext (obj_cache); 95 HE *he = hv_iternext (obj_cache);
90 96
91 if (he) 97 if (he)
92 { 98 {
93 SV *sv = SvRV (hv_iterval (obj_cache, he)); 99 SV *sv = hv_iterval (obj_cache, he);
94 100
95 // emopty and unreferened? nuke it 101 // empty and unreferenced? nuke it
96 if (SvREFCNT (sv) == 1 && !HvFILL ((HV *)sv)) 102 if (SvREFCNT (sv) == 1 && SvREFCNT (SvRV (sv)) == 1 && !HvFILL ((HV *)(SvRV (sv))))
97 { 103 {
98 hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD); 104 hv_delete (obj_cache, HeKEY (he), HeKLEN (he), G_DISCARD);
99 todo++; 105 todo++;
100 } 106 }
101 } 107 }
244} 250}
245 251
246///////////////////////////////////////////////////////////////////////////// 252/////////////////////////////////////////////////////////////////////////////
247 253
248void 254void
249inject_event (CFPContext *context) 255inject_event (const char *func, CFPContext *context)
250{ 256{
251 dSP; 257 dSP;
252 258
253 ENTER; 259 ENTER;
254 SAVETMPS; 260 SAVETMPS;
255 261
256 PUSHMARK (SP); 262 PUSHMARK (SP);
257
258 EXTEND (SP, 2);
259 //PUSHs (sv_2mortal (newSViv (type)));
260 263
261 HV *hv = newHV (); 264 HV *hv = newHV ();
262#define hv_context(type,addr,expr) hv_store (hv, #expr, sizeof (#expr) - 1, newSVcfapi (type, addr context->expr), 0) 265#define hv_context(type,addr,expr) hv_store (hv, #expr, sizeof (#expr) - 1, newSVcfapi (type, addr context->expr), 0)
263 hv_context (CFAPI_POBJECT, ,who); 266 hv_context (CFAPI_POBJECT, ,who);
264 hv_context (CFAPI_POBJECT, ,activator); 267 hv_context (CFAPI_POBJECT, ,activator);
265 hv_context (CFAPI_POBJECT, ,third); 268 hv_context (CFAPI_POBJECT, ,third);
266 hv_context (CFAPI_STRING , ,message); 269 hv_context (CFAPI_STRING , ,message);
267 hv_context (CFAPI_INT ,&,fix); 270 hv_context (CFAPI_INT ,&,fix);
268 hv_context (CFAPI_INT ,&,event_code); 271 hv_context (CFAPI_INT ,&,event_code);
269 hv_context (CFAPI_STRING , ,options); 272 hv_context (CFAPI_STRING , ,options);
273 hv_context (CFAPI_STRING , ,extension);
270 274
271 PUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); 275 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
272 276
273 PUTBACK; 277 PUTBACK;
274 int count = call_pv ("cf::inject_event", G_SCALAR | G_EVAL); 278 int count = call_pv (func, G_SCALAR | G_EVAL);
275 SPAGAIN; 279 SPAGAIN;
276 280
277 if (SvTRUE (ERRSV)) 281 if (SvTRUE (ERRSV))
278 LOG (llevError, "event '%d' callback evaluation error: %s", context->event_code, SvPV_nolen (ERRSV)); 282 LOG (llevError, "event '%d' callback evaluation error: %s", context->event_code, SvPV_nolen (ERRSV));
279 283
488 case EVENT_LOGOUT: 492 case EVENT_LOGOUT:
489 pl = va_arg (args, player *); 493 pl = va_arg (args, player *);
490 context.activator = pl->ob; 494 context.activator = pl->ob;
491 buf = va_arg (args, char *); 495 buf = va_arg (args, char *);
492 if (buf != 0) 496 if (buf != 0)
493 strcpy (context.message, buf); 497 strncpy (context.message, buf, sizeof (context.message));
494 break; 498 break;
495 499
496 case EVENT_SHOUT: 500 case EVENT_SHOUT:
497 case EVENT_MUZZLE: 501 case EVENT_MUZZLE:
498 case EVENT_KICK: 502 case EVENT_KICK:
499 context.activator = va_arg (args, object *); 503 context.activator = va_arg (args, object *);
500 buf = va_arg (args, char *); 504 buf = va_arg (args, char *);
501 if (buf != 0) 505 if (buf != 0)
502 strcpy (context.message, buf); 506 strncpy (context.message, buf, sizeof (context.message));
503 break; 507 break;
504 508
505 case EVENT_CLOCK: 509 case EVENT_CLOCK:
506 clean_obj_cache (); 510 clean_obj_cache ();
507 break; 511 break;
510 break; 514 break;
511 515
512 case EVENT_MAPRESET: 516 case EVENT_MAPRESET:
513 buf = va_arg (args, char *); 517 buf = va_arg (args, char *);
514 if (buf != 0) 518 if (buf != 0)
515 strcpy (context.message, buf); 519 strncpy (context.message, buf, sizeof (context.message));
516 break; 520 break;
517 } 521 }
518 522
519 va_end (args); 523 va_end (args);
520 524
521 if (context.event_code == EVENT_FREE_OB) 525 if (context.event_code == EVENT_FREE_OB)
522 { 526 {
523 SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (object *), 0); 527 SV **svp = hv_fetch (obj_cache, (char *)&context.activator, sizeof (void *), 0);
524 528
525 if (sv) 529 if (svp)
526 {
527 clearSVptr (sv); 530 clearSVptr (*svp);
528 SvREFCNT_dec (sv);
529 }
530 } 531 }
531 else 532 else
532 inject_event (&context); 533 inject_event ("cf::inject_global_event", &context);
533 534
534 rv = context.returnvalue; 535 rv = context.returnvalue;
535 536
536 return &rv; 537 return &rv;
537} 538}
553 554
554 context.who = va_arg (args, object *); 555 context.who = va_arg (args, object *);
555 context.event_code = va_arg (args, int); 556 context.event_code = va_arg (args, int);
556 context.activator = va_arg (args, object *); 557 context.activator = va_arg (args, object *);
557 context.third = va_arg (args, object *); 558 context.third = va_arg (args, object *);
559
558 buf = va_arg (args, char *); 560 buf = va_arg (args, char *);
559
560 if (buf != 0) 561 if (buf != 0)
561 strcpy (context.message, buf); 562 strncpy (context.message, buf, sizeof (context.message));
562 563
563 context.fix = va_arg (args, int); 564 context.fix = va_arg (args, int);
565 strncpy (context.extension, va_arg (args, char *), sizeof (context.extension));
564 strcpy (context.options, va_arg (args, char *)); 566 strncpy (context.options, va_arg (args, char *), sizeof (context.options));
565 context.returnvalue = 0; 567 context.returnvalue = 0;
566 va_end (args); 568 va_end (args);
567 569
568 inject_event (&context); 570 inject_event ("cf::inject_event", &context);
569 571
570 rv = context.returnvalue; 572 rv = context.returnvalue;
571 return &rv; 573 return &rv;
572} 574}
573 575
1174int cf_object_get_flag (object *op, int flag) 1176int cf_object_get_flag (object *op, int flag)
1175 ALIAS: flag = 0 1177 ALIAS: flag = 0
1176 1178
1177void cf_object_set_flag (object *op, int flag, int value) 1179void cf_object_set_flag (object *op, int flag, int value)
1178 1180
1179void cf_object_move (object *op, object *originator, int dir) 1181void cf_object_move (object *op, int dir, object *originator)
1180 1182
1181void cf_object_apply (object *op, object *author, int flags = 0) 1183void cf_object_apply (object *op, object *author, int flags = 0)
1182 1184
1183void cf_object_apply_below (object *op) 1185void cf_object_apply_below (object *op)
1184 1186
1267void cf_fix_object (object *pl) 1269void cf_fix_object (object *pl)
1268 ALIAS: fix = 0 1270 ALIAS: fix = 0
1269 1271
1270object *cf_insert_ob_in_ob (object *ob, object *where) 1272object *cf_insert_ob_in_ob (object *ob, object *where)
1271 1273
1274object *get_nearest_player (object *ob)
1275 ALIAS: nearest_player = 0
1276 PREINIT:
1277 extern object *get_nearest_player (object *);
1278
1279void rangevector (object *ob, object *other, int flags = 0)
1280 PROTOTYPE: $$;$
1281 PPCODE:
1282{
1283 rv_vector rv;
1284 get_rangevector (ob, other, &rv, flags);
1285 EXTEND (SP, 5);
1286 PUSHs (newSVuv (rv.distance));
1287 PUSHs (newSViv (rv.distance_x));
1288 PUSHs (newSViv (rv.distance_y));
1289 PUSHs (newSViv (rv.direction));
1290 PUSHs (newSVcfapi (CFAPI_POBJECT, rv.part));
1291}
1292
1293bool on_same_map_as (object *ob, object *other)
1294 CODE:
1295 RETVAL = on_same_map (ob, other);
1296 OUTPUT: RETVAL
1297
1272 1298
1273MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_ 1299MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_
1274 1300
1275player *player (object *op) 1301player *player (object *op)
1276 CODE: 1302 CODE:
1307# nonstandard 1333# nonstandard
1308object *ob (player *pl) 1334object *ob (player *pl)
1309 CODE: 1335 CODE:
1310 RETVAL = pl->ob; 1336 RETVAL = pl->ob;
1311 OUTPUT: RETVAL 1337 OUTPUT: RETVAL
1338
1339player *first ()
1340 CODE:
1341 RETVAL = first_player;
1342 OUTPUT: RETVAL
1343
1344player *next (player *pl)
1345 CODE:
1346 RETVAL = pl->next;
1347 OUTPUT: RETVAL
1348
1349void
1350list ()
1351 PPCODE:
1352{
1353 player *pl;
1354 for (pl = first_player; pl; pl = pl->next)
1355 XPUSHs (newSVcfapi (CFAPI_PPLAYER, pl));
1356}
1312 1357
1313 1358
1314MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 1359MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
1315 1360
1316SV * 1361SV *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines