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.127 by root, Thu Jan 4 20:15:16 2007 UTC vs.
Revision 1.173 by root, Mon Mar 5 19:54:49 2007 UTC

4 4
5/* 5/*
6 * This code is placed under the GNU General Public Licence (GPL) 6 * This code is placed under the GNU General Public Licence (GPL)
7 * 7 *
8 * Copyright (C) 2001-2005 by Chachkoff Yann 8 * Copyright (C) 2001-2005 by Chachkoff Yann
9 * Copyright (C) 2006 by Marc Lehmann <cf@schmorp.de> 9 * Copyright (C) 2006,2007 by Marc Lehmann <cf@schmorp.de>
10 * 10 *
11 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or 13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version. 14 * (at your option) any later version.
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"
36 37
37#include <unistd.h> 38#include <unistd.h>
38#if _POSIX_MEMLOCK 39#if _POSIX_MEMLOCK
99 100
100////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 101//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
101 102
102unordered_vector<attachable *> attachable::mortals; 103unordered_vector<attachable *> attachable::mortals;
103 104
104#if 0
105attachable *attachable::rc_first;
106
107attachable::attachable ()
108{
109 refcnt = 0;
110 rc_next = rc_first;
111 rc_first = this;
112}
113#endif
114
115attachable::~attachable () 105attachable::~attachable ()
116{ 106{
117 assert (!(flags & F_BORROWED));//D//TODO//remove when stable 107 flags |=0x3300;//D
118#if 0
119 assert (!rc_next);
120 assert (!refcnt); 108 assert (!self);
121#endif 109 assert (!cb);
110}
111
112int
113attachable::refcnt_cnt () const
114{
115 return refcnt + (self ? SvREFCNT (self) - 1 : 0);
116}
117
118void
119attachable::sever_self ()
120{
121 if (HV *self = this->self)
122 {
123 // keep a refcount because sv_unmagic might call attachable_free,
124 // which might clear self, causing sv_unmagic to crash on a now
125 // invalid object.
126 SvREFCNT_inc (self);
127 hv_clear (self);
128 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
129 SvREFCNT_dec (self);
130
131 // self *must* be null now because thats sv_unmagic's job.
132 assert (!this->self);
133 flags |= 0x80; // severed //D
134 }
135}
136
137void
138attachable::optimise ()
139{
140 if (self
141 && SvREFCNT (self) == 1
142 && !HvTOTALKEYS (self))
143 flags |= 0x40,//D
144 sever_self ();
122} 145}
123 146
124// check wether the object really is dead 147// check wether the object really is dead
125void 148void
126attachable::do_check () 149attachable::do_check ()
127{ 150{
128 if (refcnt > 0) 151 if (refcnt_cnt () > 0)
129 return; 152 return;
130 153
131 // try to unborrow the refcnt from perl 154 destroy ();
132 if (flags & F_BORROWED) 155}
156
157void
158attachable::do_destroy ()
159{
160 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
161
162 if (cb)
133 { 163 {
134 assert (self);//D//TODO//remove when stable
135 flags &= ~F_BORROWED;
136 refcnt_inc ();
137 SvREFCNT_dec (self); 164 SvREFCNT_dec (cb);
165 cb = 0;
138 } 166 }
139 167
140 if (refcnt > 0 || self)
141 return;
142
143 destroy ();
144}
145
146void
147attachable::do_destroy ()
148{
149 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
150
151 if (self) 168 if (self)
152 hv_clear (self); 169 sever_self ();
153 170
154 //TODO: call generic destroy callback 171 flags |= 0x20; //D
155 mortals.push_back (this); 172 mortals.push_back (this);
156} 173}
157 174
158void 175void
159attachable::destroy () 176attachable::destroy ()
163 180
164 flags |= F_DESTROYED; 181 flags |= F_DESTROYED;
165 do_destroy (); 182 do_destroy ();
166} 183}
167 184
185void
168void attachable::check_mortals () 186attachable::check_mortals ()
169{ 187{
170 for (int i = 0; i < mortals.size (); ) 188 static int i = 0;
189
190 for (;;)
171 { 191 {
192 if (i >= mortals.size ())
193 {
194 i = 0;
195
196 if (mortals.size () > 1000)
197 fprintf (stderr, "mortal queue size (%d) exceeds 1000.\n", (int)mortals.size ());
198
199 break;
200 }
201
172 attachable *obj = mortals [i]; 202 attachable *obj = mortals [i];
173 203
174 obj->refcnt_chk (); // unborrow from perl, if necessary 204 obj->refcnt_chk (); // unborrow from perl, if necessary
175 205
206 //if (obj->refcnt > 0 || obj->self)
176 if (obj->refcnt || obj->self) 207 if (obj->refcnt || obj->self)
177 { 208 {
178#if 0 209//printf ("%p rc %d\n", obj, obj->refcnt_cnt ());//D
179 if (mortals.size() > 5)fprintf (stderr, "%d delaying %d:%p:%s %d (self %p:%d)\n", time(0),i, obj, typeid (*obj).name (),
180 obj->refcnt, obj->self, obj->self ? SvREFCNT(obj->self): - 1);//D
181#endif
182
183 ++i; // further delay freeing 210 ++i; // further delay freeing
211
212 if (!(i & 0x3ff))
213 break;
184 }//D 214 }
185 else 215 else
186 { 216 {
187 //Dfprintf (stderr, "deleteing %d:%p:%s\n", i, obj,typeid (*obj).name ());//D
188 mortals.erase (i); 217 mortals.erase (i);
189 delete obj; 218 delete obj;
190 } 219 }
191 } 220 }
192} 221}
217 246
218static int 247static int
219attachable_free (pTHX_ SV *sv, MAGIC *mg) 248attachable_free (pTHX_ SV *sv, MAGIC *mg)
220{ 249{
221 attachable *at = (attachable *)mg->mg_ptr; 250 attachable *at = (attachable *)mg->mg_ptr;
222 assert (!(at->flags & attachable::F_BORROWED));//D//TODO//remove when stable 251
252 //TODO: check if transaction behaviour is really required here
253 if (SV *self = (SV *)at->self)
254 {
223 at->self = 0; 255 at->self = 0;
256 SvREFCNT_dec (self);
257 }
258
224 // next line makes sense, but most objects still have refcnt 0 by default 259 // next line makes sense, but most objects still have refcnt 0 by default
225 //at->refcnt_chk (); 260 //at->refcnt_chk ();
226 return 0; 261 return 0;
227} 262}
228 263
236 271
237 if (!obj->self) 272 if (!obj->self)
238 { 273 {
239 obj->self = newHV (); 274 obj->self = newHV ();
240 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 275 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
276 obj->flags |= (obj->flags & 0xc0) << 8;
277 obj->flags &= ~0xc0;//D
278 obj->flags |= 0x10;//D
241 279
242 // borrow the refcnt from the object 280 // now bless the object _once_
243 obj->flags |= attachable::F_BORROWED; 281 return sv_bless (newRV_inc ((SV *)obj->self), stash);
244 obj->refcnt_dec ();
245 } 282 }
283 else
284 {
285 SV *sv = newRV_inc ((SV *)obj->self);
246 286
247 return sv_bless (newRV_inc ((SV *)obj->self), stash); 287 if (Gv_AMG (stash)) // handle overload correctly, as the perl core does not
288 SvAMAGIC_on (sv);
289
290 return sv;
291 }
248} 292}
249 293
250static void 294static void
251clearSVptr (SV *sv) 295clearSVptr (SV *sv)
252{ 296{
305inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); } 349inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
306 350
307inline SV *to_sv (object & v) { return to_sv (&v); } 351inline SV *to_sv (object & v) { return to_sv (&v); }
308inline SV *to_sv (living & v) { return to_sv (&v); } 352inline SV *to_sv (living & v) { return to_sv (&v); }
309 353
310//TODO:
311inline SV *to_sv (New_Face * v) { return to_sv (v->name); } 354inline SV *to_sv (facetile * v) { return to_sv (v->name); }
312inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } 355inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
313 356
314inline SV *to_sv (UUID v) 357inline SV *to_sv (UUID v)
315{ 358{
316 char buf[128]; 359 char buf[128];
317 snprintf (buf, 128, "<1,%" PRIx64 ">", v.seq); 360 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq);
318 return newSVpv (buf, 0); 361 return newSVpv (buf, 0);
319} 362}
320 363
321inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } 364inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; }
322inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } 365inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
336inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); } 379inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); }
337inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); } 380inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); }
338inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); } 381inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); }
339inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); } 382inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); }
340inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); } 383inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); }
384inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
341inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 385inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
342inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 386inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
343inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 387inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
344 388
345inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } //TODO 389inline void sv_to (SV *sv, facetile * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; }
346inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); } // TODO 390inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
347 391
348template<class T> 392template<class T>
349inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } 393inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
350 394
351template<int N> 395template<int N>
486{ 530{
487 if (!ext->cb) 531 if (!ext->cb)
488 ext->cb = newAV (); 532 ext->cb = newAV ();
489 533
490 return newRV_inc ((SV *)ext->cb); 534 return newRV_inc ((SV *)ext->cb);
491}
492
493#if 0
494void attachable::clear ()
495{
496 if (self)
497 {
498 // disconnect Perl from C, to avoid crashes
499 sv_unmagic (SvRV ((SV *)self), PERL_MAGIC_ext);
500
501 // clear the perl hash, might or might not be a good idea
502 hv_clear ((HV *)SvRV ((SV *)self));
503
504 SvREFCNT_dec (self);
505 self = 0;
506 }
507
508 if (cb)
509 {
510 SvREFCNT_dec (cb);
511 cb = 0;
512 }
513
514 attach = 0;
515}
516#endif
517
518void attachable::optimise ()
519{
520 if (self
521 && SvREFCNT (self) == 1
522 && !HvTOTALKEYS (self))
523 {
524 flags &= ~F_BORROWED;
525 refcnt_inc ();
526 SvREFCNT_dec ((SV *)self);
527 }
528} 535}
529 536
530///////////////////////////////////////////////////////////////////////////// 537/////////////////////////////////////////////////////////////////////////////
531 538
532extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) 539extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
605 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl)) 612 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
606 { 613 {
607 printf ("unable to initialize perl-interpreter, aborting.\n"); 614 printf ("unable to initialize perl-interpreter, aborting.\n");
608 exit (EXIT_FAILURE); 615 exit (EXIT_FAILURE);
609 } 616 }
617
618 {
619 dSP;
620
621 PUSHMARK (SP);
622 PUTBACK;
623 call_pv ("cf::init", G_DISCARD | G_VOID);
624 }
610} 625}
611 626
612void cfperl_main () 627void cfperl_main ()
613{ 628{
614 dSP; 629 dSP;
828} 843}
829 844
830///////////////////////////////////////////////////////////////////////////// 845/////////////////////////////////////////////////////////////////////////////
831 846
832void 847void
833maptile::emergency_save () 848cfperl_emergency_save ()
834{ 849{
835 CALL_BEGIN (0); 850 CALL_BEGIN (0);
836 CALL_CALL ("cf::map::emergency_save", G_VOID); 851 CALL_CALL ("cf::emergency_save", G_VOID);
852 CALL_END;
853}
854
855void
856cfperl_cleanup (int make_core)
857{
858 CALL_BEGIN (1);
859 CALL_ARG (make_core);
860 CALL_CALL ("cf::post_cleanup", G_VOID);
837 CALL_END; 861 CALL_END;
838} 862}
839 863
840maptile * 864maptile *
841maptile::find_sync (const char *path, maptile *origin) 865maptile::find_sync (const char *path, maptile *origin)
842{ 866{
843 CALL_BEGIN (2); 867 CALL_BEGIN (2);
844 CALL_ARG (path); 868 CALL_ARG (path);
845 CALL_ARG (origin); 869 CALL_ARG (origin);
846 CALL_CALL ("cf::map::find_sync", G_SCALAR); 870 CALL_CALL ("cf::map::find_sync", G_SCALAR);
871
872 maptile *retval;
873
874 if (count)
875 sv_to (POPs, retval);
876 else
877 retval = 0;
878
879 CALL_END;
880
881 return retval;
882}
883
884maptile *
885maptile::find_async (const char *path, maptile *origin)
886{
887 CALL_BEGIN (2);
888 CALL_ARG (path);
889 CALL_ARG (origin);
890 CALL_CALL ("cf::map::find_async", G_SCALAR);
847 891
848 maptile *retval; 892 maptile *retval;
849 893
850 if (count) 894 if (count)
851 sv_to (POPs, retval); 895 sv_to (POPs, retval);
904void 948void
905iw::alloc () 949iw::alloc ()
906{ 950{
907 pe = GEventAPI->new_idle (0, 0); 951 pe = GEventAPI->new_idle (0, 0);
908 952
953 WaREENTRANT_off (pe);
909 pe->base.callback = (void *)iw_dispatch; 954 pe->base.callback = (void *)iw_dispatch;
910 pe->base.ext_data = (void *)this; 955 pe->base.ext_data = (void *)this;
911} 956}
912 957
913static void iow_dispatch (pe_event *ev) 958static void iow_dispatch (pe_event *ev)
919void 964void
920iow::alloc () 965iow::alloc ()
921{ 966{
922 pe = GEventAPI->new_io (0, 0); 967 pe = GEventAPI->new_io (0, 0);
923 968
969 WaREENTRANT_off (pe);
924 pe->base.callback = (void *)iow_dispatch; 970 pe->base.callback = (void *)iow_dispatch;
925 pe->base.ext_data = (void *)this; 971 pe->base.ext_data = (void *)this;
926 972
927 pe->fd = -1; 973 pe->fd = -1;
928 pe->poll = 0; 974 pe->poll = 0;
1256 const_iv (FLAG_ACTIVATE_ON_RELEASE) 1302 const_iv (FLAG_ACTIVATE_ON_RELEASE)
1257 const_iv (FLAG_IS_WATER) 1303 const_iv (FLAG_IS_WATER)
1258 const_iv (FLAG_CONTENT_ON_GEN) 1304 const_iv (FLAG_CONTENT_ON_GEN)
1259 const_iv (FLAG_IS_A_TEMPLATE) 1305 const_iv (FLAG_IS_A_TEMPLATE)
1260 const_iv (FLAG_IS_BUILDABLE) 1306 const_iv (FLAG_IS_BUILDABLE)
1307 const_iv (FLAG_DESTROY_ON_DEATH)
1308 const_iv (FLAG_NO_MAP_SAVE)
1261 1309
1262 const_iv (NDI_BLACK) 1310 const_iv (NDI_BLACK)
1263 const_iv (NDI_WHITE) 1311 const_iv (NDI_WHITE)
1264 const_iv (NDI_NAVY) 1312 const_iv (NDI_NAVY)
1265 const_iv (NDI_RED) 1313 const_iv (NDI_RED)
1450 const_iv (ATNR_BLIND) 1498 const_iv (ATNR_BLIND)
1451 const_iv (ATNR_INTERNAL) 1499 const_iv (ATNR_INTERNAL)
1452 const_iv (ATNR_LIFE_STEALING) 1500 const_iv (ATNR_LIFE_STEALING)
1453 const_iv (ATNR_DISEASE) 1501 const_iv (ATNR_DISEASE)
1454 1502
1455 const_iv (MAP_FLUSH)
1456 const_iv (MAP_PLAYER_UNIQUE)
1457 const_iv (MAP_BLOCK)
1458 const_iv (MAP_STYLE)
1459 const_iv (MAP_OVERLAY)
1460
1461 const_iv (MAP_IN_MEMORY) 1503 const_iv (MAP_IN_MEMORY)
1462 const_iv (MAP_SWAPPED) 1504 const_iv (MAP_SWAPPED)
1463 const_iv (MAP_LOADING) 1505 const_iv (MAP_LOADING)
1464 const_iv (MAP_SAVING) 1506 const_iv (MAP_SAVING)
1465 1507
1478 const_iv (ST_SETUP) 1520 const_iv (ST_SETUP)
1479 const_iv (ST_PLAYING) 1521 const_iv (ST_PLAYING)
1480 const_iv (ST_CUSTOM) 1522 const_iv (ST_CUSTOM)
1481 1523
1482 const_iv (ST_CHANGE_CLASS) 1524 const_iv (ST_CHANGE_CLASS)
1483 const_iv (ST_CONFIRM_QUIT)
1484 const_iv (ST_GET_PARTY_PASSWORD)
1485 1525
1486 const_iv (IO_HEADER) 1526 const_iv (IO_HEADER)
1487 const_iv (IO_OBJECTS) 1527 const_iv (IO_OBJECTS)
1488 const_iv (IO_UNIQUES) 1528 const_iv (IO_UNIQUES)
1489 1529
1543 1583
1544void _global_reattach () 1584void _global_reattach ()
1545 CODE: 1585 CODE:
1546{ 1586{
1547 // reattach to all attachable objects in the game. 1587 // reattach to all attachable objects in the game.
1548 for (sockvec::iterator i = clients.begin (); i != clients.end (); ++i) 1588 for_all_clients (ns)
1549 (*i)->reattach (); 1589 ns->reattach ();
1550 1590
1551 for_all_players (pl) 1591 for_all_players (pl)
1552 pl->reattach (); 1592 pl->reattach ();
1553 1593
1554 //TODO 1594 //TODO
1555 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i) 1595 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i)
1556 // i->second->reattach (); 1596 // i->second->reattach ();
1557 1597
1558 for (object *op = object::first; op; op = op->next) 1598 for_all_objects (op)
1559 op->reattach (); 1599 op->reattach ();
1560} 1600}
1561 1601
1562NV floor (NV x) 1602NV floor (NV x)
1563 1603
1564NV ceil (NV x) 1604NV ceil (NV x)
1605
1606NV rndm (...)
1607 CODE:
1608 switch (items)
1609 {
1610 case 0: RETVAL = rndm (); break;
1611 case 1: RETVAL = rndm (SvUV (ST (0))); break;
1612 case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1613 default: croak ("cf::rndm requires none, one or two parameters."); break;
1614 }
1615 OUTPUT:
1616 RETVAL
1565 1617
1566void server_tick () 1618void server_tick ()
1567 CODE: 1619 CODE:
1568 runtime = SvNVx (sv_runtime); 1620 runtime = SvNVx (sv_runtime);
1569 server_tick (); 1621 server_tick ();
1616 } 1668 }
1617 OUTPUT: RETVAL 1669 OUTPUT: RETVAL
1618 1670
1619void abort () 1671void abort ()
1620 1672
1673void fork_abort (char *cause = "cf::fork_abort")
1674
1675void cleanup (const char *cause, bool make_core = false)
1676
1621void emergency_save () 1677void emergency_save ()
1622 1678
1623void _exit (int status = 0) 1679void _exit (int status = EXIT_SUCCESS)
1680
1681UV sv_2watcher (SV *w)
1682 CODE:
1683 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1684 OUTPUT:
1685 RETVAL
1624 1686
1625#if _POSIX_MEMLOCK 1687#if _POSIX_MEMLOCK
1626 1688
1627int mlockall (int flags = MCL_CURRENT | MCL_FUTURE) 1689int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1628 1690
1674 RETVAL = newSVpv (resist_plus[atnr], 0); 1736 RETVAL = newSVpv (resist_plus[atnr], 0);
1675 else 1737 else
1676 XSRETURN_UNDEF; 1738 XSRETURN_UNDEF;
1677 OUTPUT: RETVAL 1739 OUTPUT: RETVAL
1678 1740
1741bool
1742load_resource_file (const char *filename)
1743
1679MODULE = cf PACKAGE = cf::attachable 1744MODULE = cf PACKAGE = cf::attachable
1680 1745
1681int 1746int
1682valid (SV *obj) 1747valid (SV *obj)
1683 CODE: 1748 CODE:
1684 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1749 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1685 OUTPUT: 1750 OUTPUT:
1686 RETVAL 1751 RETVAL
1687 1752
1688#bool
1689#destroyed (attachable *at)
1690#
1691#void 1753void
1692#destroy (attachable *at) 1754debug_trace (attachable *obj, bool on = true)
1755 CODE:
1756 obj->flags &= ~attachable::F_DEBUG_TRACE;
1757 if (on)
1758 obj->flags |= attachable::F_DEBUG_TRACE;
1759
1760int mortals_size ()
1761 CODE:
1762 RETVAL = attachable::mortals.size ();
1763 OUTPUT: RETVAL
1764
1765#object *mortals (U32 index)
1766# CODE:
1767# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1768# OUTPUT: RETVAL
1769
1770INCLUDE: $PERL $srcdir/genacc attachable ../include/cfperl.h |
1693 1771
1694MODULE = cf PACKAGE = cf::global 1772MODULE = cf PACKAGE = cf::global
1695 1773
1696int invoke (SV *klass, int event, ...) 1774int invoke (SV *klass, int event, ...)
1697 CODE: 1775 CODE:
1701 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END); 1779 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END);
1702 OUTPUT: RETVAL 1780 OUTPUT: RETVAL
1703 1781
1704MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ 1782MODULE = cf PACKAGE = cf::object PREFIX = cf_object_
1705 1783
1706INCLUDE: $PERL genacc object ../include/object.h | 1784INCLUDE: $PERL $srcdir/genacc object ../include/object.h |
1707 1785
1708int invoke (object *op, int event, ...) 1786int invoke (object *op, int event, ...)
1709 CODE: 1787 CODE:
1710 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT"); 1788 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT");
1711 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 1789 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1713 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); 1791 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1714 OUTPUT: RETVAL 1792 OUTPUT: RETVAL
1715 1793
1716SV *registry (object *op) 1794SV *registry (object *op)
1717 1795
1718void mortals () 1796int objects_size ()
1719 PPCODE: 1797 CODE:
1720 EXTEND (SP, object::mortals.size ());
1721 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1722 PUSHs (to_sv (*i));
1723
1724object *first ()
1725 CODE:
1726 RETVAL = object::first; 1798 RETVAL = objects.size ();
1799 OUTPUT: RETVAL
1800
1801object *objects (U32 index)
1802 CODE:
1803 RETVAL = index < objects.size () ? objects [index] : 0;
1804 OUTPUT: RETVAL
1805
1806int actives_size ()
1807 CODE:
1808 RETVAL = actives.size ();
1809 OUTPUT: RETVAL
1810
1811object *actives (U32 index)
1812 CODE:
1813 RETVAL = index < actives.size () ? actives [index] : 0;
1727 OUTPUT: RETVAL 1814 OUTPUT: RETVAL
1728 1815
1729# missing properties 1816# missing properties
1730 1817
1731object *head (object *op) 1818object *head (object *op)
1732 PROTOTYPE: $ 1819 PROTOTYPE: $
1733 CODE: 1820 CODE:
1734 RETVAL = op->head ? op->head : op; 1821 RETVAL = op->head_ ();
1735 OUTPUT: RETVAL 1822 OUTPUT: RETVAL
1736 1823
1737int is_head (object *op) 1824int is_head (object *op)
1738 PROTOTYPE: $ 1825 PROTOTYPE: $
1739 CODE: 1826 CODE:
1740 RETVAL = !op->head; 1827 RETVAL = op->head_ () == op;
1741 OUTPUT: RETVAL 1828 OUTPUT: RETVAL
1742 1829
1743void 1830void
1744inv (object *obj) 1831inv (object *obj)
1745 PROTOTYPE: $ 1832 PROTOTYPE: $
1753void 1840void
1754set_animation (object *op, int idx) 1841set_animation (object *op, int idx)
1755 CODE: 1842 CODE:
1756 SET_ANIMATION (op, idx); 1843 SET_ANIMATION (op, idx);
1757 1844
1845int
1846num_animations (object *op)
1847 CODE:
1848 RETVAL = NUM_ANIMATIONS (op);
1849 OUTPUT: RETVAL
1850
1758object *find_best_object_match (object *op, const char *match) 1851object *find_best_object_match (object *op, const char *match)
1759 1852
1760object *find_marked_object (object *op) 1853object *find_marked_object (object *op)
1761 1854
1762int need_identify (object *obj); 1855int need_identify (object *obj);
1763 1856
1764int apply_shop_mat (object *shop_mat, object *op); 1857int apply_shop_mat (object *shop_mat, object *op);
1858
1859int move_player (object *op, int dir)
1860 CODE:
1861 RETVAL = move_player (op, dir);
1862 OUTPUT:
1863 RETVAL
1765 1864
1766int move (object *op, int dir, object *originator = op) 1865int move (object *op, int dir, object *originator = op)
1767 CODE: 1866 CODE:
1768 RETVAL = move_ob (op, dir, originator); 1867 RETVAL = move_ob (op, dir, originator);
1769 OUTPUT: 1868 OUTPUT:
1774 manual_apply (applied, applier, flags); 1873 manual_apply (applied, applier, flags);
1775 1874
1776void apply_below (object *op) 1875void apply_below (object *op)
1777 CODE: 1876 CODE:
1778 player_apply_below (op); 1877 player_apply_below (op);
1878
1879int cast_heal (object *op, object *caster, object *spell, int dir = 0)
1779 1880
1780object *cf_object_present_archname_inside (object *op, char *whatstr) 1881object *cf_object_present_archname_inside (object *op, char *whatstr)
1781 1882
1782int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0) 1883int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0)
1783 1884
1836 1937
1837void drop (object *who, object *op) 1938void drop (object *who, object *op)
1838 1939
1839void pick_up (object *who, object *op) 1940void pick_up (object *who, object *op)
1840 1941
1841object *cf_object_insert_object (object *op, object *container)
1842
1843object *cf_object_insert_in_ob (object *ob, object *where)
1844
1845int cf_object_teleport (object *op, maptile *map, int x, int y) 1942int cf_object_teleport (object *op, maptile *map, int x, int y)
1846 1943
1847void update_object (object *op, int action) 1944void update_object (object *op, int action)
1848 1945
1849object *cf_create_object_by_name (const char *name) 1946object *cf_create_object_by_name (const char *name)
1968void esrv_update_item (object *op, int what, object *item) 2065void esrv_update_item (object *op, int what, object *item)
1969 C_ARGS: what, op, item 2066 C_ARGS: what, op, item
1970 2067
1971void clear_los (object *op) 2068void clear_los (object *op)
1972 2069
1973int command_teleport (object *op, char *params)
1974
1975int command_summon (object *op, char *params) 2070int command_summon (object *op, char *params)
1976 2071
1977int command_arrest (object *op, char *params) 2072int command_arrest (object *op, char *params)
1978 2073
1979int command_kick (object *op, char *params)
1980
1981int command_banish (object *op, char *params) 2074int command_banish (object *op, char *params)
1982 2075
1983 2076
1984MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ 2077MODULE = cf PACKAGE = cf::player PREFIX = cf_player_
1985 2078
1986INCLUDE: $PERL genacc player ../include/player.h | 2079INCLUDE: $PERL $srcdir/genacc player ../include/player.h |
1987 2080
1988int invoke (player *pl, int event, ...) 2081int invoke (player *pl, int event, ...)
1989 CODE: 2082 CODE:
1990 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER"); 2083 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER");
1991 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 2084 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2001 pl->ob->stats.hp = pl->ob->stats.maxhp; 2094 pl->ob->stats.hp = pl->ob->stats.maxhp;
2002 pl->ob->stats.sp = pl->ob->stats.maxsp; 2095 pl->ob->stats.sp = pl->ob->stats.maxsp;
2003 pl->ob->stats.grace = pl->ob->stats.maxgrace; 2096 pl->ob->stats.grace = pl->ob->stats.maxgrace;
2004 pl->orig_stats = pl->ob->stats; 2097 pl->orig_stats = pl->ob->stats;
2005 2098
2006player *cf_player_find (char *name)
2007 PROTOTYPE: $
2008
2009void cf_player_move (player *pl, int dir) 2099void cf_player_move (player *pl, int dir)
2010 2100
2011void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0); 2101void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
2012
2013player *first ()
2014 CODE:
2015 RETVAL = first_player;
2016 OUTPUT: RETVAL
2017 2102
2018bool 2103bool
2019cell_visible (player *pl, int dx, int dy) 2104cell_visible (player *pl, int dx, int dy)
2020 CODE: 2105 CODE:
2021 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2 2106 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2058 if (y) sv_to (y, pl->bed_y); 2143 if (y) sv_to (y, pl->bed_y);
2059 2144
2060void 2145void
2061list () 2146list ()
2062 PPCODE: 2147 PPCODE:
2063 for (player *pl = first_player; pl; pl = pl->next) 2148 for_all_players (pl)
2064 XPUSHs (sv_2mortal (to_sv (pl))); 2149 XPUSHs (sv_2mortal (to_sv (pl)));
2065
2066bool
2067peaceful (player *pl, bool new_setting = 0)
2068 PROTOTYPE: $;$
2069 CODE:
2070 RETVAL = pl->peaceful;
2071 if (items > 1)
2072 pl->peaceful = new_setting;
2073 OUTPUT:
2074 RETVAL
2075
2076living *
2077orig_stats (player *pl)
2078 CODE:
2079 RETVAL = &pl->orig_stats;
2080 OUTPUT: RETVAL
2081
2082living *
2083last_stats (player *pl)
2084 CODE:
2085 RETVAL = &pl->last_stats;
2086 OUTPUT: RETVAL
2087 2150
2088 2151
2089MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 2152MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2090 2153
2091int invoke (maptile *map, int event, ...) 2154int invoke (maptile *map, int event, ...)
2096 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END); 2159 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END);
2097 OUTPUT: RETVAL 2160 OUTPUT: RETVAL
2098 2161
2099SV *registry (maptile *map) 2162SV *registry (maptile *map)
2100 2163
2101INCLUDE: $PERL genacc maptile ../include/map.h | 2164INCLUDE: $PERL $srcdir/genacc maptile ../include/map.h |
2102 2165
2103void 2166void
2104maptile::instantiate () 2167maptile::instantiate ()
2105 2168
2106maptile *new () 2169maptile *new ()
2107 PROTOTYPE: 2170 PROTOTYPE:
2108 CODE: 2171 CODE:
2109 RETVAL = new maptile; 2172 RETVAL = new maptile;
2110 OUTPUT: 2173 OUTPUT:
2111 RETVAL 2174 RETVAL
2112
2113void
2114maptile::destroy ()
2115 2175
2116void 2176void
2117maptile::players () 2177maptile::players ()
2118 PPCODE: 2178 PPCODE:
2119 if (GIMME_V == G_SCALAR) 2179 if (GIMME_V == G_SCALAR)
2124 for_all_players (pl) 2184 for_all_players (pl)
2125 if (pl->ob && pl->ob->map == THIS) 2185 if (pl->ob && pl->ob->map == THIS)
2126 PUSHs (sv_2mortal (to_sv (pl->ob))); 2186 PUSHs (sv_2mortal (to_sv (pl->ob)));
2127 } 2187 }
2128 2188
2189void
2190maptile::add_underlay (SV *data, int offset, int stride, SV *palette)
2191 CODE:
2192{
2193 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2194 croak ("maptile::add_underlay: palette must be arrayref");
2195
2196 palette = SvRV (palette);
2197
2198 STRLEN idxlen;
2199 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2200
2201 for (int x = 0; x < THIS->width; ++x)
2202 for (int y = 0; y < THIS->height; ++y)
2203 {
2204 for (object *op = THIS->at (x, y).bot; op; op = op->above)
2205 if (op->flag [FLAG_IS_FLOOR])
2206 goto skip_space;
2207
2208 {
2209 int offs = offset + y * stride + x;
2210 if (IN_RANGE_EXC (offs, 0, idxlen))
2211 {
2212 if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0))
2213 {
2214 object *ob = get_archetype (SvPVutf8_nolen (*elem));
2215 ob->flag [FLAG_NO_MAP_SAVE] = true;
2216 THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY);
2217 }
2218 }
2219 }
2220
2221 skip_space: ;
2222 }
2223}
2224
2225void
2226maptile::set_regiondata (SV *data, int offset, int stride, SV *palette)
2227 CODE:
2228{
2229 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2230 croak ("maptile::set_regiondata: palette must be arrayref");
2231
2232 palette = SvRV (palette);
2233
2234 STRLEN idxlen;
2235 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2236
2237 region **regionmap = (region **)malloc (
2238 (av_len ((AV *)palette) + 1) * sizeof (region *));
2239 uint8_t *regions = salloc<uint8_t> (THIS->size ());
2240
2241 for (int i = av_len ((AV *)palette) + 1; i--; )
2242 regionmap [i] = region::find (
2243 SvPVutf8_nolen (*av_fetch ((AV *)palette, i, 1)));
2244
2245 for (int y = 0; y < THIS->height; ++y)
2246 memcpy (regions + y * THIS->width, idx + offset + y * stride, THIS->width);
2247
2248 sfree (THIS->regions, THIS->size ());
2249 free (THIS->regionmap);
2250
2251 THIS->regions = regions;
2252 THIS->regionmap = regionmap;
2253}
2254
2129void play_sound_map (maptile *map, int x, int y, int sound_num) 2255void play_sound_map (maptile *map, int x, int y, int sound_num)
2130 2256
2131int out_of_map (maptile *map, int x, int y) 2257int out_of_map (maptile *map, int x, int y)
2132 2258
2133void 2259void
2149 2275
2150object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny) 2276object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny)
2151 C_ARGS: str, map, nx, ny 2277 C_ARGS: str, map, nx, ny
2152 2278
2153void 2279void
2154cf_map_normalise (maptile *map, int x, int y) 2280get_map_flags (maptile *map, int x, int y)
2155 PPCODE: 2281 PPCODE:
2156{ 2282{
2157 maptile *nmap = 0; 2283 maptile *nmap = 0;
2158 I16 nx = 0, ny = 0; 2284 I16 nx = 0, ny = 0;
2159 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny); 2285 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny);
2214 2340
2215void fix_walls (maptile *map, int x, int y) 2341void fix_walls (maptile *map, int x, int y)
2216 2342
2217void fix_walls_around (maptile *map, int x, int y) 2343void fix_walls_around (maptile *map, int x, int y)
2218 2344
2219const char *
2220region_name (maptile *m)
2221 CODE:
2222 RETVAL = get_name_of_region_for_map (m);
2223 OUTPUT: RETVAL
2224
2225# worst xs function of my life 2345# worst xs function of my life
2226maptile * 2346bool
2227_create_random_map (\ 2347_create_random_map (\
2228 char *path,\ 2348 maptile *self,\
2229 char *wallstyle,\ 2349 char *wallstyle,\
2230 char *wall_name,\ 2350 char *wall_name,\
2231 char *floorstyle,\ 2351 char *floorstyle,\
2232 char *monsterstyle,\ 2352 char *monsterstyle,\
2233 char *treasurestyle,\ 2353 char *treasurestyle,\
2237 char *origin_map,\ 2357 char *origin_map,\
2238 char *final_map,\ 2358 char *final_map,\
2239 char *exitstyle,\ 2359 char *exitstyle,\
2240 char *this_map,\ 2360 char *this_map,\
2241 char *exit_on_final_map,\ 2361 char *exit_on_final_map,\
2242 int Xsize,\ 2362 int xsize,\
2243 int Ysize,\ 2363 int ysize,\
2244 int expand2x,\ 2364 int expand2x,\
2245 int layoutoptions1,\ 2365 int layoutoptions1,\
2246 int layoutoptions2,\ 2366 int layoutoptions2,\
2247 int layoutoptions3,\ 2367 int layoutoptions3,\
2248 int symmetry,\ 2368 int symmetry,\
2253 int dungeon_depth,\ 2373 int dungeon_depth,\
2254 int decoroptions,\ 2374 int decoroptions,\
2255 int orientation,\ 2375 int orientation,\
2256 int origin_y,\ 2376 int origin_y,\
2257 int origin_x,\ 2377 int origin_x,\
2258 int random_seed,\ 2378 U32 random_seed,\
2259 val64 total_map_hp,\ 2379 val64 total_map_hp,\
2260 int map_layout_style,\ 2380 int map_layout_style,\
2261 int treasureoptions,\ 2381 int treasureoptions,\
2262 int symmetry_used,\ 2382 int symmetry_used,\
2263 region *region\ 2383 region *region,\
2384 char *custom\
2264) 2385)
2265 CODE: 2386 CODE:
2266{ 2387{
2267 random_map_params rmp; 2388 random_map_params rmp;
2268 2389
2278 assign (rmp.exit_on_final_map, exit_on_final_map); 2399 assign (rmp.exit_on_final_map, exit_on_final_map);
2279 2400
2280 rmp.origin_map = origin_map; 2401 rmp.origin_map = origin_map;
2281 rmp.final_map = final_map; 2402 rmp.final_map = final_map;
2282 rmp.this_map = this_map; 2403 rmp.this_map = this_map;
2283 rmp.Xsize = Xsize; 2404 rmp.xsize = xsize;
2284 rmp.Ysize = Ysize; 2405 rmp.ysize = ysize;
2285 rmp.expand2x = expand2x; 2406 rmp.expand2x = expand2x;
2286 rmp.layoutoptions1 = layoutoptions1; 2407 rmp.layoutoptions1 = layoutoptions1;
2287 rmp.layoutoptions2 = layoutoptions2; 2408 rmp.layoutoptions2 = layoutoptions2;
2288 rmp.layoutoptions3 = layoutoptions3; 2409 rmp.layoutoptions3 = layoutoptions3;
2289 rmp.symmetry = symmetry; 2410 rmp.symmetry = symmetry;
2300 rmp.total_map_hp = total_map_hp; 2421 rmp.total_map_hp = total_map_hp;
2301 rmp.map_layout_style = map_layout_style; 2422 rmp.map_layout_style = map_layout_style;
2302 rmp.treasureoptions = treasureoptions; 2423 rmp.treasureoptions = treasureoptions;
2303 rmp.symmetry_used = symmetry_used; 2424 rmp.symmetry_used = symmetry_used;
2304 rmp.region = region; 2425 rmp.region = region;
2426 rmp.custom = custom;
2305 2427
2306 RETVAL = generate_random_map (path, &rmp); 2428 RETVAL = self->generate_random_map (&rmp);
2307} 2429}
2308 OUTPUT: 2430 OUTPUT:
2309 RETVAL 2431 RETVAL
2310 2432
2311MODULE = cf PACKAGE = cf::arch 2433MODULE = cf PACKAGE = cf::arch
2320 PROTOTYPE: 2442 PROTOTYPE:
2321 CODE: 2443 CODE:
2322 RETVAL = first_archetype; 2444 RETVAL = first_archetype;
2323 OUTPUT: RETVAL 2445 OUTPUT: RETVAL
2324 2446
2325INCLUDE: $PERL genacc archetype ../include/object.h | 2447INCLUDE: $PERL $srcdir/genacc archetype ../include/object.h |
2326 2448
2327MODULE = cf PACKAGE = cf::party 2449MODULE = cf PACKAGE = cf::party
2328 2450
2329partylist *first () 2451partylist *first ()
2330 PROTOTYPE: 2452 PROTOTYPE:
2331 CODE: 2453 CODE:
2332 RETVAL = get_firstparty (); 2454 RETVAL = get_firstparty ();
2333 OUTPUT: RETVAL 2455 OUTPUT: RETVAL
2334 2456
2335INCLUDE: $PERL genacc partylist ../include/player.h | 2457INCLUDE: $PERL $srcdir/genacc partylist ../include/player.h |
2336 2458
2337MODULE = cf PACKAGE = cf::region 2459MODULE = cf PACKAGE = cf::region
2338 2460
2339region *first () 2461void
2340 PROTOTYPE: 2462list ()
2341 CODE: 2463 PPCODE:
2342 RETVAL = first_region; 2464 for_all_regions (rgn)
2343 OUTPUT: RETVAL 2465 XPUSHs (sv_2mortal (to_sv (rgn)));
2344 2466
2345region *find (char *name) 2467region *find (char *name)
2346 PROTOTYPE: $ 2468 PROTOTYPE: $
2347 CODE: 2469 CODE:
2348 RETVAL = get_region_by_name (name); 2470 RETVAL = region::find (name);
2349 OUTPUT: RETVAL 2471 OUTPUT: RETVAL
2350 2472
2473region *find_fuzzy (char *name)
2474 PROTOTYPE: $
2475 CODE:
2476 RETVAL = region::find_fuzzy (name);
2477 OUTPUT: RETVAL
2478
2351INCLUDE: $PERL genacc region ../include/map.h | 2479INCLUDE: $PERL $srcdir/genacc region ../include/map.h |
2352 2480
2353MODULE = cf PACKAGE = cf::living 2481MODULE = cf PACKAGE = cf::living
2354 2482
2355INCLUDE: $PERL genacc living ../include/living.h | 2483INCLUDE: $PERL $srcdir/genacc living ../include/living.h |
2356 2484
2357MODULE = cf PACKAGE = cf::settings 2485MODULE = cf PACKAGE = cf::settings
2358 2486
2359INCLUDE: $PERL genacc Settings ../include/global.h | 2487INCLUDE: $PERL $srcdir/genacc Settings ../include/global.h |
2360 2488
2361MODULE = cf PACKAGE = cf::client 2489MODULE = cf PACKAGE = cf::client
2362 2490
2363INCLUDE: $PERL genacc client ../include/client.h | 2491INCLUDE: $PERL $srcdir/genacc client ../include/client.h |
2364 2492
2365int invoke (client *ns, int event, ...) 2493int invoke (client *ns, int event, ...)
2366 CODE: 2494 CODE:
2367 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT"); 2495 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT");
2368 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 2496 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2387 char *buf = SvPVbyte (packet, len); 2515 char *buf = SvPVbyte (packet, len);
2388 2516
2389 THIS->send_packet (buf, len); 2517 THIS->send_packet (buf, len);
2390} 2518}
2391 2519
2392void
2393client::destroy ()
2394

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines