experimental asset load scripts
This commit is contained in:
parent
696abcca71
commit
6fa0afd758
@ -275,6 +275,8 @@ if(STAR_COMPILER_GNU)
|
||||
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -Ofast")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Ofast")
|
||||
|
||||
set(BUILD_RPATH_USE_ORIGIN TRUE)
|
||||
|
||||
elseif(STAR_COMPILER_CLANG)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wuninitialized -Wno-parentheses-equality -Wno-deprecated-declarations")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -Wuninitialized -Wno-parentheses-equality -Wno-deprecated-declarations")
|
||||
@ -304,6 +306,8 @@ elseif(STAR_COMPILER_CLANG)
|
||||
set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG -Ofast")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG -Ofast")
|
||||
|
||||
set(BUILD_RPATH_USE_ORIGIN TRUE)
|
||||
|
||||
elseif(STAR_COMPILER_MSVC)
|
||||
# /MP - Multi-processor building
|
||||
# /EHsc - Enable normal C++ exception handling
|
||||
@ -513,7 +517,10 @@ set(STAR_EXTERN_INCLUDES ${PROJECT_SOURCE_DIR}/extern)
|
||||
add_subdirectory(extern)
|
||||
|
||||
# Core support code, not specific to starbound.
|
||||
set(STAR_CORE_INCLUDES ${PROJECT_SOURCE_DIR}/core)
|
||||
set(STAR_CORE_INCLUDES
|
||||
${PROJECT_SOURCE_DIR}/core
|
||||
${PROJECT_SOURCE_DIR}/core/scripting
|
||||
)
|
||||
add_subdirectory(core)
|
||||
|
||||
# Less general purpose code than core that is available to both the game and
|
||||
|
@ -17,33 +17,35 @@
|
||||
#include "StarLexicalCast.hpp"
|
||||
#include "StarSha256.hpp"
|
||||
#include "StarDataStreamDevices.hpp"
|
||||
#include "StarLua.hpp"
|
||||
#include "StarUtilityLuaBindings.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
static void validatePath(AssetPath const& components, bool canContainSubPath, bool canContainDirectives) {
|
||||
if (components.basePath.empty() || components.basePath[0] != '/')
|
||||
throw AssetException(strf("Path '{}' must be absolute", components.basePath));
|
||||
static void validateBasePath(std::string_view const& basePath) {
|
||||
if (basePath.empty() || basePath[0] != '/')
|
||||
throw AssetException(strf("Path '{}' must be absolute", basePath));
|
||||
|
||||
bool first = true;
|
||||
bool slashed = true;
|
||||
bool dotted = false;
|
||||
for (auto c : components.basePath) {
|
||||
for (auto c : basePath) {
|
||||
if (c == '/') {
|
||||
if (!first) {
|
||||
if (slashed)
|
||||
throw AssetException(strf("Path '{}' contains consecutive //, not allowed", components.basePath));
|
||||
throw AssetException(strf("Path '{}' contains consecutive //, not allowed", basePath));
|
||||
else if (dotted)
|
||||
throw AssetException(strf("Path '{}' '.' and '..' not allowed", components.basePath));
|
||||
throw AssetException(strf("Path '{}' '.' and '..' not allowed", basePath));
|
||||
}
|
||||
slashed = true;
|
||||
dotted = false;
|
||||
} else if (c == ':') {
|
||||
if (slashed)
|
||||
throw AssetException(strf("Path '{}' has ':' after directory", components.basePath));
|
||||
throw AssetException(strf("Path '{}' has ':' after directory", basePath));
|
||||
break;
|
||||
} else if (c == '?') {
|
||||
if (slashed)
|
||||
throw AssetException(strf("Path '{}' has '?' after directory", components.basePath));
|
||||
throw AssetException(strf("Path '{}' has '?' after directory", basePath));
|
||||
break;
|
||||
} else {
|
||||
slashed = false;
|
||||
@ -52,7 +54,11 @@ static void validatePath(AssetPath const& components, bool canContainSubPath, bo
|
||||
first = false;
|
||||
}
|
||||
if (slashed)
|
||||
throw AssetException(strf("Path '{}' cannot be a file", components.basePath));
|
||||
throw AssetException(strf("Path '{}' cannot be a file", basePath));
|
||||
}
|
||||
|
||||
static void validatePath(AssetPath const& components, bool canContainSubPath, bool canContainDirectives) {
|
||||
validateBasePath(components.basePath.utf8());
|
||||
|
||||
if (!canContainSubPath && components.subPath)
|
||||
throw AssetException::format("Path '{}' cannot contain sub-path", components);
|
||||
@ -60,6 +66,32 @@ static void validatePath(AssetPath const& components, bool canContainSubPath, bo
|
||||
throw AssetException::format("Path '{}' cannot contain directives", components);
|
||||
}
|
||||
|
||||
static void validatePath(StringView const& path, bool canContainSubPath, bool canContainDirectives) {
|
||||
std::string_view const& str = path.utf8();
|
||||
|
||||
size_t end = str.find_first_of(":?");
|
||||
auto basePath = str.substr(0, end);
|
||||
validateBasePath(basePath);
|
||||
|
||||
bool subPath = false;
|
||||
if (str[end] == ':') {
|
||||
size_t beg = end + 1;
|
||||
if (beg != str.size()) {
|
||||
end = str.find_first_of('?', beg);
|
||||
if (end == NPos && beg + 1 != str.size())
|
||||
subPath = true;
|
||||
else if (size_t len = end - beg)
|
||||
subPath = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (subPath)
|
||||
throw AssetException::format("Path '{}' cannot contain sub-path", path);
|
||||
|
||||
if (end != NPos && str[end] == '?' && !canContainDirectives)
|
||||
throw AssetException::format("Path '{}' cannot contain directives", path);
|
||||
}
|
||||
|
||||
Maybe<RectU> FramesSpecification::getRect(String const& frame) const {
|
||||
if (auto alias = aliases.ptr(frame)) {
|
||||
return frames.get(*alias);
|
||||
@ -75,6 +107,22 @@ Assets::Assets(Settings settings, StringList assetSources) {
|
||||
m_stopThreads = false;
|
||||
m_assetSources = std::move(assetSources);
|
||||
|
||||
auto luaEngine = LuaEngine::create();
|
||||
auto decorateLuaContext = [this](LuaContext& context) {
|
||||
context.setCallbacks("sb", LuaBindings::makeUtilityCallbacks());
|
||||
LuaCallbacks callbacks;
|
||||
callbacks.registerCallbackWithSignature<StringSet, String>("byExtension", bind(&Assets::scanExtension, this, _1));
|
||||
callbacks.registerCallbackWithSignature<Json, String>("json", bind(&Assets::json, this, _1));
|
||||
callbacks.registerCallback("bytes", [this](String const& path) -> String {
|
||||
auto assetBytes = bytes(path);
|
||||
return String(assetBytes->ptr(), assetBytes->size());
|
||||
});
|
||||
callbacks.registerCallback("scan", [this](Maybe<String> const& a, Maybe<String> const& b) -> StringList {
|
||||
return b ? scan(a.value(), *b) : scan(a.value());
|
||||
});
|
||||
context.setCallbacks("assets", callbacks);
|
||||
};
|
||||
|
||||
for (auto& sourcePath : m_assetSources) {
|
||||
Logger::info("Loading assets from: '{}'", sourcePath);
|
||||
AssetSourcePtr source;
|
||||
@ -105,6 +153,25 @@ Assets::Assets(Settings settings, StringList assetSources) {
|
||||
auto& descriptor = m_files[filename];
|
||||
descriptor.sourceName = filename;
|
||||
descriptor.source = source;
|
||||
m_filesByExtension[AssetPath::extension(filename).toLower()].insert(filename);
|
||||
}
|
||||
auto metadata = source->metadata();
|
||||
if (auto scripts = metadata.ptr("scripts")) {
|
||||
if (auto onLoad = scripts->optArray("onLoad")) {
|
||||
Logger::info("Running onLoad scripts {}", *onLoad);
|
||||
try {
|
||||
auto context = luaEngine->createContext();
|
||||
decorateLuaContext(context);
|
||||
for (auto& jPath : *onLoad) {
|
||||
auto path = jPath.toString();
|
||||
auto script = source->read(path);
|
||||
context.load(script, path);
|
||||
}
|
||||
}
|
||||
catch (LuaException const& e) {
|
||||
Logger::error("Exception while running onLoad scripts from asset source '{}': {}", sourcePath, e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -133,9 +200,6 @@ Assets::Assets(Settings settings, StringList assetSources) {
|
||||
|
||||
m_digest = digest.compute();
|
||||
|
||||
for (auto const& filename : m_files.keys())
|
||||
m_filesByExtension[AssetPath::extension(filename).toLower()].append(filename);
|
||||
|
||||
int workerPoolSize = m_settings.workerPoolSize;
|
||||
for (int i = 0; i < workerPoolSize; i++)
|
||||
m_workerThreads.append(Thread::invoke("Assets::workerMain", mem_fn(&Assets::workerMain), this));
|
||||
@ -194,7 +258,9 @@ Maybe<String> Assets::assetSourcePath(AssetSourcePtr const& source) const {
|
||||
|
||||
StringList Assets::scan(String const& suffix) const {
|
||||
if (suffix.beginsWith(".") && !suffix.substr(1).hasChar('.')) {
|
||||
return scanExtension(suffix);
|
||||
return scanExtension(suffix).values();
|
||||
} else if (suffix.empty()) {
|
||||
return m_files.keys();
|
||||
} else {
|
||||
StringList result;
|
||||
for (auto const& fileEntry : m_files) {
|
||||
@ -210,7 +276,7 @@ StringList Assets::scan(String const& suffix) const {
|
||||
StringList Assets::scan(String const& prefix, String const& suffix) const {
|
||||
StringList result;
|
||||
if (suffix.beginsWith(".") && !suffix.substr(1).hasChar('.')) {
|
||||
StringList filesWithExtension = scanExtension(suffix);
|
||||
StringSet filesWithExtension = scanExtension(suffix);
|
||||
for (auto const& file : filesWithExtension) {
|
||||
if (file.beginsWith(prefix, String::CaseInsensitive))
|
||||
result.append(file);
|
||||
@ -225,11 +291,11 @@ StringList Assets::scan(String const& prefix, String const& suffix) const {
|
||||
return result;
|
||||
}
|
||||
|
||||
StringList Assets::scanExtension(String const& extension) const {
|
||||
if (extension.beginsWith("."))
|
||||
return m_filesByExtension.value(extension.substr(1));
|
||||
else
|
||||
return m_filesByExtension.value(extension);
|
||||
const StringSet NullStringSet;
|
||||
|
||||
StringSet const& Assets::scanExtension(String const& extension) const {
|
||||
auto find = m_filesByExtension.find(extension.beginsWith(".") ? extension.substr(1) : extension);
|
||||
return find != m_filesByExtension.end() ? find->second : NullStringSet;
|
||||
}
|
||||
|
||||
Json Assets::json(String const& path) const {
|
||||
@ -255,6 +321,16 @@ void Assets::queueJsons(StringList const& paths) const {
|
||||
}));
|
||||
}
|
||||
|
||||
void Assets::queueJsons(StringSet const& paths) const {
|
||||
MutexLocker assetsLocker(m_assetsMutex);
|
||||
for (String const& path : paths) {
|
||||
auto components = AssetPath::split(path);
|
||||
validatePath(components, true, false);
|
||||
|
||||
queueAsset(AssetId{AssetType::Json, {components.basePath, {}, {}}});
|
||||
};
|
||||
}
|
||||
|
||||
ImageConstPtr Assets::image(AssetPath const& path) const {
|
||||
validatePath(path, true, true);
|
||||
|
||||
@ -270,6 +346,16 @@ void Assets::queueImages(StringList const& paths) const {
|
||||
}));
|
||||
}
|
||||
|
||||
void Assets::queueImages(StringSet const& paths) const {
|
||||
MutexLocker assetsLocker(m_assetsMutex);
|
||||
for (String const& path : paths) {
|
||||
auto components = AssetPath::split(path);
|
||||
validatePath(components, true, true);
|
||||
|
||||
queueAsset(AssetId{AssetType::Image, std::move(components)});
|
||||
};
|
||||
}
|
||||
|
||||
ImageConstPtr Assets::tryImage(AssetPath const& path) const {
|
||||
validatePath(path, true, true);
|
||||
|
||||
@ -296,13 +382,23 @@ AudioConstPtr Assets::audio(String const& path) const {
|
||||
|
||||
void Assets::queueAudios(StringList const& paths) const {
|
||||
queueAssets(paths.transformed([](String const& path) {
|
||||
const auto components = AssetPath::split(path);
|
||||
auto components = AssetPath::split(path);
|
||||
validatePath(components, false, false);
|
||||
|
||||
return AssetId{AssetType::Audio, std::move(components)};
|
||||
}));
|
||||
}
|
||||
|
||||
void Assets::queueAudios(StringSet const& paths) const {
|
||||
MutexLocker assetsLocker(m_assetsMutex);
|
||||
for (String const& path : paths) {
|
||||
auto components = AssetPath::split(path);
|
||||
validatePath(components, false, true);
|
||||
|
||||
queueAsset(AssetId{AssetType::Audio, std::move(components)});
|
||||
};
|
||||
}
|
||||
|
||||
AudioConstPtr Assets::tryAudio(String const& path) const {
|
||||
auto components = AssetPath::split(path);
|
||||
validatePath(components, false, false);
|
||||
@ -490,17 +586,20 @@ FramesSpecification Assets::parseFramesSpecification(Json const& frameConfig, St
|
||||
void Assets::queueAssets(List<AssetId> const& assetIds) const {
|
||||
MutexLocker assetsLocker(m_assetsMutex);
|
||||
|
||||
for (auto const& id : assetIds) {
|
||||
auto i = m_assetsCache.find(id);
|
||||
if (i != m_assetsCache.end()) {
|
||||
if (i->second)
|
||||
freshen(i->second);
|
||||
} else {
|
||||
auto j = m_queue.find(id);
|
||||
if (j == m_queue.end()) {
|
||||
m_queue[id] = QueuePriority::Load;
|
||||
m_assetsQueued.signal();
|
||||
}
|
||||
for (auto const& id : assetIds)
|
||||
queueAsset(id);
|
||||
}
|
||||
|
||||
void Assets::queueAsset(AssetId const& assetId) const {
|
||||
auto i = m_assetsCache.find(assetId);
|
||||
if (i != m_assetsCache.end()) {
|
||||
if (i->second)
|
||||
freshen(i->second);
|
||||
} else {
|
||||
auto j = m_queue.find(assetId);
|
||||
if (j == m_queue.end()) {
|
||||
m_queue[assetId] = QueuePriority::Load;
|
||||
m_assetsQueued.signal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ public:
|
||||
// Scans all assets for files with the given extension, which is specially
|
||||
// indexed and much faster than a normal scan. Extension may contain leading
|
||||
// '.' character or it may be omitted.
|
||||
StringList scanExtension(String const& extension) const;
|
||||
StringSet const& scanExtension(String const& extension) const;
|
||||
|
||||
// Get json asset with an optional sub-path. The sub-path portion of the
|
||||
// path refers to a key in the top-level object, and may use dot notation
|
||||
@ -201,6 +201,7 @@ public:
|
||||
|
||||
// Load all the given jsons using background processing.
|
||||
void queueJsons(StringList const& paths) const;
|
||||
void queueJsons(StringSet const& paths) const;
|
||||
|
||||
// Returns *either* an image asset or a sub-frame. Frame files are JSON
|
||||
// descriptor files that reference a particular image and label separate
|
||||
@ -212,6 +213,7 @@ public:
|
||||
ImageConstPtr image(AssetPath const& path) const;
|
||||
// Load images using background processing
|
||||
void queueImages(StringList const& paths) const;
|
||||
void queueImages(StringSet const& paths) const;
|
||||
// Return the given image *if* it is already loaded, otherwise queue it for
|
||||
// loading.
|
||||
ImageConstPtr tryImage(AssetPath const& path) const;
|
||||
@ -226,6 +228,7 @@ public:
|
||||
AudioConstPtr audio(String const& path) const;
|
||||
// Load audios using background processing
|
||||
void queueAudios(StringList const& paths) const;
|
||||
void queueAudios(StringSet const& paths) const;
|
||||
// Return the given audio *if* it is already loaded, otherwise queue it for
|
||||
// loading.
|
||||
AudioConstPtr tryAudio(String const& path) const;
|
||||
@ -249,6 +252,8 @@ private:
|
||||
static FramesSpecification parseFramesSpecification(Json const& frameConfig, String path);
|
||||
|
||||
void queueAssets(List<AssetId> const& assetIds) const;
|
||||
//Lock before calling!
|
||||
void queueAsset(AssetId const& assetId) const;
|
||||
shared_ptr<AssetData> tryAsset(AssetId const& id) const;
|
||||
shared_ptr<AssetData> getAsset(AssetId const& id) const;
|
||||
|
||||
@ -317,7 +322,7 @@ private:
|
||||
// Maps the source asset name to the source containing it
|
||||
CaseInsensitiveStringMap<AssetFileDescriptor> m_files;
|
||||
// Maps an extension to the files with that extension
|
||||
CaseInsensitiveStringMap<StringList> m_filesByExtension;
|
||||
CaseInsensitiveStringMap<StringSet> m_filesByExtension;
|
||||
|
||||
ByteArray m_digest;
|
||||
|
||||
|
@ -127,6 +127,7 @@ SET (star_core_HEADERS
|
||||
StarWorkerPool.hpp
|
||||
StarXXHash.hpp
|
||||
StarZSTDCompression.hpp
|
||||
scripting/StarUtilityLuaBindings.hpp
|
||||
)
|
||||
|
||||
SET (star_core_SOURCES
|
||||
@ -183,6 +184,7 @@ SET (star_core_SOURCES
|
||||
StarUuid.cpp
|
||||
StarWorkerPool.cpp
|
||||
StarZSTDCompression.cpp
|
||||
scripting/StarUtilityLuaBindings.cpp
|
||||
)
|
||||
|
||||
IF (STAR_SYSTEM_FAMILY_UNIX)
|
||||
|
@ -41,7 +41,7 @@ AssetPath AssetPath::split(String const& path) {
|
||||
if (str[end] == ':') {
|
||||
size_t beg = end + 1;
|
||||
if (beg != str.size()) {
|
||||
end = str.find_first_of("?", beg);
|
||||
end = str.find_first_of('?', beg);
|
||||
if (end == NPos && beg + 1 != str.size())
|
||||
components.subPath.emplace(str.substr(beg));
|
||||
else if (size_t len = end - beg)
|
||||
|
@ -407,7 +407,7 @@ bool String::hasCharOrWhitespace(Char c) const {
|
||||
return hasChar(c);
|
||||
}
|
||||
|
||||
String String::replace(String const& rplc, String const& val) const {
|
||||
String String::replace(String const& rplc, String const& val, CaseSensitivity cs) const {
|
||||
size_t index;
|
||||
size_t sz = size();
|
||||
size_t rsz = rplc.size();
|
||||
@ -417,7 +417,7 @@ String String::replace(String const& rplc, String const& val) const {
|
||||
if (rplc.empty())
|
||||
return *this;
|
||||
|
||||
index = find(rplc);
|
||||
index = find(rplc, 0, cs);
|
||||
if (index == NPos)
|
||||
return *this;
|
||||
|
||||
@ -431,7 +431,7 @@ String String::replace(String const& rplc, String const& val) const {
|
||||
for (size_t i = 0; i < rsz; ++i)
|
||||
++it;
|
||||
|
||||
size_t nindex = find(rplc, index);
|
||||
size_t nindex = find(rplc, index, cs);
|
||||
for (size_t i = index; i < nindex && i < sz; ++i)
|
||||
ret.append(*it++);
|
||||
|
||||
|
@ -148,7 +148,7 @@ public:
|
||||
// whitespace.
|
||||
bool hasCharOrWhitespace(Char c) const;
|
||||
|
||||
String replace(String const& rplc, String const& val) const;
|
||||
String replace(String const& rplc, String const& val, CaseSensitivity cs = CaseSensitive) const;
|
||||
|
||||
String trimEnd(String const& chars = "") const;
|
||||
String trimBeg(String const& chars = "") const;
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "StarUtilityLuaBindings.hpp"
|
||||
#include "StarJsonExtra.hpp"
|
||||
#include "StarLuaGameConverters.hpp"
|
||||
#include "StarUuid.hpp"
|
||||
#include "StarRandom.hpp"
|
||||
#include "StarPerlin.hpp"
|
||||
#include "StarXXHash.hpp"
|
||||
#include "StarLogging.hpp"
|
||||
#include "StarInterpolation.hpp"
|
||||
#include "StarLuaConverters.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
@ -251,7 +251,6 @@ SET (star_game_HEADERS
|
||||
scripting/StarStatusControllerLuaBindings.hpp
|
||||
scripting/StarWorldLuaBindings.hpp
|
||||
scripting/StarUniverseServerLuaBindings.hpp
|
||||
scripting/StarUtilityLuaBindings.hpp
|
||||
|
||||
terrain/StarCacheSelector.hpp
|
||||
terrain/StarConstantSelector.hpp
|
||||
@ -489,7 +488,6 @@ SET (star_game_SOURCES
|
||||
scripting/StarStatusControllerLuaBindings.cpp
|
||||
scripting/StarWorldLuaBindings.cpp
|
||||
scripting/StarUniverseServerLuaBindings.cpp
|
||||
scripting/StarUtilityLuaBindings.cpp
|
||||
|
||||
terrain/StarCacheSelector.cpp
|
||||
terrain/StarConstantSelector.cpp
|
||||
|
@ -10,7 +10,7 @@ AiDatabase::AiDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto config = assets->json("/ai/ai.config");
|
||||
|
||||
auto missions = assets->scanExtension("aimission");
|
||||
auto& missions = assets->scanExtension("aimission");
|
||||
assets->queueJsons(missions);
|
||||
|
||||
for (auto const& file : missions) {
|
||||
|
@ -151,12 +151,12 @@ BehaviorTree::BehaviorTree(String const& name, StringSet scripts, JsonObject con
|
||||
BehaviorDatabase::BehaviorDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
StringList nodeFiles = assets->scanExtension("nodes");
|
||||
auto& nodeFiles = assets->scanExtension("nodes");
|
||||
assets->queueJsons(nodeFiles);
|
||||
for (String const& file : nodeFiles) {
|
||||
try {
|
||||
Json nodes = assets->json(file);
|
||||
for (auto node : nodes.toObject()) {
|
||||
for (auto& node : nodes.toObject()) {
|
||||
StringMap<NodeParameter> parameters;
|
||||
for (auto p : node.second.getObject("properties", {}))
|
||||
parameters.set(p.first, jsonToNodeParameter(p.second));
|
||||
@ -174,7 +174,7 @@ BehaviorDatabase::BehaviorDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
auto behaviorFiles = assets->scanExtension("behavior");
|
||||
auto& behaviorFiles = assets->scanExtension("behavior");
|
||||
assets->queueJsons(behaviorFiles);
|
||||
for (auto const& file : behaviorFiles) {
|
||||
try {
|
||||
@ -190,7 +190,7 @@ BehaviorDatabase::BehaviorDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto pair : m_configs) {
|
||||
for (auto& pair : m_configs) {
|
||||
if (!m_behaviors.contains(pair.first))
|
||||
loadTree(pair.first);
|
||||
}
|
||||
|
@ -15,9 +15,9 @@ BiomeDatabase::BiomeDatabase() {
|
||||
|
||||
// 'type' here is the extension of the file, and determines the selector type
|
||||
auto scanFiles = [=](String const& type, ConfigMap& map) {
|
||||
auto files = assets->scanExtension(type);
|
||||
auto& files = assets->scanExtension(type);
|
||||
assets->queueJsons(files);
|
||||
for (auto path : files) {
|
||||
for (auto& path : files) {
|
||||
auto parameters = assets->json(path);
|
||||
if (parameters.isNull())
|
||||
continue;
|
||||
|
@ -7,10 +7,10 @@ namespace Star {
|
||||
|
||||
CodexDatabase::CodexDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("codex");
|
||||
auto& files = assets->scanExtension("codex");
|
||||
auto codexConfig = assets->json("/codex.config");
|
||||
assets->queueJsons(files);
|
||||
for (auto const& file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
auto codexJson = assets->json(file);
|
||||
codexJson = codexJson.set("icon",
|
||||
|
@ -23,9 +23,9 @@ Collectable::Collectable(String const& name, int order, String const& title, Str
|
||||
|
||||
CollectionDatabase::CollectionDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("collection");
|
||||
auto& files = assets->scanExtension("collection");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
auto config = assets->json(file);
|
||||
|
||||
Collection collection;
|
||||
|
@ -18,9 +18,9 @@ DamageDatabase::DamageDatabase() {
|
||||
m_elementalTypes.set(p.first, std::move(type));
|
||||
}
|
||||
|
||||
auto files = assets->scanExtension("damage");
|
||||
auto& files = assets->scanExtension("damage");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
auto config = assets->json(file);
|
||||
String name = config.getString("kind");
|
||||
if (m_damageKinds.contains(name))
|
||||
|
@ -5,8 +5,8 @@ namespace Star {
|
||||
|
||||
DanceDatabase::DanceDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("dance");
|
||||
for (auto file : files) {
|
||||
auto& files = assets->scanExtension("dance");
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
DancePtr dance = readDance(file);
|
||||
m_dances[dance->name] = dance;
|
||||
|
@ -1309,7 +1309,7 @@ namespace Dungeon {
|
||||
DungeonDefinitions::DungeonDefinitions() : m_paths(), m_cacheMutex(), m_definitionCache(DefinitionsCacheSize) {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
for (auto file : assets->scan(".dungeon")) {
|
||||
for (auto& file : assets->scan(".dungeon")) {
|
||||
Json dungeon = assets->json(file);
|
||||
m_paths.insert(dungeon.get("metadata").getString("name"), file);
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ namespace Star {
|
||||
EffectSourceDatabase::EffectSourceDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("effectsource");
|
||||
auto& files = assets->scanExtension("effectsource");
|
||||
assets->queueJsons(files);
|
||||
for (auto const& file : files) {
|
||||
auto sourceConfig = make_shared<EffectSourceConfig>(assets->json(file));
|
||||
|
@ -552,7 +552,7 @@ ItemRecipe ItemDatabase::makeRecipe(List<ItemDescriptor> inputs, ItemDescriptor
|
||||
|
||||
void ItemDatabase::addItemSet(ItemType type, String const& extension) {
|
||||
auto assets = Root::singleton().assets();
|
||||
for (auto file : assets->scanExtension(extension)) {
|
||||
for (auto& file : assets->scanExtension(extension)) {
|
||||
ItemData data;
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
@ -662,9 +662,9 @@ void ItemDatabase::addObjectItems() {
|
||||
void ItemDatabase::scanRecipes() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("recipe");
|
||||
auto& files = assets->scanExtension("recipe");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
m_recipes.add(parseRecipe(assets->json(file)));
|
||||
} catch (std::exception const& e) {
|
||||
|
@ -32,10 +32,10 @@ LiquidsDatabase::LiquidsDatabase() {
|
||||
|
||||
m_liquidNames["empty"] = EmptyLiquidId;
|
||||
|
||||
auto liquids = assets->scanExtension("liquid");
|
||||
auto& liquids = assets->scanExtension("liquid");
|
||||
assets->queueJsons(liquids);
|
||||
|
||||
for (auto file : liquids) {
|
||||
for (auto& file : liquids) {
|
||||
try {
|
||||
auto liquidConfig = assets->json(file);
|
||||
|
||||
|
@ -54,13 +54,13 @@ MaterialDatabase::MaterialDatabase() {
|
||||
setMetaMaterial(matId, MaterialDatabase::MetaMaterialInfo{matName, matId, matCollisionKind, blocksLiquidFlow});
|
||||
}
|
||||
|
||||
auto materials = assets->scanExtension("material");
|
||||
auto mods = assets->scanExtension("matmod");
|
||||
auto& materials = assets->scanExtension("material");
|
||||
auto& mods = assets->scanExtension("matmod");
|
||||
|
||||
assets->queueJsons(materials);
|
||||
assets->queueJsons(mods);
|
||||
|
||||
for (auto file : materials) {
|
||||
for (auto& file : materials) {
|
||||
try {
|
||||
auto matConfig = assets->json(file);
|
||||
|
||||
@ -140,7 +140,7 @@ MaterialDatabase::MaterialDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : mods) {
|
||||
for (auto& file : mods) {
|
||||
try {
|
||||
auto modConfig = assets->json(file);
|
||||
|
||||
|
@ -11,10 +11,10 @@ namespace Star {
|
||||
MonsterDatabase::MonsterDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto monsterTypes = assets->scanExtension("monstertype");
|
||||
auto monsterParts = assets->scanExtension("monsterpart");
|
||||
auto monsterSkills = assets->scanExtension("monsterskill");
|
||||
auto monsterColors = assets->scanExtension("monstercolors");
|
||||
auto& monsterTypes = assets->scanExtension("monstertype");
|
||||
auto& monsterParts = assets->scanExtension("monsterpart");
|
||||
auto& monsterSkills = assets->scanExtension("monsterskill");
|
||||
auto& monsterColors = assets->scanExtension("monstercolors");
|
||||
|
||||
assets->queueJsons(monsterTypes);
|
||||
assets->queueJsons(monsterParts);
|
||||
@ -66,7 +66,7 @@ MonsterDatabase::MonsterDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : monsterParts) {
|
||||
for (auto const& file : monsterParts) {
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
if (config.isNull())
|
||||
@ -91,7 +91,7 @@ MonsterDatabase::MonsterDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : monsterSkills) {
|
||||
for (auto const& file : monsterSkills) {
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
if (config.isNull())
|
||||
@ -115,7 +115,7 @@ MonsterDatabase::MonsterDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : monsterColors) {
|
||||
for (auto const& file : monsterColors) {
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
if (config.isNull())
|
||||
|
@ -7,9 +7,9 @@ namespace Star {
|
||||
|
||||
PatternedNameGenerator::PatternedNameGenerator() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("namesource");
|
||||
auto &files = assets->scanExtension("namesource");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
auto sourceConfig = assets->json(file);
|
||||
|
||||
@ -24,7 +24,7 @@ PatternedNameGenerator::PatternedNameGenerator() {
|
||||
}
|
||||
|
||||
auto profanityFilter = assets->json("/names/profanityfilter.config").toArray();
|
||||
for (auto naughtyWord : profanityFilter)
|
||||
for (auto& naughtyWord : profanityFilter)
|
||||
m_profanityFilter.add(naughtyWord.toString().toLower());
|
||||
}
|
||||
|
||||
|
@ -17,9 +17,9 @@ namespace Star {
|
||||
NpcDatabase::NpcDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("npctype");
|
||||
auto& files = assets->scanExtension("npctype");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
String typeName = config.getString("type");
|
||||
|
@ -309,9 +309,9 @@ List<ObjectOrientationPtr> ObjectDatabase::parseOrientations(String const& path,
|
||||
ObjectDatabase::ObjectDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("object");
|
||||
auto& files = assets->scanExtension("object");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
String name = assets->json(file).getString("objectName");
|
||||
if (m_paths.contains(name))
|
||||
|
@ -23,9 +23,9 @@ Particle ParticleConfig::instance() {
|
||||
|
||||
ParticleDatabase::ParticleDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("particle");
|
||||
auto& files = assets->scanExtension("particle");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
auto particleConfig = make_shared<ParticleConfig>(assets->json(file));
|
||||
if (m_configs.contains(particleConfig->kind()))
|
||||
throw StarException(strf("Duplicate particle asset kind Name {}. configfile {}", particleConfig->kind(), file));
|
||||
|
@ -104,10 +104,10 @@ Json BushVariant::toJson() const {
|
||||
PlantDatabase::PlantDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto stems = assets->scanExtension("modularstem");
|
||||
auto foliages = assets->scanExtension("modularfoliage");
|
||||
auto grasses = assets->scanExtension("grass");
|
||||
auto bushes = assets->scanExtension("bush");
|
||||
auto& stems = assets->scanExtension("modularstem");
|
||||
auto& foliages = assets->scanExtension("modularfoliage");
|
||||
auto& grasses = assets->scanExtension("grass");
|
||||
auto& bushes = assets->scanExtension("bush");
|
||||
|
||||
assets->queueJsons(stems);
|
||||
assets->queueJsons(foliages);
|
||||
@ -115,22 +115,22 @@ PlantDatabase::PlantDatabase() {
|
||||
assets->queueJsons(bushes);
|
||||
|
||||
try {
|
||||
for (auto file : stems) {
|
||||
for (auto& file : stems) {
|
||||
auto config = assets->json(file);
|
||||
m_treeStemConfigs.insert(config.getString("name"), Config{AssetPath::directory(file), config.toObject()});
|
||||
}
|
||||
|
||||
for (auto file : foliages) {
|
||||
for (auto& file : foliages) {
|
||||
auto config = assets->json(file);
|
||||
m_treeFoliageConfigs.insert(config.getString("name"), Config{AssetPath::directory(file), config.toObject()});
|
||||
}
|
||||
|
||||
for (auto file : grasses) {
|
||||
for (auto& file : grasses) {
|
||||
auto config = assets->json(file);
|
||||
m_grassConfigs.insert(config.getString("name"), Config{AssetPath::directory(file), config.toObject()});
|
||||
}
|
||||
|
||||
for (auto file : bushes) {
|
||||
for (auto& file : bushes) {
|
||||
auto config = assets->json(file);
|
||||
m_bushConfigs.insert(config.getString("name"), Config{AssetPath::directory(file), config.toObject()});
|
||||
}
|
||||
|
@ -9,9 +9,9 @@ namespace Star {
|
||||
ProjectileDatabase::ProjectileDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("projectile");
|
||||
auto& files = assets->scanExtension("projectile");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
auto projectileConfig = readConfig(file);
|
||||
if (m_configs.contains(projectileConfig->typeName))
|
||||
|
@ -60,9 +60,9 @@ QuestTemplate::QuestTemplate(Json const& config) {
|
||||
|
||||
QuestTemplateDatabase::QuestTemplateDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("questtemplate");
|
||||
auto& files = assets->scanExtension("questtemplate");
|
||||
assets->queueJsons(files);
|
||||
for (auto qt : files) {
|
||||
for (auto& qt : files) {
|
||||
auto questTemplate = make_shared<QuestTemplate>(assets->json(qt));
|
||||
if (!m_templates.insert(questTemplate->templateId, questTemplate).second)
|
||||
throw StarException(strf("Duplicate quest template '{}'", questTemplate->templateId));
|
||||
|
@ -13,8 +13,8 @@ EnumMap<RadioMessageType> const RadioMessageTypeNames{
|
||||
|
||||
RadioMessageDatabase::RadioMessageDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("radiomessages");
|
||||
for (auto file : files) {
|
||||
auto& files = assets->scanExtension("radiomessages");
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
Json messages = assets->json(file);
|
||||
for (auto pair : messages.iterateObject()) {
|
||||
|
@ -697,11 +697,12 @@ StringList Root::scanForAssetSources(StringList const& directories, StringList c
|
||||
|
||||
StringList sourcePaths;
|
||||
for (auto const& source : dependencySortedSources) {
|
||||
auto path = File::convertDirSeparators(source->path);
|
||||
if (source->name)
|
||||
Logger::info("Root: Detected asset source named '{}' at '{}'", *source->name, source->path);
|
||||
Logger::info("Root: Detected asset source named '{}' at '{}'", *source->name, path);
|
||||
else
|
||||
Logger::info("Root: Detected unnamed asset source at '{}'", source->path);
|
||||
sourcePaths.append(source->path);
|
||||
Logger::info("Root: Detected unnamed asset source at '{}'", path);
|
||||
sourcePaths.append(path);
|
||||
}
|
||||
|
||||
return sourcePaths;
|
||||
|
@ -113,7 +113,7 @@ SpawnProfile constructSpawnProfile(Json const& config, uint64_t seed) {
|
||||
|
||||
SpawnTypeDatabase::SpawnTypeDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("spawntypes");
|
||||
auto& files = assets->scanExtension("spawntypes");
|
||||
assets->queueJsons(files);
|
||||
uint64_t seedMix = 0;
|
||||
for (auto const& file : files) {
|
||||
|
@ -27,9 +27,9 @@ SpeciesOption::SpeciesOption()
|
||||
SpeciesDatabase::SpeciesDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("species");
|
||||
auto& files = assets->scanExtension("species");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
auto speciesDefinition = make_shared<SpeciesDefinition>(assets->json(file));
|
||||
if (m_species.contains(speciesDefinition->kind()))
|
||||
throw StarException(strf("Duplicate species asset with kind {}. configfile {}", speciesDefinition->kind(), file));
|
||||
|
@ -8,9 +8,9 @@ namespace Star {
|
||||
|
||||
StagehandDatabase::StagehandDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("stagehand");
|
||||
auto& files = assets->scanExtension("stagehand");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
|
||||
|
@ -6,12 +6,12 @@ namespace Star {
|
||||
StatisticsDatabase::StatisticsDatabase() : m_cacheMutex(), m_eventCache() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto eventFiles = assets->scanExtension("event");
|
||||
auto& eventFiles = assets->scanExtension("event");
|
||||
assets->queueJsons(eventFiles);
|
||||
auto achievementFiles = assets->scanExtension("achievement");
|
||||
auto& achievementFiles = assets->scanExtension("achievement");
|
||||
assets->queueJsons(achievementFiles);
|
||||
|
||||
for (auto file : eventFiles) {
|
||||
for (auto& file : eventFiles) {
|
||||
try {
|
||||
String name = assets->json(file).getString("eventName");
|
||||
if (m_eventPaths.contains(name))
|
||||
@ -23,7 +23,7 @@ StatisticsDatabase::StatisticsDatabase() : m_cacheMutex(), m_eventCache() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : achievementFiles) {
|
||||
for (auto& file : achievementFiles) {
|
||||
try {
|
||||
Json achievement = assets->json(file);
|
||||
String name = achievement.getString("name");
|
||||
|
@ -7,9 +7,9 @@ namespace Star {
|
||||
|
||||
StatusEffectDatabase::StatusEffectDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("statuseffect");
|
||||
auto& files = assets->scanExtension("statuseffect");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
auto uniqueEffect = parseUniqueEffect(assets->json(file), file);
|
||||
|
||||
if (m_uniqueEffects.contains(uniqueEffect.name))
|
||||
|
@ -121,15 +121,15 @@ Json StoredConfigFunction::get(double value) const {
|
||||
FunctionDatabase::FunctionDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto functions = assets->scanExtension("functions");
|
||||
auto sndFunctions = assets->scanExtension("2functions");
|
||||
auto configFunctions = assets->scanExtension("configfunctions");
|
||||
auto& functions = assets->scanExtension("functions");
|
||||
auto& sndFunctions = assets->scanExtension("2functions");
|
||||
auto& configFunctions = assets->scanExtension("configfunctions");
|
||||
|
||||
assets->queueJsons(functions);
|
||||
assets->queueJsons(sndFunctions);
|
||||
assets->queueJsons(configFunctions);
|
||||
|
||||
for (auto file : functions) {
|
||||
for (auto& file : functions) {
|
||||
for (auto const& functionPair : assets->json(file).iterateObject()) {
|
||||
if (m_functions.contains(functionPair.first))
|
||||
throw StarException(strf("Named Function '{}' defined twice, second time from {}", functionPair.first, file));
|
||||
@ -137,7 +137,7 @@ FunctionDatabase::FunctionDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : sndFunctions) {
|
||||
for (auto& file : sndFunctions) {
|
||||
for (auto const& functionPair : assets->json(file).iterateObject()) {
|
||||
if (m_functions2.contains(functionPair.first))
|
||||
throw StarException(
|
||||
@ -146,7 +146,7 @@ FunctionDatabase::FunctionDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : configFunctions) {
|
||||
for (auto& file : configFunctions) {
|
||||
for (auto const& tablePair : assets->json(file).iterateObject()) {
|
||||
if (m_configFunctions.contains(tablePair.first))
|
||||
throw StarException(
|
||||
|
@ -13,9 +13,9 @@ EnumMap<TechType> const TechTypeNames{
|
||||
|
||||
TechDatabase::TechDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("tech");
|
||||
auto& files = assets->scanExtension("tech");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
auto tech = parseTech(assets->json(file), file);
|
||||
|
||||
if (m_tech.contains(tech.name))
|
||||
|
@ -15,9 +15,9 @@ bool Tenant::criteriaSatisfied(StringMap<unsigned> const& colonyTags) const {
|
||||
TenantDatabase::TenantDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto files = assets->scanExtension("tenant");
|
||||
auto& files = assets->scanExtension("tenant");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
String name = assets->json(file).getString("name");
|
||||
if (m_paths.contains(name))
|
||||
|
@ -59,9 +59,9 @@ TerrainDatabase::TerrainDatabase() {
|
||||
|
||||
// 'type' here is the extension of the file, and determines the selector type
|
||||
auto scanFiles = [this, assets](String const& type) {
|
||||
auto files = assets->scanExtension(type);
|
||||
auto& files = assets->scanExtension(type);
|
||||
assets->queueJsons(files);
|
||||
for (auto path : files) {
|
||||
for (auto& path : files) {
|
||||
auto parameters = assets->json(path);
|
||||
auto name = parameters.getString("name");
|
||||
if (m_terrainSelectors.contains(name))
|
||||
@ -74,9 +74,9 @@ TerrainDatabase::TerrainDatabase() {
|
||||
scanFiles(WormCaveSelector::Name);
|
||||
scanFiles(RidgeBlocksSelector::Name);
|
||||
|
||||
auto files = assets->scanExtension("terrain");
|
||||
auto& files = assets->scanExtension("terrain");
|
||||
assets->queueJsons(files);
|
||||
for (auto path : files) {
|
||||
for (auto& path : files) {
|
||||
auto parameters = assets->json(path);
|
||||
auto name = parameters.getString("name");
|
||||
auto type = parameters.getString("type");
|
||||
|
@ -13,13 +13,13 @@ namespace Star {
|
||||
TreasureDatabase::TreasureDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto treasurePools = assets->scanExtension("treasurepools");
|
||||
auto treasureChests = assets->scanExtension("treasurechests");
|
||||
auto& treasurePools = assets->scanExtension("treasurepools");
|
||||
auto& treasureChests = assets->scanExtension("treasurechests");
|
||||
|
||||
assets->queueJsons(treasurePools);
|
||||
assets->queueJsons(treasureChests);
|
||||
|
||||
for (auto file : treasurePools) {
|
||||
for (auto& file : treasurePools) {
|
||||
for (auto const& pair : assets->json(file).iterateObject()) {
|
||||
if (m_treasurePools.contains(pair.first))
|
||||
throw TreasureException(strf("Duplicate TreasurePool config '{}' from file '{}'", pair.first, file));
|
||||
@ -70,7 +70,7 @@ TreasureDatabase::TreasureDatabase() {
|
||||
}
|
||||
}
|
||||
|
||||
for (auto file : treasureChests) {
|
||||
for (auto& file : treasureChests) {
|
||||
for (auto const& pair : assets->json(file).iterateObject()) {
|
||||
if (m_treasureChestSets.contains(pair.first))
|
||||
throw TreasureException(strf("Duplicate TreasureChestSet config '{}' from file '{}'", pair.first, file));
|
||||
|
@ -8,9 +8,9 @@ namespace Star {
|
||||
|
||||
VehicleDatabase::VehicleDatabase() {
|
||||
auto assets = Root::singleton().assets();
|
||||
auto files = assets->scanExtension("vehicle");
|
||||
auto& files = assets->scanExtension("vehicle");
|
||||
assets->queueJsons(files);
|
||||
for (auto file : files) {
|
||||
for (auto& file : files) {
|
||||
try {
|
||||
auto config = assets->json(file);
|
||||
String name = config.getString("name");
|
||||
|
@ -30,7 +30,6 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
|
||||
|
||||
auto root = Root::singletonPtr();
|
||||
|
||||
callbacks.registerCallbackWithSignature<StringList, String>("assetsByExtension", bind(RootCallbacks::assetsByExtension, root, _1));
|
||||
callbacks.registerCallbackWithSignature<String, String>("assetData", bind(RootCallbacks::assetData, root, _1));
|
||||
callbacks.registerCallbackWithSignature<Json, String>("assetJson", bind(RootCallbacks::assetJson, root, _1));
|
||||
callbacks.registerCallbackWithSignature<Json, String, Json>("makeCurrentVersionedJson", bind(RootCallbacks::makeCurrentVersionedJson, root, _1, _2));
|
||||
@ -63,6 +62,15 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
|
||||
callbacks.registerCallbackWithSignature<Maybe<String>, String, Maybe<String>>("materialMiningSound", bind(RootCallbacks::materialMiningSound, root, _1, _2));
|
||||
callbacks.registerCallbackWithSignature<Maybe<String>, String, Maybe<String>>("materialFootstepSound", bind(RootCallbacks::materialFootstepSound, root, _1, _2));
|
||||
|
||||
callbacks.registerCallback("assetsByExtension", [root](LuaEngine& engine, String const& extension) -> LuaTable {
|
||||
auto& extensions = root->assets()->scanExtension(extension);
|
||||
auto table = engine.createTable(extensions.size(), 0);
|
||||
size_t i = 0;
|
||||
for (auto& file : extensions)
|
||||
table.set(++i, file);
|
||||
return table;
|
||||
});
|
||||
|
||||
callbacks.registerCallback("assetOrigin", [root](String const& path) -> Maybe<String> {
|
||||
auto assets = root->assets();
|
||||
if (auto descriptor = assets->assetDescriptor(path))
|
||||
@ -242,10 +250,6 @@ LuaCallbacks LuaBindings::makeRootCallbacks() {
|
||||
return callbacks;
|
||||
}
|
||||
|
||||
StringList LuaBindings::RootCallbacks::assetsByExtension(Root* root, String const& extension) {
|
||||
return root->assets()->scanExtension(extension);
|
||||
}
|
||||
|
||||
String LuaBindings::RootCallbacks::assetData(Root* root, String const& path) {
|
||||
auto bytes = root->assets()->bytes(path);
|
||||
return String(bytes->ptr(), bytes->size());
|
||||
|
@ -12,7 +12,6 @@ namespace LuaBindings {
|
||||
LuaCallbacks makeRootCallbacks();
|
||||
|
||||
namespace RootCallbacks {
|
||||
StringList assetsByExtension(Root* root, String const& extension);
|
||||
String assetData(Root* root, String const& path);
|
||||
Json assetJson(Root* root, String const& path);
|
||||
Json makeCurrentVersionedJson(Root* root, String const& identifier, Json const& content);
|
||||
|
@ -22,11 +22,11 @@ int main(int argc, char** argv) {
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
auto countWordsInType = [&](String const& type, function<int(Json const&)> countFunction, Maybe<function<bool(String const&)>> filterFunction = {}, Maybe<String> wordCountKey = {}) {
|
||||
auto files = assets->scanExtension(type);
|
||||
auto& files = assets->scanExtension(type).values();
|
||||
if (filterFunction)
|
||||
files.filter(*filterFunction);
|
||||
assets->queueJsons(files);
|
||||
for (auto path : files) {
|
||||
for (auto& path : files) {
|
||||
auto json = assets->json(path);
|
||||
if (json.isNull())
|
||||
continue;
|
||||
@ -62,7 +62,7 @@ int main(int argc, char** argv) {
|
||||
"activeitem",
|
||||
"augment" };
|
||||
|
||||
for (auto itemFileType : itemFileTypes) {
|
||||
for (auto& itemFileType : itemFileTypes) {
|
||||
countWordsInType(itemFileType, [](Json const& json) {
|
||||
int wordCount = 0;
|
||||
wordCount += json.getString("shortdescription", "").split(" ").count();
|
||||
|
Loading…
Reference in New Issue
Block a user