Skip to content

Commit

Permalink
reduce ExplGenHandler string wrangling
Browse files Browse the repository at this point in the history
  • Loading branch information
rt committed Feb 20, 2019
1 parent da20824 commit 12317c4
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 89 deletions.
14 changes: 4 additions & 10 deletions rts/Lua/LuaSyncedCtrl.cpp
Expand Up @@ -3406,7 +3406,7 @@ int LuaSyncedCtrl::SetProjectileCEG(lua_State* L)
unsigned int cegID = CExplosionGeneratorHandler::EXPGEN_ID_INVALID;

if (lua_isstring(L, 2)) {
cegID = explGenHandler.LoadGeneratorID(std::string(CEG_PREFIX_STRING) + lua_tostring(L, 2));
cegID = explGenHandler.LoadCustomGeneratorID(lua_tostring(L, 2));
} else {
cegID = luaL_checknumber(L, 2);
}
Expand Down Expand Up @@ -4517,15 +4517,9 @@ int LuaSyncedCtrl::SpawnCEG(lua_State* L)
const float damage = luaL_optfloat(L, 9, 0.0f);
const float dmgMod = luaL_optfloat(L, 10, 1.0f);

unsigned int cegID = CExplosionGeneratorHandler::EXPGEN_ID_INVALID;

if (lua_isstring(L, 1)) {
// args from Lua are assumed not to include the prefix
// (Spawn*C*EG implies only custom generators can fire)
cegID = explGenHandler.LoadGeneratorID(std::string(CEG_PREFIX_STRING) + lua_tostring(L, 1));
} else {
cegID = luaL_checknumber(L, 1);
}
// args from Lua are assumed not to include the prefix
// (Spawn*C*EG implies only custom generators can fire)
const unsigned int cegID = lua_isstring(L, 1)? explGenHandler.LoadCustomGeneratorID(lua_tostring(L, 1)): luaL_checkint(L, 1);

lua_pushboolean(L, explGenHandler.GenExplosion(cegID, pos, dir, damage, radius, dmgMod, nullptr, nullptr));
lua_pushnumber(L, cegID);
Expand Down
4 changes: 1 addition & 3 deletions rts/Lua/LuaSyncedRead.cpp
Expand Up @@ -3976,9 +3976,7 @@ int LuaSyncedRead::GetUnitDefDimensions(lua_State* L)

int LuaSyncedRead::GetCEGID(lua_State* L)
{
const unsigned int cegID = explGenHandler.LoadGeneratorID(std::string(CEG_PREFIX_STRING) + lua_tostring(L, 1));

lua_pushnumber(L, cegID);
lua_pushnumber(L, explGenHandler.LoadCustomGeneratorID(lua_tostring(L, 1)));
return 1;
}

