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.21 by root, Fri Feb 10 04:35:33 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 }
106} 112}
107 113
108static SV * 114static SV *
109newSVptr (void *ptr, const char *klass) 115newSVptr (void *ptr, const char *klass)
110{ 116{
117 SV *sv;
118
111 if (!ptr) 119 if (!ptr)
112 return &PL_sv_undef; 120 return &PL_sv_undef;
113 121
114 HV *hv = newHV (); 122 sv = newSV (0);
115 sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0); 123 sv_magic (sv, 0, PERL_MAGIC_ext, (char *)ptr, 0);
116 return sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1)); 124 return sv_bless (newRV_noinc (sv), gv_stashpv (klass, 1));
117} 125}
118 126
119static SV * 127static SV *
120newSVptr_cached (void *ptr, const char *klass) 128newSVptr_cached (void *ptr, const char *klass)
121{ 129{
128 136
129 if (he) 137 if (he)
130 sv = *he; 138 sv = *he;
131 else 139 else
132 { 140 {
133 sv = newSVptr (ptr, klass); 141 HV *hv = newHV ();
142 sv_magic ((SV *)hv, 0, PERL_MAGIC_ext, (char *)ptr, 0);
143 sv = sv_bless (newRV_noinc ((SV *)hv), gv_stashpv (klass, 1));
134 hv_store (obj_cache, (char *)&ptr, sizeof (ptr), sv, 0); 144 hv_store (obj_cache, (char *)&ptr, sizeof (ptr), sv, 0);
135 } 145 }
136 146
137 return newSVsv (sv); 147 return newSVsv (sv);
138} 148}
244} 254}
245 255
246///////////////////////////////////////////////////////////////////////////// 256/////////////////////////////////////////////////////////////////////////////
247 257
248void 258void
249inject_event (CFPContext *context) 259inject_event (const char *func, CFPContext *context)
250{ 260{
251 dSP; 261 dSP;
252 262
253 ENTER; 263 ENTER;
254 SAVETMPS; 264 SAVETMPS;
255 265
256 PUSHMARK (SP); 266 PUSHMARK (SP);
257
258 EXTEND (SP, 2);
259 //PUSHs (sv_2mortal (newSViv (type)));
260 267
261 HV *hv = newHV (); 268 HV *hv = newHV ();
262#define hv_context(type,addr,expr) hv_store (hv, #expr, sizeof (#expr) - 1, newSVcfapi (type, addr context->expr), 0) 269#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); 270 hv_context (CFAPI_POBJECT, ,who);
264 hv_context (CFAPI_POBJECT, ,activator); 271 hv_context (CFAPI_POBJECT, ,activator);
265 hv_context (CFAPI_POBJECT, ,third); 272 hv_context (CFAPI_POBJECT, ,third);
266 hv_context (CFAPI_STRING , ,message); 273 hv_context (CFAPI_STRING , ,message);
267 hv_context (CFAPI_INT ,&,fix); 274 hv_context (CFAPI_INT ,&,fix);
268 hv_context (CFAPI_INT ,&,event_code); 275 hv_context (CFAPI_INT ,&,event_code);
269 hv_context (CFAPI_STRING , ,options); 276 hv_context (CFAPI_STRING , ,options);
277 hv_context (CFAPI_STRING , ,extension);
270 278
271 PUSHs (sv_2mortal (newRV_noinc ((SV *)hv))); 279 XPUSHs (sv_2mortal (newRV_noinc ((SV *)hv)));
272 280
273 PUTBACK; 281 PUTBACK;
274 int count = call_pv ("cf::inject_event", G_SCALAR | G_EVAL); 282 int count = call_pv (func, G_SCALAR | G_EVAL);
275 SPAGAIN; 283 SPAGAIN;
276 284
277 if (SvTRUE (ERRSV)) 285 if (SvTRUE (ERRSV))
278 LOG (llevError, "event '%d' callback evaluation error: %s", context->event_code, SvPV_nolen (ERRSV)); 286 LOG (llevError, "event '%d' callback evaluation error: %s", context->event_code, SvPV_nolen (ERRSV));
279 287
488 case EVENT_LOGOUT: 496 case EVENT_LOGOUT:
489 pl = va_arg (args, player *); 497 pl = va_arg (args, player *);
490 context.activator = pl->ob; 498 context.activator = pl->ob;
491 buf = va_arg (args, char *); 499 buf = va_arg (args, char *);
492 if (buf != 0) 500 if (buf != 0)
493 strcpy (context.message, buf); 501 strncpy (context.message, buf, sizeof (context.message));
494 break; 502 break;
495 503
496 case EVENT_SHOUT: 504 case EVENT_SHOUT:
497 case EVENT_MUZZLE: 505 case EVENT_MUZZLE:
498 case EVENT_KICK: 506 case EVENT_KICK:
499 context.activator = va_arg (args, object *); 507 context.activator = va_arg (args, object *);
500 buf = va_arg (args, char *); 508 buf = va_arg (args, char *);
501 if (buf != 0) 509 if (buf != 0)
502 strcpy (context.message, buf); 510 strncpy (context.message, buf, sizeof (context.message));
503 break; 511 break;
504 512
505 case EVENT_CLOCK: 513 case EVENT_CLOCK:
506 clean_obj_cache (); 514 clean_obj_cache ();
507 break; 515 break;
510 break; 518 break;
511 519
512 case EVENT_MAPRESET: 520 case EVENT_MAPRESET:
513 buf = va_arg (args, char *); 521 buf = va_arg (args, char *);
514 if (buf != 0) 522 if (buf != 0)
515 strcpy (context.message, buf); 523 strncpy (context.message, buf, sizeof (context.message));
516 break; 524 break;
517 } 525 }
518 526
519 va_end (args); 527 va_end (args);
520 528
521 if (context.event_code == EVENT_FREE_OB) 529 if (context.event_code == EVENT_FREE_OB)
522 { 530 {
523 SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (object *), 0); 531 SV *sv = hv_delete (obj_cache, (char *)&context.activator, sizeof (void *), 0);
524 532
525 if (sv) 533 if (sv)
526 {
527 clearSVptr (sv); 534 clearSVptr (sv);
528 SvREFCNT_dec (sv);
529 }
530 } 535 }
531 else 536 else
532 inject_event (&context); 537 inject_event ("cf::inject_global_event", &context);
533 538
534 rv = context.returnvalue; 539 rv = context.returnvalue;
535 540
536 return &rv; 541 return &rv;
537} 542}
553 558
554 context.who = va_arg (args, object *); 559 context.who = va_arg (args, object *);
555 context.event_code = va_arg (args, int); 560 context.event_code = va_arg (args, int);
556 context.activator = va_arg (args, object *); 561 context.activator = va_arg (args, object *);
557 context.third = va_arg (args, object *); 562 context.third = va_arg (args, object *);
563
558 buf = va_arg (args, char *); 564 buf = va_arg (args, char *);
559
560 if (buf != 0) 565 if (buf != 0)
561 strcpy (context.message, buf); 566 strncpy (context.message, buf, sizeof (context.message));
562 567
563 context.fix = va_arg (args, int); 568 context.fix = va_arg (args, int);
569 strncpy (context.extension, va_arg (args, char *), sizeof (context.extension));
564 strcpy (context.options, va_arg (args, char *)); 570 strncpy (context.options, va_arg (args, char *), sizeof (context.options));
565 context.returnvalue = 0; 571 context.returnvalue = 0;
566 va_end (args); 572 va_end (args);
567 573
568 inject_event (&context); 574 inject_event ("cf::inject_event", &context);
569 575
570 rv = context.returnvalue; 576 rv = context.returnvalue;
571 return &rv; 577 return &rv;
572} 578}
573 579
1174int cf_object_get_flag (object *op, int flag) 1180int cf_object_get_flag (object *op, int flag)
1175 ALIAS: flag = 0 1181 ALIAS: flag = 0
1176 1182
1177void cf_object_set_flag (object *op, int flag, int value) 1183void cf_object_set_flag (object *op, int flag, int value)
1178 1184
1179void cf_object_move (object *op, object *originator, int dir) 1185void cf_object_move (object *op, int dir, object *originator = op)
1180 1186
1181void cf_object_apply (object *op, object *author, int flags = 0) 1187void cf_object_apply (object *op, object *author, int flags = 0)
1182 1188
1183void cf_object_apply_below (object *op) 1189void cf_object_apply_below (object *op)
1184 1190
1190 1196
1191int cf_object_transfer (object *op, int x, int y, int r, object *orig) 1197int cf_object_transfer (object *op, int x, int y, int r, object *orig)
1192 1198
1193int cf_object_change_map (object *op, int x, int y, mapstruct *map) 1199int cf_object_change_map (object *op, int x, int y, mapstruct *map)
1194 1200
1195object *cf_object_clone (object *op, int clonetype) 1201object *cf_object_clone (object *op, int clonetype = 0)
1196 1202
1197int cf_object_pay_item (object *op, object *buyer) 1203int cf_object_pay_item (object *op, object *buyer)
1198 1204
1199int cf_object_pay_amount (object *op, double amount) 1205int cf_object_pay_amount (object *op, double amount)
1200 1206
1267void cf_fix_object (object *pl) 1273void cf_fix_object (object *pl)
1268 ALIAS: fix = 0 1274 ALIAS: fix = 0
1269 1275
1270object *cf_insert_ob_in_ob (object *ob, object *where) 1276object *cf_insert_ob_in_ob (object *ob, object *where)
1271 1277
1278object *get_nearest_player (object *ob)
1279 ALIAS: nearest_player = 0
1280 PREINIT:
1281 extern object *get_nearest_player (object *);
1282
1283void rangevector (object *ob, object *other, int flags = 0)
1284 PROTOTYPE: $$;$
1285 PPCODE:
1286{
1287 rv_vector rv;
1288 get_rangevector (ob, other, &rv, flags);
1289 EXTEND (SP, 5);
1290 PUSHs (newSVuv (rv.distance));
1291 PUSHs (newSViv (rv.distance_x));
1292 PUSHs (newSViv (rv.distance_y));
1293 PUSHs (newSViv (rv.direction));
1294 PUSHs (newSVcfapi (CFAPI_POBJECT, rv.part));
1295}
1296
1297bool on_same_map_as (object *ob, object *other)
1298 CODE:
1299 RETVAL = on_same_map (ob, other);
1300 OUTPUT: RETVAL
1301
1272 1302
1273MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_ 1303MODULE = cf PACKAGE = cf::object::player PREFIX = cf_player_
1274 1304
1275player *player (object *op) 1305player *player (object *op)
1276 CODE: 1306 CODE:
1307# nonstandard 1337# nonstandard
1308object *ob (player *pl) 1338object *ob (player *pl)
1309 CODE: 1339 CODE:
1310 RETVAL = pl->ob; 1340 RETVAL = pl->ob;
1311 OUTPUT: RETVAL 1341 OUTPUT: RETVAL
1342
1343player *first ()
1344 CODE:
1345 RETVAL = first_player;
1346 OUTPUT: RETVAL
1347
1348player *next (player *pl)
1349 CODE:
1350 RETVAL = pl->next;
1351 OUTPUT: RETVAL
1352
1353void
1354list ()
1355 PPCODE:
1356{
1357 player *pl;
1358 for (pl = first_player; pl; pl = pl->next)
1359 XPUSHs (newSVcfapi (CFAPI_PPLAYER, pl));
1360}
1312 1361
1313 1362
1314MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 1363MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
1315 1364
1316SV * 1365SV *

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines