From 703686beee1e06c09996a812c7cb0195ea5bcee3 Mon Sep 17 00:00:00 2001 From: Alexander Kromm Date: Sun, 29 Dec 2019 17:35:06 +0700 Subject: [PATCH] export TMap to ZScript --- src/CMakeLists.txt | 1 + src/scripting/thingdef_data.cpp | 16 +++++++ src/serializer.cpp | 70 +++++++++++++++++++++++++++++ src/serializer.h | 4 ++ src/utility/dictionary.cpp | 70 +++++++++++++++++++++++++++++ src/utility/dictionary.h | 6 +++ wadsrc/static/zscript.txt | 1 + wadsrc/static/zscript/dictionary.zs | 10 +++++ 8 files changed, 178 insertions(+) create mode 100644 src/utility/dictionary.cpp create mode 100644 src/utility/dictionary.h create mode 100644 wadsrc/static/zscript/dictionary.zs diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 700d1c6095..839914811a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1171,6 +1171,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE utility/x86.cpp utility/strnatcmp.c utility/zstring.cpp + utility/dictionary.cpp utility/math/asin.c utility/math/atan.c utility/math/const.c diff --git a/src/scripting/thingdef_data.cpp b/src/scripting/thingdef_data.cpp index 43982bc25f..efb630891d 100644 --- a/src/scripting/thingdef_data.cpp +++ b/src/scripting/thingdef_data.cpp @@ -55,6 +55,7 @@ #include "wi_stuff.h" #include "a_dynlight.h" #include "types.h" +#include "utility/dictionary.h" static TArray properties; static TArray AFTable; @@ -841,6 +842,21 @@ void InitThingdef() wbplayerstruct->Size = sizeof(wbplayerstruct_t); wbplayerstruct->Align = alignof(wbplayerstruct_t); + auto dictionarystruct = NewStruct("Dictionary", nullptr, true); + dictionarystruct->Size = sizeof(Dictionary); + dictionarystruct->Align = alignof(Dictionary); + NewPointer(dictionarystruct, false)->InstallHandlers( + [](FSerializer &ar, const char *key, const void *addr) + { + ar(key, *(Dictionary **)addr); + }, + [](FSerializer &ar, const char *key, void *addr) + { + Serialize(ar, key, *(Dictionary **)addr, nullptr); + return true; + } + ); + FAutoSegIterator probe(CRegHead, CRegTail); while (*++probe != NULL) diff --git a/src/serializer.cpp b/src/serializer.cpp index 57ce752cbc..c336af2f6e 100644 --- a/src/serializer.cpp +++ b/src/serializer.cpp @@ -2156,6 +2156,76 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&fon } +//========================================================================== +// +// Dictionary +// +//========================================================================== + +FString DictionaryToString(const Dictionary &dict) +{ + Dictionary::ConstPair *pair; + Dictionary::ConstIterator i { dict }; + + rapidjson::StringBuffer buffer; + rapidjson::Writer writer(buffer); + writer.StartObject(); + + while (i.NextPair(pair)) + { + writer.Key(pair->Key); + writer.String(pair->Value); + } + + writer.EndObject(); + + FString contents { buffer.GetString(), buffer.GetSize() }; + return contents; +} + +Dictionary *DictionaryFromString(const FString &string) +{ + Dictionary *const dict = new Dictionary; + + rapidjson::Document doc; + doc.Parse(string.GetChars(), string.Len()); + + if (doc.GetType() != rapidjson::Type::kObjectType) + { + I_Error("Dictionary is expected to be an object."); + return dict; + } + + for (auto i = doc.MemberBegin(); i != doc.MemberEnd(); ++i) + { + if (i->value.GetType() != rapidjson::Type::kStringType) + { + I_Error("Dictionary value is expected to be a string."); + return dict; + } + + dict->Insert(i->name.GetString(), i->value.GetString()); + } + + return dict; +} + +template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **) +{ + if (arc.isWriting()) + { + FString contents { DictionaryToString(*dict) }; + return arc(key, contents); + } + else + { + FString contents; + arc(key, contents); + dict = DictionaryFromString(contents); + return arc; + } +} + //========================================================================== // // Handler to retrieve a numeric value of any kind. diff --git a/src/serializer.h b/src/serializer.h index 46f6dfbb28..71f8f76e11 100644 --- a/src/serializer.h +++ b/src/serializer.h @@ -7,6 +7,7 @@ #include "r_defs.h" #include "resourcefiles/file_zip.h" #include "tflags.h" +#include "utility/dictionary.h" extern bool save_full; @@ -270,6 +271,7 @@ template<> FSerializer &Serialize(FSerializer &arc, const char *key, FDoorAnimat template<> FSerializer &Serialize(FSerializer &arc, const char *key, char *&pstr, char **def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, FFont *&font, FFont **def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, FLevelLocals *&font, FLevelLocals **def); +template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **def); FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState **def, bool *retcode); template<> inline FSerializer &Serialize(FSerializer &arc, const char *key, FState *&state, FState **def) @@ -311,5 +313,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, TFlags &flags, return Serialize(arc, key, flags.Value, def? &def->Value : nullptr); } +FString DictionaryToString(const Dictionary &dict); +Dictionary *DictionaryFromString(const FString &string); #endif diff --git a/src/utility/dictionary.cpp b/src/utility/dictionary.cpp new file mode 100644 index 0000000000..59db6ec08a --- /dev/null +++ b/src/utility/dictionary.cpp @@ -0,0 +1,70 @@ +#include "utility/dictionary.h" + +#include "scripting/vm/vm.h" +#include "serializer.h" + +//===================================================================================== +// +// Dictionary exports +// +//===================================================================================== + +DEFINE_ACTION_FUNCTION(_Dictionary, Create) +{ + PARAM_PROLOGUE; + ACTION_RETURN_POINTER(new Dictionary); +} + +static void DictInsert(Dictionary *dict, const FString &key, const FString &value) +{ + dict->Insert(key, value); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Insert, DictInsert) +{ + PARAM_SELF_STRUCT_PROLOGUE(Dictionary); + PARAM_STRING(key); + PARAM_STRING(value); + DictInsert(self, key, value); + return 0; +} + +static void DictAt(const Dictionary *dict, const FString &key, FString *result) +{ + const FString *value = dict->CheckKey(key); + *result = value ? *value : ""; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, At, DictAt) +{ + PARAM_SELF_STRUCT_PROLOGUE(Dictionary); + PARAM_STRING(key); + FString result; + DictAt(self, key, &result); + ACTION_RETURN_STRING(result); +} + +static void DictToString(const Dictionary *dict, FString *result) +{ + *result = DictionaryToString(*dict); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, ToString, DictToString) +{ + PARAM_SELF_STRUCT_PROLOGUE(Dictionary); + FString result; + DictToString(self, &result); + ACTION_RETURN_STRING(result); +} + +static Dictionary *DictFromString(const FString& string) +{ + return DictionaryFromString(string); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, FromString, DictFromString) +{ + PARAM_PROLOGUE; + PARAM_STRING(string); + ACTION_RETURN_POINTER(DictFromString(string)); +} diff --git a/src/utility/dictionary.h b/src/utility/dictionary.h new file mode 100644 index 0000000000..460716c91c --- /dev/null +++ b/src/utility/dictionary.h @@ -0,0 +1,6 @@ +#pragma once + +#include "tarray.h" +#include "zstring.h" + +using Dictionary = TMap; diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 7981d90327..921c9beb8b 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -8,6 +8,7 @@ version "4.2" #include "zscript/destructible.zs" #include "zscript/level_postprocessor.zs" #include "zscript/level_compatibility.zs" +#include "zscript/dictionary.zs" #include "zscript/actors/actor.zs" #include "zscript/actors/checks.zs" diff --git a/wadsrc/static/zscript/dictionary.zs b/wadsrc/static/zscript/dictionary.zs new file mode 100644 index 0000000000..10f9cb20c2 --- /dev/null +++ b/wadsrc/static/zscript/dictionary.zs @@ -0,0 +1,10 @@ +struct Dictionary native +{ + native static Dictionary Create(); + native static Dictionary FromString(String s); + + native void Insert(String key, String value); + native String At(String key) const; + + native String ToString() const; +}