… | |
… | |
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 | freed.push_back (*i);//D |
|
|
933 | //delete *i; |
909 | delete *i; |
934 | mortals.erase (i); |
910 | mortals.erase (i); |
935 | } |
911 | } |
936 | |
912 | |
937 | if (mortals.size() && 0)//D |
913 | static int lastmortals = 0;//D |
|
|
914 | |
|
|
915 | if (mortals.size() != lastmortals)//D |
|
|
916 | { |
|
|
917 | lastmortals = mortals.size ();//D |
938 | LOG (llevDebug, "%d objects in mortal queue\n", mortals.size());//D |
918 | LOG (llevDebug, "%d objects in mortal queue\n", lastmortals);//D |
|
|
919 | } |
939 | } |
920 | } |
940 | |
921 | |
941 | object::object () |
922 | object::object () |
942 | { |
923 | { |
943 | SET_FLAG (this, FLAG_REMOVED); |
924 | SET_FLAG (this, FLAG_REMOVED); |
944 | |
925 | |
945 | expmul = 1.0; |
926 | expmul = 1.0; |
946 | face = blank_face; |
927 | face = blank_face; |
947 | attacked_by_count = -1; |
|
|
948 | } |
928 | } |
949 | |
929 | |
950 | object::~object () |
930 | object::~object () |
951 | { |
931 | { |
952 | free_key_values (this); |
932 | free_key_values (this); |
953 | } |
933 | } |
954 | |
934 | |
955 | void object::link () |
935 | void object::link () |
956 | { |
936 | { |
957 | count = ++ob_count; |
937 | count = ++ob_count; |
|
|
938 | uuid = gen_uuid (); |
958 | |
939 | |
959 | prev = 0; |
940 | prev = 0; |
960 | next = objects; |
941 | next = objects; |
961 | |
942 | |
962 | if (objects) |
943 | if (objects) |
… | |
… | |
965 | objects = this; |
946 | objects = this; |
966 | } |
947 | } |
967 | |
948 | |
968 | void object::unlink () |
949 | void object::unlink () |
969 | { |
950 | { |
970 | count = 0; |
951 | //count = 0;//D |
971 | uuid = gen_uuid (); |
952 | if (!prev && !next) return;//D |
972 | |
953 | |
973 | if (this == objects) |
954 | if (this == objects) |
974 | objects = next; |
955 | objects = next; |
975 | |
956 | |
976 | /* Remove this object from the list of used objects */ |
957 | /* Remove this object from the list of used objects */ |
977 | if (prev) |
|
|
978 | { |
|
|
979 | prev->next = next; |
958 | if (prev) prev->next = next; |
|
|
959 | if (next) next->prev = prev; |
|
|
960 | |
980 | prev = 0; |
961 | prev = 0; |
981 | } |
|
|
982 | |
|
|
983 | if (next) |
|
|
984 | { |
|
|
985 | next->prev = prev; |
|
|
986 | next = 0; |
962 | next = 0; |
987 | } |
|
|
988 | } |
963 | } |
989 | |
964 | |
990 | object *object::create () |
965 | object *object::create () |
991 | { |
966 | { |
992 | object *op; |
|
|
993 | |
|
|
994 | if (freed.empty ()) |
|
|
995 | op = new object; |
967 | object *op = new object; |
996 | else |
|
|
997 | { |
|
|
998 | // highly annoying, but the only way to get it stable right now |
|
|
999 | op = freed.back (); |
|
|
1000 | freed.pop_back (); |
|
|
1001 | op->~object (); |
|
|
1002 | new ((void *) op) object; |
|
|
1003 | } |
|
|
1004 | |
|
|
1005 | op->link (); |
968 | op->link (); |
1006 | return op; |
969 | return op; |
1007 | } |
970 | } |
1008 | |
971 | |
1009 | /* |
972 | /* |
… | |
… | |
1075 | op = tmp; |
1038 | op = tmp; |
1076 | } |
1039 | } |
1077 | } |
1040 | } |
1078 | } |
1041 | } |
1079 | |
1042 | |
|
|
1043 | // clear those pointers that likely might have circular references to us |
1080 | owner = 0; |
1044 | owner = 0; |
|
|
1045 | enemy = 0; |
|
|
1046 | attacked_by = 0; |
1081 | |
1047 | |
1082 | /* Remove object from the active list */ |
1048 | /* Remove object from the active list */ |
1083 | speed = 0; |
1049 | speed = 0; |
1084 | update_ob_speed (this); |
1050 | update_ob_speed (this); |
1085 | |
1051 | |
… | |
… | |
2735 | |
2701 | |
2736 | if (tempfile == NULL) |
2702 | if (tempfile == NULL) |
2737 | { |
2703 | { |
2738 | LOG (llevError, "Error - Unable to access load object temp file\n"); |
2704 | LOG (llevError, "Error - Unable to access load object temp file\n"); |
2739 | return NULL; |
2705 | return NULL; |
2740 | }; |
2706 | } |
|
|
2707 | |
2741 | fprintf (tempfile, obstr); |
2708 | fprintf (tempfile, obstr); |
2742 | fclose (tempfile); |
2709 | fclose (tempfile); |
2743 | |
2710 | |
2744 | op = get_object (); |
2711 | op = get_object (); |
2745 | |
2712 | |