1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-08-15 20:03:15 +02:00

Identifiers that can be added by mods are now serialized as string

This commit is contained in:
Ivan Savenko
2023-11-17 00:48:55 +02:00
parent c0e54b338a
commit 843e97349a
5 changed files with 371 additions and 219 deletions

View File

@@ -13,10 +13,10 @@
VCMI_LIB_NAMESPACE_BEGIN
class DLL_LINKAGE BonusCustomSource : public Identifier<BonusCustomSource>
class DLL_LINKAGE BonusCustomSource : public StaticIdentifier<BonusCustomSource>
{
public:
using Identifier<BonusCustomSource>::Identifier;
using StaticIdentifier<BonusCustomSource>::StaticIdentifier;
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);
@@ -24,10 +24,10 @@ public:
static const BonusCustomSource undeadMoraleDebuff; // -2
};
class DLL_LINKAGE BonusCustomSubtype : public Identifier<BonusCustomSubtype>
class DLL_LINKAGE BonusCustomSubtype : public StaticIdentifier<BonusCustomSubtype>
{
public:
using Identifier<BonusCustomSubtype>::Identifier;
using StaticIdentifier<BonusCustomSubtype>::StaticIdentifier;
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);

View File

@@ -123,15 +123,16 @@ namespace GameConstants
si32 HeroClassID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "heroClass", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "heroClass", identifier);
return rawId.value();
}
std::string HeroClassID::encode(const si32 index)
{
if (index == -1)
return "";
return VLC->heroClasses()->getByIndex(index)->getJsonKey();
}
@@ -162,29 +163,50 @@ std::string CampaignScenarioID::encode(const si32 index)
std::string MapObjectID::encode(int32_t index)
{
if (index == -1)
return "";
return VLC->objtypeh->getObjectHandlerName(MapObjectID(index));
}
si32 MapObjectID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "objects", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "objects", identifier);
return rawId.value();
}
std::string BoatId::encode(int32_t index)
{
if (index == -1)
return "";
return VLC->objtypeh->getObjectHandlerName(MapObjectID(index));
}
si32 BoatId::decode(const std::string & identifier)
{
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "objects", identifier);
return rawId.value();
}
si32 HeroTypeID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "hero", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
if (identifier == "random")
return -2;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeMap(), "hero", identifier);
return rawId.value();
}
std::string HeroTypeID::encode(const si32 index)
{
if (index == -1)
return "";
if (index == -2)
return "random";
return VLC->heroTypes()->getByIndex(index)->getJsonKey();
}
@@ -205,15 +227,16 @@ const Artifact * ArtifactIDBase::toEntity(const Services * services) const
si32 ArtifactID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "artifact", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "artifact", identifier);
return rawId.value();
}
std::string ArtifactID::encode(const si32 index)
{
if (index == -1)
return "";
return VLC->artifacts()->getByIndex(index)->getJsonKey();
}
@@ -224,15 +247,16 @@ std::string ArtifactID::entityType()
si32 SecondarySkill::decode(const std::string& identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "secondarySkill", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "secondarySkill", identifier);
return rawId.value();
}
std::string SecondarySkill::encode(const si32 index)
{
if (index == -1)
return "";
return VLC->skills()->getById(SecondarySkill(index))->getJsonKey();
}
@@ -263,15 +287,16 @@ const Creature * CreatureIDBase::toEntity(const CreatureService * creatures) con
si32 CreatureID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "creature", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "creature", identifier);
return rawId.value();
}
std::string CreatureID::encode(const si32 index)
{
if (index == -1)
return "";
return VLC->creatures()->getById(CreatureID(index))->getJsonKey();
}
@@ -312,11 +337,10 @@ const HeroType * HeroTypeID::toEntity(const Services * services) const
si32 SpellID::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
return rawId.value();
}
std::string SpellID::encode(const si32 index)
@@ -326,11 +350,10 @@ std::string SpellID::encode(const si32 index)
si32 BattleField::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), "spell", identifier);
return rawId.value();
}
std::string BattleField::encode(const si32 index)
@@ -399,15 +422,17 @@ std::string PrimarySkill::entityType()
si32 FactionID::decode(const std::string & identifier)
{
if (identifier.empty())
return -1;
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
if(rawId)
return rawId.value();
else
return FactionID::DEFAULT.getNum();
}
std::string FactionID::encode(const si32 index)
{
if (index == -1)
return "";
return VLC->factions()->getByIndex(index)->getJsonKey();
}
@@ -423,15 +448,17 @@ const Faction * FactionID::toEntity(const Services * service) const
si32 TerrainId::decode(const std::string & identifier)
{
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
if(rawId)
return rawId.value();
else
if (identifier.empty())
return static_cast<si32>(TerrainId::NONE);
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
return rawId.value();
}
std::string TerrainId::encode(const si32 index)
{
if (index == TerrainId::NONE)
return "";
return VLC->terrainTypeHandler->getByIndex(index)->getJsonKey();
}
@@ -440,6 +467,48 @@ std::string TerrainId::entityType()
return "terrain";
}
si32 RoadId::decode(const std::string & identifier)
{
if (identifier.empty())
return RoadId::NO_ROAD.getNum();
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
return rawId.value();
}
std::string RoadId::encode(const si32 index)
{
if (index == RoadId::NO_ROAD.getNum())
return "";
return VLC->roadTypeHandler->getByIndex(index)->getJsonKey();
}
std::string RoadId::entityType()
{
return "road";
}
si32 RiverId::decode(const std::string & identifier)
{
if (identifier.empty())
return RiverId::NO_RIVER.getNum();
auto rawId = VLC->identifiers()->getIdentifier(ModScope::scopeGame(), entityType(), identifier);
return rawId.value();
}
std::string RiverId::encode(const si32 index)
{
if (index == RiverId::NO_RIVER.getNum())
return "";
return VLC->riverTypeHandler->getByIndex(index)->getJsonKey();
}
std::string RiverId::entityType()
{
return "road";
}
const TerrainType * TerrainId::toEntity(const Services * service) const
{
return VLC->terrainTypeHandler->getByIndex(num);

View File

@@ -43,153 +43,50 @@ class CSkill;
class CGameInfoCallback;
class CNonConstInfoCallback;
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Note: use template to force different type, blocking any Identifier<A> <=> Identifier<B> comparisons
template<typename FinalClass>
class Identifier : public IdentifierBase
class ArtifactInstanceID : public StaticIdentifier<ArtifactInstanceID>
{
using BaseClass = IdentifierBase;
public:
constexpr Identifier()
{}
explicit constexpr Identifier(int32_t value):
IdentifierBase(value)
{}
constexpr bool operator == (const Identifier & b) const { return BaseClass::num == b.num; }
constexpr bool operator <= (const Identifier & b) const { return BaseClass::num <= b.num; }
constexpr bool operator >= (const Identifier & b) const { return BaseClass::num >= b.num; }
constexpr bool operator != (const Identifier & b) const { return BaseClass::num != b.num; }
constexpr bool operator < (const Identifier & b) const { return BaseClass::num < b.num; }
constexpr bool operator > (const Identifier & b) const { return BaseClass::num > b.num; }
constexpr FinalClass & operator++()
{
++BaseClass::num;
return static_cast<FinalClass&>(*this);
}
constexpr FinalClass & operator--()
{
--BaseClass::num;
return static_cast<FinalClass&>(*this);
}
constexpr FinalClass operator--(int)
{
FinalClass ret(num);
--BaseClass::num;
return ret;
}
constexpr FinalClass operator++(int)
{
FinalClass ret(num);
++BaseClass::num;
return ret;
}
using StaticIdentifier<ArtifactInstanceID>::StaticIdentifier;
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename FinalClass, typename BaseClass>
class IdentifierWithEnum : public BaseClass
{
using EnumType = typename BaseClass::Type;
static_assert(std::is_same_v<std::underlying_type_t<EnumType>, int32_t>, "Entity Identifier must use int32_t");
public:
constexpr EnumType toEnum() const
{
return static_cast<EnumType>(BaseClass::num);
}
constexpr IdentifierWithEnum(const EnumType & enumValue)
{
BaseClass::num = static_cast<int32_t>(enumValue);
}
constexpr IdentifierWithEnum(int32_t _num = -1)
{
BaseClass::num = _num;
}
constexpr bool operator == (const EnumType & b) const { return BaseClass::num == static_cast<int32_t>(b); }
constexpr bool operator <= (const EnumType & b) const { return BaseClass::num <= static_cast<int32_t>(b); }
constexpr bool operator >= (const EnumType & b) const { return BaseClass::num >= static_cast<int32_t>(b); }
constexpr bool operator != (const EnumType & b) const { return BaseClass::num != static_cast<int32_t>(b); }
constexpr bool operator < (const EnumType & b) const { return BaseClass::num < static_cast<int32_t>(b); }
constexpr bool operator > (const EnumType & b) const { return BaseClass::num > static_cast<int32_t>(b); }
constexpr bool operator == (const IdentifierWithEnum & b) const { return BaseClass::num == b.num; }
constexpr bool operator <= (const IdentifierWithEnum & b) const { return BaseClass::num <= b.num; }
constexpr bool operator >= (const IdentifierWithEnum & b) const { return BaseClass::num >= b.num; }
constexpr bool operator != (const IdentifierWithEnum & b) const { return BaseClass::num != b.num; }
constexpr bool operator < (const IdentifierWithEnum & b) const { return BaseClass::num < b.num; }
constexpr bool operator > (const IdentifierWithEnum & b) const { return BaseClass::num > b.num; }
constexpr FinalClass & operator++()
{
++BaseClass::num;
return static_cast<FinalClass&>(*this);
}
constexpr FinalClass operator++(int)
{
FinalClass ret(BaseClass::num);
++BaseClass::num;
return ret;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class ArtifactInstanceID : public Identifier<ArtifactInstanceID>
class QueryID : public StaticIdentifier<QueryID>
{
public:
using Identifier<ArtifactInstanceID>::Identifier;
};
class QueryID : public Identifier<QueryID>
{
public:
using Identifier<QueryID>::Identifier;
using StaticIdentifier<QueryID>::StaticIdentifier;
DLL_LINKAGE static const QueryID NONE;
DLL_LINKAGE static const QueryID CLIENT;
};
class BattleID : public Identifier<BattleID>
class BattleID : public StaticIdentifier<BattleID>
{
public:
using Identifier<BattleID>::Identifier;
using StaticIdentifier<BattleID>::StaticIdentifier;
DLL_LINKAGE static const BattleID NONE;
};
class DLL_LINKAGE ObjectInstanceID : public Identifier<ObjectInstanceID>
class DLL_LINKAGE ObjectInstanceID : public StaticIdentifier<ObjectInstanceID>
{
public:
using Identifier<ObjectInstanceID>::Identifier;
using StaticIdentifier<ObjectInstanceID>::StaticIdentifier;
static const ObjectInstanceID NONE;
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
};
class HeroClassID : public Identifier<HeroClassID>
class HeroClassID : public EntityIdentifier<HeroClassID>
{
public:
using Identifier<HeroClassID>::Identifier;
using EntityIdentifier<HeroClassID>::EntityIdentifier;
///json serialization helpers
DLL_LINKAGE static si32 decode(const std::string & identifier);
DLL_LINKAGE static std::string encode(const si32 index);
static std::string entityType();
};
class DLL_LINKAGE HeroTypeID : public Identifier<HeroTypeID>
class DLL_LINKAGE HeroTypeID : public EntityIdentifier<HeroTypeID>
{
public:
using Identifier<HeroTypeID>::Identifier;
using EntityIdentifier<HeroTypeID>::EntityIdentifier;
///json serialization helpers
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
@@ -207,10 +104,10 @@ public:
}
};
class SlotID : public Identifier<SlotID>
class SlotID : public StaticIdentifier<SlotID>
{
public:
using Identifier<SlotID>::Identifier;
using StaticIdentifier<SlotID>::StaticIdentifier;
DLL_LINKAGE static const SlotID COMMANDER_SLOT_PLACEHOLDER;
DLL_LINKAGE static const SlotID SUMMONED_SLOT_PLACEHOLDER; ///<for all summoned creatures, only during battle
@@ -223,10 +120,10 @@ public:
}
};
class DLL_LINKAGE PlayerColor : public Identifier<PlayerColor>
class DLL_LINKAGE PlayerColor : public StaticIdentifier<PlayerColor>
{
public:
using Identifier<PlayerColor>::Identifier;
using StaticIdentifier<PlayerColor>::StaticIdentifier;
enum EPlayerColor
{
@@ -249,18 +146,18 @@ public:
static std::string entityType();
};
class TeamID : public Identifier<TeamID>
class TeamID : public StaticIdentifier<TeamID>
{
public:
using Identifier<TeamID>::Identifier;
using StaticIdentifier<TeamID>::StaticIdentifier;
DLL_LINKAGE static const TeamID NO_TEAM;
};
class TeleportChannelID : public Identifier<TeleportChannelID>
class TeleportChannelID : public StaticIdentifier<TeleportChannelID>
{
public:
using Identifier<TeleportChannelID>::Identifier;
using StaticIdentifier<TeleportChannelID>::StaticIdentifier;
};
class SecondarySkillBase : public IdentifierBase
@@ -302,10 +199,10 @@ public:
static_assert(GameConstants::SKILL_QUANTITY == SKILL_SIZE, "Incorrect number of skills");
};
class SecondarySkill : public IdentifierWithEnum<SecondarySkill, SecondarySkillBase>
class DLL_LINKAGE SecondarySkill : public EntityIdentifierWithEnum<SecondarySkill, SecondarySkillBase>
{
public:
using IdentifierWithEnum<SecondarySkill, SecondarySkillBase>::IdentifierWithEnum;
using EntityIdentifierWithEnum<SecondarySkill, SecondarySkillBase>::EntityIdentifierWithEnum;
static std::string entityType();
static si32 decode(const std::string& identifier);
static std::string encode(const si32 index);
@@ -314,10 +211,10 @@ public:
const Skill * toEntity(const Services * services) const;
};
class DLL_LINKAGE PrimarySkill : public Identifier<PrimarySkill>
class DLL_LINKAGE PrimarySkill : public StaticIdentifier<PrimarySkill>
{
public:
using Identifier<PrimarySkill>::Identifier;
using StaticIdentifier<PrimarySkill>::StaticIdentifier;
static const PrimarySkill NONE;
static const PrimarySkill ATTACK;
@@ -335,10 +232,10 @@ public:
static std::string entityType();
};
class DLL_LINKAGE FactionID : public Identifier<FactionID>
class DLL_LINKAGE FactionID : public EntityIdentifier<FactionID>
{
public:
using Identifier<FactionID>::Identifier;
using EntityIdentifier<FactionID>::EntityIdentifier;
static const FactionID NONE;
static const FactionID DEFAULT;
@@ -413,10 +310,10 @@ public:
}
};
class DLL_LINKAGE BuildingID : public IdentifierWithEnum<BuildingID, BuildingIDBase>
class DLL_LINKAGE BuildingID : public StaticIdentifierWithEnum<BuildingID, BuildingIDBase>
{
public:
using IdentifierWithEnum<BuildingID, BuildingIDBase>::IdentifierWithEnum;
using StaticIdentifierWithEnum<BuildingID, BuildingIDBase>::StaticIdentifierWithEnum;
static BuildingID HALL_LEVEL(unsigned int level)
{
@@ -578,10 +475,10 @@ public:
};
};
class DLL_LINKAGE MapObjectID : public IdentifierWithEnum<MapObjectID, MapObjectBaseID>
class DLL_LINKAGE MapObjectID : public EntityIdentifierWithEnum<MapObjectID, MapObjectBaseID>
{
public:
using IdentifierWithEnum<MapObjectID, MapObjectBaseID>::IdentifierWithEnum;
using EntityIdentifierWithEnum<MapObjectID, MapObjectBaseID>::EntityIdentifierWithEnum;
static std::string encode(int32_t index);
static si32 decode(const std::string & identifier);
@@ -593,14 +490,16 @@ public:
}
};
class MapObjectSubID : public Identifier<MapObjectSubID>
class MapObjectSubID : public StaticIdentifier<MapObjectSubID>
{
public:
MapObjectID primaryIdentifier;
constexpr MapObjectSubID(const IdentifierBase & value):
Identifier<MapObjectSubID>(value.getNum())
StaticIdentifier<MapObjectSubID>(value.getNum())
{}
constexpr MapObjectSubID(int32_t value = -1):
Identifier<MapObjectSubID>(value)
StaticIdentifier<MapObjectSubID>(value)
{}
MapObjectSubID & operator =(int32_t value)
@@ -615,6 +514,9 @@ public:
return *this;
}
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
// TODO: Remove
constexpr operator int32_t () const
{
@@ -622,10 +524,13 @@ public:
}
};
class DLL_LINKAGE RoadId : public Identifier<RoadId>
class DLL_LINKAGE RoadId : public EntityIdentifier<RoadId>
{
public:
using Identifier<RoadId>::Identifier;
using EntityIdentifier<RoadId>::EntityIdentifier;
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
static std::string entityType();
static const RoadId NO_ROAD;
static const RoadId DIRT_ROAD;
@@ -635,10 +540,13 @@ public:
const RoadType * toEntity(const Services * service) const;
};
class DLL_LINKAGE RiverId : public Identifier<RiverId>
class DLL_LINKAGE RiverId : public EntityIdentifier<RiverId>
{
public:
using Identifier<RiverId>::Identifier;
using EntityIdentifier<RiverId>::EntityIdentifier;
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
static std::string entityType();
static const RiverId NO_RIVER;
static const RiverId WATER_RIVER;
@@ -658,10 +566,10 @@ public:
};
};
class EPathfindingLayer : public IdentifierWithEnum<EPathfindingLayer, EPathfindingLayerBase>
class EPathfindingLayer : public StaticIdentifierWithEnum<EPathfindingLayer, EPathfindingLayerBase>
{
public:
using IdentifierWithEnum<EPathfindingLayer, EPathfindingLayerBase>::IdentifierWithEnum;
using StaticIdentifierWithEnum<EPathfindingLayer, EPathfindingLayerBase>::StaticIdentifierWithEnum;
};
class ArtifactPositionBase : public IdentifierBase
@@ -694,10 +602,10 @@ public:
DLL_LINKAGE static std::string encode(const si32 index);
};
class ArtifactPosition : public IdentifierWithEnum<ArtifactPosition, ArtifactPositionBase>
class ArtifactPosition : public StaticIdentifierWithEnum<ArtifactPosition, ArtifactPositionBase>
{
public:
using IdentifierWithEnum<ArtifactPosition, ArtifactPositionBase>::IdentifierWithEnum;
using StaticIdentifierWithEnum<ArtifactPosition, ArtifactPositionBase>::StaticIdentifierWithEnum;
// TODO: Remove
constexpr operator int32_t () const
@@ -730,10 +638,10 @@ public:
DLL_LINKAGE const Artifact * toEntity(const Services * service) const;
};
class ArtifactID : public IdentifierWithEnum<ArtifactID, ArtifactIDBase>
class ArtifactID : public EntityIdentifierWithEnum<ArtifactID, ArtifactIDBase>
{
public:
using IdentifierWithEnum<ArtifactID, ArtifactIDBase>::IdentifierWithEnum;
using EntityIdentifierWithEnum<ArtifactID, ArtifactIDBase>::EntityIdentifierWithEnum;
///json serialization helpers
DLL_LINKAGE static si32 decode(const std::string & identifier);
@@ -773,10 +681,10 @@ public:
DLL_LINKAGE const Creature * toEntity(const CreatureService * creatures) const;
};
class DLL_LINKAGE CreatureID : public IdentifierWithEnum<CreatureID, CreatureIDBase>
class DLL_LINKAGE CreatureID : public EntityIdentifierWithEnum<CreatureID, CreatureIDBase>
{
public:
using IdentifierWithEnum<CreatureID, CreatureIDBase>::IdentifierWithEnum;
using EntityIdentifierWithEnum<CreatureID, CreatureIDBase>::EntityIdentifierWithEnum;
///json serialization helpers
static si32 decode(const std::string & identifier);
@@ -892,10 +800,10 @@ public:
const spells::Spell * toEntity(const spells::Service * service) const;
};
class DLL_LINKAGE SpellID : public IdentifierWithEnum<SpellID, SpellIDBase>
class DLL_LINKAGE SpellID : public EntityIdentifierWithEnum<SpellID, SpellIDBase>
{
public:
using IdentifierWithEnum<SpellID, SpellIDBase>::IdentifierWithEnum;
using EntityIdentifierWithEnum<SpellID, SpellIDBase>::EntityIdentifierWithEnum;
///json serialization helpers
static si32 decode(const std::string & identifier);
@@ -904,10 +812,10 @@ public:
};
class BattleFieldInfo;
class DLL_LINKAGE BattleField : public Identifier<BattleField>
class DLL_LINKAGE BattleField : public EntityIdentifier<BattleField>
{
public:
using Identifier<BattleField>::Identifier;
using EntityIdentifier<BattleField>::EntityIdentifier;
static const BattleField NONE;
const BattleFieldInfo * getInfo() const;
@@ -916,10 +824,13 @@ public:
static std::string encode(const si32 index);
};
class DLL_LINKAGE BoatId : public Identifier<BoatId>
class DLL_LINKAGE BoatId : public EntityIdentifier<BoatId>
{
public:
using Identifier<BoatId>::Identifier;
using EntityIdentifier<BoatId>::EntityIdentifier;
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
static const BoatId NONE;
static const BoatId NECROPOLIS;
@@ -950,29 +861,29 @@ public:
};
};
class TerrainId : public IdentifierWithEnum<TerrainId, TerrainIdBase>
class DLL_LINKAGE TerrainId : public EntityIdentifierWithEnum<TerrainId, TerrainIdBase>
{
public:
using IdentifierWithEnum<TerrainId, TerrainIdBase>::IdentifierWithEnum;
using EntityIdentifierWithEnum<TerrainId, TerrainIdBase>::EntityIdentifierWithEnum;
DLL_LINKAGE static si32 decode(const std::string & identifier);
DLL_LINKAGE static std::string encode(const si32 index);
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
static std::string entityType();
const TerrainType * toEntity(const Services * service) const;
};
class ObstacleInfo;
class Obstacle : public Identifier<Obstacle>
class Obstacle : public EntityIdentifier<Obstacle>
{
public:
using Identifier<Obstacle>::Identifier;
using EntityIdentifier<Obstacle>::EntityIdentifier;
DLL_LINKAGE const ObstacleInfo * getInfo() const;
};
class DLL_LINKAGE SpellSchool : public Identifier<SpellSchool>
class DLL_LINKAGE SpellSchool : public StaticIdentifier<SpellSchool>
{
public:
using Identifier<SpellSchool>::Identifier;
using StaticIdentifier<SpellSchool>::StaticIdentifier;
static const SpellSchool ANY;
static const SpellSchool AIR;
@@ -1005,10 +916,10 @@ public:
};
};
class DLL_LINKAGE GameResID : public IdentifierWithEnum<GameResID, GameResIDBase>
class DLL_LINKAGE GameResID : public StaticIdentifierWithEnum<GameResID, GameResIDBase>
{
public:
using IdentifierWithEnum<GameResID, GameResIDBase>::IdentifierWithEnum;
using StaticIdentifierWithEnum<GameResID, GameResIDBase>::StaticIdentifierWithEnum;
static si32 decode(const std::string & identifier);
static std::string encode(const si32 index);
@@ -1017,7 +928,7 @@ public:
static const std::array<GameResID, 7> & ALL_RESOURCES();
};
class DLL_LINKAGE BuildingTypeUniqueID : public Identifier<BuildingTypeUniqueID>
class DLL_LINKAGE BuildingTypeUniqueID : public StaticIdentifier<BuildingTypeUniqueID>
{
public:
BuildingTypeUniqueID(FactionID faction, BuildingID building );
@@ -1028,13 +939,13 @@ public:
BuildingID getBuilding() const;
FactionID getFaction() const;
using Identifier<BuildingTypeUniqueID>::Identifier;
using StaticIdentifier<BuildingTypeUniqueID>::StaticIdentifier;
};
class DLL_LINKAGE CampaignScenarioID : public Identifier<CampaignScenarioID>
class DLL_LINKAGE CampaignScenarioID : public StaticIdentifier<CampaignScenarioID>
{
public:
using Identifier<CampaignScenarioID>::Identifier;
using StaticIdentifier<CampaignScenarioID>::StaticIdentifier;
static si32 decode(const std::string & identifier);
static std::string encode(int32_t index);

View File

@@ -42,11 +42,6 @@ public:
}
};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & num;
}
constexpr void advance(int change)
{
num += change;
@@ -62,3 +57,180 @@ public:
return os << dt.num;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Note: use template to force different type, blocking any Identifier<A> <=> Identifier<B> comparisons
template<typename FinalClass>
class Identifier : public IdentifierBase
{
using BaseClass = IdentifierBase;
public:
constexpr Identifier()
{}
explicit constexpr Identifier(int32_t value):
IdentifierBase(value)
{}
constexpr bool operator == (const Identifier & b) const { return BaseClass::num == b.num; }
constexpr bool operator <= (const Identifier & b) const { return BaseClass::num <= b.num; }
constexpr bool operator >= (const Identifier & b) const { return BaseClass::num >= b.num; }
constexpr bool operator != (const Identifier & b) const { return BaseClass::num != b.num; }
constexpr bool operator < (const Identifier & b) const { return BaseClass::num < b.num; }
constexpr bool operator > (const Identifier & b) const { return BaseClass::num > b.num; }
constexpr FinalClass & operator++()
{
++BaseClass::num;
return static_cast<FinalClass&>(*this);
}
constexpr FinalClass & operator--()
{
--BaseClass::num;
return static_cast<FinalClass&>(*this);
}
constexpr FinalClass operator--(int)
{
FinalClass ret(num);
--BaseClass::num;
return ret;
}
constexpr FinalClass operator++(int)
{
FinalClass ret(num);
++BaseClass::num;
return ret;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename FinalClass, typename BaseClass>
class IdentifierWithEnum : public BaseClass
{
using EnumType = typename BaseClass::Type;
static_assert(std::is_same_v<std::underlying_type_t<EnumType>, int32_t>, "Entity Identifier must use int32_t");
public:
constexpr EnumType toEnum() const
{
return static_cast<EnumType>(BaseClass::num);
}
constexpr IdentifierWithEnum(const EnumType & enumValue)
{
BaseClass::num = static_cast<int32_t>(enumValue);
}
constexpr IdentifierWithEnum(int32_t _num = -1)
{
BaseClass::num = _num;
}
constexpr bool operator == (const EnumType & b) const { return BaseClass::num == static_cast<int32_t>(b); }
constexpr bool operator <= (const EnumType & b) const { return BaseClass::num <= static_cast<int32_t>(b); }
constexpr bool operator >= (const EnumType & b) const { return BaseClass::num >= static_cast<int32_t>(b); }
constexpr bool operator != (const EnumType & b) const { return BaseClass::num != static_cast<int32_t>(b); }
constexpr bool operator < (const EnumType & b) const { return BaseClass::num < static_cast<int32_t>(b); }
constexpr bool operator > (const EnumType & b) const { return BaseClass::num > static_cast<int32_t>(b); }
constexpr bool operator == (const IdentifierWithEnum & b) const { return BaseClass::num == b.num; }
constexpr bool operator <= (const IdentifierWithEnum & b) const { return BaseClass::num <= b.num; }
constexpr bool operator >= (const IdentifierWithEnum & b) const { return BaseClass::num >= b.num; }
constexpr bool operator != (const IdentifierWithEnum & b) const { return BaseClass::num != b.num; }
constexpr bool operator < (const IdentifierWithEnum & b) const { return BaseClass::num < b.num; }
constexpr bool operator > (const IdentifierWithEnum & b) const { return BaseClass::num > b.num; }
constexpr FinalClass & operator++()
{
++BaseClass::num;
return static_cast<FinalClass&>(*this);
}
constexpr FinalClass operator++(int)
{
FinalClass ret(BaseClass::num);
++BaseClass::num;
return ret;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename FinalClass>
class EntityIdentifier : public Identifier<FinalClass>
{
public:
using Identifier<FinalClass>::Identifier;
template <typename Handler>
void serialize(Handler &h, const int version)
{
auto * finalClass = static_cast<FinalClass*>(this);
std::string value;
if (h.saving)
value = FinalClass::encode(finalClass->num);
h & value;
if (!h.saving)
finalClass->num = FinalClass::decode(value);
}
};
template<typename FinalClass, typename BaseClass>
class EntityIdentifierWithEnum : public IdentifierWithEnum<FinalClass, BaseClass>
{
public:
using IdentifierWithEnum<FinalClass, BaseClass>::IdentifierWithEnum;
template <typename Handler>
void serialize(Handler &h, const int version)
{
auto * finalClass = static_cast<FinalClass*>(this);
std::string value;
if (h.saving)
value = FinalClass::encode(finalClass->num);
h & value;
if (!h.saving)
finalClass->num = FinalClass::decode(value);
}
};
template<typename FinalClass>
class StaticIdentifier : public Identifier<FinalClass>
{
public:
using Identifier<FinalClass>::Identifier;
template <typename Handler>
void serialize(Handler &h, const int version)
{
auto * finalClass = static_cast<FinalClass*>(this);
h & finalClass->num;
}
};
template<typename FinalClass, typename BaseClass>
class StaticIdentifierWithEnum : public IdentifierWithEnum<FinalClass, BaseClass>
{
public:
using IdentifierWithEnum<FinalClass, BaseClass>::IdentifierWithEnum;
template <typename Handler>
void serialize(Handler &h, const int version)
{
auto * finalClass = static_cast<FinalClass*>(this);
h & finalClass->num;
}
};
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -53,10 +53,10 @@ enum class ObjProperty : int8_t
REWARD_CLEARED
};
class NumericID : public Identifier<NumericID>
class NumericID : public StaticIdentifier<NumericID>
{
public:
using Identifier<NumericID>::Identifier;
using StaticIdentifier<NumericID>::StaticIdentifier;
static si32 decode(const std::string & identifier)
{