Веб-сайт самохостера Lotigara

summaryrefslogtreecommitdiff
path: root/source/core
diff options
context:
space:
mode:
Diffstat (limited to 'source/core')
-rw-r--r--source/core/StarAssetPath.cpp2
-rw-r--r--source/core/StarDirectives.cpp83
-rw-r--r--source/core/StarDirectives.hpp16
-rw-r--r--source/core/StarFormattedJson.cpp4
-rw-r--r--source/core/StarJson.cpp8
-rw-r--r--source/core/StarJson.hpp3
-rw-r--r--source/core/StarJsonBuilder.hpp8
-rw-r--r--source/core/StarJsonParser.hpp66
-rw-r--r--source/core/StarLua.cpp4
-rw-r--r--source/core/StarLua.hpp2
-rw-r--r--source/core/StarText.cpp28
-rw-r--r--source/core/StarText.hpp22
-rw-r--r--source/core/scripting/StarUtilityLuaBindings.cpp4
13 files changed, 194 insertions, 56 deletions
diff --git a/source/core/StarAssetPath.cpp b/source/core/StarAssetPath.cpp
index e54a139..23743d9 100644
--- a/source/core/StarAssetPath.cpp
+++ b/source/core/StarAssetPath.cpp
@@ -162,7 +162,7 @@ std::ostream& operator<<(std::ostream& os, AssetPath const& rhs) {
rhs.directives.forEach([&](auto const& entry, Directives const& directives) {
os << "?";
- os << entry.string(*directives.shared);
+ os << entry.string(*directives);
});
return os;
diff --git a/source/core/StarDirectives.cpp b/source/core/StarDirectives.cpp
index 4770200..89985a0 100644
--- a/source/core/StarDirectives.cpp
+++ b/source/core/StarDirectives.cpp
@@ -42,6 +42,8 @@ bool Directives::Shared::empty() const {
return entries.empty();
}
+Directives::Shared::Shared() {}
+
Directives::Shared::Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix) {
entries = std::move(givenEntries);
string = std::move(givenString);
@@ -74,7 +76,7 @@ Directives::Directives(Directives const& directives) {
Directives::~Directives() {}
Directives& Directives::operator=(String const& s) {
- if (shared && shared->string == s)
+ if (m_shared && m_shared->string == s)
return *this;
parse(String(s));
@@ -82,7 +84,7 @@ Directives& Directives::operator=(String const& s) {
}
Directives& Directives::operator=(String&& s) {
- if (shared && shared->string == s) {
+ if (m_shared && m_shared->string == s) {
s.clear();
return *this;
}
@@ -92,7 +94,7 @@ Directives& Directives::operator=(String&& s) {
}
Directives& Directives::operator=(const char* s) {
- if (shared && shared->string.utf8().compare(s) == 0)
+ if (m_shared && m_shared->string.utf8().compare(s) == 0)
return *this;
parse(s);
@@ -100,27 +102,29 @@ Directives& Directives::operator=(const char* s) {
}
Directives& Directives::operator=(Directives&& other) noexcept {
- shared = std::move(other.shared);
+ m_shared = std::move(other.m_shared);
return *this;
}
Directives& Directives::operator=(Directives const& other) {
- shared = other.shared;
+ m_shared = other.m_shared;
return *this;
}
void Directives::loadOperations() const {
- if (!shared)
+ if (!m_shared)
return;
- MutexLocker lock(shared->mutex, true);
- for (auto& entry : shared->entries)
- entry.loadOperation(*shared);
+ MutexLocker locker(m_shared->mutex, false);
+ if (!m_shared.unique())
+ locker.lock();
+ for (auto& entry : m_shared->entries)
+ entry.loadOperation(*m_shared);
}
void Directives::parse(String&& directives) {
if (directives.empty()) {
- shared.reset();
+ m_shared.reset();
return;
}
@@ -147,46 +151,46 @@ void Directives::parse(String&& directives) {
});
if (entries.empty() && !prefix.empty()) {
- shared.reset();
+ m_shared.reset();
return;
}
- shared = std::make_shared<Shared const>(std::move(entries), std::move(directives), prefix);
+ m_shared = std::make_shared<Shared const>(std::move(entries), std::move(directives), prefix);
if (view.utf8().size() < 1000) { // Pre-load short enough directives
- for (auto& entry : shared->entries)
- entry.loadOperation(*shared);
+ for (auto& entry : m_shared->entries)
+ entry.loadOperation(*m_shared);
}
}
String Directives::string() const {
- if (!shared)
+ if (!m_shared)
return "";
else
- return shared->string;
+ return m_shared->string;
}
StringView Directives::prefix() const {
- if (!shared)
+ if (!m_shared)
return "";
else
- return shared->prefix;
+ return m_shared->prefix;
}
String const* Directives::stringPtr() const {
- if (!shared)
+ if (!m_shared)
return nullptr;
else
- return &shared->string;
+ return &m_shared->string;
}
String Directives::buildString() const {
- if (shared) {
- String built = shared->prefix;
+ if (m_shared) {
+ String built = m_shared->prefix;
- for (auto& entry : shared->entries) {
+ for (auto& entry : m_shared->entries) {
built += "?";
- built += entry.string(*shared);
+ built += entry.string(*m_shared);
}
return built;
@@ -197,23 +201,25 @@ String Directives::buildString() const {
String& Directives::addToString(String& out) const {
if (!empty())
- out += shared->string;
+ out += m_shared->string;
return out;
}
size_t Directives::hash() const {
- return shared ? shared->hash : 0;
+ return m_shared ? m_shared->hash : 0;
}
size_t Directives::size() const {
- return shared ? shared->entries.size() : 0;
+ return m_shared ? m_shared->entries.size() : 0;
}
bool Directives::empty() const {
- return !shared || shared->empty();
+ return !m_shared || m_shared->empty();
}
-Directives::operator bool() const { return !empty(); }
+Directives::operator bool() const {
+ return !empty();
+}
bool Directives::equals(Directives const& other) const {
return hash() == other.hash();
@@ -243,7 +249,7 @@ DataStream& operator>>(DataStream& ds, Directives& directives) {
DataStream& operator<<(DataStream & ds, Directives const& directives) {
if (directives)
- ds.write(directives.shared->string);
+ ds.write(directives->string);
else
ds.write(String());
@@ -326,21 +332,22 @@ String DirectivesGroup::toString() const {
}
void DirectivesGroup::addToString(String& string) const {
- for (auto& directives : m_directives)
- if (directives.shared) {
- auto& dirString = directives.shared->string;
+ for (auto& directives : m_directives) {
+ if (directives) {
+ auto& dirString = directives->string;
if (!dirString.empty()) {
if (dirString.utf8().front() != '?')
string += "?";
string += dirString;
}
}
+ }
}
void DirectivesGroup::forEach(DirectivesCallback callback) const {
for (auto& directives : m_directives) {
- if (directives.shared) {
- for (auto& entry : directives.shared->entries)
+ if (directives) {
+ for (auto& entry : directives->entries)
callback(entry, directives);
}
}
@@ -348,8 +355,8 @@ void DirectivesGroup::forEach(DirectivesCallback callback) const {
bool DirectivesGroup::forEachAbortable(AbortableDirectivesCallback callback) const {
for (auto& directives : m_directives) {
- if (directives.shared) {
- for (auto& entry : directives.shared->entries) {
+ if (directives) {
+ for (auto& entry : directives->entries) {
if (!callback(entry, directives))
return false;
}
@@ -367,7 +374,7 @@ Image DirectivesGroup::applyNewImage(Image const& image) const {
void DirectivesGroup::applyExistingImage(Image& image) const {
forEach([&](auto const& entry, Directives const& directives) {
- ImageOperation const& operation = entry.loadOperation(*directives.shared);
+ ImageOperation const& operation = entry.loadOperation(*directives);
if (auto error = operation.ptr<ErrorImageOperation>())
std::rethrow_exception(error->exception);
else
diff --git a/source/core/StarDirectives.hpp b/source/core/StarDirectives.hpp
index e272915..fa10a33 100644
--- a/source/core/StarDirectives.hpp
+++ b/source/core/StarDirectives.hpp
@@ -36,6 +36,7 @@ public:
mutable Mutex mutex;
bool empty() const;
+ Shared();
Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix);
};
@@ -65,6 +66,9 @@ public:
bool empty() const;
operator bool() const;
+ Shared const& operator*() const;
+ Shared const* operator->() const;
+
bool equals(Directives const& other) const;
bool equals(String const& string) const;
@@ -78,7 +82,7 @@ public:
//friend bool operator==(Directives const& directives, String const& string);
//friend bool operator==(String const& string, Directives const& directives);
- std::shared_ptr<Shared const> shared;
+ std::shared_ptr<Shared const> m_shared;
};
class DirectivesGroup {
@@ -122,7 +126,6 @@ private:
size_t m_count;
};
-
template <>
struct hash<DirectivesGroup> {
size_t operator()(DirectivesGroup const& s) const;
@@ -130,4 +133,13 @@ struct hash<DirectivesGroup> {
typedef DirectivesGroup ImageDirectives;
+inline Directives::Shared const& Directives::operator*() const {
+ return *m_shared;
+}
+inline Directives::Shared const* Directives::operator->() const {
+ if (!m_shared)
+ throw DirectivesException("Directives::operator-> nullptr");
+ return m_shared.get();
+}
+
}
diff --git a/source/core/StarFormattedJson.cpp b/source/core/StarFormattedJson.cpp
index d7bd8c7..a770ac6 100644
--- a/source/core/StarFormattedJson.cpp
+++ b/source/core/StarFormattedJson.cpp
@@ -65,12 +65,12 @@ bool CommaElement::operator==(CommaElement const&) const {
FormattedJson FormattedJson::parse(String const& string) {
return inputUtf32Json<String::const_iterator, FormattedJsonBuilderStream, FormattedJson>(
- string.begin(), string.end(), true);
+ string.begin(), string.end(), JsonParseType::Value);
}
FormattedJson FormattedJson::parseJson(String const& string) {
return inputUtf32Json<String::const_iterator, FormattedJsonBuilderStream, FormattedJson>(
- string.begin(), string.end(), false);
+ string.begin(), string.end(), JsonParseType::Top);
}
FormattedJson FormattedJson::ofType(Json::Type type) {
diff --git a/source/core/StarJson.cpp b/source/core/StarJson.cpp
index 04ac544..7cf1cda 100644
--- a/source/core/StarJson.cpp
+++ b/source/core/StarJson.cpp
@@ -105,11 +105,15 @@ Json Json::ofType(Type t) {
}
Json Json::parse(String const& string) {
- return inputUtf32Json<String::const_iterator>(string.begin(), string.end(), true);
+ return inputUtf32Json<String::const_iterator>(string.begin(), string.end(), JsonParseType::Value);
+}
+
+Json Json::parseSequence(String const& sequence) {
+ return inputUtf32Json<String::const_iterator>(sequence.begin(), sequence.end(), JsonParseType::Sequence);
}
Json Json::parseJson(String const& json) {
- return inputUtf32Json<String::const_iterator>(json.begin(), json.end(), false);
+ return inputUtf32Json<String::const_iterator>(json.begin(), json.end(), JsonParseType::Top);
}
Json::Json() {}
diff --git a/source/core/StarJson.hpp b/source/core/StarJson.hpp
index a533e47..b58b9a0 100644
--- a/source/core/StarJson.hpp
+++ b/source/core/StarJson.hpp
@@ -51,6 +51,9 @@ public:
// Parses JSON or JSON sub-type
static Json parse(String const& string);
+ // Parses JSON sequence
+ static Json parseSequence(String const& sequence);
+
// Parses JSON object or array only (the only top level types allowed by
// JSON)
static Json parseJson(String const& json);
diff --git a/source/core/StarJsonBuilder.hpp b/source/core/StarJsonBuilder.hpp
index ea0df46..46f192c 100644
--- a/source/core/StarJsonBuilder.hpp
+++ b/source/core/StarJsonBuilder.hpp
@@ -50,7 +50,7 @@ public:
};
template <typename InputIterator>
-Json inputUtf8Json(InputIterator begin, InputIterator end, bool fragment) {
+Json inputUtf8Json(InputIterator begin, InputIterator end, JsonParseType parseType) {
typedef U8ToU32Iterator<InputIterator> Utf32Input;
typedef JsonParser<Utf32Input> Parser;
@@ -58,7 +58,7 @@ Json inputUtf8Json(InputIterator begin, InputIterator end, bool fragment) {
Parser parser(stream);
Utf32Input wbegin(begin);
Utf32Input wend(end);
- Utf32Input pend = parser.parse(wbegin, wend, fragment);
+ Utf32Input pend = parser.parse(wbegin, wend, parseType);
if (parser.error())
throw JsonParsingException(strf("Error parsing json: {} at {}:{}", parser.error(), parser.line(), parser.column()));
@@ -77,11 +77,11 @@ void outputUtf8Json(Json const& val, OutputIterator out, int pretty, bool sort)
}
template <typename InputIterator, typename Stream = JsonBuilderStream, typename Jsonlike = Json>
-Jsonlike inputUtf32Json(InputIterator begin, InputIterator end, bool fragment) {
+Jsonlike inputUtf32Json(InputIterator begin, InputIterator end, JsonParseType parseType) {
Stream stream;
JsonParser<InputIterator> parser(stream);
- InputIterator pend = parser.parse(begin, end, fragment);
+ InputIterator pend = parser.parse(begin, end, parseType);
if (parser.error()) {
throw JsonParsingException(strf("Error parsing json: {} at {}:{}", parser.error(), parser.line(), parser.column()));
diff --git a/source/core/StarJsonParser.hpp b/source/core/StarJsonParser.hpp
index d814edb..0bf7443 100644
--- a/source/core/StarJsonParser.hpp
+++ b/source/core/StarJsonParser.hpp
@@ -27,6 +27,12 @@ struct JsonStream {
virtual void putComma() = 0;
};
+enum class JsonParseType : uint8_t {
+ Top, // Top-level Object or Array
+ Value, // Any singular Json value
+ Sequence // Like an array, but without needing the [] or commas.
+};
+
// Will parse JSON and output to a given JsonStream. Parses an *extension* to
// the JSON format that includes comments.
template <typename InputIterator>
@@ -39,15 +45,17 @@ public:
// Does not throw. On error, returned iterator will not be equal to end, and
// error() will be non-null. Set fragment to true to parse any JSON type
// rather than just object or array.
- InputIterator parse(InputIterator begin, InputIterator end, bool fragment = false) {
+ InputIterator parse(InputIterator begin, InputIterator end, JsonParseType parseType = JsonParseType::Top) {
init(begin, end);
try {
white();
- if (fragment)
- value();
- else
+ if (parseType == JsonParseType::Top)
top();
+ else if (parseType == JsonParseType::Value)
+ value();
+ else if (parseType == JsonParseType::Sequence)
+ sequence();
white();
} catch (ParsingException const&) {
}
@@ -190,6 +198,56 @@ private:
}
}
+ void sequence() {
+ m_stream.beginArray();
+ while (true) {
+ if (isSpace(m_char)) {
+ next();
+ continue;
+ } else if (m_char == '{')
+ object();
+ else if (m_char == '[')
+ array();
+ else if (m_char == '"')
+ string();
+ else if (m_char == '-')
+ number();
+ else if (m_char == 0)
+ break;
+ else {
+ auto begin = m_current;
+ if (m_char >= '0' && m_char <= '9') {
+ number();
+ if (m_error.empty()) {
+ next();
+ continue;
+ }
+ }
+ m_error.clear();
+ m_current = begin;
+ if (m_char == 't' || m_char == 'f' || m_char == 'n') {
+ word();
+ if (m_error.empty()) {
+ next();
+ continue;
+ }
+ }
+ m_error.clear();
+ m_current = begin;
+ // well, shit. do a simple string parse until we hit whitespace
+ // no fancy things like \n, do a proper string if you want that
+ CharArray str;
+ do {
+ str += m_char;
+ next();
+ } while (m_char && !isSpace(m_char));
+ m_stream.putString(str.c_str(), str.length());
+ }
+ next();
+ }
+ m_stream.endArray();
+ }
+
void string() {
CharArray s = parseString();
m_stream.putString(s.c_str(), s.length());
diff --git a/source/core/StarLua.cpp b/source/core/StarLua.cpp
index 73955f2..5a2effa 100644
--- a/source/core/StarLua.cpp
+++ b/source/core/StarLua.cpp
@@ -60,6 +60,10 @@ LuaInt LuaTable::rawLength() const {
return engine().tableLength(true, handleIndex());
}
+void LuaCallbacks::copyCallback(String srcName, String dstName) {
+ m_callbacks.set(dstName, m_callbacks.get(srcName));
+}
+
LuaCallbacks& LuaCallbacks::merge(LuaCallbacks const& callbacks) {
try {
for (auto const& pair : callbacks.m_callbacks)
diff --git a/source/core/StarLua.hpp b/source/core/StarLua.hpp
index 09e81e6..57afb98 100644
--- a/source/core/StarLua.hpp
+++ b/source/core/StarLua.hpp
@@ -267,6 +267,8 @@ LuaValue const LuaNil = LuaValue();
class LuaCallbacks {
public:
+ void copyCallback(String srcName, String dstName);
+
template <typename Function>
void registerCallback(String name, Function&& func);
diff --git a/source/core/StarText.cpp b/source/core/StarText.cpp
index 11fca27..86c9f25 100644
--- a/source/core/StarText.cpp
+++ b/source/core/StarText.cpp
@@ -1,9 +1,35 @@
#include "StarText.hpp"
-
+#include "StarJsonExtra.hpp"
#include <regex>
namespace Star {
+TextStyle::TextStyle(Json const& config) : TextStyle() {
+ if (config.isType(Json::Type::String))
+ font = config.toString();
+ else
+ loadJson(config);
+}
+TextStyle& TextStyle::loadJson(Json const& config) {
+ if (!config)
+ return *this;
+
+ lineSpacing = config.getFloat("lineSpacing", lineSpacing);
+ if (auto jColor = config.opt("color"))
+ color = jsonToColor(*jColor).toRgba();
+ if (auto jShadow = config.opt("shadow"))
+ shadow = jsonToColor(*jShadow).toRgba();
+ fontSize = config.getUInt("fontSize", fontSize);
+ if (auto jFont = config.optString("font"))
+ font = *jFont;
+ if (auto jDirectives = config.optString("directives"))
+ directives = *jDirectives;
+ if (auto jBackDirectives = config.optString("backDirectives"))
+ backDirectives = *jBackDirectives;
+
+ return *this;
+}
+
namespace Text {
static auto stripEscapeRegex = std::regex(strf("\\{:c}[^;]*{:c}", CmdEsc, EndEsc));
String stripEscapeCodes(String const& s) {
diff --git a/source/core/StarText.hpp b/source/core/StarText.hpp
index 4f6a97a..ff6880c 100644
--- a/source/core/StarText.hpp
+++ b/source/core/StarText.hpp
@@ -2,9 +2,29 @@
#include "StarString.hpp"
#include "StarStringView.hpp"
+#include "StarVector.hpp"
+#include "StarDirectives.hpp"
+#include "StarJson.hpp"
namespace Star {
-
+
+unsigned const DefaultFontSize = 8;
+float const DefaultLineSpacing = 1.3f;
+
+struct TextStyle {
+ float lineSpacing = DefaultLineSpacing;
+ Vec4B color = Vec4B::filled(255);
+ Vec4B shadow = Vec4B::filled(0);
+ unsigned fontSize = DefaultFontSize;
+ String font = "";
+ Directives directives;
+ Directives backDirectives;
+
+ TextStyle() = default;
+ TextStyle(Json const& config);
+ TextStyle& loadJson(Json const& config);
+};
+
namespace Text {
unsigned char const StartEsc = '\x1b';
unsigned char const EndEsc = ';';
diff --git a/source/core/scripting/StarUtilityLuaBindings.cpp b/source/core/scripting/StarUtilityLuaBindings.cpp
index 5ab6e19..98ad239 100644
--- a/source/core/scripting/StarUtilityLuaBindings.cpp
+++ b/source/core/scripting/StarUtilityLuaBindings.cpp
@@ -118,12 +118,14 @@ LuaCallbacks LuaBindings::makeUtilityCallbacks() {
callbacks.registerCallback("print", UtilityCallbacks::print);
callbacks.registerCallback("interpolateSinEase", UtilityCallbacks::interpolateSinEase);
callbacks.registerCallback("replaceTags", UtilityCallbacks::replaceTags);
- callbacks.registerCallback("jsonParse", [](String const& json) { return Json::parse(json); });
+ callbacks.registerCallback("parseJsonSequence", [](String const& json) { return Json::parseSequence(json); });
callbacks.registerCallback("jsonMerge", [](Json const& a, Json const& b) { return jsonMerge(a, b); });
callbacks.registerCallback("jsonQuery", [](Json const& json, String const& path, Json const& def) { return json.query(path, def); });
callbacks.registerCallback("makeRandomSource", [](Maybe<uint64_t> seed) { return seed ? RandomSource(*seed) : RandomSource(); });
callbacks.registerCallback("makePerlinSource", [](Json const& config) { return PerlinF(config); });
+ callbacks.copyCallback("parseJson", "jsonFromString"); // SE compat
+
auto hash64LuaValues = [](LuaVariadic<LuaValue> const& values) -> uint64_t {
XXHash64 hash;