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.129 by root, Sun Jan 7 21:54:59 2007 UTC vs.
Revision 1.177 by root, Wed Mar 14 00:04:59 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
101 102
102unordered_vector<attachable *> attachable::mortals; 103unordered_vector<attachable *> attachable::mortals;
103 104
104attachable::~attachable () 105attachable::~attachable ()
105{ 106{
106 assert (!(flags & F_BORROWED)); 107 flags |=0x3300;//D
108 assert (!self);
109 assert (!cb);
107} 110}
108 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
109void attachable::optimise () 138attachable::optimise ()
110{ 139{
111 if (self 140 if (self
112 && SvREFCNT (self) == 1 141 && SvREFCNT (self) == 1
113 && !HvTOTALKEYS (self)) 142 && !HvTOTALKEYS (self))
143 flags |= 0x40,//D
144 sever_self ();
145}
146
147// check wether the object really is dead
148void
149attachable::do_check ()
150{
151 if (refcnt_cnt () > 0)
152 return;
153
154 destroy ();
155}
156
157void
158attachable::do_destroy ()
159{
160 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
161
162 if (cb)
114 { 163 {
115 flags &= ~F_BORROWED;
116 refcnt_inc ();
117 SvREFCNT_dec ((SV *)self); 164 SvREFCNT_dec (cb);
165 cb = 0;
118 } 166 }
119}
120
121// check wether the object really is dead
122void
123attachable::do_check ()
124{
125 if (refcnt > 0)
126 return;
127
128 optimise ();
129 167
130 if (self) 168 if (self)
131 { 169 sever_self ();
132 if (refcnt + SvREFCNT (self) > 0)
133 return;
134 170
135 assert (flags & F_BORROWED); 171 flags |= 0x20; //D
136
137 flags &= ~F_BORROWED;
138 refcnt_inc ();
139 SvREFCNT_dec (self);
140 self = 0;
141 }
142
143 if (refcnt > 0)
144 return;
145
146 destroy ();
147}
148
149void
150attachable::do_destroy ()
151{
152 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
153
154 if (self)
155 hv_clear (self);
156
157 mortals.push_back (this); 172 mortals.push_back (this);
158} 173}
159 174
160void 175void
161attachable::destroy () 176attachable::destroy ()
165 180
166 flags |= F_DESTROYED; 181 flags |= F_DESTROYED;
167 do_destroy (); 182 do_destroy ();
168} 183}
169 184
185void
170void attachable::check_mortals () 186attachable::check_mortals ()
171{ 187{
172 for (int i = 0; i < mortals.size (); ) 188 static int i = 0;
189
190 for (;;)
173 { 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
174 attachable *obj = mortals [i]; 202 attachable *obj = mortals [i];
175 203
176 obj->refcnt_chk (); // unborrow from perl, if necessary 204 obj->refcnt_chk (); // unborrow from perl, if necessary
177 205
206 //if (obj->refcnt > 0 || obj->self)
178 if (obj->refcnt || obj->self) 207 if (obj->refcnt || obj->self)
179 { 208 {
180#if 0 209//printf ("%p rc %d\n", obj, obj->refcnt_cnt ());//D
181 if (mortals.size() > 5)fprintf (stderr, "%d delaying %d:%p:%s %d (self %p:%d)\n", time(0),i, obj, typeid (*obj).name (),
182 obj->refcnt, obj->self, obj->self ? SvREFCNT(obj->self): - 1);//D
183#endif
184
185 ++i; // further delay freeing 210 ++i; // further delay freeing
211
212 if (!(i & 0x3ff))
213 break;
186 }//D 214 }
187 else 215 else
188 { 216 {
189 //Dfprintf (stderr, "deleteing %d:%p:%s\n", i, obj,typeid (*obj).name ());//D
190 mortals.erase (i); 217 mortals.erase (i);
191 delete obj; 218 delete obj;
192 } 219 }
193 } 220 }
194} 221}
219 246
220static int 247static int
221attachable_free (pTHX_ SV *sv, MAGIC *mg) 248attachable_free (pTHX_ SV *sv, MAGIC *mg)
222{ 249{
223 attachable *at = (attachable *)mg->mg_ptr; 250 attachable *at = (attachable *)mg->mg_ptr;
224 assert (!(at->flags & attachable::F_BORROWED)); 251
252 //TODO: check if transaction behaviour is really required here
253 if (SV *self = (SV *)at->self)
254 {
225 at->self = 0; 255 at->self = 0;
256 SvREFCNT_dec (self);
257 }
258
226 // 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
227 //at->refcnt_chk (); 260 //at->refcnt_chk ();
228 return 0; 261 return 0;
229} 262}
230 263
238 271
239 if (!obj->self) 272 if (!obj->self)
240 { 273 {
241 obj->self = newHV (); 274 obj->self = newHV ();
242 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);
243 276 obj->flags |= (obj->flags & 0xc0) << 8;
244 // borrow the refcnt from the object 277 obj->flags &= ~0xc0;//D
245 obj->flags |= attachable::F_BORROWED; 278 obj->flags |= 0x10;//D
246 obj->refcnt_dec ();
247 279
248 // now bless the object _once_ 280 // now bless the object _once_
249 return sv_bless (newRV_inc ((SV *)obj->self), stash); 281 return sv_bless (newRV_inc ((SV *)obj->self), stash);
250 } 282 }
251 else 283 else
284 {
252 return newRV_inc ((SV *)obj->self); 285 SV *sv = newRV_inc ((SV *)obj->self);
286
287 if (Gv_AMG (stash)) // handle overload correctly, as the perl core does not
288 SvAMAGIC_on (sv);
289
290 return sv;
291 }
253} 292}
254 293
255static void 294static void
256clearSVptr (SV *sv) 295clearSVptr (SV *sv)
257{ 296{
310inline 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); }
311 350
312inline SV *to_sv (object & v) { return to_sv (&v); } 351inline SV *to_sv (object & v) { return to_sv (&v); }
313inline SV *to_sv (living & v) { return to_sv (&v); } 352inline SV *to_sv (living & v) { return to_sv (&v); }
314 353
315//TODO:
316inline SV *to_sv (New_Face * v) { return to_sv (v->name); } 354//inline SV *to_sv (faceinfo * v) { return to_sv (v->name); }
317inline SV *to_sv (treasurelist * v) { return to_sv (v->name); } 355inline SV *to_sv (treasurelist * v) { return to_sv (v->name); }
356inline SV *to_sv (std::string & v) { return newSVpvn (v.data (), v.size ()); }
318 357
319inline SV *to_sv (UUID v) 358inline SV *to_sv (UUID v)
320{ 359{
321 char buf[128]; 360 char buf[128];
322 snprintf (buf, 128, "<1,%" PRIx64 ">", v.seq); 361 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq);
323 return newSVpv (buf, 0); 362 return newSVpv (buf, 0);
324} 363}
325 364
326inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } 365inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; }
327inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } 366inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
346inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } 385inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
347inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 386inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
348inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 387inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
349inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 388inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
350 389
351inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } //TODO 390//inline void sv_to (SV *sv, faceinfo * &v) { v = &faces [face_find (SvPV_nolen (sv), 0)]; }
352inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); } // TODO 391inline void sv_to (SV *sv, treasurelist * &v) { v = find_treasurelist (SvPV_nolen (sv)); }
353 392
354template<class T> 393template<class T>
355inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; } 394inline void sv_to (SV *sv, refptr<T> &v) { T *tmp; sv_to (sv, tmp); v = tmp; }
356 395
357template<int N> 396template<int N>
360inline void sv_to (SV *sv, rangetype &v) { v = (rangetype) SvIV (sv); } 399inline void sv_to (SV *sv, rangetype &v) { v = (rangetype) SvIV (sv); }
361inline void sv_to (SV *sv, bowtype_t &v) { v = (bowtype_t) SvIV (sv); } 400inline void sv_to (SV *sv, bowtype_t &v) { v = (bowtype_t) SvIV (sv); }
362inline void sv_to (SV *sv, petmode_t &v) { v = (petmode_t) SvIV (sv); } 401inline void sv_to (SV *sv, petmode_t &v) { v = (petmode_t) SvIV (sv); }
363inline void sv_to (SV *sv, usekeytype &v) { v = (usekeytype) SvIV (sv); } 402inline void sv_to (SV *sv, usekeytype &v) { v = (usekeytype) SvIV (sv); }
364inline void sv_to (SV *sv, unapplymode &v) { v = (unapplymode) SvIV (sv); } 403inline void sv_to (SV *sv, unapplymode &v) { v = (unapplymode) SvIV (sv); }
404
405inline void sv_to (SV *sv, std::string &v)
406{
407 STRLEN len;
408 char *data = SvPVbyte (sv, len);
409 v.assign (data, len);
410}
365 411
366inline void sv_to (SV *sv, UUID &v) 412inline void sv_to (SV *sv, UUID &v)
367{ 413{
368 unsigned int version; 414 unsigned int version;
369 415
493 if (!ext->cb) 539 if (!ext->cb)
494 ext->cb = newAV (); 540 ext->cb = newAV ();
495 541
496 return newRV_inc ((SV *)ext->cb); 542 return newRV_inc ((SV *)ext->cb);
497} 543}
498
499#if 0
500void attachable::clear ()
501{
502 if (self)
503 {
504 // disconnect Perl from C, to avoid crashes
505 sv_unmagic (SvRV ((SV *)self), PERL_MAGIC_ext);
506
507 // clear the perl hash, might or might not be a good idea
508 hv_clear ((HV *)SvRV ((SV *)self));
509
510 SvREFCNT_dec (self);
511 self = 0;
512 }
513
514 if (cb)
515 {
516 SvREFCNT_dec (cb);
517 cb = 0;
518 }
519
520 attach = 0;
521}
522#endif
523 544
524///////////////////////////////////////////////////////////////////////////// 545/////////////////////////////////////////////////////////////////////////////
525 546
526extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) 547extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
527{ 548{
599 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl)) 620 if (perl_parse (perl, xs_init, 2, argv, (char **)NULL) || perl_run (perl))
600 { 621 {
601 printf ("unable to initialize perl-interpreter, aborting.\n"); 622 printf ("unable to initialize perl-interpreter, aborting.\n");
602 exit (EXIT_FAILURE); 623 exit (EXIT_FAILURE);
603 } 624 }
625
626 {
627 dSP;
628
629 PUSHMARK (SP);
630 PUTBACK;
631 call_pv ("cf::init", G_DISCARD | G_VOID);
632 }
604} 633}
605 634
606void cfperl_main () 635void cfperl_main ()
607{ 636{
608 dSP; 637 dSP;
822} 851}
823 852
824///////////////////////////////////////////////////////////////////////////// 853/////////////////////////////////////////////////////////////////////////////
825 854
826void 855void
827maptile::emergency_save () 856cfperl_emergency_save ()
828{ 857{
829 CALL_BEGIN (0); 858 CALL_BEGIN (0);
830 CALL_CALL ("cf::map::emergency_save", G_VOID); 859 CALL_CALL ("cf::emergency_save", G_VOID);
860 CALL_END;
861}
862
863void
864cfperl_cleanup (int make_core)
865{
866 CALL_BEGIN (1);
867 CALL_ARG (make_core);
868 CALL_CALL ("cf::post_cleanup", G_VOID);
831 CALL_END; 869 CALL_END;
832} 870}
833 871
834maptile * 872maptile *
835maptile::find_sync (const char *path, maptile *origin) 873maptile::find_sync (const char *path, maptile *origin)
836{ 874{
837 CALL_BEGIN (2); 875 CALL_BEGIN (2);
838 CALL_ARG (path); 876 CALL_ARG (path);
839 CALL_ARG (origin); 877 CALL_ARG (origin);
840 CALL_CALL ("cf::map::find_sync", G_SCALAR); 878 CALL_CALL ("cf::map::find_sync", G_SCALAR);
879
880 maptile *retval;
881
882 if (count)
883 sv_to (POPs, retval);
884 else
885 retval = 0;
886
887 CALL_END;
888
889 return retval;
890}
891
892maptile *
893maptile::find_async (const char *path, maptile *origin)
894{
895 CALL_BEGIN (2);
896 CALL_ARG (path);
897 CALL_ARG (origin);
898 CALL_CALL ("cf::map::find_async", G_SCALAR);
841 899
842 maptile *retval; 900 maptile *retval;
843 901
844 if (count) 902 if (count)
845 sv_to (POPs, retval); 903 sv_to (POPs, retval);
898void 956void
899iw::alloc () 957iw::alloc ()
900{ 958{
901 pe = GEventAPI->new_idle (0, 0); 959 pe = GEventAPI->new_idle (0, 0);
902 960
961 WaREENTRANT_off (pe);
903 pe->base.callback = (void *)iw_dispatch; 962 pe->base.callback = (void *)iw_dispatch;
904 pe->base.ext_data = (void *)this; 963 pe->base.ext_data = (void *)this;
905} 964}
906 965
907static void iow_dispatch (pe_event *ev) 966static void iow_dispatch (pe_event *ev)
913void 972void
914iow::alloc () 973iow::alloc ()
915{ 974{
916 pe = GEventAPI->new_io (0, 0); 975 pe = GEventAPI->new_io (0, 0);
917 976
977 WaREENTRANT_off (pe);
918 pe->base.callback = (void *)iow_dispatch; 978 pe->base.callback = (void *)iow_dispatch;
919 pe->base.ext_data = (void *)this; 979 pe->base.ext_data = (void *)this;
920 980
921 pe->fd = -1; 981 pe->fd = -1;
922 pe->poll = 0; 982 pe->poll = 0;
1250 const_iv (FLAG_ACTIVATE_ON_RELEASE) 1310 const_iv (FLAG_ACTIVATE_ON_RELEASE)
1251 const_iv (FLAG_IS_WATER) 1311 const_iv (FLAG_IS_WATER)
1252 const_iv (FLAG_CONTENT_ON_GEN) 1312 const_iv (FLAG_CONTENT_ON_GEN)
1253 const_iv (FLAG_IS_A_TEMPLATE) 1313 const_iv (FLAG_IS_A_TEMPLATE)
1254 const_iv (FLAG_IS_BUILDABLE) 1314 const_iv (FLAG_IS_BUILDABLE)
1315 const_iv (FLAG_DESTROY_ON_DEATH)
1316 const_iv (FLAG_NO_MAP_SAVE)
1255 1317
1256 const_iv (NDI_BLACK) 1318 const_iv (NDI_BLACK)
1257 const_iv (NDI_WHITE) 1319 const_iv (NDI_WHITE)
1258 const_iv (NDI_NAVY) 1320 const_iv (NDI_NAVY)
1259 const_iv (NDI_RED) 1321 const_iv (NDI_RED)
1444 const_iv (ATNR_BLIND) 1506 const_iv (ATNR_BLIND)
1445 const_iv (ATNR_INTERNAL) 1507 const_iv (ATNR_INTERNAL)
1446 const_iv (ATNR_LIFE_STEALING) 1508 const_iv (ATNR_LIFE_STEALING)
1447 const_iv (ATNR_DISEASE) 1509 const_iv (ATNR_DISEASE)
1448 1510
1449 const_iv (MAP_FLUSH)
1450 const_iv (MAP_PLAYER_UNIQUE)
1451 const_iv (MAP_BLOCK)
1452 const_iv (MAP_STYLE)
1453 const_iv (MAP_OVERLAY)
1454
1455 const_iv (MAP_IN_MEMORY) 1511 const_iv (MAP_IN_MEMORY)
1456 const_iv (MAP_SWAPPED) 1512 const_iv (MAP_SWAPPED)
1457 const_iv (MAP_LOADING) 1513 const_iv (MAP_LOADING)
1458 const_iv (MAP_SAVING) 1514 const_iv (MAP_SAVING)
1459 1515
1538{ 1594{
1539 // reattach to all attachable objects in the game. 1595 // reattach to all attachable objects in the game.
1540 for_all_clients (ns) 1596 for_all_clients (ns)
1541 ns->reattach (); 1597 ns->reattach ();
1542 1598
1543 for_all_players (pl)
1544 pl->reattach ();
1545
1546 //TODO
1547 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i)
1548 // i->second->reattach ();
1549
1550 for_all_objects (op) 1599 for_all_objects (op)
1551 op->reattach (); 1600 op->reattach ();
1552} 1601}
1553 1602
1554NV floor (NV x) 1603NV floor (NV x)
1555 1604
1556NV ceil (NV x) 1605NV ceil (NV x)
1606
1607NV rndm (...)
1608 CODE:
1609 switch (items)
1610 {
1611 case 0: RETVAL = rndm (); break;
1612 case 1: RETVAL = rndm (SvUV (ST (0))); break;
1613 case 2: RETVAL = rndm (SvIV (ST (0)), SvIV (ST (1))); break;
1614 default: croak ("cf::rndm requires none, one or two parameters."); break;
1615 }
1616 OUTPUT:
1617 RETVAL
1557 1618
1558void server_tick () 1619void server_tick ()
1559 CODE: 1620 CODE:
1560 runtime = SvNVx (sv_runtime); 1621 runtime = SvNVx (sv_runtime);
1561 server_tick (); 1622 server_tick ();
1608 } 1669 }
1609 OUTPUT: RETVAL 1670 OUTPUT: RETVAL
1610 1671
1611void abort () 1672void abort ()
1612 1673
1674void fork_abort (char *cause = "cf::fork_abort")
1675
1676void cleanup (const char *cause, bool make_core = false)
1677
1613void emergency_save () 1678void emergency_save ()
1614 1679
1615void _exit (int status = 0) 1680void _exit (int status = EXIT_SUCCESS)
1681
1682UV sv_2watcher (SV *w)
1683 CODE:
1684 RETVAL = (UV)GEventAPI->sv_2watcher (w);
1685 OUTPUT:
1686 RETVAL
1616 1687
1617#if _POSIX_MEMLOCK 1688#if _POSIX_MEMLOCK
1618 1689
1619int mlockall (int flags = MCL_CURRENT | MCL_FUTURE) 1690int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1620 1691
1666 RETVAL = newSVpv (resist_plus[atnr], 0); 1737 RETVAL = newSVpv (resist_plus[atnr], 0);
1667 else 1738 else
1668 XSRETURN_UNDEF; 1739 XSRETURN_UNDEF;
1669 OUTPUT: RETVAL 1740 OUTPUT: RETVAL
1670 1741
1742bool
1743load_resource_file (const char *filename)
1744
1671MODULE = cf PACKAGE = cf::attachable 1745MODULE = cf PACKAGE = cf::attachable
1672 1746
1673int 1747int
1674valid (SV *obj) 1748valid (SV *obj)
1675 CODE: 1749 CODE:
1676 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1750 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1677 OUTPUT: 1751 OUTPUT:
1678 RETVAL 1752 RETVAL
1679 1753
1754void
1755debug_trace (attachable *obj, bool on = true)
1756 CODE:
1757 obj->flags &= ~attachable::F_DEBUG_TRACE;
1758 if (on)
1759 obj->flags |= attachable::F_DEBUG_TRACE;
1760
1761int mortals_size ()
1762 CODE:
1763 RETVAL = attachable::mortals.size ();
1764 OUTPUT: RETVAL
1765
1766#object *mortals (U32 index)
1767# CODE:
1768# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1769# OUTPUT: RETVAL
1770
1680INCLUDE: $PERL genacc attachable ../include/cfperl.h | 1771INCLUDE: $PERL $srcdir/genacc attachable ../include/cfperl.h |
1681 1772
1682MODULE = cf PACKAGE = cf::global 1773MODULE = cf PACKAGE = cf::global
1683 1774
1684int invoke (SV *klass, int event, ...) 1775int invoke (SV *klass, int event, ...)
1685 CODE: 1776 CODE:
1689 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END); 1780 RETVAL = gbl_ev.invoke ((event_type)event, ARG_AV (av), DT_END);
1690 OUTPUT: RETVAL 1781 OUTPUT: RETVAL
1691 1782
1692MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ 1783MODULE = cf PACKAGE = cf::object PREFIX = cf_object_
1693 1784
1694INCLUDE: $PERL genacc object ../include/object.h | 1785INCLUDE: $PERL $srcdir/genacc object ../include/object.h |
1695 1786
1696int invoke (object *op, int event, ...) 1787int invoke (object *op, int event, ...)
1697 CODE: 1788 CODE:
1698 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT"); 1789 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT");
1699 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 1790 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1701 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END); 1792 RETVAL = op->invoke ((event_type)event, ARG_AV (av), DT_END);
1702 OUTPUT: RETVAL 1793 OUTPUT: RETVAL
1703 1794
1704SV *registry (object *op) 1795SV *registry (object *op)
1705 1796
1706void mortals () 1797int objects_size ()
1707 PPCODE: 1798 CODE:
1708 EXTEND (SP, object::mortals.size ());
1709 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1710 PUSHs (to_sv (*i));
1711
1712object *first ()
1713 CODE:
1714 RETVAL = object::first; 1799 RETVAL = objects.size ();
1800 OUTPUT: RETVAL
1801
1802object *objects (U32 index)
1803 CODE:
1804 RETVAL = index < objects.size () ? objects [index] : 0;
1805 OUTPUT: RETVAL
1806
1807int actives_size ()
1808 CODE:
1809 RETVAL = actives.size ();
1810 OUTPUT: RETVAL
1811
1812object *actives (U32 index)
1813 CODE:
1814 RETVAL = index < actives.size () ? actives [index] : 0;
1715 OUTPUT: RETVAL 1815 OUTPUT: RETVAL
1716 1816
1717# missing properties 1817# missing properties
1718 1818
1719object *head (object *op) 1819object *head (object *op)
1720 PROTOTYPE: $ 1820 PROTOTYPE: $
1721 CODE: 1821 CODE:
1722 RETVAL = op->head ? op->head : op; 1822 RETVAL = op->head_ ();
1723 OUTPUT: RETVAL 1823 OUTPUT: RETVAL
1724 1824
1725int is_head (object *op) 1825int is_head (object *op)
1726 PROTOTYPE: $ 1826 PROTOTYPE: $
1727 CODE: 1827 CODE:
1728 RETVAL = !op->head; 1828 RETVAL = op->head_ () == op;
1729 OUTPUT: RETVAL 1829 OUTPUT: RETVAL
1730 1830
1731void 1831void
1732inv (object *obj) 1832inv (object *obj)
1733 PROTOTYPE: $ 1833 PROTOTYPE: $
1741void 1841void
1742set_animation (object *op, int idx) 1842set_animation (object *op, int idx)
1743 CODE: 1843 CODE:
1744 SET_ANIMATION (op, idx); 1844 SET_ANIMATION (op, idx);
1745 1845
1846int
1847num_animations (object *op)
1848 CODE:
1849 RETVAL = NUM_ANIMATIONS (op);
1850 OUTPUT: RETVAL
1851
1746object *find_best_object_match (object *op, const char *match) 1852object *find_best_object_match (object *op, const char *match)
1747 1853
1748object *find_marked_object (object *op) 1854object *find_marked_object (object *op)
1749 1855
1750int need_identify (object *obj); 1856int need_identify (object *obj);
1751 1857
1752int apply_shop_mat (object *shop_mat, object *op); 1858int apply_shop_mat (object *shop_mat, object *op);
1859
1860int move_player (object *op, int dir)
1861 CODE:
1862 RETVAL = move_player (op, dir);
1863 OUTPUT:
1864 RETVAL
1753 1865
1754int move (object *op, int dir, object *originator = op) 1866int move (object *op, int dir, object *originator = op)
1755 CODE: 1867 CODE:
1756 RETVAL = move_ob (op, dir, originator); 1868 RETVAL = move_ob (op, dir, originator);
1757 OUTPUT: 1869 OUTPUT:
1762 manual_apply (applied, applier, flags); 1874 manual_apply (applied, applier, flags);
1763 1875
1764void apply_below (object *op) 1876void apply_below (object *op)
1765 CODE: 1877 CODE:
1766 player_apply_below (op); 1878 player_apply_below (op);
1879
1880int cast_heal (object *op, object *caster, object *spell, int dir = 0)
1767 1881
1768object *cf_object_present_archname_inside (object *op, char *whatstr) 1882object *cf_object_present_archname_inside (object *op, char *whatstr)
1769 1883
1770int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0) 1884int cf_object_transfer (object *op, int x, int y, int r = 0, object_ornull *orig = 0)
1771 1885
1824 1938
1825void drop (object *who, object *op) 1939void drop (object *who, object *op)
1826 1940
1827void pick_up (object *who, object *op) 1941void pick_up (object *who, object *op)
1828 1942
1829object *cf_object_insert_object (object *op, object *container)
1830
1831object *cf_object_insert_in_ob (object *ob, object *where)
1832
1833int cf_object_teleport (object *op, maptile *map, int x, int y) 1943int cf_object_teleport (object *op, maptile *map, int x, int y)
1834 1944
1835void update_object (object *op, int action) 1945void update_object (object *op, int action)
1836 1946
1837object *cf_create_object_by_name (const char *name) 1947object *cf_create_object_by_name (const char *name)
1956void esrv_update_item (object *op, int what, object *item) 2066void esrv_update_item (object *op, int what, object *item)
1957 C_ARGS: what, op, item 2067 C_ARGS: what, op, item
1958 2068
1959void clear_los (object *op) 2069void clear_los (object *op)
1960 2070
1961int command_teleport (object *op, char *params)
1962
1963int command_summon (object *op, char *params) 2071int command_summon (object *op, char *params)
1964 2072
1965int command_arrest (object *op, char *params) 2073int command_arrest (object *op, char *params)
1966 2074
1967int command_kick (object *op, char *params)
1968
1969int command_banish (object *op, char *params)
1970
1971 2075
1972MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ 2076MODULE = cf PACKAGE = cf::player PREFIX = cf_player_
1973 2077
1974INCLUDE: $PERL genacc player ../include/player.h | 2078INCLUDE: $PERL $srcdir/genacc player ../include/player.h |
1975 2079
1976int invoke (player *pl, int event, ...) 2080int invoke (player *pl, int event, ...)
1977 CODE: 2081 CODE:
1978 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER"); 2082 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER");
1979 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 2083 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
1992 pl->orig_stats = pl->ob->stats; 2096 pl->orig_stats = pl->ob->stats;
1993 2097
1994void cf_player_move (player *pl, int dir) 2098void cf_player_move (player *pl, int dir)
1995 2099
1996void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0); 2100void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
1997
1998player *first ()
1999 CODE:
2000 RETVAL = first_player;
2001 OUTPUT: RETVAL
2002 2101
2003bool 2102bool
2004cell_visible (player *pl, int dx, int dy) 2103cell_visible (player *pl, int dx, int dy)
2005 CODE: 2104 CODE:
2006 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2 2105 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2046list () 2145list ()
2047 PPCODE: 2146 PPCODE:
2048 for_all_players (pl) 2147 for_all_players (pl)
2049 XPUSHs (sv_2mortal (to_sv (pl))); 2148 XPUSHs (sv_2mortal (to_sv (pl)));
2050 2149
2051bool
2052peaceful (player *pl, bool new_setting = 0)
2053 PROTOTYPE: $;$
2054 CODE:
2055 RETVAL = pl->peaceful;
2056 if (items > 1)
2057 pl->peaceful = new_setting;
2058 OUTPUT:
2059 RETVAL
2060
2061living *
2062orig_stats (player *pl)
2063 CODE:
2064 RETVAL = &pl->orig_stats;
2065 OUTPUT: RETVAL
2066
2067living *
2068last_stats (player *pl)
2069 CODE:
2070 RETVAL = &pl->last_stats;
2071 OUTPUT: RETVAL
2072
2073 2150
2074MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 2151MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2075 2152
2076int invoke (maptile *map, int event, ...) 2153int invoke (maptile *map, int event, ...)
2077 CODE: 2154 CODE:
2081 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END); 2158 RETVAL = map->invoke ((event_type)event, ARG_AV (av), DT_END);
2082 OUTPUT: RETVAL 2159 OUTPUT: RETVAL
2083 2160
2084SV *registry (maptile *map) 2161SV *registry (maptile *map)
2085 2162
2086INCLUDE: $PERL genacc maptile ../include/map.h | 2163INCLUDE: $PERL $srcdir/genacc maptile ../include/map.h |
2087 2164
2088void 2165void
2089maptile::instantiate () 2166maptile::instantiate ()
2090 2167
2091maptile *new () 2168maptile *new ()
2106 for_all_players (pl) 2183 for_all_players (pl)
2107 if (pl->ob && pl->ob->map == THIS) 2184 if (pl->ob && pl->ob->map == THIS)
2108 PUSHs (sv_2mortal (to_sv (pl->ob))); 2185 PUSHs (sv_2mortal (to_sv (pl->ob)));
2109 } 2186 }
2110 2187
2188void
2189maptile::add_underlay (SV *data, int offset, int stride, SV *palette)
2190 CODE:
2191{
2192 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2193 croak ("maptile::add_underlay: palette must be arrayref");
2194
2195 palette = SvRV (palette);
2196
2197 STRLEN idxlen;
2198 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2199
2200 for (int x = 0; x < THIS->width; ++x)
2201 for (int y = 0; y < THIS->height; ++y)
2202 {
2203 for (object *op = THIS->at (x, y).bot; op; op = op->above)
2204 if (op->flag [FLAG_IS_FLOOR])
2205 goto skip_space;
2206
2207 {
2208 int offs = offset + y * stride + x;
2209 if (IN_RANGE_EXC (offs, 0, idxlen))
2210 {
2211 if (SV **elem = av_fetch ((AV *)palette, idx [offs], 0))
2212 {
2213 object *ob = get_archetype (SvPVutf8_nolen (*elem));
2214 ob->flag [FLAG_NO_MAP_SAVE] = true;
2215 THIS->insert (ob, x, y, 0, INS_ABOVE_FLOOR_ONLY);
2216 }
2217 }
2218 }
2219
2220 skip_space: ;
2221 }
2222}
2223
2224void
2225maptile::set_regiondata (SV *data, int offset, int stride, SV *palette)
2226 CODE:
2227{
2228 if (!SvROK (palette) || SvTYPE (SvRV (palette)) != SVt_PVAV)
2229 croak ("maptile::set_regiondata: palette must be arrayref");
2230
2231 palette = SvRV (palette);
2232
2233 STRLEN idxlen;
2234 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2235
2236 region **regionmap = (region **)malloc (
2237 (av_len ((AV *)palette) + 1) * sizeof (region *));
2238 uint8_t *regions = salloc<uint8_t> (THIS->size ());
2239
2240 for (int i = av_len ((AV *)palette) + 1; i--; )
2241 regionmap [i] = region::find (
2242 SvPVutf8_nolen (*av_fetch ((AV *)palette, i, 1)));
2243
2244 for (int y = 0; y < THIS->height; ++y)
2245 memcpy (regions + y * THIS->width, idx + offset + y * stride, THIS->width);
2246
2247 sfree (THIS->regions, THIS->size ());
2248 free (THIS->regionmap);
2249
2250 THIS->regions = regions;
2251 THIS->regionmap = regionmap;
2252}
2253
2111void play_sound_map (maptile *map, int x, int y, int sound_num) 2254void play_sound_map (maptile *map, int x, int y, int sound_num)
2112 2255
2113int out_of_map (maptile *map, int x, int y) 2256int out_of_map (maptile *map, int x, int y)
2114 2257
2115void 2258void
2131 2274
2132object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny) 2275object* cf_map_present_arch_by_name (maptile *map, const char* str, int nx, int ny)
2133 C_ARGS: str, map, nx, ny 2276 C_ARGS: str, map, nx, ny
2134 2277
2135void 2278void
2136cf_map_normalise (maptile *map, int x, int y) 2279get_map_flags (maptile *map, int x, int y)
2137 PPCODE: 2280 PPCODE:
2138{ 2281{
2139 maptile *nmap = 0; 2282 maptile *nmap = 0;
2140 I16 nx = 0, ny = 0; 2283 I16 nx = 0, ny = 0;
2141 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny); 2284 int flags = get_map_flags (map, &nmap, x, y, &nx, &ny);
2196 2339
2197void fix_walls (maptile *map, int x, int y) 2340void fix_walls (maptile *map, int x, int y)
2198 2341
2199void fix_walls_around (maptile *map, int x, int y) 2342void fix_walls_around (maptile *map, int x, int y)
2200 2343
2201const char *
2202region_name (maptile *m)
2203 CODE:
2204 RETVAL = get_name_of_region_for_map (m);
2205 OUTPUT: RETVAL
2206
2207# worst xs function of my life 2344# worst xs function of my life
2208maptile * 2345bool
2209_create_random_map (\ 2346_create_random_map (\
2210 char *path,\ 2347 maptile *self,\
2211 char *wallstyle,\ 2348 char *wallstyle,\
2212 char *wall_name,\ 2349 char *wall_name,\
2213 char *floorstyle,\ 2350 char *floorstyle,\
2214 char *monsterstyle,\ 2351 char *monsterstyle,\
2215 char *treasurestyle,\ 2352 char *treasurestyle,\
2219 char *origin_map,\ 2356 char *origin_map,\
2220 char *final_map,\ 2357 char *final_map,\
2221 char *exitstyle,\ 2358 char *exitstyle,\
2222 char *this_map,\ 2359 char *this_map,\
2223 char *exit_on_final_map,\ 2360 char *exit_on_final_map,\
2224 int Xsize,\ 2361 int xsize,\
2225 int Ysize,\ 2362 int ysize,\
2226 int expand2x,\ 2363 int expand2x,\
2227 int layoutoptions1,\ 2364 int layoutoptions1,\
2228 int layoutoptions2,\ 2365 int layoutoptions2,\
2229 int layoutoptions3,\ 2366 int layoutoptions3,\
2230 int symmetry,\ 2367 int symmetry,\
2235 int dungeon_depth,\ 2372 int dungeon_depth,\
2236 int decoroptions,\ 2373 int decoroptions,\
2237 int orientation,\ 2374 int orientation,\
2238 int origin_y,\ 2375 int origin_y,\
2239 int origin_x,\ 2376 int origin_x,\
2240 int random_seed,\ 2377 U32 random_seed,\
2241 val64 total_map_hp,\ 2378 val64 total_map_hp,\
2242 int map_layout_style,\ 2379 int map_layout_style,\
2243 int treasureoptions,\ 2380 int treasureoptions,\
2244 int symmetry_used,\ 2381 int symmetry_used,\
2245 region *region\ 2382 region *region,\
2383 char *custom\
2246) 2384)
2247 CODE: 2385 CODE:
2248{ 2386{
2249 random_map_params rmp; 2387 random_map_params rmp;
2250 2388
2260 assign (rmp.exit_on_final_map, exit_on_final_map); 2398 assign (rmp.exit_on_final_map, exit_on_final_map);
2261 2399
2262 rmp.origin_map = origin_map; 2400 rmp.origin_map = origin_map;
2263 rmp.final_map = final_map; 2401 rmp.final_map = final_map;
2264 rmp.this_map = this_map; 2402 rmp.this_map = this_map;
2265 rmp.Xsize = Xsize; 2403 rmp.xsize = xsize;
2266 rmp.Ysize = Ysize; 2404 rmp.ysize = ysize;
2267 rmp.expand2x = expand2x; 2405 rmp.expand2x = expand2x;
2268 rmp.layoutoptions1 = layoutoptions1; 2406 rmp.layoutoptions1 = layoutoptions1;
2269 rmp.layoutoptions2 = layoutoptions2; 2407 rmp.layoutoptions2 = layoutoptions2;
2270 rmp.layoutoptions3 = layoutoptions3; 2408 rmp.layoutoptions3 = layoutoptions3;
2271 rmp.symmetry = symmetry; 2409 rmp.symmetry = symmetry;
2282 rmp.total_map_hp = total_map_hp; 2420 rmp.total_map_hp = total_map_hp;
2283 rmp.map_layout_style = map_layout_style; 2421 rmp.map_layout_style = map_layout_style;
2284 rmp.treasureoptions = treasureoptions; 2422 rmp.treasureoptions = treasureoptions;
2285 rmp.symmetry_used = symmetry_used; 2423 rmp.symmetry_used = symmetry_used;
2286 rmp.region = region; 2424 rmp.region = region;
2425 rmp.custom = custom;
2287 2426
2288 RETVAL = generate_random_map (path, &rmp); 2427 RETVAL = self->generate_random_map (&rmp);
2289} 2428}
2290 OUTPUT: 2429 OUTPUT:
2291 RETVAL 2430 RETVAL
2292 2431
2293MODULE = cf PACKAGE = cf::arch 2432MODULE = cf PACKAGE = cf::arch
2302 PROTOTYPE: 2441 PROTOTYPE:
2303 CODE: 2442 CODE:
2304 RETVAL = first_archetype; 2443 RETVAL = first_archetype;
2305 OUTPUT: RETVAL 2444 OUTPUT: RETVAL
2306 2445
2307INCLUDE: $PERL genacc archetype ../include/object.h | 2446INCLUDE: $PERL $srcdir/genacc archetype ../include/object.h |
2308 2447
2309MODULE = cf PACKAGE = cf::party 2448MODULE = cf PACKAGE = cf::party
2310 2449
2311partylist *first () 2450partylist *first ()
2312 PROTOTYPE: 2451 PROTOTYPE:
2313 CODE: 2452 CODE:
2314 RETVAL = get_firstparty (); 2453 RETVAL = get_firstparty ();
2315 OUTPUT: RETVAL 2454 OUTPUT: RETVAL
2316 2455
2317INCLUDE: $PERL genacc partylist ../include/player.h | 2456INCLUDE: $PERL $srcdir/genacc partylist ../include/player.h |
2318 2457
2319MODULE = cf PACKAGE = cf::region 2458MODULE = cf PACKAGE = cf::region
2320 2459
2321region *first () 2460void
2322 PROTOTYPE: 2461list ()
2323 CODE: 2462 PPCODE:
2324 RETVAL = first_region; 2463 for_all_regions (rgn)
2325 OUTPUT: RETVAL 2464 XPUSHs (sv_2mortal (to_sv (rgn)));
2326 2465
2327region *find (char *name) 2466region *find (char *name)
2328 PROTOTYPE: $ 2467 PROTOTYPE: $
2329 CODE: 2468 CODE:
2330 RETVAL = get_region_by_name (name); 2469 RETVAL = region::find (name);
2331 OUTPUT: RETVAL 2470 OUTPUT: RETVAL
2332 2471
2472region *find_fuzzy (char *name)
2473 PROTOTYPE: $
2474 CODE:
2475 RETVAL = region::find_fuzzy (name);
2476 OUTPUT: RETVAL
2477
2333INCLUDE: $PERL genacc region ../include/map.h | 2478INCLUDE: $PERL $srcdir/genacc region ../include/map.h |
2334 2479
2335MODULE = cf PACKAGE = cf::living 2480MODULE = cf PACKAGE = cf::living
2336 2481
2337INCLUDE: $PERL genacc living ../include/living.h | 2482INCLUDE: $PERL $srcdir/genacc living ../include/living.h |
2338 2483
2339MODULE = cf PACKAGE = cf::settings 2484MODULE = cf PACKAGE = cf::settings
2340 2485
2341INCLUDE: $PERL genacc Settings ../include/global.h | 2486INCLUDE: $PERL $srcdir/genacc Settings ../include/global.h |
2342 2487
2343MODULE = cf PACKAGE = cf::client 2488MODULE = cf PACKAGE = cf::client
2344 2489
2345INCLUDE: $PERL genacc client ../include/client.h | 2490INCLUDE: $PERL $srcdir/genacc client ../include/client.h |
2346 2491
2347int invoke (client *ns, int event, ...) 2492int invoke (client *ns, int event, ...)
2348 CODE: 2493 CODE:
2349 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT"); 2494 if (KLASS_OF (event) != KLASS_CLIENT) croak ("event class must be CLIENT");
2350 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); 2495 AV *av = (AV *)sv_2mortal ((SV *)newAV ());
2369 char *buf = SvPVbyte (packet, len); 2514 char *buf = SvPVbyte (packet, len);
2370 2515
2371 THIS->send_packet (buf, len); 2516 THIS->send_packet (buf, len);
2372} 2517}
2373 2518
2519MODULE = cf PACKAGE = cf::face PREFIX = face_
2520
2521INCLUDE: $PERL $srcdir/genacc faceset ../include/face.h |
2522
2523faceidx face_find (const char *name, faceidx defidx = 0)
2524
2525faceidx alloc (const char *name)
2526 CODE:
2527{
2528 do
2529 {
2530 RETVAL = faces.size ();
2531 faces.resize (RETVAL + 1);
2532 }
2533 while (!RETVAL); // crude way to leave index 0
2534
2535 faces [RETVAL].name = name;
2536 facehash.insert (std::make_pair (faces [RETVAL].name, RETVAL));
2537
2538 if (!strcmp (name, BLANK_FACE_NAME)) blank_face = RETVAL;
2539 if (!strcmp (name, EMPTY_FACE_NAME)) empty_face = RETVAL;
2540}
2541 OUTPUT: RETVAL
2542
2543void set (faceidx idx, int visibility, int magicmap)
2544 CODE:
2545 faceinfo *f = face_info (idx);
2546 assert (f);
2547 f->visibility = visibility;
2548 f->magicmap = magicmap;
2549
2550void set_smooth (faceidx idx, faceidx smooth)
2551 CODE:
2552 faceinfo *f = face_info (idx);
2553 assert (f);
2554 f->smooth = smooth;
2555
2556void set_data (faceidx idx, int faceset, SV *data, SV *chksum)
2557 CODE:
2558 facedata *d = face_data (idx, faceset);
2559 assert (d);
2560 assert (sv_len (chksum) == CHKSUM_SIZE);
2561 sv_to (data, d->data); memcpy (d->chksum, SvPVbyte_nolen (chksum), CHKSUM_SIZE);
2562
2563void invalidate (faceidx idx)
2564 CODE:
2565 for_all_clients (ns)
2566 ns->faces_sent [idx] = 0;
2567
2568void invalidate_all ()
2569 CODE:
2570 for_all_clients (ns)
2571 memset (ns->faces_sent, 0, sizeof (ns->faces_sent));
2572

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines