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.119 by root, Sun Dec 31 10:28:36 2006 UTC vs.
Revision 1.162 by root, Thu Feb 1 19:40:42 2007 UTC

29#include <plugin_common.h> 29#include <plugin_common.h>
30#include <sounds.h> 30#include <sounds.h>
31#include <cstdarg> 31#include <cstdarg>
32#include <sproto.h> 32#include <sproto.h>
33 33
34#include "loader.h"
34#include "cfperl.h" 35#include "cfperl.h"
35#include "shstr.h" 36#include "shstr.h"
37
38#include <unistd.h>
39#if _POSIX_MEMLOCK
40# include <sys/mman.h>
41#endif
36 42
37#include <EXTERN.h> 43#include <EXTERN.h>
38#include <perl.h> 44#include <perl.h>
39#include <XSUB.h> 45#include <XSUB.h>
40 46
94 100
95////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 101//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
96 102
97unordered_vector<attachable *> attachable::mortals; 103unordered_vector<attachable *> attachable::mortals;
98 104
99#if 0
100attachable *attachable::rc_first;
101
102attachable::attachable ()
103{
104 refcnt = 0;
105 rc_next = rc_first;
106 rc_first = this;
107}
108#endif
109
110attachable::~attachable () 105attachable::~attachable ()
111{ 106{
112 assert (!(flags & F_BORROWED));//D//TODO//remove when stable
113#if 0
114 assert (!rc_next);
115 assert (!refcnt); 107 assert (!self);
116#endif 108 assert (!cb);
109}
110
111int
112attachable::refcnt_cnt () const
113{
114 return refcnt + (self ? SvREFCNT (self) - 1 : 0);
115}
116
117void
118attachable::sever_self ()
119{
120 if (HV *self = this->self)
121 {
122 // keep a refcount because sv_unmagic might call attachable_free,
123 // which might clear self, causing sv_unmagic to crash on a now
124 // invalid object.
125 SvREFCNT_inc (self);
126 hv_clear (self);
127 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
128 SvREFCNT_dec (self);
129
130 // self *must* be null now because thats sv_unmagic's job.
131 assert (!this->self);
132 }
133}
134
135void
136attachable::optimise ()
137{
138 if (self
139 && SvREFCNT (self) == 1
140 && !HvTOTALKEYS (self))
141 sever_self ();
117} 142}
118 143
119// check wether the object really is dead 144// check wether the object really is dead
120void 145void
121attachable::do_check () 146attachable::do_check ()
122{ 147{
123 if (refcnt > 0) 148 if (refcnt_cnt () > 0)
124 return; 149 return;
125 150
126 // try to unborrow the refcnt from perl 151 destroy ();
127 if (flags & F_BORROWED) 152}
153
154void
155attachable::do_destroy ()
156{
157 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
158
159 if (cb)
128 { 160 {
129 assert (self);//D//TODO//remove when stable
130 flags &= ~F_BORROWED;
131 refcnt_inc ();
132 SvREFCNT_dec (self); 161 SvREFCNT_dec (cb);
162 cb = 0;
133 } 163 }
134 164
135 if (refcnt > 0 || self) 165 if (self)
136 return; 166 sever_self ();
137 167
138 destroy ();
139}
140
141void
142attachable::do_destroy ()
143{
144 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
145
146 //TODO: call generic destroy callback
147 mortals.push_back (this); 168 mortals.push_back (this);
148} 169}
149 170
150void 171void
151attachable::destroy () 172attachable::destroy ()
155 176
156 flags |= F_DESTROYED; 177 flags |= F_DESTROYED;
157 do_destroy (); 178 do_destroy ();
158} 179}
159 180
181void
160void attachable::check_mortals () 182attachable::check_mortals ()
161{ 183{
162 for (int i = 0; i < mortals.size (); ) 184 static int i = 0;
185
186 for (;;)
163 { 187 {
188 if (i >= mortals.size ())
189 {
190 i = 0;
191
192 if (mortals.size () > 1000)
193 fprintf (stderr, "mortal queue size (%d) exceeds 1000.\n", (int)mortals.size ());
194
195 break;
196 }
197
164 attachable *obj = mortals [i]; 198 attachable *obj = mortals [i];
165 199
166 obj->refcnt_chk (); // unborrow from perl, if necessary 200 obj->refcnt_chk (); // unborrow from perl, if necessary
167 201
202 //if (obj->refcnt > 0 || obj->self)
168 if (obj->refcnt || obj->self) 203 if (obj->refcnt || obj->self)
169 { 204 {
170#if 0 205//printf ("%p rc %d\n", obj, obj->refcnt_cnt ());//D
171 if (mortals.size() > 5)fprintf (stderr, "%d delaying %d:%p:%s %d (self %p:%d)\n", time(0),i, obj, typeid (*obj).name (),
172 obj->refcnt, obj->self, obj->self ? SvREFCNT(obj->self): - 1);//D
173#endif
174
175 ++i; // further delay freeing 206 ++i; // further delay freeing
207
208 if (!(i & 0x3ff))
209 break;
176 }//D 210 }
177 else 211 else
178 { 212 {
179 //Dfprintf (stderr, "deleteing %d:%p:%s\n", i, obj,typeid (*obj).name ());//D
180 mortals.erase (i); 213 mortals.erase (i);
181 delete obj; 214 delete obj;
182 } 215 }
183 } 216 }
184} 217}
209 242
210static int 243static int
211attachable_free (pTHX_ SV *sv, MAGIC *mg) 244attachable_free (pTHX_ SV *sv, MAGIC *mg)
212{ 245{
213 attachable *at = (attachable *)mg->mg_ptr; 246 attachable *at = (attachable *)mg->mg_ptr;
214 assert (!(at->flags & attachable::F_BORROWED));//D//TODO//remove when stable 247
248 //TODO: check if transaction behaviour is really required here
249 if (SV *self = (SV *)at->self)
250 {
215 at->self = 0; 251 at->self = 0;
252 SvREFCNT_dec (self);
253 }
254
216 // next line makes sense, but most objects still have refcnt 0 by default 255 // next line makes sense, but most objects still have refcnt 0 by default
217 //at->refcnt_chk (); 256 //at->refcnt_chk ();
218 return 0; 257 return 0;
219} 258}
220 259
229 if (!obj->self) 268 if (!obj->self)
230 { 269 {
231 obj->self = newHV (); 270 obj->self = newHV ();
232 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 271 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
233 272
234 // borrow the refcnt from the object 273 // now bless the object _once_
235 obj->flags |= attachable::F_BORROWED; 274 return sv_bless (newRV_inc ((SV *)obj->self), stash);
236 obj->refcnt_dec ();
237 } 275 }
276 else
277 {
278 SV *sv = newRV_inc ((SV *)obj->self);
238 279
239 return sv_bless (newRV_inc ((SV *)obj->self), stash); 280 if (Gv_AMG (stash)) // handle overload correctly, as the perl core does not
281 SvAMAGIC_on (sv);
282
283 return sv;
284 }
240} 285}
241 286
242static void 287static void
243clearSVptr (SV *sv) 288clearSVptr (SV *sv)
244{ 289{
297inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); } 342inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
298 343
299inline SV *to_sv (object & v) { return to_sv (&v); } 344inline SV *to_sv (object & v) { return to_sv (&v); }
300inline SV *to_sv (living & v) { return to_sv (&v); } 345inline SV *to_sv (living & v) { return to_sv (&v); }
301 346
302//TODO:
303inline SV *to_sv (New_Face * v) { return to_sv (v->name); } 347inline SV *to_sv (facetile * v) { return to_sv (v->name); }
304inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } 348inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
305 349
306inline SV *to_sv (UUID v) 350inline SV *to_sv (UUID v)
307{ 351{
308 char buf[128]; 352 char buf[128];
309 snprintf (buf, 128, "<1,%" PRIx64 ">", v.seq); 353 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq);
310 return newSVpv (buf, 0); 354 return newSVpv (buf, 0);
311} 355}
312 356
313inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } 357inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; }
314inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } 358inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
328inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); } 372inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); }
329inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); } 373inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); }
330inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); } 374inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); }
331inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); } 375inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); }
332inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); } 376inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); }
377inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
333inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 378inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
334inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 379inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
335inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 380inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
336 381
337inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } //TODO 382inline void sv_to (SV *sv, facetile * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; }
338inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); } // TODO 383inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
339 384
340template<class T> 385template<class T>
341inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } 386inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
342 387
343template<int N> 388template<int N>
478{ 523{
479 if (!ext->cb) 524 if (!ext->cb)
480 ext->cb = newAV (); 525 ext->cb = newAV ();
481 526
482 return newRV_inc ((SV *)ext->cb); 527 return newRV_inc ((SV *)ext->cb);
483}
484
485#if 0
486void attachable::clear ()
487{
488 if (self)
489 {
490 // disconnect Perl from C, to avoid crashes
491 sv_unmagic (SvRV ((SV *)self), PERL_MAGIC_ext);
492
493 // clear the perl hash, might or might not be a good idea
494 hv_clear ((HV *)SvRV ((SV *)self));
495
496 SvREFCNT_dec (self);
497 self = 0;
498 }
499
500 if (cb)
501 {
502 SvREFCNT_dec (cb);
503 cb = 0;
504 }
505
506 attach = 0;
507}
508#endif
509
510void attachable::optimise ()
511{
512 if (self
513 && SvREFCNT (self) == 1
514 && !HvTOTALKEYS (self))
515 {
516 flags &= ~F_BORROWED;
517 refcnt_inc ();
518 SvREFCNT_dec ((SV *)self);
519 }
520} 528}
521 529
522///////////////////////////////////////////////////////////////////////////// 530/////////////////////////////////////////////////////////////////////////////
523 531
524extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) 532extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
597 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl)) 605 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
598 { 606 {
599 printf ("unable to initialize perl-interpreter, aborting.\n"); 607 printf ("unable to initialize perl-interpreter, aborting.\n");
600 exit (EXIT_FAILURE); 608 exit (EXIT_FAILURE);
601 } 609 }
610
611 {
612 dSP;
613
614 PUSHMARK (SP);
615 PUTBACK;
616 call_pv ("cf::init", G_DISCARD | G_VOID);
617 }
602} 618}
603 619
604void cfperl_main () 620void cfperl_main ()
605{ 621{
606 dSP; 622 dSP;
820} 836}
821 837
822///////////////////////////////////////////////////////////////////////////// 838/////////////////////////////////////////////////////////////////////////////
823 839
824void 840void
825maptile::emergency_save () 841cfperl_emergency_save ()
826{ 842{
827 CALL_BEGIN (0); 843 CALL_BEGIN (0);
828 CALL_CALL ("cf::map::emergency_save", G_VOID); 844 CALL_CALL ("cf::emergency_save", G_VOID);
829 CALL_END; 845 CALL_END;
830} 846}
831 847
832maptile * 848maptile *
833maptile::load_map_sync (const char *path, maptile *origin) 849maptile::find_sync (const char *path, maptile *origin)
834{ 850{
835 CALL_BEGIN (2); 851 CALL_BEGIN (2);
836 CALL_ARG (path); 852 CALL_ARG (path);
837 CALL_ARG (origin); 853 CALL_ARG (origin);
838 CALL_CALL ("cf::map::load_map_sync", G_SCALAR); 854 CALL_CALL ("cf::map::find_sync", G_SCALAR);
839 855
840 maptile *retval; 856 maptile *retval;
841 857
842 if (count) 858 if (count)
843 sv_to (POPs, retval); 859 sv_to (POPs, retval);
845 retval = 0; 861 retval = 0;
846 862
847 CALL_END; 863 CALL_END;
848 864
849 return retval; 865 return retval;
866}
867
868maptile *
869maptile::find_async (const char *path, maptile *origin)
870{
871 CALL_BEGIN (2);
872 CALL_ARG (path);
873 CALL_ARG (origin);
874 CALL_CALL ("cf::map::find_async", G_SCALAR);
875
876 maptile *retval;
877
878 if (count)
879 sv_to (POPs, retval);
880 else
881 retval = 0;
882
883 CALL_END;
884
885 return retval;
886}
887
888void
889maptile::do_load_sync ()
890{
891 CALL_BEGIN (1);
892 CALL_ARG (this);
893 CALL_CALL ("cf::map::do_load_sync", G_SCALAR);
894 CALL_END;
850} 895}
851 896
852void 897void
853maptile::change_all_map_light (int change) 898maptile::change_all_map_light (int change)
854{ 899{
874///////////////////////////////////////////////////////////////////////////// 919/////////////////////////////////////////////////////////////////////////////
875 920
876struct EventAPI *watcher_base::GEventAPI; 921struct EventAPI *watcher_base::GEventAPI;
877struct CoroAPI *coroapi::GCoroAPI; 922struct CoroAPI *coroapi::GCoroAPI;
878 923
924int coroapi::cede_counter;
925
879static void iw_dispatch (pe_event *ev) 926static void iw_dispatch (pe_event *ev)
880{ 927{
881 iw *w = (iw *)ev->ext_data; 928 iw *w = (iw *)ev->ext_data;
882 w->call (*w); 929 w->call (*w);
883} 930}
885void 932void
886iw::alloc () 933iw::alloc ()
887{ 934{
888 pe = GEventAPI->new_idle (0, 0); 935 pe = GEventAPI->new_idle (0, 0);
889 936
937 WaREENTRANT_off (pe);
890 pe->base.callback = (void *)iw_dispatch; 938 pe->base.callback = (void *)iw_dispatch;
891 pe->base.ext_data = (void *)this; 939 pe->base.ext_data = (void *)this;
892} 940}
893 941
894static void iow_dispatch (pe_event *ev) 942static void iow_dispatch (pe_event *ev)
900void 948void
901iow::alloc () 949iow::alloc ()
902{ 950{
903 pe = GEventAPI->new_io (0, 0); 951 pe = GEventAPI->new_io (0, 0);
904 952
953 WaREENTRANT_off (pe);
905 pe->base.callback = (void *)iow_dispatch; 954 pe->base.callback = (void *)iow_dispatch;
906 pe->base.ext_data = (void *)this; 955 pe->base.ext_data = (void *)this;
907 956
908 pe->fd = -1; 957 pe->fd = -1;
909 pe->poll = 0; 958 pe->poll = 0;
1237 const_iv (FLAG_ACTIVATE_ON_RELEASE) 1286 const_iv (FLAG_ACTIVATE_ON_RELEASE)
1238 const_iv (FLAG_IS_WATER) 1287 const_iv (FLAG_IS_WATER)
1239 const_iv (FLAG_CONTENT_ON_GEN) 1288 const_iv (FLAG_CONTENT_ON_GEN)
1240 const_iv (FLAG_IS_A_TEMPLATE) 1289 const_iv (FLAG_IS_A_TEMPLATE)
1241 const_iv (FLAG_IS_BUILDABLE) 1290 const_iv (FLAG_IS_BUILDABLE)
1291 const_iv (FLAG_DESTROY_ON_DEATH)
1292 const_iv (FLAG_NO_MAP_SAVE)
1242 1293
1243 const_iv (NDI_BLACK) 1294 const_iv (NDI_BLACK)
1244 const_iv (NDI_WHITE) 1295 const_iv (NDI_WHITE)
1245 const_iv (NDI_NAVY) 1296 const_iv (NDI_NAVY)
1246 const_iv (NDI_RED) 1297 const_iv (NDI_RED)
1288 const_iv (P_BLOCKSVIEW) 1339 const_iv (P_BLOCKSVIEW)
1289 const_iv (P_PLAYER) 1340 const_iv (P_PLAYER)
1290 const_iv (P_NO_MAGIC) 1341 const_iv (P_NO_MAGIC)
1291 const_iv (P_IS_ALIVE) 1342 const_iv (P_IS_ALIVE)
1292 const_iv (P_NO_CLERIC) 1343 const_iv (P_NO_CLERIC)
1293 const_iv (P_NEED_UPDATE)
1294 const_iv (P_OUT_OF_MAP) 1344 const_iv (P_OUT_OF_MAP)
1295 const_iv (P_NEW_MAP) 1345 const_iv (P_NEW_MAP)
1346 const_iv (P_UPTODATE)
1296 1347
1297 const_iv (UP_OBJ_INSERT) 1348 const_iv (UP_OBJ_INSERT)
1298 const_iv (UP_OBJ_REMOVE) 1349 const_iv (UP_OBJ_REMOVE)
1299 const_iv (UP_OBJ_CHANGE) 1350 const_iv (UP_OBJ_CHANGE)
1300 const_iv (UP_OBJ_FACE) 1351 const_iv (UP_OBJ_FACE)
1431 const_iv (ATNR_BLIND) 1482 const_iv (ATNR_BLIND)
1432 const_iv (ATNR_INTERNAL) 1483 const_iv (ATNR_INTERNAL)
1433 const_iv (ATNR_LIFE_STEALING) 1484 const_iv (ATNR_LIFE_STEALING)
1434 const_iv (ATNR_DISEASE) 1485 const_iv (ATNR_DISEASE)
1435 1486
1436 const_iv (MAP_FLUSH)
1437 const_iv (MAP_PLAYER_UNIQUE)
1438 const_iv (MAP_BLOCK)
1439 const_iv (MAP_STYLE)
1440 const_iv (MAP_OVERLAY)
1441
1442 const_iv (MAP_IN_MEMORY) 1487 const_iv (MAP_IN_MEMORY)
1443 const_iv (MAP_SWAPPED) 1488 const_iv (MAP_SWAPPED)
1444 const_iv (MAP_LOADING) 1489 const_iv (MAP_LOADING)
1445 const_iv (MAP_SAVING) 1490 const_iv (MAP_SAVING)
1446 1491
1459 const_iv (ST_SETUP) 1504 const_iv (ST_SETUP)
1460 const_iv (ST_PLAYING) 1505 const_iv (ST_PLAYING)
1461 const_iv (ST_CUSTOM) 1506 const_iv (ST_CUSTOM)
1462 1507
1463 const_iv (ST_CHANGE_CLASS) 1508 const_iv (ST_CHANGE_CLASS)
1464 const_iv (ST_CONFIRM_QUIT)
1465 const_iv (ST_GET_PARTY_PASSWORD)
1466 1509
1467 const_iv (IO_HEADER) 1510 const_iv (IO_HEADER)
1468 const_iv (IO_OBJECTS) 1511 const_iv (IO_OBJECTS)
1469 const_iv (IO_UNIQUES) 1512 const_iv (IO_UNIQUES)
1470 1513
1524 1567
1525void _global_reattach () 1568void _global_reattach ()
1526 CODE: 1569 CODE:
1527{ 1570{
1528 // reattach to all attachable objects in the game. 1571 // reattach to all attachable objects in the game.
1529 for (sockvec::iterator i = clients.begin (); i != clients.end (); ++i) 1572 for_all_clients (ns)
1530 (*i)->reattach (); 1573 ns->reattach ();
1531 1574
1532 for_all_players (pl) 1575 for_all_players (pl)
1533 pl->reattach (); 1576 pl->reattach ();
1534 1577
1535 //TODO 1578 //TODO
1536 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i) 1579 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i)
1537 // i->second->reattach (); 1580 // i->second->reattach ();
1538 1581
1539 for (object *op = object::first; op; op = op->next) 1582 for_all_objects (op)
1540 op->reattach (); 1583 op->reattach ();
1541} 1584}
1542 1585
1543NV floor (NV x) 1586NV floor (NV x)
1544 1587
1545NV ceil (NV x) 1588NV ceil (NV x)
1589
1590NV rndm (...)
1591 CODE:
1592 switch (items)
1593 {
1594 case 0: RETVAL = rndm (); break;
1595 case 1: RETVAL = rndm (SvUV (ST (0))); break;
1596 case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1597 default: croak ("cf::rndm requires none, one or two parameters."); break;
1598 }
1599 OUTPUT:
1600 RETVAL
1546 1601
1547void server_tick () 1602void server_tick ()
1548 CODE: 1603 CODE:
1549 runtime = SvNVx (sv_runtime); 1604 runtime = SvNVx (sv_runtime);
1550 server_tick (); 1605 server_tick ();
1595 case 5: RETVAL = settings.playerdir; break; 1650 case 5: RETVAL = settings.playerdir; break;
1596 case 6: RETVAL = settings.datadir ; break; 1651 case 6: RETVAL = settings.datadir ; break;
1597 } 1652 }
1598 OUTPUT: RETVAL 1653 OUTPUT: RETVAL
1599 1654
1655void abort ()
1656
1657void fork_abort (char *cause = "cf::fork_abort")
1658
1659void cleanup (const char *cause, bool make_core = false)
1660
1600void emergency_save () 1661void emergency_save ()
1601 1662
1602void _exit (int status = 0) 1663void _exit (int status = EXIT_SUCCESS)
1664
1665UV sv_2watcher (SV *w)
1666 CODE:
1667 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1668 OUTPUT:
1669 RETVAL
1670
1671#if _POSIX_MEMLOCK
1672
1673int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1674
1675int munlockall ()
1676
1677#endif
1603 1678
1604int find_animation (char *text) 1679int find_animation (char *text)
1605 PROTOTYPE: $ 1680 PROTOTYPE: $
1606 1681
1607int random_roll (int min, int max, object *op, int goodbad); 1682int random_roll (int min, int max, object *op, int goodbad);
1645 RETVAL = newSVpv (resist_plus[atnr], 0); 1720 RETVAL = newSVpv (resist_plus[atnr], 0);
1646 else 1721 else
1647 XSRETURN_UNDEF; 1722 XSRETURN_UNDEF;
1648 OUTPUT: RETVAL 1723 OUTPUT: RETVAL
1649 1724
1725bool
1726load_regions (const char *filename)
1727 CODE:
1728 RETVAL = loader_region ().load (filename);
1729 OUTPUT: RETVAL
1730
1650MODULE = cf PACKAGE = cf::attachable 1731MODULE = cf PACKAGE = cf::attachable
1651 1732
1652int 1733int
1653valid (SV *obj) 1734valid (SV *obj)
1654 CODE: 1735 CODE:
1655 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1736 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1656 OUTPUT: 1737 OUTPUT:
1657 RETVAL 1738 RETVAL
1658 1739
1659#bool 1740int mortals_size ()
1660#destroyed (attachable *at) 1741 CODE:
1661# 1742 RETVAL = attachable::mortals.size ();
1662#void 1743 OUTPUT: RETVAL
1663#destroy (attachable *at) 1744
1745#object *mortals (U32 index)
1746# CODE:
1747# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1748# OUTPUT: RETVAL
1749
1750INCLUDE: $PERL genacc attachable ../include/cfperl.h |
1664 1751
1665MODULE = cf PACKAGE = cf::global 1752MODULE = cf PACKAGE = cf::global
1666 1753
1667int invoke (SV *klass, int event, ...) 1754int invoke (SV *klass, int event, ...)
1668 CODE: 1755 CODE:
1684 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); 1771 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1685 OUTPUT: RETVAL 1772 OUTPUT: RETVAL
1686 1773
1687SV *registry (object *op) 1774SV *registry (object *op)
1688 1775
1689void mortals () 1776int objects_size ()
1690 PPCODE: 1777 CODE:
1691 EXTEND (SP, object::mortals.size ());
1692 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1693 PUSHs (to_sv (*i));
1694
1695object *first ()
1696 CODE:
1697 RETVAL = object::first; 1778 RETVAL = objects.size ();
1779 OUTPUT: RETVAL
1780
1781object *objects (U32 index)
1782 CODE:
1783 RETVAL = index < objects.size () ? objects [index] : 0;
1784 OUTPUT: RETVAL
1785
1786int actives_size ()
1787 CODE:
1788 RETVAL = actives.size ();
1789 OUTPUT: RETVAL
1790
1791object *actives (U32 index)
1792 CODE:
1793 RETVAL = index < actives.size () ? actives [index] : 0;
1698 OUTPUT: RETVAL 1794 OUTPUT: RETVAL
1699 1795
1700# missing properties 1796# missing properties
1701 1797
1702object *head (object *op) 1798object *head (object *op)
1703 PROTOTYPE: $ 1799 PROTOTYPE: $
1704 CODE: 1800 CODE:
1705 RETVAL = op->head ? op->head : op; 1801 RETVAL = op->head_ ();
1706 OUTPUT: RETVAL 1802 OUTPUT: RETVAL
1707 1803
1708int is_head (object *op) 1804int is_head (object *op)
1709 PROTOTYPE: $ 1805 PROTOTYPE: $
1710 CODE: 1806 CODE:
1711 RETVAL = !op->head; 1807 RETVAL = op->head_ () == op;
1712 OUTPUT: RETVAL 1808 OUTPUT: RETVAL
1713 1809
1714void 1810void
1715inv (object *obj) 1811inv (object *obj)
1716 PROTOTYPE: $ 1812 PROTOTYPE: $
1723 1819
1724void 1820void
1725set_animation (object *op, int idx) 1821set_animation (object *op, int idx)
1726 CODE: 1822 CODE:
1727 SET_ANIMATION (op, idx); 1823 SET_ANIMATION (op, idx);
1824
1825int
1826num_animations (object *op)
1827 CODE:
1828 RETVAL = NUM_ANIMATIONS (op);
1829 OUTPUT: RETVAL
1728 1830
1729object *find_best_object_match (object *op, const char *match) 1831object *find_best_object_match (object *op, const char *match)
1730 1832
1731object *find_marked_object (object *op) 1833object *find_marked_object (object *op)
1732 1834
1807 1909
1808void drop (object *who, object *op) 1910void drop (object *who, object *op)
1809 1911
1810void pick_up (object *who, object *op) 1912void pick_up (object *who, object *op)
1811 1913
1812object *cf_object_insert_object (object *op, object *container)
1813
1814object *cf_object_insert_in_ob (object *ob, object *where)
1815
1816int cf_object_teleport (object *op, maptile *map, int x, int y) 1914int cf_object_teleport (object *op, maptile *map, int x, int y)
1817 1915
1818void update_object (object *op, int action) 1916void update_object (object *op, int action)
1819 1917
1820object *cf_create_object_by_name (const char *name) 1918object *cf_create_object_by_name (const char *name)
1913 RETVAL = op->contr; 2011 RETVAL = op->contr;
1914 OUTPUT: RETVAL 2012 OUTPUT: RETVAL
1915 2013
1916void check_score (object *op) 2014void check_score (object *op)
1917 2015
1918void cf_player_message (object *obj, char *txt, int flags = NDI_ORANGE | NDI_UNIQUE) 2016void message (object *op, char *txt, int flags = NDI_ORANGE | NDI_UNIQUE)
2017 CODE:
2018 new_draw_info (flags, 0, op, txt);
1919 2019
1920object *cf_player_send_inventory (object *op) 2020object *cf_player_send_inventory (object *op)
1921 2021
1922char *cf_player_get_ip (object *op) 2022char *cf_player_get_ip (object *op)
1923 ALIAS: ip = 0 2023 ALIAS: ip = 0
1936 2036
1937void esrv_update_item (object *op, int what, object *item) 2037void esrv_update_item (object *op, int what, object *item)
1938 C_ARGS: what, op, item 2038 C_ARGS: what, op, item
1939 2039
1940void clear_los (object *op) 2040void clear_los (object *op)
1941
1942int command_teleport (object *op, char *params)
1943 2041
1944int command_summon (object *op, char *params) 2042int command_summon (object *op, char *params)
1945 2043
1946int command_arrest (object *op, char *params) 2044int command_arrest (object *op, char *params)
1947 2045
1970 pl->ob->stats.hp = pl->ob->stats.maxhp; 2068 pl->ob->stats.hp = pl->ob->stats.maxhp;
1971 pl->ob->stats.sp = pl->ob->stats.maxsp; 2069 pl->ob->stats.sp = pl->ob->stats.maxsp;
1972 pl->ob->stats.grace = pl->ob->stats.maxgrace; 2070 pl->ob->stats.grace = pl->ob->stats.maxgrace;
1973 pl->orig_stats = pl->ob->stats; 2071 pl->orig_stats = pl->ob->stats;
1974 2072
1975player *cf_player_find (char *name)
1976 PROTOTYPE: $
1977
1978void cf_player_move (player *pl, int dir) 2073void cf_player_move (player *pl, int dir)
1979 2074
1980void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0); 2075void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
1981
1982player *first ()
1983 CODE:
1984 RETVAL = first_player;
1985 OUTPUT: RETVAL
1986 2076
1987bool 2077bool
1988cell_visible (player *pl, int dx, int dy) 2078cell_visible (player *pl, int dx, int dy)
1989 CODE: 2079 CODE:
1990 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2 2080 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2027 if (y) sv_to (y, pl->bed_y); 2117 if (y) sv_to (y, pl->bed_y);
2028 2118
2029void 2119void
2030list () 2120list ()
2031 PPCODE: 2121 PPCODE:
2032 for (player *pl = first_player; pl; pl = pl->next) 2122 for_all_players (pl)
2033 XPUSHs (sv_2mortal (to_sv (pl))); 2123 XPUSHs (sv_2mortal (to_sv (pl)));
2034
2035bool
2036peaceful (player *pl, bool new_setting = 0)
2037 PROTOTYPE: $;$
2038 CODE:
2039 RETVAL = pl->peaceful;
2040 if (items > 1)
2041 pl->peaceful = new_setting;
2042 OUTPUT:
2043 RETVAL
2044
2045living *
2046orig_stats (player *pl)
2047 CODE:
2048 RETVAL = &pl->orig_stats;
2049 OUTPUT: RETVAL
2050
2051living *
2052last_stats (player *pl)
2053 CODE:
2054 RETVAL = &pl->last_stats;
2055 OUTPUT: RETVAL
2056 2124
2057 2125
2058MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 2126MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2059 2127
2060int invoke (maptile *map, int event, ...) 2128int invoke (maptile *map, int event, ...)
2076 PROTOTYPE: 2144 PROTOTYPE:
2077 CODE: 2145 CODE:
2078 RETVAL = new maptile; 2146 RETVAL = new maptile;
2079 OUTPUT: 2147 OUTPUT:
2080 RETVAL 2148 RETVAL
2081
2082void
2083maptile::destroy ()
2084 2149
2085void 2150void
2086maptile::players () 2151maptile::players ()
2087 PPCODE: 2152 PPCODE:
2088 if (GIMME_V == G_SCALAR) 2153 if (GIMME_V == G_SCALAR)
2093 for_all_players (pl) 2158 for_all_players (pl)
2094 if (pl->ob && pl->ob->map == THIS) 2159 if (pl->ob && pl->ob->map == THIS)
2095 PUSHs (sv_2mortal (to_sv (pl->ob))); 2160 PUSHs (sv_2mortal (to_sv (pl->ob)));
2096 } 2161 }
2097 2162
2163void
2164maptile::set_regiondata (SV *data, SV *plt)
2165 CODE:
2166{
2167 if (!SvROK (plt) || SvTYPE (SvRV (plt)) != SVt_PVAV)
2168 croak ("maptile::set_regiondata needs arrayref as plt arg");
2169
2170 AV *av = (AV *)SvRV (plt);
2171
2172 region **regionmap = (region **)malloc ((av_len (av) + 1) * sizeof (region *));
2173
2174 for (int i = av_len (av) + 1; i--; )
2175 regionmap [i] = region::find (SvPVutf8_nolen (*av_fetch (av, i, 1)));
2176
2177 THIS->regions = salloc<uint8_t> (THIS->size (), (uint8_t *)SvPVbyte_nolen (data));
2178 THIS->regionmap = regionmap;
2179}
2180
2098void play_sound_map (maptile *map, int x, int y, int sound_num) 2181void play_sound_map (maptile *map, int x, int y, int sound_num)
2099 2182
2100int out_of_map (maptile *map, int x, int y) 2183int out_of_map (maptile *map, int x, int y)
2101 2184
2102void 2185void
2118 2201
2119object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny) 2202object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny)
2120 C_ARGS: str, map, nx, ny 2203 C_ARGS: str, map, nx, ny
2121 2204
2122void 2205void
2123cf_map_normalise (maptile *map, int x, int y) 2206get_map_flags (maptile *map, int x, int y)
2124 PPCODE: 2207 PPCODE:
2125{ 2208{
2126 maptile *nmap = 0; 2209 maptile *nmap = 0;
2127 I16 nx = 0, ny = 0; 2210 I16 nx = 0, ny = 0;
2128 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny); 2211 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny);
2177 case 4: RETVAL = newSVuv ( GET_MAP_MOVE_BLOCK (obj, x, y)); break; 2260 case 4: RETVAL = newSVuv ( GET_MAP_MOVE_BLOCK (obj, x, y)); break;
2178 case 5: RETVAL = newSVuv ( GET_MAP_MOVE_SLOW (obj, x, y)); break; 2261 case 5: RETVAL = newSVuv ( GET_MAP_MOVE_SLOW (obj, x, y)); break;
2179 case 6: RETVAL = newSVuv ( GET_MAP_MOVE_ON (obj, x, y)); break; 2262 case 6: RETVAL = newSVuv ( GET_MAP_MOVE_ON (obj, x, y)); break;
2180 case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break; 2263 case 7: RETVAL = newSVuv ( GET_MAP_MOVE_OFF (obj, x, y)); break;
2181 } 2264 }
2182 OUTPUT: 2265 OUTPUT: RETVAL
2183 RETVAL
2184 2266
2185void fix_walls (maptile *map, int x, int y) 2267void fix_walls (maptile *map, int x, int y)
2186 2268
2187void fix_walls_around (maptile *map, int x, int y) 2269void fix_walls_around (maptile *map, int x, int y)
2188 2270
2189# worst xs function of my life 2271# worst xs function of my life
2190maptile * 2272bool
2191_create_random_map (\ 2273_create_random_map (\
2192 char *path,\ 2274 maptile *self,\
2193 char *wallstyle,\ 2275 char *wallstyle,\
2194 char *wall_name,\ 2276 char *wall_name,\
2195 char *floorstyle,\ 2277 char *floorstyle,\
2196 char *monsterstyle,\ 2278 char *monsterstyle,\
2197 char *treasurestyle,\ 2279 char *treasurestyle,\
2201 char *origin_map,\ 2283 char *origin_map,\
2202 char *final_map,\ 2284 char *final_map,\
2203 char *exitstyle,\ 2285 char *exitstyle,\
2204 char *this_map,\ 2286 char *this_map,\
2205 char *exit_on_final_map,\ 2287 char *exit_on_final_map,\
2206 int Xsize,\ 2288 int xsize,\
2207 int Ysize,\ 2289 int ysize,\
2208 int expand2x,\ 2290 int expand2x,\
2209 int layoutoptions1,\ 2291 int layoutoptions1,\
2210 int layoutoptions2,\ 2292 int layoutoptions2,\
2211 int layoutoptions3,\ 2293 int layoutoptions3,\
2212 int symmetry,\ 2294 int symmetry,\
2217 int dungeon_depth,\ 2299 int dungeon_depth,\
2218 int decoroptions,\ 2300 int decoroptions,\
2219 int orientation,\ 2301 int orientation,\
2220 int origin_y,\ 2302 int origin_y,\
2221 int origin_x,\ 2303 int origin_x,\
2222 int random_seed,\ 2304 U32 random_seed,\
2223 val64 total_map_hp,\ 2305 val64 total_map_hp,\
2224 int map_layout_style,\ 2306 int map_layout_style,\
2225 int treasureoptions,\ 2307 int treasureoptions,\
2226 int symmetry_used,\ 2308 int symmetry_used,\
2227 region *region\ 2309 region *region,\
2310 char *custom\
2228) 2311)
2229 CODE: 2312 CODE:
2230{ 2313{
2231 random_map_params rmp; 2314 random_map_params rmp;
2232 2315
2236 assign (rmp.monsterstyle , monsterstyle); 2319 assign (rmp.monsterstyle , monsterstyle);
2237 assign (rmp.treasurestyle , treasurestyle); 2320 assign (rmp.treasurestyle , treasurestyle);
2238 assign (rmp.layoutstyle , layoutstyle); 2321 assign (rmp.layoutstyle , layoutstyle);
2239 assign (rmp.doorstyle , doorstyle); 2322 assign (rmp.doorstyle , doorstyle);
2240 assign (rmp.decorstyle , decorstyle); 2323 assign (rmp.decorstyle , decorstyle);
2241 assign (rmp.origin_map , origin_map);
2242 assign (rmp.final_map , final_map);
2243 assign (rmp.exitstyle , exitstyle); 2324 assign (rmp.exitstyle , exitstyle);
2244 assign (rmp.this_map , this_map);
2245 assign (rmp.exit_on_final_map, exit_on_final_map); 2325 assign (rmp.exit_on_final_map, exit_on_final_map);
2246 2326
2327 rmp.origin_map = origin_map;
2328 rmp.final_map = final_map;
2329 rmp.this_map = this_map;
2247 rmp.Xsize = Xsize; 2330 rmp.xsize = xsize;
2248 rmp.Ysize = Ysize; 2331 rmp.ysize = ysize;
2249 rmp.expand2x = expand2x; 2332 rmp.expand2x = expand2x;
2250 rmp.layoutoptions1 = layoutoptions1; 2333 rmp.layoutoptions1 = layoutoptions1;
2251 rmp.layoutoptions2 = layoutoptions2; 2334 rmp.layoutoptions2 = layoutoptions2;
2252 rmp.layoutoptions3 = layoutoptions3; 2335 rmp.layoutoptions3 = layoutoptions3;
2253 rmp.symmetry = symmetry; 2336 rmp.symmetry = symmetry;
2264 rmp.total_map_hp = total_map_hp; 2347 rmp.total_map_hp = total_map_hp;
2265 rmp.map_layout_style = map_layout_style; 2348 rmp.map_layout_style = map_layout_style;
2266 rmp.treasureoptions = treasureoptions; 2349 rmp.treasureoptions = treasureoptions;
2267 rmp.symmetry_used = symmetry_used; 2350 rmp.symmetry_used = symmetry_used;
2268 rmp.region = region; 2351 rmp.region = region;
2352 rmp.custom = custom;
2269 2353
2270 RETVAL = generate_random_map (path, &rmp); 2354 RETVAL = self->generate_random_map (&rmp);
2271} 2355}
2272 OUTPUT: 2356 OUTPUT:
2273 RETVAL 2357 RETVAL
2274 2358
2275MODULE = cf PACKAGE = cf::arch 2359MODULE = cf PACKAGE = cf::arch
2298 2382
2299INCLUDE: $PERL genacc partylist ../include/player.h | 2383INCLUDE: $PERL genacc partylist ../include/player.h |
2300 2384
2301MODULE = cf PACKAGE = cf::region 2385MODULE = cf PACKAGE = cf::region
2302 2386
2303region *first () 2387void
2388list ()
2389 PPCODE:
2390 for_all_regions (rgn)
2391 XPUSHs (sv_2mortal (to_sv (rgn)));
2392
2393region *find (char *name)
2304 PROTOTYPE: 2394 PROTOTYPE: $
2305 CODE: 2395 CODE:
2306 RETVAL = first_region; 2396 RETVAL = region::find (name);
2397 OUTPUT: RETVAL
2398
2399region *find_fuzzy (char *name)
2400 PROTOTYPE: $
2401 CODE:
2402 RETVAL = region::find_fuzzy (name);
2307 OUTPUT: RETVAL 2403 OUTPUT: RETVAL
2308 2404
2309INCLUDE: $PERL genacc region ../include/map.h | 2405INCLUDE: $PERL genacc region ../include/map.h |
2310 2406
2311MODULE = cf PACKAGE = cf::living 2407MODULE = cf PACKAGE = cf::living
2345 char *buf = SvPVbyte (packet, len); 2441 char *buf = SvPVbyte (packet, len);
2346 2442
2347 THIS->send_packet (buf, len); 2443 THIS->send_packet (buf, len);
2348} 2444}
2349 2445
2350void
2351client::destroy ()
2352

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines