… | |
… | |
515 | { |
515 | { |
516 | LOG (llevDebug, "%d allocated objects\n", nrofallocobjects); |
516 | LOG (llevDebug, "%d allocated objects\n", nrofallocobjects); |
517 | } |
517 | } |
518 | |
518 | |
519 | /* |
519 | /* |
520 | * Returns the object which this object marks as being the owner. |
|
|
521 | * A id-scheme is used to avoid pointing to objects which have been |
|
|
522 | * freed and are now reused. If this is detected, the owner is |
|
|
523 | * set to NULL, and NULL is returned. |
|
|
524 | * Changed 2004-02-12 - if the player is setting at the play again |
|
|
525 | * prompt, he is removed, and we don't want to treat him as an owner of |
|
|
526 | * anything, so check removed flag. I don't expect that this should break |
|
|
527 | * anything - once an object is removed, it is basically dead anyways. |
|
|
528 | */ |
|
|
529 | object * |
|
|
530 | object::get_owner () |
|
|
531 | { |
|
|
532 | if (!owner |
|
|
533 | || QUERY_FLAG (owner, FLAG_FREED) |
|
|
534 | || QUERY_FLAG (owner, FLAG_REMOVED)) |
|
|
535 | owner = 0; |
|
|
536 | |
|
|
537 | return owner; |
|
|
538 | } |
|
|
539 | |
|
|
540 | /* |
|
|
541 | * Sets the owner and sets the skill and exp pointers to owner's current |
520 | * Sets the owner and sets the skill and exp pointers to owner's current |
542 | * skill and experience objects. |
521 | * skill and experience objects. |
543 | */ |
522 | */ |
544 | void |
523 | void |
545 | object::set_owner (object *owner) |
524 | object::set_owner (object *owner) |
… | |
… | |
612 | |
591 | |
613 | /* What is not cleared is next, prev, and count */ |
592 | /* What is not cleared is next, prev, and count */ |
614 | |
593 | |
615 | expmul = 1.0; |
594 | expmul = 1.0; |
616 | face = blank_face; |
595 | face = blank_face; |
617 | attacked_by_count = -1; |
|
|
618 | |
596 | |
619 | if (settings.casting_time) |
597 | if (settings.casting_time) |
620 | casting_time = -1; |
598 | casting_time = -1; |
621 | } |
599 | } |
622 | |
600 | |
… | |
… | |
918 | if (op->more != NULL) |
896 | if (op->more != NULL) |
919 | update_object (op->more, action); |
897 | update_object (op->more, action); |
920 | } |
898 | } |
921 | |
899 | |
922 | static unordered_vector<object *> mortals; |
900 | static unordered_vector<object *> mortals; |
923 | static std::vector<object *, slice_allocator <object *> > freed; |
|
|
924 | |
901 | |
925 | void object::free_mortals () |
902 | void object::free_mortals () |
926 | { |
903 | { |
927 | for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();) |
904 | for (unordered_vector<object *>::iterator i = mortals.begin (); i != mortals.end ();) |
928 | if ((*i)->refcnt) |
905 | if ((*i)->refcnt) |
929 | ++i; // further delay freeing |
906 | ++i; // further delay freeing |
930 | else |
907 | else |
931 | { |
908 | { |
932 | //printf ("free_mortal(%p,%ld,%ld)\n", *i, pticks, (*i)->count);//D |
|
|
933 | //freed.push_back (*i);//D |
|
|
934 | delete *i; |
909 | delete *i; |
935 | mortals.erase (i); |
910 | mortals.erase (i); |
936 | } |
911 | } |
937 | |
912 | |
938 | if (mortals.size() && 0)//D |
913 | static int lastmortals = 0;//D |
|
|
914 | |
|
|
915 | if (mortals.size() != lastmortals)//D |
|
|
916 | { |
|
|
917 | lastmortals = mortals.size ();//D |
939 | LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D |
918 | LOG (llevDebug, "%d objects in mortal queue\n", lastmortals);//D |
|
|
919 | } |
940 | } |
920 | } |
941 | |
921 | |
942 | object::object () |
922 | object::object () |
943 | { |
923 | { |
944 | SET_FLAG (this, FLAG_REMOVED); |
924 | SET_FLAG (this, FLAG_REMOVED); |
945 | |
925 | |
946 | expmul = 1.0; |
926 | expmul = 1.0; |
947 | face = blank_face; |
927 | face = blank_face; |
948 | attacked_by_count = -1; |
|
|
949 | } |
928 | } |
950 | |
929 | |
951 | object::~object () |
930 | object::~object () |
952 | { |
931 | { |
953 | free_key_values (this); |
932 | free_key_values (this); |
… | |
… | |
983 | next = 0; |
962 | next = 0; |
984 | } |
963 | } |
985 | |
964 | |
986 | object *object::create () |
965 | object *object::create () |
987 | { |
966 | { |
988 | object *op; |
|
|
989 | |
|
|
990 | if (freed.empty ()) |
|
|
991 | op = new object; |
967 | object *op = new object; |
992 | else |
|
|
993 | { |
|
|
994 | // highly annoying, but the only way to get it stable right now |
|
|
995 | op = freed.back (); |
|
|
996 | freed.pop_back (); |
|
|
997 | op->~object (); |
|
|
998 | new ((void *) op) object; |
|
|
999 | } |
|
|
1000 | |
|
|
1001 | op->link (); |
968 | op->link (); |
1002 | return op; |
969 | return op; |
1003 | } |
970 | } |
1004 | |
971 | |
1005 | /* |
972 | /* |
… | |
… | |
1022 | |
989 | |
1023 | if (!QUERY_FLAG (this, FLAG_REMOVED)) |
990 | if (!QUERY_FLAG (this, FLAG_REMOVED)) |
1024 | remove_ob (this); |
991 | remove_ob (this); |
1025 | |
992 | |
1026 | SET_FLAG (this, FLAG_FREED); |
993 | SET_FLAG (this, FLAG_FREED); |
1027 | |
|
|
1028 | //printf ("free(%p,%ld,%ld)\n", this, pticks, count);//D |
|
|
1029 | |
994 | |
1030 | if (more) |
995 | if (more) |
1031 | { |
996 | { |
1032 | more->free (free_inventory); |
997 | more->free (free_inventory); |
1033 | more = 0; |
998 | more = 0; |