Expand Down
8 changes: 4 additions & 4 deletions rts/Rendering/Env/Particles/ProjectileDrawer.cpp
Expand Up @@ -409,15 +409,15 @@ void CProjectileDrawer::LoadWeaponTextures() {
if (!wd.visuals.texNames[2].empty()) { wd.visuals.texture3 = &textureAtlas->GetTexture(wd.visuals.texNames[2]); }
if (!wd.visuals.texNames[3].empty()) { wd.visuals.texture4 = &textureAtlas->GetTexture(wd.visuals.texNames[3]); }

// these can only be custom EG's so prefix is not required game-side
// trails can only be custom EG's, prefix is not required game-side
if (!wd.visuals.ptrailExpGenTag.empty())
wd.ptrailExplosionGeneratorID = explGenHandler.LoadGeneratorID(CEG_PREFIX_STRING + wd.visuals.ptrailExpGenTag);
wd.ptrailExplosionGeneratorID = explGenHandler.LoadCustomGeneratorID(wd.visuals.ptrailExpGenTag.c_str());

if (!wd.visuals.impactExpGenTag.empty())
wd.impactExplosionGeneratorID = explGenHandler.LoadGeneratorID(wd.visuals.impactExpGenTag);
wd.impactExplosionGeneratorID = explGenHandler.LoadGeneratorID(wd.visuals.impactExpGenTag.c_str());

if (!wd.visuals.bounceExpGenTag.empty())
wd.bounceExplosionGeneratorID = explGenHandler.LoadGeneratorID(wd.visuals.bounceExpGenTag);
wd.bounceExplosionGeneratorID = explGenHandler.LoadGeneratorID(wd.visuals.bounceExpGenTag.c_str());

}
}
Expand Down
9 changes: 4 additions & 5 deletions rts/Rendering/UnitDrawer.cpp
Expand Up @@ -72,15 +72,14 @@ static FixedDynMemPool<sizeof(GhostSolidObject), MAX_UNITS / 1000, MAX_UNITS / 3
static void LoadUnitExplosionGenerators() {
using F = decltype(&UnitDef::AddModelExpGenID);
using T = decltype(UnitDef::modelCEGTags);
using S = T::value_type;

const auto LoadGenerators = [](UnitDef* ud, const F addExplGenID, const T& explGenTags, const S& explGenPrefix) {
for (const S& explGenTag: explGenTags) {
if (explGenTag.empty())
const auto LoadGenerators = [](UnitDef* ud, const F addExplGenID, const T& explGenTags, const char* explGenPrefix) {
for (const auto& explGenTag: explGenTags) {
if (explGenTag[0] == 0)
break;

// build a contiguous range of valid ID's
(ud->*addExplGenID)(explGenHandler.LoadGeneratorID(explGenPrefix + explGenTag));
(ud->*addExplGenID)(explGenHandler.LoadGeneratorID(explGenTag, explGenPrefix));
}
};

Expand Down
2 changes: 1 addition & 1 deletion rts/Sim/Projectiles/ExpGenSpawnableMemberInfo.h
Expand Up @@ -64,7 +64,7 @@ struct SExpGenSpawnableMemberInfo

#define CHECK_MEMBER_INFO_PTR(t, member, callback) \
static_assert(std::is_same<decltype(callback("")), decltype(member)>::value, "Member and callback type mismatch"); \
SET_MEMBER_INFO(memberInfo, MEMBER_HASH(member), offsetof_expgen(t, member), sizeof_expgen(t, member), 1, SExpGenSpawnableMemberInfo::TYPE_PTR, [](const std::string& s) { return (void *) callback(s); } );
SET_MEMBER_INFO(memberInfo, MEMBER_HASH(member), offsetof_expgen(t, member), sizeof_expgen(t, member), 1, SExpGenSpawnableMemberInfo::TYPE_PTR, [](const std::string& s) { return (void *) callback(s.c_str()); } );

#define CHECK_MEMBER_INFO_BOOL(type, member) CHECK_MEMBER_INFO_INT(type, member)
#define CHECK_MEMBER_INFO_SCOLOR(type, member) CHECK_MEMBER_INFO_INT(type, member.i)
Expand Down
80 changes: 41 additions & 39 deletions rts/Sim/Projectiles/ExplosionGenerator.cpp
Expand Up @@ -37,6 +37,7 @@
#include "System/Exceptions.h"
#include "System/myMath.h"
#include "System/SafeUtil.h"
#include "System/StringHash.h"


CR_BIND_INTERFACE(IExplosionGenerator)
Expand Down Expand Up @@ -86,6 +87,8 @@ static uint8_t exploParserMem[sizeof(LuaParser)];
static uint8_t aliasParserMem[sizeof(LuaParser)];
static uint8_t explTblRootMem[sizeof(LuaTable )];

static constexpr size_t CEG_PREFIX_STRLEN = strlen(CEG_PREFIX_STRING);

CExplosionGeneratorHandler explGenHandler;


Expand Down Expand Up @@ -222,8 +225,8 @@ void CExplosionGeneratorHandler::Kill()

explosionGenerators.clear();

expGenTagIdentMap.clear(); // never iterated
expGenIdentTagMap.clear(); // never iterated
expGenHashIdentMap.clear(); // never iterated
expGenIdentNameMap.clear(); // never iterated
}

void CExplosionGeneratorHandler::ParseExplosionTables()
Expand Down Expand Up @@ -267,17 +270,17 @@ void CExplosionGeneratorHandler::ReloadGenerators(const std::string& tag) {
// but the Lua subtables that define each CEG are
// only indexed by tag postfix
if (!tag.empty()) {
const auto it = expGenTagIdentMap.find(tag);
const auto it = expGenHashIdentMap.find(hashString(tag.c_str()));

if (it == expGenTagIdentMap.end()) {
if (it == expGenHashIdentMap.end()) {
LOG_L(L_WARNING, "[%s] no CEG named \"%s\" (forgot the \"%s\" prefix?)", __func__, tag.c_str(), CEG_PREFIX_STRING);
return;
}

assert(explosionGenerators[it->second]->GetGeneratorID() == it->second);
LOG(preFmt, __func__, it->second, tag.c_str());

if (!explosionGenerators[it->second]->Reload(this, tag.substr(7)))
if (!explosionGenerators[it->second]->Reload(this, tag.c_str() + CEG_PREFIX_STRLEN))
LOG_L(L_WARNING, pstFmt, __func__, it->second, tag.c_str());

return;
Expand All @@ -287,24 +290,24 @@ void CExplosionGeneratorHandler::ReloadGenerators(const std::string& tag) {
IExplosionGenerator* eg = explosionGenerators[n];

// standard EG's (empty postfix) do not need to be reloaded
if (expGenIdentTagMap.find(n) == expGenIdentTagMap.end())
if (expGenIdentNameMap.find(n) == expGenIdentNameMap.end())
continue;

assert(eg->GetGeneratorID() == n);
LOG(preFmt, __func__, n, expGenIdentTagMap[n].c_str());
LOG(preFmt, __func__, n, expGenIdentNameMap[n].data());

if (eg->Reload(this, expGenIdentTagMap[n].substr(7)))
if (eg->Reload(this, expGenIdentNameMap[n].data() + CEG_PREFIX_STRLEN))
continue;

LOG_L(L_WARNING, pstFmt, __func__, n, expGenIdentTagMap[n].c_str());
LOG_L(L_WARNING, pstFmt, __func__, n, expGenIdentNameMap[n]);
}
}



unsigned int CExplosionGeneratorHandler::LoadGeneratorID(const std::string& tag)
unsigned int CExplosionGeneratorHandler::LoadGeneratorID(const char* tag, const char* pre)
{
IExplosionGenerator* eg = LoadGenerator(tag);
IExplosionGenerator* eg = LoadGenerator(tag, pre);

if (eg == nullptr)
return EXPGEN_ID_INVALID;
Expand All @@ -317,32 +320,32 @@ unsigned int CExplosionGeneratorHandler::LoadGeneratorID(const std::string& tag)
// can be called recursively for custom instances (LoadGenerator ->
// Load -> ParseExplosionCode -> LoadGenerator -> ...), generators
// must NOT be overwritten
IExplosionGenerator* CExplosionGeneratorHandler::LoadGenerator(const string& tag)
IExplosionGenerator* CExplosionGeneratorHandler::LoadGenerator(const char* tag, const char* pre)
{
const auto it = expGenTagIdentMap.find(tag);
decltype(expGenIdentNameMap)::mapped_type key = {0};

char* ptr = key.data();
char* sep = nullptr;

ptr += snprintf(ptr, sizeof(key) - (ptr - key.data()), "%s", pre);
ptr += snprintf(ptr, sizeof(key) - (ptr - key.data()), "%s", tag);

if (it != expGenTagIdentMap.end())
return explosionGenerators[it->second];
const auto hash = hashString(key.data());
const auto iter = expGenHashIdentMap.find(hash);

if (iter != expGenHashIdentMap.end())
return explosionGenerators[iter->second];

// tag is either "CStdExplosionGenerator" (or some sub-string, eg.
// "std") which maps to CStdExplosionGenerator or "custom:postfix"
// which maps to CCustomExplosionGenerator, all others cause NULL
// to be returned
string prefix;
string postfix;

const string::size_type seppos = tag.find(':');

IExplosionGenerator* explGen;
IExplosionGenerator* explGen = nullptr;

if (seppos != string::npos) {
if ((sep = strstr(key.data(), ":")) != nullptr) {
// grab the "custom" prefix (the only supported value)
prefix = tag.substr(0, seppos);
postfix = tag.substr(seppos + 1);
assert((prefix + ":") == CEG_PREFIX_STRING);
explGen = egMemPool.alloc<CCustomExplosionGenerator>();
} else {
prefix = tag;
explGen = egMemPool.alloc<CStdExplosionGenerator>();
}

Expand All @@ -354,13 +357,13 @@ IExplosionGenerator* CExplosionGeneratorHandler::LoadGenerator(const string& tag
// save generator so ID is valid *before* possible recursion
explosionGenerators.push_back(explGen);

if (!postfix.empty()) {
if (sep != nullptr) {
// standard EG's have no postfix (nor always a prefix)
// custom EG's always have CEG_PREFIX_STRING in front
expGenTagIdentMap[tag] = explGen->GetGeneratorID();
expGenIdentTagMap[explGen->GetGeneratorID()] = tag;
expGenHashIdentMap.insert(hash, explGen->GetGeneratorID());
expGenIdentNameMap.insert(explGen->GetGeneratorID(), key);

explGen->Load(this, postfix);
explGen->Load(this, sep + 1);
}

return explGen;
Expand Down Expand Up @@ -830,8 +833,7 @@ void CCustomExplosionGenerator::ParseExplosionCode(
else if (c == 'q') { opcode = OP_POWBUFF; useInt = true; }
else if (isdigit(c) || c == '.' || c == '-') { opcode = OP_ADD; p--; }
else {
const char* fmt = "[CCEG::ParseExplosionCode] unknown op-code \"%c\" in \"%s\" at index %d";
LOG_L(L_WARNING, fmt, c, script.c_str(), p);
LOG_L(L_WARNING, "[CCEG::%s] unknown op-code \"%c\" in \"%s\" at index %d", __func__, c, script.c_str(), p);
continue;
}

Expand Down Expand Up @@ -869,14 +871,14 @@ void CCustomExplosionGenerator::ParseExplosionCode(



bool CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* handler, const string& tag)
bool CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* handler, const char* tag)
{
const LuaTable* root = handler->GetExplosionTableRoot();
const LuaTable& expTable = (root != nullptr)? root->SubTable(tag): LuaTable();

if (!expTable.IsValid()) {
// not a fatal error: any calls to Explosion will just return early
LOG_L(L_WARNING, "[CCEG::%s] table for CEG \"%s\" invalid (parse errors?)", __func__, tag.c_str());
LOG_L(L_WARNING, "[CCEG::%s] table for CEG \"%s\" invalid (parse errors?)", __func__, tag);
return false;
}

Expand All @@ -889,7 +891,7 @@ bool CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* handler, const
for (unsigned int n = 0; n < spawns.size(); n++) {
ProjectileSpawnInfo psi;

const string& spawnName = spawns[n];
const std::string& spawnName = spawns[n];
const LuaTable& spawnTable = expTable.SubTable(spawnName);

// NOTE:
Expand All @@ -903,14 +905,14 @@ bool CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* handler, const
const string& className = handler->GetProjectileClasses().ResolveAlias(spawnTable.GetString("class", spawnName));

if ((psi.spawnableID = CExpGenSpawnable::GetSpawnableID(className)) == -1u) {
LOG_L(L_WARNING, "[CCEG::%s] %s: Unknown class \"%s\"", __func__, tag.c_str(), className.c_str());
LOG_L(L_WARNING, "[CCEG::%s] %s: unknown class \"%s\"", __func__, tag, className.c_str());
continue;
}

psi.flags = GetFlagsFromTable(spawnTable);
psi.count = std::max(0, spawnTable.GetInt("count", 1));

string code;
std::string code;
spring::unordered_map<string, string> props;

spawnTable.SubTable("properties").GetMap(props);
Expand All @@ -921,7 +923,7 @@ bool CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* handler, const
if (CExpGenSpawnable::GetSpawnableMemberInfo(className, memberInfo)) {
ParseExplosionCode(&psi, propIt.second, memberInfo, code);
} else {
LOG_L(L_WARNING, "[CCEG::%s] %s: Unknown tag %s::%s", __func__, tag.c_str(), className.c_str(), propIt.first.c_str());
LOG_L(L_WARNING, "[CCEG::%s] %s: unknown tag %s::%s", __func__, tag, className.c_str(), propIt.first.c_str());
}
}

Expand Down Expand Up @@ -950,7 +952,7 @@ bool CCustomExplosionGenerator::Load(CExplosionGeneratorHandler* handler, const
return true;
}

bool CCustomExplosionGenerator::Reload(CExplosionGeneratorHandler* handler, const std::string& tag) {
bool CCustomExplosionGenerator::Reload(CExplosionGeneratorHandler* handler, const char* tag) {
const ExpGenParams oldParams = expGenParams;

if (!Load(handler, tag)) {
Expand Down
20 changes: 11 additions & 9 deletions rts/Sim/Projectiles/ExplosionGenerator.h
Expand Up @@ -50,8 +50,10 @@ class CExplosionGeneratorHandler
void ParseExplosionTables();
void ReloadGenerators(const std::string&);

unsigned int LoadGeneratorID(const std::string& tag);
IExplosionGenerator* LoadGenerator(const std::string& tag);
unsigned int LoadCustomGeneratorID(const char* tag) { return (LoadGeneratorID(tag, CEG_PREFIX_STRING)); }
unsigned int LoadGeneratorID(const char* tag, const char* pre = "");

IExplosionGenerator* LoadGenerator(const char* tag, const char* pre = "");
IExplosionGenerator* GetGenerator(unsigned int expGenID);

bool GenExplosion(
Expand All @@ -77,8 +79,8 @@ class CExplosionGeneratorHandler

std::vector<IExplosionGenerator*> explosionGenerators;

spring::unordered_map<std::string, unsigned int> expGenTagIdentMap;
spring::unordered_map<unsigned int, std::string> expGenIdentTagMap;
spring::unordered_map<unsigned int, unsigned int> expGenHashIdentMap; // hash->id
spring::unordered_map<unsigned int, std::array<char, 64>> expGenIdentNameMap; // id->name
};


Expand All @@ -92,8 +94,8 @@ class IExplosionGenerator
IExplosionGenerator(): generatorID(CExplosionGeneratorHandler::EXPGEN_ID_INVALID) {}
virtual ~IExplosionGenerator() {}

virtual bool Load(CExplosionGeneratorHandler* handler, const std::string& tag) = 0;
virtual bool Reload(CExplosionGeneratorHandler* handler, const std::string& tag) { return true; }
virtual bool Load(CExplosionGeneratorHandler* handler, const char* tag) = 0;
virtual bool Reload(CExplosionGeneratorHandler* handler, const char* tag) { return true; }
virtual bool Explosion(
const float3& pos,
const float3& dir,
Expand Down Expand Up @@ -121,7 +123,7 @@ class CStdExplosionGenerator: public IExplosionGenerator
public:
CStdExplosionGenerator(): IExplosionGenerator() {}

bool Load(CExplosionGeneratorHandler* handler, const std::string& tag) override { return false; }
bool Load(CExplosionGeneratorHandler* handler, const char* tag) override { return false; }
bool Explosion(
const float3& pos,
const float3& dir,
Expand Down Expand Up @@ -186,8 +188,8 @@ class CCustomExplosionGenerator: public IExplosionGenerator
static unsigned int GetFlagsFromHeight(float height, float groundHeight);

/// @throws content_error/runtime_error on errors
bool Load(CExplosionGeneratorHandler* handler, const std::string& tag) override;
bool Reload(CExplosionGeneratorHandler* handler, const std::string& tag) override;
bool Load(CExplosionGeneratorHandler* handler, const char* tag) override;
bool Reload(CExplosionGeneratorHandler* handler, const char* tag) override;
bool Explosion(const float3& pos, const float3& dir, float damage, float radius, float gfxMod, CUnit* owner, CUnit* hit) override;

// spawn-flags
Expand Down
8 changes: 1 addition & 7 deletions rts/Sim/Units/Scripts/LuaUnitScript.cpp
Expand Up @@ -1197,13 +1197,7 @@ int CLuaUnitScript::EmitSfx(lua_State* L)

// note: the arguments are reversed compared to the C++ (and COB?) function
const int piece = luaL_checkint(L, 1) - 1;
int type = CExplosionGeneratorHandler::EXPGEN_ID_INVALID;

if (lua_isstring(L, 2)) {
type = explGenHandler.LoadGeneratorID(std::string(CEG_PREFIX_STRING) + lua_tostring(L, 2)) & SFX_GLOBAL;
} else {
type = luaL_checkint(L, 2);
}
const int type = lua_isnumber(L, 2)? luaL_checkint(L, 2): (explGenHandler.LoadCustomGeneratorID(lua_tostring(L, 2)) & SFX_GLOBAL);

activeScript->EmitSfx(type, piece);
return 0;
Expand Down

0 comments on commit 12317c4

Please sign in to comment.