Rework metadata to have a standard handling.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
cf01511cfb
commit
8919ae4b02
|
@ -0,0 +1,70 @@
|
||||||
|
#ifndef PKMNLIB_ANGELSCRIPTMETADATA_HPP
|
||||||
|
#define PKMNLIB_ANGELSCRIPTMETADATA_HPP
|
||||||
|
|
||||||
|
class AngelscriptMetadata {
|
||||||
|
public:
|
||||||
|
explicit AngelscriptMetadata(const std::string& metadataString) { Parse(metadataString); }
|
||||||
|
|
||||||
|
inline const ArbUt::StringView& GetIdentifier() const noexcept { return _identifier; }
|
||||||
|
inline const std::string& GetParameter(const ArbUt::StringView& name) const noexcept {
|
||||||
|
return _parameters.Get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ArbUt::StringView _identifier;
|
||||||
|
ArbUt::Dictionary<ArbUt::StringView, std::string> _parameters;
|
||||||
|
|
||||||
|
size_t ReadUpToOrEnd(const std::string& s, const char symbol, size_t start) {
|
||||||
|
for (size_t i = start; i < s.length(); ++i) {
|
||||||
|
if (s.at(i) == symbol) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t FindNextNonSpace(const std::string& s, size_t start) {
|
||||||
|
for (size_t i = start; i < s.length(); ++i) {
|
||||||
|
if (s.at(i) != ' ') {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return s.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Parse(const std::string& metadataString) {
|
||||||
|
auto idEnd = ReadUpToOrEnd(metadataString, ' ', 0);
|
||||||
|
_identifier = ArbUt::StringView(metadataString.substr(0, idEnd).c_str(), idEnd);
|
||||||
|
auto current = idEnd;
|
||||||
|
while (true) {
|
||||||
|
current = FindNextNonSpace(metadataString, current);
|
||||||
|
if (current >= metadataString.length()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ParseParameter(metadataString, current);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ParseParameter(const std::string& metadataString, size_t& current) {
|
||||||
|
auto start = current;
|
||||||
|
current = ReadUpToOrEnd(metadataString, '=', current);
|
||||||
|
auto name = ArbUt::StringView(metadataString.substr(start, current - start).c_str(), current - start);
|
||||||
|
current++;
|
||||||
|
start = current;
|
||||||
|
auto isQuoted = metadataString[current] == '"';
|
||||||
|
if (isQuoted) {
|
||||||
|
current++;
|
||||||
|
start++;
|
||||||
|
current = ReadUpToOrEnd(metadataString, '"', current);
|
||||||
|
} else {
|
||||||
|
current = ReadUpToOrEnd(metadataString, ' ', current);
|
||||||
|
}
|
||||||
|
auto value = metadataString.substr(start, current - start);
|
||||||
|
_parameters.Insert(name, value);
|
||||||
|
if (isQuoted){
|
||||||
|
current += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PKMNLIB_ANGELSCRIPTMETADATA_HPP
|
|
@ -8,6 +8,7 @@
|
||||||
#include "../../../extern/angelscript_addons/scriptstdstring/scriptstdstring.h"
|
#include "../../../extern/angelscript_addons/scriptstdstring/scriptstdstring.h"
|
||||||
#include "../../Battling/PkmnScriptCategory.hpp"
|
#include "../../Battling/PkmnScriptCategory.hpp"
|
||||||
#include "../../Battling/Pokemon/Pokemon.hpp"
|
#include "../../Battling/Pokemon/Pokemon.hpp"
|
||||||
|
#include "AngelScriptMetadata.hpp"
|
||||||
#include "ByteCodeHandling/FileByteCodeStream.hpp"
|
#include "ByteCodeHandling/FileByteCodeStream.hpp"
|
||||||
#include "ByteCodeHandling/MemoryByteCodeStream.hpp"
|
#include "ByteCodeHandling/MemoryByteCodeStream.hpp"
|
||||||
#include "TypeRegistry/BasicScriptClass.hpp"
|
#include "TypeRegistry/BasicScriptClass.hpp"
|
||||||
|
@ -238,66 +239,23 @@ void AngelScriptResolver::FinalizeModule() {
|
||||||
auto typeInfo = _mainModule->GetObjectTypeByIndex(n);
|
auto typeInfo = _mainModule->GetObjectTypeByIndex(n);
|
||||||
if (typeInfo->DerivesFrom(pkmnScriptType)) {
|
if (typeInfo->DerivesFrom(pkmnScriptType)) {
|
||||||
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
||||||
for (size_t m = 0; m < metadata.size(); m++) {
|
for (auto& m : metadata) {
|
||||||
auto data = metadata[m];
|
auto data = AngelscriptMetadata(m);
|
||||||
if (std::regex_match(data, base_match, metadataMatcher)) {
|
RegisterScriptType(typeInfo, data.GetIdentifier(),
|
||||||
auto mt = base_match[1].str();
|
ArbUt::StringView(data.GetParameter("effect"_cnc).c_str()));
|
||||||
auto metadataKind = ArbUt::StringView(mt.c_str(), mt.length());
|
|
||||||
auto metadataVariables = base_match[2].str();
|
|
||||||
if (!std::regex_match(metadataVariables, base_match, variableMatcher)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ArbUt::StringView effectName;
|
|
||||||
for (size_t variableIndex = 1; variableIndex < base_match.size(); variableIndex += 2) {
|
|
||||||
if (ArbUt::StringView::CalculateHash(base_match[variableIndex].str().c_str()) == "effect"_cnc) {
|
|
||||||
auto val = base_match[variableIndex + 1].str();
|
|
||||||
effectName = ArbUt::StringView(val.c_str(), val.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RegisterScriptType(typeInfo, metadataKind, effectName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (typeInfo->DerivesFrom(itemUseScriptType)) {
|
} else if (typeInfo->DerivesFrom(itemUseScriptType)) {
|
||||||
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
||||||
for (size_t m = 0; m < metadata.size(); m++) {
|
for (auto& m : metadata) {
|
||||||
auto data = metadata[m];
|
auto data = AngelscriptMetadata(m);
|
||||||
if (std::regex_match(data, base_match, metadataMatcher)) {
|
_itemUseTypes.Insert(ArbUt::StringView(data.GetParameter("effect"_cnc).c_str()), typeInfo);
|
||||||
auto mt = base_match[1].str();
|
|
||||||
auto metadataKind = ArbUt::StringView(mt.c_str(), mt.length());
|
|
||||||
auto metadataVariables = base_match[2].str();
|
|
||||||
if (!std::regex_match(metadataVariables, base_match, variableMatcher)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ArbUt::StringView effectName;
|
|
||||||
for (size_t variableIndex = 1; variableIndex < base_match.size(); variableIndex += 2) {
|
|
||||||
if (ArbUt::StringView::CalculateHash(base_match[variableIndex].str().c_str()) == "effect"_cnc) {
|
|
||||||
auto val = base_match[variableIndex + 1].str();
|
|
||||||
effectName = ArbUt::StringView(val.c_str(), val.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_itemUseTypes.Insert(effectName, typeInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (typeInfo->DerivesFrom(evolutionScriptType)) {
|
} else if (typeInfo->DerivesFrom(evolutionScriptType)) {
|
||||||
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
auto metadata = _builder.GetMetadataForType(typeInfo->GetTypeId());
|
||||||
for (size_t m = 0; m < metadata.size(); m++) {
|
for (auto& m : metadata) {
|
||||||
auto data = metadata[m];
|
auto data = AngelscriptMetadata(m);
|
||||||
if (std::regex_match(data, base_match, metadataMatcher)) {
|
_evolutionTypes.Insert(ArbUt::StringView(data.GetParameter("effect"_cnc).c_str()), typeInfo);
|
||||||
auto mt = base_match[1].str();
|
|
||||||
auto metadataKind = ArbUt::StringView(mt.c_str(), mt.length());
|
|
||||||
auto metadataVariables = base_match[2].str();
|
|
||||||
if (!std::regex_match(metadataVariables, base_match, variableMatcher)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
ArbUt::StringView effectName;
|
|
||||||
for (size_t variableIndex = 1; variableIndex < base_match.size(); variableIndex += 2) {
|
|
||||||
if (ArbUt::StringView::CalculateHash(base_match[variableIndex].str().c_str()) == "effect"_cnc) {
|
|
||||||
auto val = base_match[variableIndex + 1].str();
|
|
||||||
effectName = ArbUt::StringView(val.c_str(), val.length());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_evolutionTypes.Insert(effectName, typeInfo);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
#ifdef TESTS_BUILD
|
||||||
|
#include "../../extern/doctest.hpp"
|
||||||
|
#include "../../src/ScriptResolving/AngelScript/AngelScriptMetadata.hpp"
|
||||||
|
|
||||||
|
TEST_CASE("Metadata without parameters") {
|
||||||
|
auto m = AngelscriptMetadata("Foo");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with single parameter") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=zet");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "zet");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with single parameter with trailing space") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=zet ");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "zet");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with single parameter with two spaces") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=zet");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "zet");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with two parameters") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=zet met=blabla");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "zet");
|
||||||
|
REQUIRE_EQ(m.GetParameter("met"_cnc), "blabla");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with two parameters and two spaces") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=zet met=blabla");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "zet");
|
||||||
|
REQUIRE_EQ(m.GetParameter("met"_cnc), "blabla");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with single parameter in quotes") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=\"this is a test string\"");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "this is a test string");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with single parameter in quotes with trailing space") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=\"this is a test string\" ");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "this is a test string");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with single parameter in quotes without closing quote") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=\"this is a test string");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "this is a test string");
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Metadata with two parameters in quotes") {
|
||||||
|
auto m = AngelscriptMetadata("Foo bar=\"this is a test string\" parameter2=\"xoxo another string\"");
|
||||||
|
REQUIRE_EQ(m.GetIdentifier(), "Foo"_cnc);
|
||||||
|
REQUIRE_EQ(m.GetParameter("bar"_cnc), "this is a test string");
|
||||||
|
REQUIRE_EQ(m.GetParameter("parameter2"_cnc), "xoxo another string");
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue