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.212 by root, Tue May 22 10:50:01 2007 UTC vs.
Revision 1.246 by root, Thu Aug 30 07:28:25 2007 UTC

1/* 1/*
2 * CrossFire, A Multiplayer game 2 * This file is part of Crossfire TRT, the Roguelike Realtime MORPG.
3 * 3 *
4 * This code is placed under the GNU General Public Licence (GPL) 4 * Copyright (©) 2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team
5 *
6 * Copyright (C) 2001-2005 by Chachkoff Yann 5 * Copyright (©) 2001-2005,2007 by Chachkoff Yann
7 * Copyright (C) 2006,2007 by Marc Lehmann <cf@schmorp.de> 6 * Copyright (©) 2006,2007 by Marc Lehmann <cf@schmorp.de>
8 * 7 *
9 * This program is free software; you can redistribute it and/or modify 8 * Crossfire TRT is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version. 11 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details. 16 * GNU General Public License for more details.
18 * 17 *
19 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 * Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 *
21 * The authors can be reached via e-mail to <crossfire@schmorp.de>
22 */ 22 */
23 23
24#include "autoconf.h" 24#include "autoconf.h"
25 25
26#define PLUGIN_NAME "perl" 26#define PLUGIN_NAME "perl"
74# define newSVval64 newSVnv 74# define newSVval64 newSVnv
75# define SvVAL64 SvNV 75# define SvVAL64 SvNV
76#endif 76#endif
77 77
78static f_plug_api gethook = cfapi_get_hooks; 78static f_plug_api gethook = cfapi_get_hooks;
79static f_plug_api object_set_property = cfapi_object_set_property;
80static f_plug_api object_insert = cfapi_object_insert; 79static f_plug_api object_insert = cfapi_object_insert;
81 80
82static PerlInterpreter *perl; 81static PerlInterpreter *perl;
83 82
84double runtime; 83tstamp NOW, runtime;
85 84
86global gbl_ev; 85global gbl_ev;
87static AV *cb_global, *cb_attachable, *cb_object, *cb_player, *cb_client, *cb_type, *cb_map; 86static AV *cb_global, *cb_attachable, *cb_object, *cb_player, *cb_client, *cb_type, *cb_map;
88static SV *sv_runtime, *sv_next_tick; 87static SV *sv_runtime, *sv_next_tick;
89 88
100 *stash_cf_arch_wrap, 99 *stash_cf_arch_wrap,
101 *stash_cf_party_wrap, 100 *stash_cf_party_wrap,
102 *stash_cf_region_wrap, 101 *stash_cf_region_wrap,
103 *stash_cf_living_wrap; 102 *stash_cf_living_wrap;
104 103
104static inline SV *
105newSVpv_utf8 (const char *s)
106{
107 SV *sv = newSVpv (s, 0);
108 SvUTF8_on (sv);
109 return sv;
110}
111
112static inline SV *
113newSVpvn_utf8 (const char *s, STRLEN l)
114{
115 SV *sv = newSVpvn (s, l);
116 SvUTF8_on (sv);
117 return sv;
118}
119
105// helper cast function, returns super class * or 0 120// helper cast function, returns super class * or 0
106template<class super> 121template<class super>
107static super * 122static super *
108is_a (attachable *at) 123is_a (attachable *at)
109{ 124{
168} 183}
169 184
170void 185void
171attachable::do_destroy () 186attachable::do_destroy ()
172{ 187{
173 invoke (EVENT_ATTACHABLE_DESTROY, DT_END); 188 INVOKE_ATTACHABLE (DESTROY, this);
174 189
175 if (cb) 190 if (cb)
176 { 191 {
177 SvREFCNT_dec (cb); 192 SvREFCNT_dec (cb);
178 cb = 0; 193 cb = 0;
201 { 216 {
202 if (i >= mortals.size ()) 217 if (i >= mortals.size ())
203 { 218 {
204 i = 0; 219 i = 0;
205 220
206 if (mortals.size () > 1000) 221 if (mortals.size () >= 512)
222 {
223 static int last_mortalcount;
224 if (mortals.size () != last_mortalcount)
225 {
226 last_mortalcount = mortals.size ();
207 LOG (llevInfo, "mortal queue size (%d) exceeds 1000.\n", (int)mortals.size ()); 227 LOG (llevInfo, "%d mortals.\n", (int)mortals.size ());
228
229 if (0)
230 {
231 for (int j = 0; j < mortals.size (); ++j)//D
232 fprintf (stderr, "%d:%s %p ", j, &((object *)mortals[j])->name, mortals[j]);//D
233 fprintf (stderr, "\n");//D
234 }
235 }
236 }
208 237
209 break; 238 break;
210 } 239 }
211 240
212 attachable *obj = mortals [i]; 241 attachable *obj = mortals [i];
233 delete obj; 262 delete obj;
234 } 263 }
235 } 264 }
236} 265}
237 266
267void
268attachable::set_key (const char *key, const char *value, bool is_utf8)
269{
270 if (!self)
271 self = newHV ();
272
273 if (value)
274 hv_store (self, key, strlen (key), is_utf8 ? newSVpv_utf8 (value) : newSVpv (value, 0), 0);
275 else
276 hv_delete (self, key, strlen (key), G_DISCARD);
277}
278
238attachable & 279attachable &
239attachable::operator =(const attachable &src) 280attachable::operator =(const attachable &src)
240{ 281{
241 //if (self || cb) 282 //if (self || cb)
242 //INVOKE_OBJECT (CLONE, this, ARG_OBJECT (dst)); 283 //INVOKE_OBJECT (CLONE, this, ARG_OBJECT (dst));
243 284
244 attach = src.attach; 285 attach = src.attach;
245 return *this; 286 return *this;
287}
288
289template<typename T>
290static bool
291find_backref (void *ptr, T *obj)
292{
293 char *s = (char *)obj;
294 while (s < (char *)obj + sizeof (T))
295 {
296 if (ptr == *(void **)s)
297 return true;
298
299 s += sizeof (void *); // assume natural alignment
300 }
301
302 return false;
303}
304
305// for debugging, find "live" objects containing this ptr
306void
307find_backref (void *ptr)
308{
309 for_all_objects (op)
310 if (find_backref (ptr, op))
311 fprintf (stderr, "O %p %d:'%s'\n", op, op->count, &op->name);
312
313 for_all_players (pl)
314 if (find_backref (ptr, pl))
315 fprintf (stderr, "P %p\n", pl);
316
317 for_all_clients (ns)
318 if (find_backref (ptr, ns))
319 fprintf (stderr, "C %p\n", ns);
320
246} 321}
247 322
248////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 323//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
249 324
250static SV * 325static SV *
283{ 358{
284 if (!obj) 359 if (!obj)
285 return &PL_sv_undef; 360 return &PL_sv_undef;
286 361
287 if (!obj->self) 362 if (!obj->self)
363 obj->self = newHV ();
364
365 if (!SvOBJECT (obj->self))
288 { 366 {
289 obj->self = newHV ();
290 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 367 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
291 368
292 // now bless the object _once_ 369 // now bless the object _once_
370 //TODO: create a class registry with c++ type<=>perl name<=>stash and use it here and elsewhere
293 return sv_bless (newRV_inc ((SV *)obj->self), stash); 371 return sv_bless (newRV_inc ((SV *)obj->self), stash);
294 } 372 }
295 else 373 else
296 { 374 {
297 SV *sv = newRV_inc ((SV *)obj->self); 375 SV *sv = newRV_inc ((SV *)obj->self);
334 return SvPTR (sv, klass); 412 return SvPTR (sv, klass);
335 else 413 else
336 return 0; 414 return 0;
337} 415}
338 416
339inline SV *to_sv (const shstr & v) { return v ? newSVpvn ((const char *)v, v.length ()) : &PL_sv_undef; } 417inline SV *to_sv (const shstr & v) { return v ? newSVpvn_utf8 ((const char *)v, v.length ()) : &PL_sv_undef; }
340inline SV *to_sv (const char * v) { return newSVpv (v, 0); } 418inline SV *to_sv (const char * v) { return newSVpv (v, 0); }
341inline SV *to_sv (bool v) { return newSViv (v); } 419inline SV *to_sv (bool v) { return newSViv (v); }
342inline SV *to_sv ( signed char v) { return newSViv (v); } 420inline SV *to_sv ( signed char v) { return newSViv (v); }
343inline SV *to_sv (unsigned char v) { return newSViv (v); } 421inline SV *to_sv (unsigned char v) { return newSViv (v); }
344inline SV *to_sv ( signed short v) { return newSViv (v); } 422inline SV *to_sv ( signed short v) { return newSViv (v); }
354inline SV *to_sv (client * v) { return newSVattachable (v, stash_cf_client_wrap); } 432inline SV *to_sv (client * v) { return newSVattachable (v, stash_cf_client_wrap); }
355inline SV *to_sv (player * v) { return newSVattachable (v, stash_cf_player_wrap); } 433inline SV *to_sv (player * v) { return newSVattachable (v, stash_cf_player_wrap); }
356inline SV *to_sv (object * v) { return newSVattachable (v, v && v->type == PLAYER ? stash_cf_object_player_wrap : stash_cf_object_wrap); } 434inline SV *to_sv (object * v) { return newSVattachable (v, v && v->type == PLAYER ? stash_cf_object_player_wrap : stash_cf_object_wrap); }
357inline SV *to_sv (maptile * v) { return newSVattachable (v, stash_cf_map_wrap); } 435inline SV *to_sv (maptile * v) { return newSVattachable (v, stash_cf_map_wrap); }
358inline SV *to_sv (archetype * v) { return newSVattachable (v, stash_cf_arch_wrap); } 436inline SV *to_sv (archetype * v) { return newSVattachable (v, stash_cf_arch_wrap); }
437inline SV *to_sv (region * v) { return newSVattachable (v, stash_cf_region_wrap); }
359inline SV *to_sv (partylist * v) { return newSVptr (v, stash_cf_party_wrap); } 438inline SV *to_sv (partylist * v) { return newSVptr (v, stash_cf_party_wrap); }
360inline SV *to_sv (region * v) { return newSVptr (v, stash_cf_region_wrap); }
361inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); } 439inline SV *to_sv (living * v) { return newSVptr (v, stash_cf_living_wrap); }
362 440
363inline SV *to_sv (object & v) { return to_sv (&v); } 441inline SV *to_sv (object & v) { return to_sv (&v); }
364inline SV *to_sv (living & v) { return to_sv (&v); } 442inline SV *to_sv (living & v) { return to_sv (&v); }
365 443
371 char buf[128]; 449 char buf[128];
372 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq); 450 snprintf (buf, 128, "<1.%" PRIx64 ">", v.seq);
373 return newSVpv (buf, 0); 451 return newSVpv (buf, 0);
374} 452}
375 453
376inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPV_nolen (sv) : 0; } 454inline void sv_to (SV *sv, shstr &v) { v = SvOK (sv) ? SvPVutf8_nolen (sv) : 0; }
377inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; } 455inline void sv_to (SV *sv, char * &v) { free (v); v = SvOK (sv) ? strdup (SvPV_nolen (sv)) : 0; }
378inline void sv_to (SV *sv, bool &v) { v = SvIV (sv); } 456inline void sv_to (SV *sv, bool &v) { v = SvIV (sv); }
379inline void sv_to (SV *sv, signed char &v) { v = SvIV (sv); } 457inline void sv_to (SV *sv, signed char &v) { v = SvIV (sv); }
380inline void sv_to (SV *sv, unsigned char &v) { v = SvIV (sv); } 458inline void sv_to (SV *sv, unsigned char &v) { v = SvIV (sv); }
381inline void sv_to (SV *sv, signed short &v) { v = SvIV (sv); } 459inline void sv_to (SV *sv, signed short &v) { v = SvIV (sv); }
391inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); } 469inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); }
392inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); } 470inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); }
393inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); } 471inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); }
394inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); } 472inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); }
395inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); } 473inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); }
474inline void sv_to (SV *sv, region * &v) { v = (region *)(attachable *)SvPTR_ornull (sv, "cf::region"); }
396inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); } 475inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
397inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 476inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
398inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
399inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 477inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
400 478
401//inline void sv_to (SV *sv, faceinfo * &v) { v = &faces [face_find (SvPV_nolen (sv), 0)]; } 479//inline void sv_to (SV *sv, faceinfo * &v) { v = &faces [face_find (SvPV_nolen (sv), 0)]; }
402inline void sv_to (SV *sv, treasurelist * &v) { v = treasurelist::find (SvPV_nolen (sv)); } 480inline void sv_to (SV *sv, treasurelist * &v) { v = treasurelist::find (SvPV_nolen (sv)); }
403 481
655void 733void
656attachable::instantiate () 734attachable::instantiate ()
657{ 735{
658 if (attach) 736 if (attach)
659 { 737 {
660 invoke (EVENT_ATTACHABLE_INSTANTIATE, ARG_STRING (attach), DT_END); 738 INVOKE_ATTACHABLE (INSTANTIATE, this, ARG_STRING (attach));
661 attach = 0; 739 attach = 0;
662 } 740 }
663} 741}
664 742
665void 743void
666attachable::reattach () 744attachable::reattach ()
667{ 745{
668 optimise (); 746 optimise ();
669 //TODO: check for _attachment's, very important for restarts 747 //TODO: check for _attachment's, very important for restarts
670 invoke (EVENT_ATTACHABLE_REATTACH, DT_END); 748 INVOKE_ATTACHABLE (REATTACH, this);
671} 749}
672 750
673static event_klass klass_of[NUM_EVENT_TYPES] = { 751static event_klass klass_of[NUM_EVENT_TYPES] = {
674# define def(type,name) KLASS_ ## type, 752# define def(type,name) KLASS_ ## type,
675# include "eventinc.h" 753# include "eventinc.h"
823 } 901 }
824 } 902 }
825} 903}
826 904
827bool 905bool
828attachable::vinvoke (event_type event, va_list &ap) 906attachable::invoke (event_type event, ...)
829{ 907{
830 data_type dt; 908 data_type dt;
831 909
832 // callback call ordering should be: 910 // callback call ordering should be:
833 // 1. per-object callback 911 // 1. per-object callback
839 gather_callbacks (callbacks, event); 917 gather_callbacks (callbacks, event);
840 918
841 // short-circuit processing if no callbacks found/defined 919 // short-circuit processing if no callbacks found/defined
842 if (!callbacks) 920 if (!callbacks)
843 return 0; 921 return 0;
922
923 va_list ap;
924 va_start (ap, event);
844 925
845 CALL_BEGIN (3); 926 CALL_BEGIN (3);
846 CALL_ARG_SV (newSViv (event)); // only used for debugging nowadays 927 CALL_ARG_SV (newSViv (event)); // only used for debugging nowadays
847 CALL_ARG_SV (newRV_noinc ((SV *)callbacks)); 928 CALL_ARG_SV (newRV_noinc ((SV *)callbacks));
848 929
883} 964}
884 965
885SV * 966SV *
886cfperl_result (int idx) 967cfperl_result (int idx)
887{ 968{
888 AV *av = get_av ("cfperl::invoke_results", 0); 969 AV *av = get_av ("cf::INVOKE_RESULTS", 0);
889 if (!av) 970 if (!av)
890 return &PL_sv_undef; 971 return &PL_sv_undef;
891 972
892 SV **sv = av_fetch (av, idx, 0); 973 SV **sv = av_fetch (av, idx, 0);
893 if (!sv) 974 if (!sv)
925 CALL_ARG (make_core); 1006 CALL_ARG (make_core);
926 CALL_CALL ("cf::post_cleanup", G_VOID); 1007 CALL_CALL ("cf::post_cleanup", G_VOID);
927 CALL_END; 1008 CALL_END;
928} 1009}
929 1010
1011void
1012cfperl_make_book (object *book, int level)
1013{
1014 CALL_BEGIN (2);
1015 CALL_ARG (book);
1016 CALL_ARG (level);
1017 CALL_CALL ("ext::books::make_book", G_VOID);
1018 CALL_END;
1019}
1020
1021void
1022cfperl_send_msg (client *ns, int color, const char *type, const char *msg)
1023{
1024 CALL_BEGIN (4);
1025 CALL_ARG (ns);
1026 CALL_ARG (type);
1027 CALL_ARG_SV (newSVpv_utf8 (msg));
1028 CALL_ARG (color);
1029 CALL_CALL ("cf::client::send_msg", G_VOID);
1030 CALL_END;
1031}
1032
1033int
1034cfperl_can_merge (object *ob1, object *ob2)
1035{
1036 int can;
1037
1038 CALL_BEGIN (2);
1039 CALL_ARG (ob1);
1040 CALL_ARG (ob2);
1041 CALL_CALL ("cf::_can_merge", G_SCALAR);
1042 can = count && SvTRUE (TOPs);
1043 CALL_END;
1044
1045 return can;
1046}
1047
1048player *
1049player::find (const char *name)
1050{
1051 CALL_BEGIN (1);
1052 CALL_ARG (name);
1053 CALL_CALL ("cf::player::find", G_SCALAR);
1054
1055 player *retval;
1056
1057 if (count)
1058 sv_to (POPs, retval);
1059 else
1060 retval = 0;
1061
1062 CALL_END;
1063
1064 return retval;
1065}
1066
930maptile * 1067maptile *
931maptile::find_sync (const char *path, maptile *origin) 1068maptile::find_sync (const char *path, maptile *origin)
932{ 1069{
933 CALL_BEGIN (2); 1070 CALL_BEGIN (2);
934 CALL_ARG (path); 1071 CALL_ARG (path);
946 1083
947 return retval; 1084 return retval;
948} 1085}
949 1086
950maptile * 1087maptile *
951maptile::find_async (const char *path, maptile *origin) 1088maptile::find_async (const char *path, maptile *origin, bool load)
952{ 1089{
953 CALL_BEGIN (2); 1090 CALL_BEGIN (3);
954 CALL_ARG (path); 1091 CALL_ARG (path);
955 CALL_ARG (origin); 1092 CALL_ARG (origin);
1093 CALL_ARG (load);
956 CALL_CALL ("cf::map::find_async", G_SCALAR); 1094 CALL_CALL ("cf::map::find_async", G_SCALAR);
957 1095
958 maptile *retval; 1096 maptile *retval;
959 1097
960 if (count) 1098 if (count)
1018 1156
1019struct EventAPI *watcher_base::GEventAPI; 1157struct EventAPI *watcher_base::GEventAPI;
1020struct CoroAPI *coroapi::GCoroAPI; 1158struct CoroAPI *coroapi::GCoroAPI;
1021 1159
1022int coroapi::cede_counter; 1160int coroapi::cede_counter;
1023double (*coroapi::time)();
1024double coroapi::next_cede; 1161tstamp coroapi::next_cede;
1025 1162
1026void coroapi::do_cede_to_tick () 1163void coroapi::do_cede_to_tick ()
1027{ 1164{
1028 cede_counter = 0; 1165 cede_counter = 0;
1029 1166
1160 1297
1161 _connect_to_perl (); 1298 _connect_to_perl ();
1162 1299
1163 newCONSTSUB (stash_cf, "VERSION", newSVpv (VERSION, sizeof (VERSION) - 1)); 1300 newCONSTSUB (stash_cf, "VERSION", newSVpv (VERSION, sizeof (VERSION) - 1));
1164 1301
1165 { 1302 //{
1166 require_pv ("Time::HiRes"); 1303 // require_pv ("Time::HiRes");
1167 1304 //
1168 SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0); 1305 // SV **svp = hv_fetch (PL_modglobal, "Time::NVtime", 12, 0);
1169 if (!svp) croak ("Time::HiRes is required"); 1306 // if (!svp) croak ("Time::HiRes is required");
1170 if (!SvIOK(*svp)) croak ("Time::NVtime isn’t a function pointer"); 1307 // if (!SvIOK(*svp)) croak ("Time::NVtime isn’t a function pointer");
1171 coroapi::time = INT2PTR (double(*)(), SvIV(*svp)); 1308 // coroapi::time = INT2PTR (double(*)(), SvIV(*svp));
1172 } 1309 //}
1173 1310
1174 static const struct { 1311 static const struct {
1175 const char *name; 1312 const char *name;
1176 IV iv; 1313 IV iv;
1177 } *civ, const_iv[] = { 1314 } *civ, const_iv[] = {
1259 const_iv (FLAG_USE_ROD) const_iv (FLAG_USE_HORN) const_iv (FLAG_MAKE_INVIS) const_iv (FLAG_INV_LOCKED) 1396 const_iv (FLAG_USE_ROD) const_iv (FLAG_USE_HORN) const_iv (FLAG_MAKE_INVIS) const_iv (FLAG_INV_LOCKED)
1260 const_iv (FLAG_IS_WOODED) const_iv (FLAG_IS_HILLY) const_iv (FLAG_READY_SKILL) const_iv (FLAG_READY_WEAPON) 1397 const_iv (FLAG_IS_WOODED) const_iv (FLAG_IS_HILLY) const_iv (FLAG_READY_SKILL) const_iv (FLAG_READY_WEAPON)
1261 const_iv (FLAG_NO_SKILL_IDENT) const_iv (FLAG_BLIND) const_iv (FLAG_SEE_IN_DARK) const_iv (FLAG_IS_CAULDRON) 1398 const_iv (FLAG_NO_SKILL_IDENT) const_iv (FLAG_BLIND) const_iv (FLAG_SEE_IN_DARK) const_iv (FLAG_IS_CAULDRON)
1262 const_iv (FLAG_NO_STEAL) const_iv (FLAG_ONE_HIT) const_iv (FLAG_CLIENT_SENT) const_iv (FLAG_BERSERK) 1399 const_iv (FLAG_NO_STEAL) const_iv (FLAG_ONE_HIT) const_iv (FLAG_CLIENT_SENT) const_iv (FLAG_BERSERK)
1263 const_iv (FLAG_NEUTRAL) const_iv (FLAG_NO_ATTACK) const_iv (FLAG_NO_DAMAGE) const_iv (FLAG_OBJ_ORIGINAL) 1400 const_iv (FLAG_NEUTRAL) const_iv (FLAG_NO_ATTACK) const_iv (FLAG_NO_DAMAGE) const_iv (FLAG_OBJ_ORIGINAL)
1264 const_iv (FLAG_OBJ_SAVE_ON_OVL) const_iv (FLAG_ACTIVATE_ON_PUSH) const_iv (FLAG_ACTIVATE_ON_RELEASE) const_iv (FLAG_IS_WATER) 1401 const_iv (FLAG_ACTIVATE_ON_PUSH) const_iv (FLAG_ACTIVATE_ON_RELEASE) const_iv (FLAG_IS_WATER)
1265 const_iv (FLAG_CONTENT_ON_GEN) const_iv (FLAG_IS_A_TEMPLATE) const_iv (FLAG_IS_BUILDABLE) 1402 const_iv (FLAG_CONTENT_ON_GEN) const_iv (FLAG_IS_A_TEMPLATE) const_iv (FLAG_IS_BUILDABLE)
1266 const_iv (FLAG_DESTROY_ON_DEATH) const_iv (FLAG_NO_MAP_SAVE) 1403 const_iv (FLAG_DESTROY_ON_DEATH) const_iv (FLAG_NO_MAP_SAVE)
1267 1404
1268 const_iv (NDI_BLACK) const_iv (NDI_WHITE) const_iv (NDI_NAVY) const_iv (NDI_RED) 1405 const_iv (NDI_BLACK) const_iv (NDI_WHITE) const_iv (NDI_NAVY) const_iv (NDI_RED)
1269 const_iv (NDI_ORANGE) const_iv (NDI_BLUE) const_iv (NDI_DK_ORANGE) const_iv (NDI_GREEN) 1406 const_iv (NDI_ORANGE) const_iv (NDI_BLUE) const_iv (NDI_DK_ORANGE) const_iv (NDI_GREEN)
1270 const_iv (NDI_LT_GREEN) const_iv (NDI_GREY) const_iv (NDI_BROWN) const_iv (NDI_GOLD) 1407 const_iv (NDI_LT_GREEN) const_iv (NDI_GREY) const_iv (NDI_BROWN) const_iv (NDI_GOLD)
1271 const_iv (NDI_TAN) const_iv (NDI_MAX_COLOR) const_iv (NDI_COLOR_MASK) const_iv (NDI_UNIQUE) 1408 const_iv (NDI_TAN) const_iv (NDI_MAX_COLOR) const_iv (NDI_COLOR_MASK) const_iv (NDI_UNIQUE)
1409 const_iv (NDI_ALL) const_iv (NDI_DEF) const_iv (NDI_REPLY) const_iv (NDI_CLIENT_MASK)
1272 const_iv (NDI_ALL) 1410 const_iv (NDI_NOCREATE)
1273 1411
1274 const_iv (UPD_LOCATION) const_iv (UPD_FLAGS) const_iv (UPD_WEIGHT) const_iv (UPD_FACE) 1412 const_iv (UPD_LOCATION) const_iv (UPD_FLAGS) const_iv (UPD_WEIGHT) const_iv (UPD_FACE)
1275 const_iv (UPD_NAME) const_iv (UPD_ANIM) const_iv (UPD_ANIMSPEED) const_iv (UPD_NROF) 1413 const_iv (UPD_NAME) const_iv (UPD_ANIM) const_iv (UPD_ANIMSPEED) const_iv (UPD_NROF)
1276 1414
1277 const_iv (UPD_SP_MANA) const_iv (UPD_SP_GRACE) const_iv (UPD_SP_DAMAGE) 1415 const_iv (UPD_SP_MANA) const_iv (UPD_SP_GRACE) const_iv (UPD_SP_DAMAGE)
1404 const_iv (SYMMETRY_Y) const_iv (SYMMETRY_XY) 1542 const_iv (SYMMETRY_Y) const_iv (SYMMETRY_XY)
1405 1543
1406 const_iv (GT_ENVIRONMENT) const_iv (GT_INVISIBLE) const_iv (GT_STARTEQUIP) 1544 const_iv (GT_ENVIRONMENT) const_iv (GT_INVISIBLE) const_iv (GT_STARTEQUIP)
1407 const_iv (GT_APPLY) const_iv (GT_ONLY_GOOD) const_iv (GT_UPDATE_INV) 1545 const_iv (GT_APPLY) const_iv (GT_ONLY_GOOD) const_iv (GT_UPDATE_INV)
1408 const_iv (GT_MINIMAL) 1546 const_iv (GT_MINIMAL)
1547
1548 const_iv (FT_FACE) const_iv (FT_MUSIC) const_iv (FT_SOUND)
1549 const_iv (FT_RSRC) const_iv (FT_NUM)
1409 }; 1550 };
1410 1551
1411 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; ) 1552 for (civ = const_iv + sizeof (const_iv) / sizeof (const_iv [0]); civ-- > const_iv; )
1412 newCONSTSUB (stash_cf, (char *)civ->name, newSViv (civ->iv)); 1553 newCONSTSUB (stash_cf, (char *)civ->name, newSViv (civ->iv));
1413 1554
1447 1588
1448 for_all_objects (op) 1589 for_all_objects (op)
1449 op->reattach (); 1590 op->reattach ();
1450} 1591}
1451 1592
1452void _post_tick ()
1453 CODE:
1454 coroapi::next_cede = SvNV (sv_next_tick) - TICK * (1. - 1. / CEDES_PER_TICK);
1455
1456# support function for map-world.ext 1593# support function for map-world.ext
1457void _quantise (SV *data_sv, SV *plt_sv) 1594void _quantise (SV *data_sv, SV *plt_sv)
1458 CODE: 1595 CODE:
1459{ 1596{
1460 if (!SvROK (plt_sv) || SvTYPE (SvRV (plt_sv)) != SVt_PVAV) 1597 if (!SvROK (plt_sv) || SvTYPE (SvRV (plt_sv)) != SVt_PVAV)
1492 len -= 3; 1629 len -= 3;
1493 } 1630 }
1494 1631
1495 SvCUR_set (data_sv, dst - SvPVX (data_sv)); 1632 SvCUR_set (data_sv, dst - SvPVX (data_sv));
1496} 1633}
1634
1635void _post_tick ()
1636 CODE:
1637 coroapi::next_cede = SvNV (sv_next_tick) - TICK * (1. - 1. / CEDES_PER_TICK);
1638
1639NV till_cede ()
1640 CODE:
1641 RETVAL = coroapi::next_cede - now ();
1642 OUTPUT:
1643 RETVAL
1644
1645NV till_tick ()
1646 CODE:
1647 RETVAL = SvNV (sv_next_tick) - now ();
1648 OUTPUT:
1649 RETVAL
1497 1650
1498NV floor (NV x) 1651NV floor (NV x)
1499 1652
1500NV ceil (NV x) 1653NV ceil (NV x)
1501 1654
1527 CODE: 1680 CODE:
1528 coroapi::cede_to_tick (); 1681 coroapi::cede_to_tick ();
1529 1682
1530void server_tick () 1683void server_tick ()
1531 CODE: 1684 CODE:
1685 NOW = now ();
1532 runtime = SvNVx (sv_runtime); 1686 runtime = SvNVx (sv_runtime);
1533 server_tick (); 1687 server_tick ();
1534 1688
1535void 1689void
1536log_backtrace (utf8_string msg) 1690log_backtrace (utf8_string msg)
1543octet_string path_combine (octet_string base, octet_string path) 1697octet_string path_combine (octet_string base, octet_string path)
1544 PROTOTYPE: $$ 1698 PROTOTYPE: $$
1545 1699
1546octet_string path_combine_and_normalize (octet_string base, octet_string path) 1700octet_string path_combine_and_normalize (octet_string base, octet_string path)
1547 PROTOTYPE: $$ 1701 PROTOTYPE: $$
1548
1549const_octet_string
1550get_maps_directory (octet_string path)
1551 PROTOTYPE: $
1552 ALIAS: maps_directory = 0
1553 CODE:
1554 RETVAL = create_pathname (path);
1555 OUTPUT: RETVAL
1556 1702
1557void 1703void
1558sub_generation_inc () 1704sub_generation_inc ()
1559 CODE: 1705 CODE:
1560 PL_sub_generation++; 1706 PL_sub_generation++;
1682#object *mortals (U32 index) 1828#object *mortals (U32 index)
1683# CODE: 1829# CODE:
1684# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0; 1830# RETVAL = index < attachable::mortals.size () ? attachable::mortals [index] : 0;
1685# OUTPUT: RETVAL 1831# OUTPUT: RETVAL
1686 1832
1687INCLUDE: $PERL $srcdir/genacc attachable ../include/cfperl.h | 1833INCLUDE: $PERL $srcdir/genacc attachable ../include/util.h ../include/cfperl.h |
1688 1834
1689MODULE = cf PACKAGE = cf::global 1835MODULE = cf PACKAGE = cf::global
1690 1836
1691int invoke (SV *klass, int event, ...) 1837int invoke (SV *klass, int event, ...)
1692 CODE: 1838 CODE:
1728object *actives (U32 index) 1874object *actives (U32 index)
1729 CODE: 1875 CODE:
1730 RETVAL = index < actives.size () ? actives [index] : 0; 1876 RETVAL = index < actives.size () ? actives [index] : 0;
1731 OUTPUT: RETVAL 1877 OUTPUT: RETVAL
1732 1878
1733const char *slot_save_name (U32 slot) 1879const char *slot_use_name (U32 slot)
1734 ALIAS: 1880 ALIAS:
1735 slot_use_name = 1
1736 slot_nonuse_name = 2 1881 slot_nonuse_name = 1
1737 CODE: 1882 CODE:
1738{ 1883{
1739 if (slot >= NUM_BODY_LOCATIONS) 1884 if (slot >= NUM_BODY_LOCATIONS)
1740 croak ("body slot index out of range"); 1885 croak ("body slot index out of range");
1741 1886
1742 switch (ix) 1887 switch (ix)
1743 { 1888 {
1744 case 0: RETVAL = body_locations[slot].save_name; break;
1745 case 1: RETVAL = body_locations[slot].use_name; break; 1889 case 0: RETVAL = body_locations[slot].use_name; break;
1746 case 2: RETVAL = body_locations[slot].nonuse_name; break; 1890 case 1: RETVAL = body_locations[slot].nonuse_name; break;
1747 } 1891 }
1748} 1892}
1749 OUTPUT: 1893 OUTPUT:
1750 RETVAL 1894 RETVAL
1751 1895
1753 1897
1754object *head (object *op) 1898object *head (object *op)
1755 PROTOTYPE: $ 1899 PROTOTYPE: $
1756 CODE: 1900 CODE:
1757 RETVAL = op->head_ (); 1901 RETVAL = op->head_ ();
1758 OUTPUT: RETVAL
1759
1760int is_head (object *op)
1761 PROTOTYPE: $
1762 CODE:
1763 RETVAL = op->head_ () == op;
1764 OUTPUT: RETVAL 1902 OUTPUT: RETVAL
1765 1903
1766void 1904void
1767inv (object *obj) 1905inv (object *obj)
1768 PROTOTYPE: $ 1906 PROTOTYPE: $
1914 2052
1915void add_button_link (object *button, maptile *map, int connected); 2053void add_button_link (object *button, maptile *map, int connected);
1916 2054
1917void remove_button_link (object *op); 2055void remove_button_link (object *op);
1918 2056
2057void handle_apply_yield (object *op);
2058
1919 2059
1920MODULE = cf PACKAGE = cf::object PREFIX = cf_ 2060MODULE = cf PACKAGE = cf::object PREFIX = cf_
1921 2061
1922object *cf_insert_ob_in_ob (object *ob, object *where) 2062object *cf_insert_ob_in_ob (object *ob, object *where)
1923 2063
1925# dumb kludgy misdesigned plug-in api slowly gets on my nerves. 2065# dumb kludgy misdesigned plug-in api slowly gets on my nerves.
1926 2066
1927object *new (utf8_string archetype = 0) 2067object *new (utf8_string archetype = 0)
1928 PROTOTYPE: ;$ 2068 PROTOTYPE: ;$
1929 CODE: 2069 CODE:
1930 RETVAL = archetype ? get_archetype (archetype) : cf_create_object (); 2070 RETVAL = archetype ? get_archetype (archetype) : object::create ();
1931 OUTPUT: 2071 OUTPUT:
1932 RETVAL 2072 RETVAL
1933 2073
2074object *find_object (U32 tag)
2075
2076# TODO: nuke
1934object *insert_ob_in_map_at (object *ob, maptile *where, object_ornull *orig, int flag, int x, int y) 2077object *insert_ob_in_map_at (object *ob, maptile *where, object_ornull *orig, int flag, int x, int y)
1935 PROTOTYPE: $$$$$$ 2078 PROTOTYPE: $$$$$$
1936 CODE: 2079 CODE:
1937{ 2080{
1938 int unused_type; 2081 int unused_type;
1939 RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y); 2082 RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y);
1940} 2083}
1941
1942player *contr (object *op)
1943 CODE:
1944 RETVAL = op->contr;
1945 OUTPUT: RETVAL
1946 2084
1947const_utf8_string get_ob_key_value (object *op, utf8_string key) 2085const_utf8_string get_ob_key_value (object *op, utf8_string key)
1948 2086
1949bool set_ob_key_value (object *op, utf8_string key, utf8_string value = 0, int add_key = 1) 2087bool set_ob_key_value (object *op, utf8_string key, utf8_string value = 0, int add_key = 1)
1950 2088
1996void kill_player (object *op) 2134void kill_player (object *op)
1997 2135
1998void esrv_update_item (object *op, int what, object *item) 2136void esrv_update_item (object *op, int what, object *item)
1999 C_ARGS: what, op, item 2137 C_ARGS: what, op, item
2000 2138
2001void clear_los (object *op)
2002
2003int command_summon (object *op, utf8_string params) 2139int command_summon (object *op, utf8_string params)
2004 2140
2005int command_arrest (object *op, utf8_string params) 2141int command_arrest (object *op, utf8_string params)
2006 2142
2007 2143
2025 pl->ob->stats.hp = pl->ob->stats.maxhp; 2161 pl->ob->stats.hp = pl->ob->stats.maxhp;
2026 pl->ob->stats.sp = pl->ob->stats.maxsp; 2162 pl->ob->stats.sp = pl->ob->stats.maxsp;
2027 pl->ob->stats.grace = pl->ob->stats.maxgrace; 2163 pl->ob->stats.grace = pl->ob->stats.maxgrace;
2028 pl->orig_stats = pl->ob->stats; 2164 pl->orig_stats = pl->ob->stats;
2029 2165
2166void clear_los (player *pl)
2167
2030void cf_player_move (player *pl, int dir) 2168void cf_player_move (player *pl, int dir)
2031
2032void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
2033 2169
2034bool 2170bool
2035cell_visible (player *pl, int dx, int dy) 2171cell_visible (player *pl, int dx, int dy)
2036 CODE: 2172 CODE:
2037 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2 2173 RETVAL = FABS (dx) <= pl->ns->mapx / 2 && FABS (dy) <= pl->ns->mapy / 2
2176 palette = SvRV (palette); 2312 palette = SvRV (palette);
2177 2313
2178 STRLEN idxlen; 2314 STRLEN idxlen;
2179 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen); 2315 const uint8_t *idx = (const uint8_t *)SvPVbyte (data, idxlen);
2180 2316
2181 region **regionmap = (region **)malloc ( 2317 region_ptr *regionmap = new region_ptr [av_len ((AV *)palette) + 1];
2182 (av_len ((AV *)palette) + 1) * sizeof (region *));
2183 uint8_t *regions = salloc<uint8_t> (THIS->size ()); 2318 uint8_t *regions = salloc<uint8_t> (THIS->size ());
2184 2319
2185 for (int i = av_len ((AV *)palette) + 1; i--; ) 2320 for (int i = av_len ((AV *)palette) + 1; i--; )
2186 regionmap [i] = region::find ( 2321 regionmap [i] = region::find (SvPVutf8_nolen (*av_fetch ((AV *)palette, i, 1)));
2187 SvPVutf8_nolen (*av_fetch ((AV *)palette, i, 1)));
2188 2322
2189 for (int y = 0; y < THIS->height; ++y) 2323 for (int y = 0; y < THIS->height; ++y)
2190 memcpy (regions + y * THIS->width, idx + offset + y * stride, THIS->width); 2324 memcpy (regions + y * THIS->width, idx + offset + y * stride, THIS->width);
2191 2325
2192 sfree (THIS->regions, THIS->size ()); 2326 sfree (THIS->regions, THIS->size ());
2193 free (THIS->regionmap); 2327 delete [] THIS->regionmap;
2194 2328
2195 THIS->regions = regions; 2329 THIS->regions = regions;
2196 THIS->regionmap = regionmap; 2330 THIS->regionmap = regionmap;
2197} 2331}
2198 2332
2218 } 2352 }
2219 } 2353 }
2220 2354
2221 op->destroy (); 2355 op->destroy ();
2222} 2356}
2223
2224void play_sound_map (maptile *map, int x, int y, int sound_num)
2225 2357
2226int out_of_map (maptile *map, int x, int y) 2358int out_of_map (maptile *map, int x, int y)
2227 2359
2228void 2360void
2229trigger (maptile *map, long connection, bool state = true) 2361trigger (maptile *map, long connection, bool state = true)
2385 rmp.decoroptions = decoroptions; 2517 rmp.decoroptions = decoroptions;
2386 rmp.orientation = orientation; 2518 rmp.orientation = orientation;
2387 rmp.origin_y = origin_y; 2519 rmp.origin_y = origin_y;
2388 rmp.origin_x = origin_x; 2520 rmp.origin_x = origin_x;
2389 rmp.random_seed = random_seed; 2521 rmp.random_seed = random_seed;
2390 rmp.total_map_hp = total_map_hp; 2522 rmp.total_map_hp = (uint64_t) total_map_hp;
2391 rmp.map_layout_style = map_layout_style; 2523 rmp.map_layout_style = map_layout_style;
2392 rmp.treasureoptions = treasureoptions; 2524 rmp.treasureoptions = treasureoptions;
2393 rmp.symmetry_used = symmetry_used; 2525 rmp.symmetry_used = symmetry_used;
2394 rmp.region = region; 2526 rmp.region = region;
2395 rmp.custom = custom; 2527 rmp.custom = custom;
2405 CODE: 2537 CODE:
2406 RETVAL = archetype::find (name); 2538 RETVAL = archetype::find (name);
2407 OUTPUT: 2539 OUTPUT:
2408 RETVAL 2540 RETVAL
2409 2541
2410archetype *first() 2542int archetypes_size ()
2411 PROTOTYPE: 2543 CODE:
2412 CODE:
2413 RETVAL = first_archetype; 2544 RETVAL = archetypes.size ();
2414 OUTPUT: RETVAL 2545 OUTPUT: RETVAL
2546
2547archetype *archetypes (U32 index)
2548 CODE:
2549 RETVAL = index < archetypes.size () ? archetypes [index] : 0;
2550 OUTPUT: RETVAL
2415 2551
2416object *instantiate (archetype *arch) 2552object *instantiate (archetype *arch)
2417 CODE: 2553 CODE:
2418 RETVAL = arch_to_object (arch); 2554 RETVAL = arch_to_object (arch);
2419 OUTPUT: 2555 OUTPUT:
2496 STRLEN len; 2632 STRLEN len;
2497 char *buf = SvPVbyte (packet, len); 2633 char *buf = SvPVbyte (packet, len);
2498 2634
2499 THIS->send_packet (buf, len); 2635 THIS->send_packet (buf, len);
2500} 2636}
2637
2638faceidx
2639client::need_face (utf8_string name, int pri = 0)
2640 CODE:
2641 RETVAL = face_find (name, 0);
2642 if (RETVAL)
2643 {
2644 THIS->send_face (RETVAL, pri);
2645 THIS->flush_fx ();
2646 }
2647 OUTPUT:
2648 RETVAL
2649
2650int
2651client::fx_want (int idx, int value = -1)
2652 CODE:
2653 if (0 < idx && idx < FT_NUM)
2654 {
2655 RETVAL = THIS->fx_want [idx];
2656 if (items > 2)
2657 THIS->fx_want [idx] = value;
2658 }
2659 else
2660 RETVAL = 0;
2661 OUTPUT:
2662 RETVAL
2663
2664MODULE = cf PACKAGE = cf::sound PREFIX = sound_
2665
2666faceidx sound_find (utf8_string name)
2667
2668void sound_set (utf8_string str, faceidx face)
2669
2670# dire hack
2671void old_sound_index (int idx, faceidx face)
2672 CODE:
2673 extern faceidx old_sound_index [SOUND_CAST_SPELL_0];
2674 old_sound_index [idx] = face;
2501 2675
2502MODULE = cf PACKAGE = cf::face PREFIX = face_ 2676MODULE = cf PACKAGE = cf::face PREFIX = face_
2503 2677
2504#INCLUDE: $PERL $srcdir/genacc faceset ../include/face.h | 2678#INCLUDE: $PERL $srcdir/genacc faceset ../include/face.h |
2505 2679
2521 if (!strcmp (name, BLANK_FACE_NAME)) blank_face = RETVAL; 2695 if (!strcmp (name, BLANK_FACE_NAME)) blank_face = RETVAL;
2522 if (!strcmp (name, EMPTY_FACE_NAME)) empty_face = RETVAL; 2696 if (!strcmp (name, EMPTY_FACE_NAME)) empty_face = RETVAL;
2523} 2697}
2524 OUTPUT: RETVAL 2698 OUTPUT: RETVAL
2525 2699
2526void set (faceidx idx, int visibility, int magicmap) 2700void set_type (faceidx idx, int value)
2527 CODE: 2701 ALIAS:
2528 faceinfo *f = face_info (idx); 2702 set_type = 0
2529 assert (f); 2703 set_visibility = 1
2530 f->visibility = visibility; 2704 set_magicmap = 2
2531 f->magicmap = magicmap; 2705 set_smooth = 3
2532 2706 set_smoothlevel = 4
2533void set_smooth (faceidx idx, faceidx smooth, int smoothlevel)
2534 CODE: 2707 CODE:
2535 faceinfo *f = face_info (idx); assert (f); 2708 faceinfo *f = face_info (idx); assert (f);
2536 f->smooth = smooth; 2709 switch (ix)
2537 f->smoothlevel = smoothlevel; 2710 {
2711 case 0: f->type = value; break;
2712 case 1: f->visibility = value; break;
2713 case 2: f->magicmap = value; break;
2714 case 3: f->smooth = value; break;
2715 case 4: f->smoothlevel = value; break;
2716 }
2538 2717
2539void set_data (faceidx idx, int faceset, SV *data, SV *chksum) 2718void set_data (faceidx idx, int faceset, SV *data, SV *chksum)
2540 CODE: 2719 CODE:
2541{ 2720{
2542 facedata *d = face_data (idx, faceset); 2721 faceinfo *f = face_info (idx); assert (f);
2543 assert (d); 2722 facedata *d = &(faceset ? f->data64 : f->data32);
2544 sv_to (data, d->data); 2723 sv_to (data, d->data);
2545 STRLEN clen; 2724 STRLEN clen;
2546 char *cdata = SvPVbyte (chksum, clen); 2725 char *cdata = SvPVbyte (chksum, clen);
2547 clen = min (CHKSUM_SIZE, clen); 2726 clen = min (CHKSUM_SIZE, clen);
2548 2727
2558 ns->force_newmap = true; 2737 ns->force_newmap = true;
2559 } 2738 }
2560 } 2739 }
2561} 2740}
2562 2741
2742int get_data_size (faceidx idx, int faceset = 0)
2743 CODE:
2744 facedata *d = face_data (idx, faceset); assert (d);
2745 RETVAL = d->data.size ();
2746 OUTPUT:
2747 RETVAL
2748
2749SV *get_chksum (faceidx idx, int faceset = 0)
2750 CODE:
2751 facedata *d = face_data (idx, faceset); assert (d);
2752 RETVAL = newSVpvn ((char *)d->chksum, CHKSUM_SIZE);
2753 OUTPUT:
2754 RETVAL
2755
2563void invalidate (faceidx idx) 2756void invalidate (faceidx idx)
2564 CODE: 2757 CODE:
2565 for_all_clients (ns) 2758 for_all_clients (ns)
2566 { 2759 {
2567 ns->faces_sent [idx] = false; 2760 ns->faces_sent [idx] = false;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines