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.17 by root, Sun Aug 27 17:59:26 2006 UTC vs.
Revision 1.18 by root, Mon Aug 28 07:07:42 2006 UTC

362 INVOKE_OBJECT (INSTANTIATE, this); 362 INVOKE_OBJECT (INSTANTIATE, this);
363} 363}
364 364
365///////////////////////////////////////////////////////////////////////////// 365/////////////////////////////////////////////////////////////////////////////
366 366
367void reattach (data_type type, void *obj)
368{
369 dSP;
370 ENTER;
371 SAVETMPS;
372 PUSHMARK (SP);
373 XPUSHs (sv_2mortal (newSVdt (type, obj)));
374 PUTBACK;
375 call_pv ("cf::reattach", G_DISCARD | G_VOID | G_EVAL);
376 FREETMPS;
377 LEAVE;
378
379 switch (type)
380 {
381 case DT_OBJECT: INVOKE_OBJECT (REATTACH, obj); break;
382 case DT_PLAYER: INVOKE_PLAYER (REATTACH, obj); break;
383 case DT_MAP: INVOKE_MAP (REATTACH, obj); break;
384 }
385}
386
387template<class subclass>
388void reattach (attachable<subclass> *obj)
389{
390 obj->optimise ();
391
392 if (obj->self)
393 reattach (subclass::get_dt (), (subclass *)obj);
394}
395
367object_freezer::object_freezer (const char *filename) 396object_freezer::object_freezer (const char *filename)
368: filename (filename) 397: filename (filename)
369{ 398{
370 av = (AV *)newAV (); 399 av = (AV *)newAV ();
371 idx = 0;
372 av_extend ((AV *)av, 1024);
373} 400}
374 401
375object_freezer::~object_freezer () 402object_freezer::~object_freezer ()
376{ 403{
377 dSP; 404 dSP;
384 call_pv ("cf::object_freezer_save", G_VOID | G_DISCARD | G_EVAL); 411 call_pv ("cf::object_freezer_save", G_VOID | G_DISCARD | G_EVAL);
385 FREETMPS; 412 FREETMPS;
386 LEAVE; 413 LEAVE;
387} 414}
388 415
389void object_freezer::put (attachable_base *ext) 416void object_freezer::put (FILE *fp, attachable_base *ext)
390{ 417{
391 ext->optimise (); 418 ext->optimise ();
392 419
393 if (ext->self) 420 if (ext->self)
421 {
422 int idx = AvFILLp ((AV *)av) + 1;
394 av_store ((AV *)av, idx, SvREFCNT_inc ((SV *)ext->self)); 423 av_store ((AV *)av, idx, SvREFCNT_inc ((SV *)ext->self));
395 424 fprintf (fp, "oid %d\n", idx);
396 ++idx; 425 }
397} 426}
398 427
399object_thawer::object_thawer (const char *filename) 428object_thawer::object_thawer (const char *filename)
400{ 429{
401 av = 0; 430 av = 0;
402 idx = 0;
403 431
404 if (!filename) 432 if (!filename)
405 return; 433 return;
406 434
407 dSP; 435 dSP;
421 449
422 FREETMPS; 450 FREETMPS;
423 LEAVE; 451 LEAVE;
424} 452}
425 453
426void reattach (data_type type, void *obj)
427{
428 dSP;
429 ENTER;
430 SAVETMPS;
431 PUSHMARK (SP);
432 XPUSHs (sv_2mortal (newSVdt (type, obj)));
433 PUTBACK;
434 call_pv ("cf::reattach", G_DISCARD | G_VOID | G_EVAL);
435 FREETMPS;
436 LEAVE;
437
438 switch (type)
439 {
440 case DT_OBJECT: INVOKE_OBJECT (REATTACH, obj); break;
441 case DT_PLAYER: INVOKE_PLAYER (REATTACH, obj); break;
442 case DT_MAP: INVOKE_MAP (REATTACH, obj); break;
443 }
444}
445
446template<class subclass>
447void reattach (attachable<subclass> *obj)
448{
449 obj->optimise ();
450
451 if (obj->self)
452 reattach (subclass::get_dt (), (subclass *)obj);
453}
454
455void object_thawer::get (data_type type, void *obj, attachable_base *ext) 454void object_thawer::get (data_type type, void *obj, attachable_base *ext, int oid)
456{ 455{
457 if (!av) 456 if (!av || oid < 0) // this is actually an error of sorts
458 return; 457 return;
459 458
460 // we have to "re-instantiate"/reattach to an object, so nuke ext->attach 459 // we have to "re-instantiate"/reattach to an object, so nuke ext->attach
461 ext->clear (); 460 ext->clear ();
462 461
463 SV **svp = av_fetch ((AV *)av, idx, 0); 462 SV **svp = av_fetch ((AV *)av, oid, 0);
464 463
465 ++idx;
466
467 if (!svp)
468 return;
469
470 if (SvROK (*svp)) 464 if (!svp || !SvROK (*svp))
471 { 465 {
472 ext->self = SvREFCNT_inc (*svp); 466 printf ("trying to thaw duplicate or never-issued oid %d, ignoring.\n", oid);
473 sv_magic (SvRV ((SV *)ext->self), 0, PERL_MAGIC_ext, (char *)obj, 0); 467 return;
474
475 reattach (type, obj);
476 } 468 }
469
470 ext->self = *svp; *svp = &PL_sv_undef;
471 sv_magic (SvRV ((SV *)ext->self), 0, PERL_MAGIC_ext, (char *)obj, 0);
472
473 reattach (type, obj);
477} 474}
478 475
479object_thawer::~object_thawer () 476object_thawer::~object_thawer ()
480{ 477{
481 if (av) 478 if (av)
638# define def(type,name) KLASS_ ## type, 635# define def(type,name) KLASS_ ## type,
639# include "eventinc.h" 636# include "eventinc.h"
640# undef def 637# undef def
641}; 638};
642 639
640#define KLASS_OF(event) (((unsigned int)event) < NUM_EVENT_TYPES ? klass_of [event] : KLASS_NONE)
641
643static void 642static void
644gather_callbacks (AV *&callbacks, AV *registry, event_type event) 643gather_callbacks (AV *&callbacks, AV *registry, event_type event)
645{ 644{
646 // event must be in array 645 // event must be in array
647 if (event >= 0 && event <= AvFILLp (registry)) 646 if (event >= 0 && event <= AvFILLp (registry))
689 // 2a. per-type callback 688 // 2a. per-type callback
690 // 4. global callbacks 689 // 4. global callbacks
691 690
692 gather_callbacks (callbacks, cb_global, event); 691 gather_callbacks (callbacks, cb_global, event);
693 692
694 switch (klass_of [event]) 693 switch (KLASS_OF (event))
695 { 694 {
696 case KLASS_GLOBAL: 695 case KLASS_GLOBAL:
697 break; 696 break;
698 697
699 case KLASS_OBJECT: 698 case KLASS_OBJECT:
765 EXTEND (SP, 3); 764 EXTEND (SP, 3);
766 765
767 PUSHs (sv_2mortal (newSViv (event))); // only used for debugging nowadays 766 PUSHs (sv_2mortal (newSViv (event))); // only used for debugging nowadays
768 PUSHs (sv_2mortal (newRV_noinc ((SV *)callbacks))); 767 PUSHs (sv_2mortal (newRV_noinc ((SV *)callbacks)));
769 768
770 switch (klass_of [event]) 769 switch (KLASS_OF (event))
771 { 770 {
772 case KLASS_OBJECT: PUSHs (sv_2mortal (newSVdt (DT_OBJECT, op))); break; 771 case KLASS_OBJECT: PUSHs (sv_2mortal (newSVdt (DT_OBJECT, op))); break;
773 case KLASS_PLAYER: PUSHs (sv_2mortal (newSVdt (DT_PLAYER, pl))); break; 772 case KLASS_PLAYER: PUSHs (sv_2mortal (newSVdt (DT_PLAYER, pl))); break;
774 case KLASS_MAP: PUSHs (sv_2mortal (newSVdt (DT_MAP, map))); break; 773 case KLASS_MAP: PUSHs (sv_2mortal (newSVdt (DT_MAP, map))); break;
775 } 774 }
1558 1557
1559int random_roll(int min, int max, object *op, int goodbad); 1558int random_roll(int min, int max, object *op, int goodbad);
1560 1559
1561const char *cost_string_from_value(uint64 cost, int approx = 0) 1560const char *cost_string_from_value(uint64 cost, int approx = 0)
1562 1561
1563int invoke (int event, SV *arg1, ...) 1562int invoke (int event, ...)
1564 CODE: 1563 CODE:
1565{ 1564 if (KLASS_OF (event) != KLASS_GLOBAL) croak ("event class must be GLOBAL");
1566 // parse first arg and call invoke_object etc as seen fit 1565 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); for (int i = 1; i < items; i++) av_push (av, ST (i));
1567 //TODO 1566 RETVAL = INVOKE_((event_type)event, ARG_AV (av));
1568 //cfperl_invoke (event, 1567 OUTPUT: RETVAL
1569}
1570 1568
1571int 1569int
1572exp_to_level (val64 exp) 1570exp_to_level (val64 exp)
1573 CODE: 1571 CODE:
1574{ 1572{
1606 else 1604 else
1607 XSRETURN_UNDEF; 1605 XSRETURN_UNDEF;
1608 OUTPUT: RETVAL 1606 OUTPUT: RETVAL
1609 1607
1610MODULE = cf PACKAGE = cf::object PREFIX = cf_object_ 1608MODULE = cf PACKAGE = cf::object PREFIX = cf_object_
1609
1610int invoke (object *op, int event, ...)
1611 CODE:
1612 if (KLASS_OF (event) != KLASS_OBJECT) croak ("event class must be OBJECT");
1613 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); for (int i = 2; i < items; i++) av_push (av, ST (i));
1614 RETVAL = INVOKE_((event_type)event, ARG_OBJECT (op), ARG_AV (av));
1615 OUTPUT: RETVAL
1616
1617SV *registry (object *op)
1618 CODE:
1619 RETVAL = registry_of (op);
1620 OUTPUT:
1621 RETVAL
1611 1622
1612SV * 1623SV *
1613get_property (object *obj, int type, int idx) 1624get_property (object *obj, int type, int idx)
1614 CODE: 1625 CODE:
1615 RETVAL = newSVcfapi (type, cf_object_get_property (obj, idx)); 1626 RETVAL = newSVcfapi (type, cf_object_get_property (obj, idx));
1813{ 1824{
1814 int unused_type; 1825 int unused_type;
1815 RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y); 1826 RETVAL = (object *)object_insert (&unused_type, ob, 0, where, orig, flag, x, y);
1816} 1827}
1817 1828
1818SV *registry (object *op)
1819 CODE:
1820 RETVAL = registry_of (op);
1821 OUTPUT:
1822 RETVAL
1823
1824# syntatic sugar for easier use in event callbacks. 1829# syntatic sugar for easier use in event callbacks.
1825const char *options (object *op) 1830const char *options (object *op)
1826 CODE: 1831 CODE:
1827 RETVAL = op->name; 1832 RETVAL = op->name;
1828 OUTPUT: 1833 OUTPUT:
1899void cf_player_set_party (object *op, partylist *party) 1904void cf_player_set_party (object *op, partylist *party)
1900 1905
1901void kill_player (object *op) 1906void kill_player (object *op)
1902 1907
1903MODULE = cf PACKAGE = cf::player PREFIX = cf_player_ 1908MODULE = cf PACKAGE = cf::player PREFIX = cf_player_
1909
1910int invoke (player *pl, int event, ...)
1911 CODE:
1912 if (KLASS_OF (event) != KLASS_PLAYER) croak ("event class must be PLAYER");
1913 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); for (int i = 2; i < items; i++) av_push (av, ST (i));
1914 RETVAL = INVOKE_((event_type)event, ARG_PLAYER (pl), ARG_AV (av));
1915 OUTPUT: RETVAL
1904 1916
1905SV *registry (player *pl) 1917SV *registry (player *pl)
1906 CODE: 1918 CODE:
1907 RETVAL = registry_of (pl); 1919 RETVAL = registry_of (pl);
1908 OUTPUT: 1920 OUTPUT:
2032 RETVAL = &pl->last_stats; 2044 RETVAL = &pl->last_stats;
2033 OUTPUT: RETVAL 2045 OUTPUT: RETVAL
2034 2046
2035 2047
2036MODULE = cf PACKAGE = cf::map PREFIX = cf_map_ 2048MODULE = cf PACKAGE = cf::map PREFIX = cf_map_
2049
2050int invoke (mapstruct *map, int event, ...)
2051 CODE:
2052 if (KLASS_OF (event) != KLASS_MAP) croak ("event class must be MAP");
2053 AV *av = (AV *)sv_2mortal ((SV *)newAV ()); for (int i = 2; i < items; i++) av_push (av, ST (i));
2054 RETVAL = INVOKE_((event_type)event, ARG_MAP (map), ARG_AV (av));
2055 OUTPUT:
2056 RETVAL
2037 2057
2038SV *registry (mapstruct *map) 2058SV *registry (mapstruct *map)
2039 CODE: 2059 CODE:
2040 RETVAL = registry_of (map); 2060 RETVAL = registry_of (map);
2041 OUTPUT: 2061 OUTPUT:

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines