Updated language gen tool to match vn scene gen style and rollup

This commit is contained in:
2023-02-18 09:57:13 -08:00
parent 3b3b97294c
commit 589a2c4c95
21 changed files with 556 additions and 194 deletions

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,93 @@
Copyright 2022 The BIZ UDGothic Project Authors (https://github.com/googlefonts/morisawa-biz-ud-mincho)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@ -0,0 +1,9 @@
<language lang="en">
<string key="undefined">Hello Undefined</string>
<group key="test">
<group key="whatever">
<string key="something">Some text</string>
</group>
<string key="other">Other string</string>
</group>
</language>

View File

@ -8,7 +8,7 @@ if(NOT DEFINED DAWN_BUILD_TARGET)
if(WIN32)
set(DAWN_BUILD_TARGET "target-pokergame-win32-glfw")
elseif(UNIX AND NOT APPLE)
set(DAWN_BUILD_TARGET "target-pokergame-linux64-glfw")
set(DAWN_BUILD_TARGET "target-tictactoe-linux64-glfw")
endif()
endif()

View File

@ -0,0 +1,8 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
set(DAWN_BUILDING dawntictactoe CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_LINUX64 true CACHE INTERNAL ${DAWN_CACHE_TARGET})
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})

View File

@ -1,38 +1,38 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "prefab/SceneItemPrefab.hpp"
#include "display/mesh/CubeMesh.hpp"
#include "scene/components/display/MeshRenderer.hpp"
#include "scene/components/display/MeshHost.hpp"
#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
#include "scene/components/example/ExampleSpin.hpp"
namespace Dawn {
class SimpleSpinningCubePrefab :
public SceneItemPrefab<SimpleSpinningCubePrefab>
{
public:
std::vector<Asset*> prefabAssets(AssetManager *man) {
return std::vector<Asset*>();
}
SimpleSpinningCubePrefab(Scene *s, sceneitemid_t i) :
SceneItemPrefab(s, i)
{
}
void prefabInit(AssetManager *man) override {
auto meshRenderer = this->addComponent<MeshRenderer>();
auto meshHost = this->addComponent<MeshHost>();
auto spinning = this->addComponent<ExampleSpin>();
auto material = this->addComponent<SimpleTexturedMaterial>();
meshHost->mesh.createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
CubeMesh::buffer(&meshHost->mesh, glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1), 0, 0);
}
};
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "prefab/SceneItemPrefab.hpp"
#include "display/mesh/CubeMesh.hpp"
#include "scene/components/display/MeshRenderer.hpp"
#include "scene/components/display/MeshHost.hpp"
#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
#include "scene/components/example/ExampleSpin.hpp"
namespace Dawn {
class SimpleSpinningCubePrefab :
public SceneItemPrefab<SimpleSpinningCubePrefab>
{
public:
static std::vector<Asset*> prefabAssets(AssetManager *man) {
return std::vector<Asset*>();
}
SimpleSpinningCubePrefab(Scene *s, sceneitemid_t i) :
SceneItemPrefab(s, i)
{
}
void prefabInit(AssetManager *man) override {
auto meshRenderer = this->addComponent<MeshRenderer>();
auto meshHost = this->addComponent<MeshHost>();
auto spinning = this->addComponent<ExampleSpin>();
auto material = this->addComponent<SimpleTexturedMaterial>();
meshHost->mesh.createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
CubeMesh::buffer(&meshHost->mesh, glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1), 0, 0);
}
};
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/Scene.hpp"
#include "prefabs/SimpleSpinningCubePrefab.hpp"
namespace Dawn {
class TestScene : public Scene {
protected:
Camera *camera;
SimpleSpinningCubePrefab *cube;
void stage() override {
camera = Camera::create(this);
camera->transform->lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0));
cube = SimpleSpinningCubePrefab::prefabCreate(this);
}
std::vector<Asset*> getRequiredAssets() override {
auto assMan = &this->game->assetManager;
std::vector<Asset*> assets;
vectorAppend(&assets, SimpleSpinningCubePrefab::getRequiredAssets(assMan));
return assets;
}
public:
TestScene(DawnGame *game) : Scene(game) {}
};
}

View File

@ -0,0 +1,25 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Set up the executable
set(DAWN_TARGET_NAME "TicTacToe" CACHE INTERNAL ${DAWN_CACHE_TARGET})
# Build Project
add_executable(${DAWN_TARGET_NAME})
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Subdirs
add_subdirectory(game)
add_subdirectory(save)
# Assets
set(DIR_GAME_ASSETS games/tictactoe)
tool_language(locale_en ${DIR_GAME_ASSETS}/locale/en.xml)

View File

@ -0,0 +1,10 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
DawnGame.cpp
)

View File

@ -0,0 +1,46 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "DawnGame.hpp"
#include "scenes/TestScene.hpp"
using namespace Dawn;
DawnGame::DawnGame(DawnHost *host) :
host(host),
renderManager(this),
inputManager(this),
localeManager(this),
physicsManager(this),
saveManager(this)
{
}
int32_t DawnGame::init() {
this->assetManager.init();
this->localeManager.init();
this->renderManager.init();
this->scene = new TestScene(this);
return DAWN_GAME_INIT_RESULT_SUCCESS;
}
int32_t DawnGame::update(float_t delta) {
this->assetManager.update();
this->inputManager.update();
this->timeManager.update(delta);
if(this->scene != nullptr) this->scene->update();
this->renderManager.update();
return DAWN_GAME_UPDATE_RESULT_SUCCESS;
}
void DawnGame::sceneCutover(Scene *scene) {
if(scene == nullptr) scene = this->scene;
this->sceneToCutTo = scene;
}

View File

@ -0,0 +1,31 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "game/_DawnGame.hpp"
#include "scene/components/Components.hpp"
#include "save/DawnGameSaveManager.hpp"
namespace Dawn {
class DawnGame : public IDawnGame {
private:
Scene *sceneToCutTo = nullptr;
public:
DawnHost *host;
RenderManager renderManager;
AssetManager assetManager;
InputManager inputManager;
TimeManager timeManager;
LocaleManager localeManager;
DawnGameSaveManager saveManager;
PhysicsManager physicsManager;
DawnGame(DawnHost *host);
int32_t init() override;
int32_t update(float_t delta) override;
void sceneCutover(Scene *scene) override;
};
}

View File

@ -0,0 +1,14 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "input/InputManager.hpp"
#define INPUT_BIND(n) ((inputbind_t)n)
#define INPUT_BIND_ACCEPT INPUT_BIND(1)
#define INPUT_BIND_NEGATIVE_X INPUT_BIND(2)
#define INPUT_BIND_POSITIVE_X INPUT_BIND(3)
#define INPUT_BIND_NEGATIVE_Y INPUT_BIND(4)
#define INPUT_BIND_POSITIVE_Y INPUT_BIND(5)

View File

@ -0,0 +1,10 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
DawnGameSaveManager.cpp
)

View File

@ -0,0 +1,28 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "DawnGameSaveManager.hpp"
using namespace Dawn;
DawnGameSaveManager::DawnGameSaveManager(DawnGame *game) : SaveManager(game) {
}
bool_t DawnGameSaveManager::validateSave(struct SaveFile raw) {
if(!raw.has(POKER_SAVE_KEY_EXAMPLE)) return true;
this->currentSave.copy(raw, POKER_SAVE_KEY_EXAMPLE);
return false;
}
void DawnGameSaveManager::setExample(int32_t val) {
savedata_t value;
value.i32 = val;
this->currentSave.set(POKER_SAVE_KEY_EXAMPLE, value);
}
int32_t DawnGameSaveManager::getExample() {
return this->currentSave.get(POKER_SAVE_KEY_EXAMPLE).i32;
}

View File

@ -0,0 +1,22 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "save/SaveManager.hpp"
#define POKER_SAVE_KEY_EXAMPLE "poker.example"
namespace Dawn {
class DawnGameSaveManager : public SaveManager {
protected:
virtual bool_t validateSave(struct SaveFile raw) override;
public:
DawnGameSaveManager(DawnGame *game);
void setExample(int32_t value);
int32_t getExample();
};
}

View File

@ -79,10 +79,12 @@ endfunction()
# Language Tool
function(tool_language target in)
add_custom_target(${target}
COMMAND languagegen "${DAWN_ASSETS_SOURCE_DIR}/${in}" "${DAWN_ASSETS_BUILD_DIR}"
COMMAND languagegen --input="${DAWN_ASSETS_SOURCE_DIR}/${in}" --output="${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language"
COMMENT "Generating language set ${target} from ${in}"
DEPENDS languagegen
)
tool_generatedlanguages("${DAWN_TOOL_GENERATED_LANG_DIR}/${target}.language")
add_dependencies(${DAWN_TARGET_NAME} ${target})
endfunction()
# Audio Tool

View File

@ -26,6 +26,7 @@ int32_t GeneratedLanguages::start() {
// Now process each language file
std::map<std::string, std::map<std::string, std::string>> strings;
std::vector<std::string> knownKeys;
auto itFiles = files.begin();
while(itFiles != files.end()) {
@ -84,6 +85,7 @@ int32_t GeneratedLanguages::start() {
File langOut(flags["output"] + FILE_PATH_SEP + "language_" + itLang->first + ".language");
bufferOut.clear();
auto itKeys = knownKeys.begin();
while(itKeys != knownKeys.end()) {
auto key = *itKeys;
@ -97,6 +99,7 @@ int32_t GeneratedLanguages::start() {
}
// Write out.
langOut.mkdirp();
if(!langOut.writeString(bufferOut)) {
std::cout << "Failed to create output file \"" + langOut.filename + "\"" << std::endl;
return 1;

View File

@ -6,31 +6,32 @@
# Texture Build Tool
project(languagegen VERSION 2.0)
add_executable(languagegen)
# Sources
target_sources(languagegen
PRIVATE
${DAWN_SHARED_SOURCES}
${DAWN_TOOL_SOURCES}
LanguageGen.cpp
../../util/DawnTool.cpp
../../util/File.cpp
../../util/file.cpp
../../util/csv.cpp
../../util/xml.cpp
)
# Includes
target_include_directories(languagegen
PUBLIC
${DAWN_SHARED_INCLUDES}
${CMAKE_CURRENT_LIST_DIR}/../../
${DAWN_TOOL_INCLUDES}
${CMAKE_CURRENT_LIST_DIR}
)
# Definitions
target_compile_definitions(languagegen
PUBLIC
DAWN_TOOL_INSTANCE=LanguageGen
DAWN_TOOL_HEADER="LanguageGen.hpp"
)
# Libraries
target_link_libraries(languagegen
PUBLIC
${DAWN_BUILD_HOST_LIBS}

View File

@ -9,162 +9,144 @@
using namespace Dawn;
int32_t LanguageGen::start() {
if(this->args.size() != 3) {
std::cout << "Invalid number of arguments provided to language gen!" << std::endl;
return 1;
std::vector<std::string> LanguageParser::getRequiredAttributes() {
return std::vector<std::string>{ "key" };
}
std::map<std::string, std::string> LanguageParser::getOptionalAttributes() {
return std::map<std::string, std::string>();
}
int32_t LanguageParser::onParse(
Xml *node,
std::map<std::string, std::string> values,
struct LanguageString *out,
std::string *error
) {
out->key = values["key"];
out->text = node->value;
return 0;
}
std::vector<std::string> LanguageGroupParser::getRequiredAttributes() {
return std::vector<std::string>{ "key" };
}
std::map<std::string, std::string> LanguageGroupParser::getOptionalAttributes() {
return std::map<std::string, std::string>();
}
int32_t LanguageGroupParser::onParse(
Xml *node,
std::map<std::string, std::string> values,
struct LanguageGroup *out,
std::string *error
) {
std::string key = values["key"];
out->key += key;
auto it = node->children.begin();
int32_t ret;
while(it != node->children.end()) {
auto c = *it;
if(c->node == "string") {
struct LanguageString string;
ret = (LanguageParser()).parse(c, &string, error);
if(ret != 0) return ret;
string.lang = out->lang;
string.key = out->key + "." + string.key;
out->strings.push_back(string);
} else if(c->node == "group") {
struct LanguageGroup group;
group.key += key + ".";
group.lang = out->lang;
ret = (LanguageGroupParser()).parse(c, &group, error);
if(ret != 0) return ret;
vectorAppend(&out->strings, group.strings);
}
++it;
}
return 0;
}
std::vector<std::string> LanguageRootParser::getRequiredAttributes() {
return std::vector<std::string>{ "lang" };
}
std::map<std::string, std::string> LanguageRootParser::getOptionalAttributes() {
return std::map<std::string, std::string>();
}
int32_t LanguageRootParser::onParse(
Xml *node,
std::map<std::string, std::string> values,
struct LanguageRoot *out,
std::string *error
) {
int32_t ret;
out->lang = values["lang"];
auto it = node->children.begin();
while(it != node->children.end()) {
auto c = *it;
if(c->node == "string") {
struct LanguageString string;
ret = (LanguageParser()).parse(c, &string, error);
if(ret != 0) return ret;
string.lang = out->lang;
out->strings.push_back(string);
} else if(c->node == "group") {
struct LanguageGroup group;
group.lang = out->lang;
ret = (LanguageGroupParser()).parse(c, &group, error);
if(ret != 0) return ret;
vectorAppend(&out->strings, group.strings);
}
++it;
}
auto fileIn = File(this->args[1]);
return 0;
}
std::vector<std::string> LanguageGen::getRequiredFlags() {
return std::vector<std::string>{ "input", "output" };
}
int32_t LanguageGen::start() {
auto fileIn = File(flags["input"]);
std::string buffer;
if(!fileIn.readString(&buffer)) {
std::cout << "Failed to open/read input file " << fileIn.filename << std::endl;
return 1;
}
auto xml = Xml::load(buffer);
std::string error;
struct LanguageRoot root;
// Begin parsing. Start by looking for the <language> tags
std::vector<std::string> languages;
auto itChildren = xml.children.begin();
while(itChildren != xml.children.end()) {
auto child = *itChildren;
if(child->node == "language") {
auto attrName = child->attributes.find("name");
if(attrName == child->attributes.end()) {
std::cout << "Missing name param on language node" << std::endl;
return 1;
}
languages.push_back(attrName->second);
}
++itChildren;
auto ret = (LanguageRootParser()).parse(&xml, &root, &error);
if(ret != 0) {
std::cout << error << std::endl;
return ret;
}
// Now begin actually parsing
std::map<std::string, std::vector<struct LanguageString>> strings;
itChildren = xml.children.begin();
while(itChildren != xml.children.end()) {
auto child = *itChildren;
if(child->node == "group") {
auto ret = this->parseGroup(child, "", &strings);
if(ret != 0) return ret;
} else if(child->node == "string") {
std::cout << "String cannot be a root node" << std::endl;
return 1;
}
++itChildren;
}
// Now we validate each lang has each key.
std::vector<std::string> keys;
auto it = strings.begin();
while(it != strings.end()) {
auto it2 = it->second.begin();
while(it2 != it->second.end()) {
auto key = it2->key;
auto exist = std::find(keys.begin(), keys.end(), key);
if(exist == keys.end()) {
keys.push_back(key);
}
it2++;
}
++it;
}
// Now we actually parse each string, validating as we go.
it = strings.begin();
while(it != strings.end()) {
std::vector<std::string> itKeys;
std::string bufferOut;
auto it2 = it->second.begin();
while(it2 != it->second.end()) {
auto l = *it2;
itKeys.push_back(l.key);
bufferOut += l.key + "|" + l.value + "|";
it2++;
}
File fileOut(this->args[2] + "/language_" + it->first + ".language");
if(!fileOut.mkdirp()) {
std::cout << "Failed to create output folder" << std::endl;
}
if(!fileOut.writeString(bufferOut)) {
std::cout << "Failed to write to output file " << fileOut.filename << std::endl;
return 1;
}
auto it3 = keys.begin();
while(it3 != keys.end()) {
auto key = *it3;
auto inIt = std::find(itKeys.begin(), itKeys.end(), key);
if(inIt == itKeys.end()) {
std::cout << "Locale " << it->first << " missing key " << key << std::endl;
}
it3++;
}
if(itKeys.size() != keys.size()) {
std::cout << "Locale is missing some keys, see above" << std::endl;
return 1;
}
++it;
}
return 0;
}
int32_t LanguageGen::parseString(
Xml *stringNode,
std::string key,
std::map<std::string,std::vector<struct LanguageString>> *strings
) {
auto attrLang = stringNode->attributes.find("lang");
if(attrLang == stringNode->attributes.end()) {
std::cout << "String is missing lang parameter." << std::endl;
return -1;
}
struct LanguageString str;
str.key = key;
str.value = stringNode->value;
auto existing = (*strings).find(attrLang->second);
if(existing == (*strings).end()) {
(*strings).insert(std::make_pair(attrLang->second, std::vector<struct LanguageString>()));
}
(*strings)[attrLang->second].push_back(str);
return 0;
}
int32_t LanguageGen::parseGroup(
Xml *groupNode,
std::string key,
std::map<std::string, std::vector<struct LanguageString>> *strings
) {
int32_t ret;
auto attrKey = groupNode->attributes.find("key");
if(attrKey == groupNode->attributes.end()) {
std::cout << "Group node is missing key" << std::endl;
return 1;
}
if(key.size() > 0) key += ".";
key += attrKey->second;
auto itChildren = groupNode->children.begin();
while(itChildren != groupNode->children.end()) {
auto child = *itChildren;
if(child->node == "string") {
ret = this->parseString(child, key, strings);
if(ret != 0) return ret;
} else if(child->node == "group") {
ret = this->parseGroup(child, key, strings);
if(ret != 0) return ret;
}
++itChildren;
}
// Now dump out the language strings to be picked up later.
ret = languageSaveStrings(flags["output"], root.strings);
if(ret != 0) return ret;
return 0;
}

View File

@ -5,17 +5,62 @@
#pragma once
#include "util/DawnTool.hpp"
#include "util/Xml.hpp"
#include "util/File.hpp"
#include "util/XmlParser.hpp"
#include "util/Language.cpp"
namespace Dawn {
struct LanguageString {
struct LanguageGroup {
std::vector<struct LanguageString> strings;
std::string key;
std::string value;
std::string lang;
};
struct LanguageRoot {
std::string lang;
std::vector<struct LanguageString> strings;
};
class LanguageParser : public XmlParser<struct LanguageString> {
protected:
std::vector<std::string> getRequiredAttributes();
std::map<std::string, std::string> getOptionalAttributes();
int32_t onParse(
Xml *node,
std::map<std::string, std::string> values,
struct LanguageString *out,
std::string *error
);
};
class LanguageGroupParser : public XmlParser<struct LanguageGroup> {
protected:
std::vector<std::string> getRequiredAttributes();
std::map<std::string, std::string> getOptionalAttributes();
int32_t onParse(
Xml *node,
std::map<std::string, std::string> values,
struct LanguageGroup *out,
std::string *error
);
};
class LanguageRootParser : public XmlParser<struct LanguageRoot> {
protected:
std::vector<std::string> getRequiredAttributes();
std::map<std::string, std::string> getOptionalAttributes();
int32_t onParse(
Xml *node,
std::map<std::string, std::string> values,
struct LanguageRoot *out,
std::string *error
) override;
};
class LanguageGen : public DawnTool {
protected:
std::vector<std::string> getRequiredFlags() override;
int32_t parseGroup(
Xml *node,
std::string key,