diff --git a/src/group.h b/src/group.h --- a/src/group.h +++ b/src/group.h @@ -13,40 +13,31 @@ enum { INVALID_GROUP = 0xFFFF, }; -struct Group { +struct Group; +DECLARE_OLD_POOL(Group, Group, 5, 2047) + +struct Group : PoolItem { StringID string_id; ///< Group Name uint16 num_vehicle; ///< Number of vehicles wich belong to the group PlayerID owner; ///< Group Owner - GroupID index; ///< Array index VehicleTypeByte vehicle_type; ///< Vehicle type of the group bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group uint16 num_engines[TOTAL_NUM_ENGINES]; ///< Caches the number of engines of each type the player owns (no need to save this) + + Group(StringID str = STR_NULL); + virtual ~Group(); + + void QuickFree(); + + bool IsValid() const; }; -DECLARE_OLD_POOL(Group, Group, 5, 2047) - - -static inline bool IsValidGroup(const Group *g) -{ - return g->string_id != STR_NULL; -} - -static inline void DestroyGroup(Group *g) -{ - DeleteName(g->string_id); -} - -static inline void DeleteGroup(Group *g) -{ - DestroyGroup(g); - g->string_id = STR_NULL; -} static inline bool IsValidGroupID(GroupID index) { - return index < GetGroupPoolSize() && IsValidGroup(GetGroup(index)); + return index < GetGroupPoolSize() && GetGroup(index)->IsValid(); } static inline bool IsDefaultGroupID(GroupID index) @@ -64,7 +55,7 @@ static inline bool IsAllGroupID(GroupID return id_g == ALL_GROUP; } -#define FOR_ALL_GROUPS_FROM(g, start) for (g = GetGroup(start); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) if (IsValidGroup(g)) +#define FOR_ALL_GROUPS_FROM(g, start) for (g = GetGroup(start); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) if (g->IsValid()) #define FOR_ALL_GROUPS(g) FOR_ALL_GROUPS_FROM(g, 0) /** diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -19,6 +19,7 @@ #include "window.h" #include "vehicle_gui.h" #include "strings.h" +#include "misc/autoptr.hpp" /** * Update the num engines of a groupID. Decrease the old one and increase the new one @@ -39,41 +40,34 @@ static inline void UpdateNumEngineGroup( } -/** - * Called if a new block is added to the group-pool - */ -static void GroupPoolNewBlock(uint start_item) +DEFINE_OLD_POOL_GENERIC(Group, Group) + + +Group::Group(StringID str) { - /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. - * TODO - This is just a temporary stage, this will be removed. */ - for (Group *g = GetGroup(start_item); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) g->index = start_item++; + this->string_id = str; } -DEFINE_OLD_POOL(Group, Group, GroupPoolNewBlock, NULL) - -static Group *AllocateGroup(void) +Group::~Group() { - /* We don't use FOR_ALL here, because FOR_ALL skips invalid items. - * TODO - This is just a temporary stage, this will be removed. */ - for (Group *g = GetGroup(0); g != NULL; g = (g->index + 1U < GetGroupPoolSize()) ? GetGroup(g->index + 1) : NULL) { - if (!IsValidGroup(g)) { - const GroupID index = g->index; + this->QuickFree(); + this->string_id = STR_NULL; +} - memset(g, 0, sizeof(*g)); - g->index = index; +void Group::QuickFree() +{ + DeleteName(this->string_id); +} - return g; - } - } - - /* Check if we can add a block to the pool */ - return (AddBlockToPool(&_Group_pool)) ? AllocateGroup() : NULL; +bool Group::IsValid() const +{ + return this->string_id != STR_NULL; } void InitializeGroup(void) { - CleanPool(&_Group_pool); - AddBlockToPool(&_Group_pool); + _Group_pool.CleanPool(); + _Group_pool.AddBlockToPool(); } @@ -100,16 +94,21 @@ CommandCost CmdCreateGroup(TileIndex til VehicleType vt = (VehicleType)p1; if (!IsPlayerBuildableVehicleType(vt)) return CMD_ERROR; - Group *g = AllocateGroup(); + AutoPtrT g_auto_delete; + + Group *g = new Group(STR_EMPTY); if (g == NULL) return CMD_ERROR; + g_auto_delete = g; + if (flags & DC_EXEC) { g->owner = _current_player; - g->string_id = STR_EMPTY; g->replace_protection = false; g->vehicle_type = vt; InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player); + + g_auto_delete.Detach(); } return CommandCost(); @@ -153,7 +152,7 @@ CommandCost CmdDeleteGroup(TileIndex til /* Delete the Replace Vehicle Windows */ DeleteWindowById(WC_REPLACE_VEHICLE, g->vehicle_type); - DeleteGroup(g); + delete g; InvalidateWindowData(GetWCForVT(vt), (vt << 11) | VLW_GROUP_LIST | _current_player); } @@ -416,7 +415,7 @@ void RemoveAllGroupsForPlayer(const Play Group *g; FOR_ALL_GROUPS(g) { - if (p->index == g->owner) DeleteGroup(g); + if (p->index == g->owner) delete g; } } @@ -447,11 +446,7 @@ static void Load_GROUP(void) int index; while ((index = SlIterateArray()) != -1) { - if (!AddBlockIfNeeded(&_Group_pool, index)) { - error("Groups: failed loading savegame: too many groups"); - } - - Group *g = GetGroup(index); + Group *g = new (index) Group(); SlObject(g, _group_desc); } } diff --git a/src/strings.cpp b/src/strings.cpp --- a/src/strings.cpp +++ b/src/strings.cpp @@ -849,7 +849,7 @@ static char* FormatString(char* buff, co const Group *g = GetGroup(GetInt32(&argv)); int64 args[1]; - assert(IsValidGroup(g)); + assert(g->IsValid()); args[0] = g->index; buff = GetStringWithArgs(buff, IsCustomName(g->string_id) ? g->string_id : (StringID)STR_GROUP_NAME_FORMAT, args, last);