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.124 by root, Mon Jan 1 00:41:03 2007 UTC vs.
Revision 1.135 by root, Wed Jan 10 01:16:54 2007 UTC

32#include <sproto.h> 32#include <sproto.h>
33 33
34#include "cfperl.h" 34#include "cfperl.h"
35#include "shstr.h" 35#include "shstr.h"
36 36
37#include <unistd.h>
38#if _POSIX_MEMLOCK
39# include <sys/mman.h>
40#endif
41
37#include <EXTERN.h> 42#include <EXTERN.h>
38#include <perl.h> 43#include <perl.h>
39#include <XSUB.h> 44#include <XSUB.h>
40 45
41#include "CoroAPI.h" 46#include "CoroAPI.h"
94 99
95////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 100//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
96 101
97unordered_vector<attachable *> attachable::mortals; 102unordered_vector<attachable *> attachable::mortals;
98 103
99#if 0
100attachable *attachable::rc_first;
101
102attachable::attachable ()
103{
104 refcnt = 0;
105 rc_next = rc_first;
106 rc_first = this;
107}
108#endif
109
110attachable::~attachable () 104attachable::~attachable ()
111{ 105{
112 assert (!(flags & F_BORROWED));//D//TODO//remove when stable
113#if 0
114 assert (!rc_next);
115 assert (!refcnt); 106 assert (!self);
116#endif 107}
108
109int
110attachable::refcnt_cnt () const
111{
112 return refcnt + (self ? SvREFCNT (self) : 0);
113}
114
115void
116attachable::optimise ()
117{
118 if (self
119 && SvREFCNT (self) == 1
120 && !HvTOTALKEYS (self))
121 {
122 refcnt_inc ();
123 SvREFCNT_dec ((SV *)self);
124 }
117} 125}
118 126
119// check wether the object really is dead 127// check wether the object really is dead
120void 128void
121attachable::do_check () 129attachable::do_check ()
122{ 130{
123 if (refcnt > 0) 131 if (refcnt > 0 || refcnt_cnt () > 0)
124 return; 132 return;
125 133
126 // try to unborrow the refcnt from perl 134 destroy ();
127 if (flags & F_BORROWED) 135
136 if (self)
128 { 137 {
129 assert (self);//D//TODO//remove when stable 138 hv_clear (self);
130 flags &= ~F_BORROWED; 139 sv_unmagic ((SV *)self, PERL_MAGIC_ext);
131 refcnt_inc ();
132 SvREFCNT_dec (self); 140 SvREFCNT_dec (self);
141 self = 0;
133 } 142 }
134
135 if (refcnt > 0 || self)
136 return;
137
138 destroy ();
139} 143}
140 144
141void 145void
142attachable::do_destroy () 146attachable::do_destroy ()
143{ 147{
144 invoke (EVENT_ATTACHABLE_DESTROY, DT_END); 148 invoke (EVENT_ATTACHABLE_DESTROY, DT_END);
145 149
146 //TODO: call generic destroy callback 150 if (self)
151 hv_clear (self);
152
147 mortals.push_back (this); 153 mortals.push_back (this);
148} 154}
149 155
150void 156void
151attachable::destroy () 157attachable::destroy ()
155 161
156 flags |= F_DESTROYED; 162 flags |= F_DESTROYED;
157 do_destroy (); 163 do_destroy ();
158} 164}
159 165
166void
160void attachable::check_mortals () 167attachable::check_mortals ()
161{ 168{
162 for (int i = 0; i < mortals.size (); ) 169 for (int i = 0; i < mortals.size (); )
163 { 170 {
164 attachable *obj = mortals [i]; 171 attachable *obj = mortals [i];
165 172
209 216
210static int 217static int
211attachable_free (pTHX_ SV *sv, MAGIC *mg) 218attachable_free (pTHX_ SV *sv, MAGIC *mg)
212{ 219{
213 attachable *at = (attachable *)mg->mg_ptr; 220 attachable *at = (attachable *)mg->mg_ptr;
214 assert (!(at->flags & attachable::F_BORROWED));//D//TODO//remove when stable
215 at->self = 0; 221 at->self = 0;
216 // next line makes sense, but most objects still have refcnt 0 by default 222 // next line makes sense, but most objects still have refcnt 0 by default
217 //at->refcnt_chk (); 223 //at->refcnt_chk ();
218 return 0; 224 return 0;
219} 225}
230 { 236 {
231 obj->self = newHV (); 237 obj->self = newHV ();
232 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0); 238 sv_magicext ((SV *)obj->self, 0, PERL_MAGIC_ext, &attachable::vtbl, (char *)obj, 0);
233 239
234 // borrow the refcnt from the object 240 // borrow the refcnt from the object
235 obj->flags |= attachable::F_BORROWED; 241 // it is important thta no refcnt_chk is being executed here
236 obj->refcnt_dec (); 242 obj->refcnt_dec ();
243
244 // now bless the object _once_
245 return sv_bless (newRV_inc ((SV *)obj->self), stash);
237 } 246 }
238 247 else
239 return sv_bless (newRV_inc ((SV *)obj->self), stash); 248 return newRV_inc ((SV *)obj->self);
240} 249}
241 250
242static void 251static void
243clearSVptr (SV *sv) 252clearSVptr (SV *sv)
244{ 253{
328inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); } 337inline void sv_to (SV *sv, client * &v) { v = (client *)(attachable *)SvPTR_ornull (sv, "cf::client"); }
329inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); } 338inline void sv_to (SV *sv, player * &v) { v = (player *)(attachable *)SvPTR_ornull (sv, "cf::player"); }
330inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); } 339inline void sv_to (SV *sv, object * &v) { v = (object *)(attachable *)SvPTR_ornull (sv, "cf::object"); }
331inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); } 340inline void sv_to (SV *sv, archetype * &v) { v = (archetype *)(attachable *)SvPTR_ornull (sv, "cf::arch"); }
332inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); } 341inline void sv_to (SV *sv, maptile * &v) { v = (maptile *)(attachable *)SvPTR_ornull (sv, "cf::map"); }
342inline void sv_to (SV *sv, attachable * &v) { v = (attachable *)SvPTR_ornull (sv, "cf::attachable"); }
333inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); } 343inline void sv_to (SV *sv, partylist * &v) { v = (partylist *)SvPTR_ornull (sv, "cf::party"); }
334inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); } 344inline void sv_to (SV *sv, region * &v) { v = (region *)SvPTR_ornull (sv, "cf::region"); }
335inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); } 345inline void sv_to (SV *sv, living * &v) { v = (living *)SvPTR_ornull (sv, "cf::living"); }
336 346
337inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } //TODO 347inline void sv_to (SV *sv, New_Face * &v) { v = &new_faces[FindFace (SvPV_nolen (sv), 0)]; } //TODO
504 } 514 }
505 515
506 attach = 0; 516 attach = 0;
507} 517}
508#endif 518#endif
509
510void attachable::optimise ()
511{
512 if (self
513 && SvREFCNT (self) == 1
514 && !HvTOTALKEYS (self))
515 {
516 flags &= ~F_BORROWED;
517 refcnt_inc ();
518 SvREFCNT_dec ((SV *)self);
519 }
520}
521 519
522///////////////////////////////////////////////////////////////////////////// 520/////////////////////////////////////////////////////////////////////////////
523 521
524extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr) 522extern "C" int cfperl_initPlugin (const char *iversion, f_plug_api gethooksptr)
525{ 523{
820} 818}
821 819
822///////////////////////////////////////////////////////////////////////////// 820/////////////////////////////////////////////////////////////////////////////
823 821
824void 822void
825maptile::emergency_save () 823cfperl_emergency_save ()
826{ 824{
827 CALL_BEGIN (0); 825 CALL_BEGIN (0);
828 CALL_CALL ("cf::map::emergency_save", G_VOID); 826 CALL_CALL ("cf::emergency_save", G_VOID);
829 CALL_END; 827 CALL_END;
830} 828}
831 829
832maptile * 830maptile *
833maptile::load_map_sync (const char *path, maptile *origin) 831maptile::find_sync (const char *path, maptile *origin)
834{ 832{
835 CALL_BEGIN (2); 833 CALL_BEGIN (2);
836 CALL_ARG (path); 834 CALL_ARG (path);
837 CALL_ARG (origin); 835 CALL_ARG (origin);
838 CALL_CALL ("cf::map::load_map_sync", G_SCALAR); 836 CALL_CALL ("cf::map::find_sync", G_SCALAR);
839 837
840 maptile *retval; 838 maptile *retval;
841 839
842 if (count) 840 if (count)
843 sv_to (POPs, retval); 841 sv_to (POPs, retval);
845 retval = 0; 843 retval = 0;
846 844
847 CALL_END; 845 CALL_END;
848 846
849 return retval; 847 return retval;
848}
849
850maptile *
851maptile::find_async (const char *path, maptile *origin)
852{
853 CALL_BEGIN (2);
854 CALL_ARG (path);
855 CALL_ARG (origin);
856 CALL_CALL ("cf::map::find_async", G_SCALAR);
857
858 maptile *retval;
859
860 if (count)
861 sv_to (POPs, retval);
862 else
863 retval = 0;
864
865 CALL_END;
866
867 return retval;
868}
869
870void
871maptile::do_load_sync ()
872{
873 CALL_BEGIN (1);
874 CALL_ARG (this);
875 CALL_CALL ("cf::map::do_load_sync", G_SCALAR);
876 CALL_END;
850} 877}
851 878
852void 879void
853maptile::change_all_map_light (int change) 880maptile::change_all_map_light (int change)
854{ 881{
1461 const_iv (ST_SETUP) 1488 const_iv (ST_SETUP)
1462 const_iv (ST_PLAYING) 1489 const_iv (ST_PLAYING)
1463 const_iv (ST_CUSTOM) 1490 const_iv (ST_CUSTOM)
1464 1491
1465 const_iv (ST_CHANGE_CLASS) 1492 const_iv (ST_CHANGE_CLASS)
1466 const_iv (ST_CONFIRM_QUIT)
1467 const_iv (ST_GET_PARTY_PASSWORD)
1468 1493
1469 const_iv (IO_HEADER) 1494 const_iv (IO_HEADER)
1470 const_iv (IO_OBJECTS) 1495 const_iv (IO_OBJECTS)
1471 const_iv (IO_UNIQUES) 1496 const_iv (IO_UNIQUES)
1472 1497
1526 1551
1527void _global_reattach () 1552void _global_reattach ()
1528 CODE: 1553 CODE:
1529{ 1554{
1530 // reattach to all attachable objects in the game. 1555 // reattach to all attachable objects in the game.
1531 for (sockvec::iterator i = clients.begin (); i != clients.end (); ++i) 1556 for_all_clients (ns)
1532 (*i)->reattach (); 1557 ns->reattach ();
1533 1558
1534 for_all_players (pl) 1559 for_all_players (pl)
1535 pl->reattach (); 1560 pl->reattach ();
1536 1561
1537 //TODO 1562 //TODO
1538 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i) 1563 //for (map_container::iterator i = maps.begin (); i != maps.end (); ++i)
1539 // i->second->reattach (); 1564 // i->second->reattach ();
1540 1565
1541 for (object *op = object::first; op; op = op->next) 1566 for_all_objects (op)
1542 op->reattach (); 1567 op->reattach ();
1543} 1568}
1544 1569
1545NV floor (NV x) 1570NV floor (NV x)
1546 1571
1599 } 1624 }
1600 OUTPUT: RETVAL 1625 OUTPUT: RETVAL
1601 1626
1602void abort () 1627void abort ()
1603 1628
1629void cleanup (const char *cause, bool make_core = false)
1630
1604void emergency_save () 1631void emergency_save ()
1605 1632
1606void _exit (int status = 0) 1633void _exit (int status = 0)
1634
1635#if _POSIX_MEMLOCK
1636
1637int mlockall (int flags = MCL_CURRENT | MCL_FUTURE)
1638
1639int munlockall ()
1640
1641#endif
1607 1642
1608int find_animation (char *text) 1643int find_animation (char *text)
1609 PROTOTYPE: $ 1644 PROTOTYPE: $
1610 1645
1611int random_roll (int min, int max, object *op, int goodbad); 1646int random_roll (int min, int max, object *op, int goodbad);
1658 CODE: 1693 CODE:
1659 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext); 1694 RETVAL = SvROK (obj) && mg_find (SvRV (obj), PERL_MAGIC_ext);
1660 OUTPUT: 1695 OUTPUT:
1661 RETVAL 1696 RETVAL
1662 1697
1663#bool 1698INCLUDE: $PERL genacc attachable ../include/cfperl.h |
1664#destroyed (attachable *at)
1665#
1666#void
1667#destroy (attachable *at)
1668 1699
1669MODULE = cf PACKAGE = cf::global 1700MODULE = cf PACKAGE = cf::global
1670 1701
1671int invoke (SV *klass, int event, ...) 1702int invoke (SV *klass, int event, ...)
1672 CODE: 1703 CODE:
1694 PPCODE: 1725 PPCODE:
1695 EXTEND (SP, object::mortals.size ()); 1726 EXTEND (SP, object::mortals.size ());
1696 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i) 1727 for (AUTODECL (i, object::mortals.begin ()); i != object::mortals.end (); ++i)
1697 PUSHs (to_sv (*i)); 1728 PUSHs (to_sv (*i));
1698 1729
1699object *first () 1730int objects_size ()
1700 CODE: 1731 CODE:
1701 RETVAL = object::first; 1732 RETVAL = objects.size ();
1733 OUTPUT: RETVAL
1734
1735object *objects (U32 index)
1736 CODE:
1737 RETVAL = index < objects.size () ? objects [index] : 0;
1738 OUTPUT: RETVAL
1739
1740int actives_size ()
1741 CODE:
1742 RETVAL = actives.size ();
1743 OUTPUT: RETVAL
1744
1745object *actives (U32 index)
1746 CODE:
1747 RETVAL = index < actives.size () ? actives [index] : 0;
1702 OUTPUT: RETVAL 1748 OUTPUT: RETVAL
1703 1749
1704# missing properties 1750# missing properties
1705 1751
1706object *head (object *op) 1752object *head (object *op)
1707 PROTOTYPE: $ 1753 PROTOTYPE: $
1708 CODE: 1754 CODE:
1709 RETVAL = op->head ? op->head : op; 1755 RETVAL = op->head_ ();
1710 OUTPUT: RETVAL 1756 OUTPUT: RETVAL
1711 1757
1712int is_head (object *op) 1758int is_head (object *op)
1713 PROTOTYPE: $ 1759 PROTOTYPE: $
1714 CODE: 1760 CODE:
1715 RETVAL = !op->head; 1761 RETVAL = op->head_ () == op;
1716 OUTPUT: RETVAL 1762 OUTPUT: RETVAL
1717 1763
1718void 1764void
1719inv (object *obj) 1765inv (object *obj)
1720 PROTOTYPE: $ 1766 PROTOTYPE: $
1975 CODE: 2021 CODE:
1976 pl->ob->stats.hp = pl->ob->stats.maxhp; 2022 pl->ob->stats.hp = pl->ob->stats.maxhp;
1977 pl->ob->stats.sp = pl->ob->stats.maxsp; 2023 pl->ob->stats.sp = pl->ob->stats.maxsp;
1978 pl->ob->stats.grace = pl->ob->stats.maxgrace; 2024 pl->ob->stats.grace = pl->ob->stats.maxgrace;
1979 pl->orig_stats = pl->ob->stats; 2025 pl->orig_stats = pl->ob->stats;
1980
1981player *cf_player_find (char *name)
1982 PROTOTYPE: $
1983 2026
1984void cf_player_move (player *pl, int dir) 2027void cf_player_move (player *pl, int dir)
1985 2028
1986void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0); 2029void play_sound_player_only (player *pl, int soundnum, int x = 0, int y = 0);
1987 2030
2033 if (y) sv_to (y, pl->bed_y); 2076 if (y) sv_to (y, pl->bed_y);
2034 2077
2035void 2078void
2036list () 2079list ()
2037 PPCODE: 2080 PPCODE:
2038 for (player *pl = first_player; pl; pl = pl->next) 2081 for_all_players (pl)
2039 XPUSHs (sv_2mortal (to_sv (pl))); 2082 XPUSHs (sv_2mortal (to_sv (pl)));
2040
2041bool
2042peaceful (player *pl, bool new_setting = 0)
2043 PROTOTYPE: $;$
2044 CODE:
2045 RETVAL = pl->peaceful;
2046 if (items > 1)
2047 pl->peaceful = new_setting;
2048 OUTPUT:
2049 RETVAL
2050
2051living *
2052orig_stats (player *pl)
2053 CODE:
2054 RETVAL = &pl->orig_stats;
2055 OUTPUT: RETVAL
2056
2057living *
2058last_stats (player *pl)
2059 CODE:
2060 RETVAL = &pl->last_stats;
2061 OUTPUT: RETVAL
2062 2083
2063 2084
2064MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 2085MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2065 2086
2066int invoke (maptile *map, int event, ...) 2087int invoke (maptile *map, int event, ...)
2082 PROTOTYPE: 2103 PROTOTYPE:
2083 CODE: 2104 CODE:
2084 RETVAL = new maptile; 2105 RETVAL = new maptile;
2085 OUTPUT: 2106 OUTPUT:
2086 RETVAL 2107 RETVAL
2087
2088void
2089maptile::destroy ()
2090 2108
2091void 2109void
2092maptile::players () 2110maptile::players ()
2093 PPCODE: 2111 PPCODE:
2094 if (GIMME_V == G_SCALAR) 2112 if (GIMME_V == G_SCALAR)
2362 char *buf = SvPVbyte (packet, len); 2380 char *buf = SvPVbyte (packet, len);
2363 2381
2364 THIS->send_packet (buf, len); 2382 THIS->send_packet (buf, len);
2365} 2383}
2366 2384
2367void
2368client::destroy ()
2369

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines