diff --git a/src/utility/dictionary.cpp b/src/utility/dictionary.cpp index e951439ec7..6da43dca18 100644 --- a/src/utility/dictionary.cpp +++ b/src/utility/dictionary.cpp @@ -11,7 +11,6 @@ DEFINE_ACTION_FUNCTION(_Dictionary, Create) { - PARAM_PROLOGUE; ACTION_RETURN_POINTER(new Dictionary); } @@ -81,3 +80,64 @@ DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Remove, DictRemove) DictRemove(self, key); return 0; } + +//===================================================================================== +// +// DictionaryIterator exports +// +//===================================================================================== + +DictionaryIterator::DictionaryIterator(const Dictionary &dict) + : Iterator(dict) + , Pair(nullptr) +{ +} + +static DictionaryIterator *DictIteratorCreate(const Dictionary *dict) +{ + return new DictionaryIterator(*dict); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Create, DictIteratorCreate) +{ + PARAM_PROLOGUE; + PARAM_POINTER(dict, Dictionary); + ACTION_RETURN_POINTER(DictIteratorCreate(dict)); +} + +static int DictIteratorNext(DictionaryIterator *self) +{ + return self->Iterator.NextPair(self->Pair); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Next, DictIteratorNext) +{ + PARAM_SELF_STRUCT_PROLOGUE(DictionaryIterator); + ACTION_RETURN_BOOL(DictIteratorNext(self)); +} + +static void DictIteratorKey(const DictionaryIterator *self, FString *result) +{ + *result = self->Pair ? self->Pair->Key : FString {}; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Key, DictIteratorKey) +{ + PARAM_SELF_STRUCT_PROLOGUE(DictionaryIterator); + FString result; + DictIteratorKey(self, &result); + ACTION_RETURN_STRING(result); +} + +static void DictIteratorValue(const DictionaryIterator *self, FString *result) +{ + *result = self->Pair ? self->Pair->Value : FString {}; +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Value, DictIteratorValue) +{ + PARAM_SELF_STRUCT_PROLOGUE(DictionaryIterator); + FString result; + DictIteratorValue(self, &result); + ACTION_RETURN_STRING(result); +} diff --git a/src/utility/dictionary.h b/src/utility/dictionary.h index 460716c91c..4ccd11370f 100644 --- a/src/utility/dictionary.h +++ b/src/utility/dictionary.h @@ -4,3 +4,11 @@ #include "zstring.h" using Dictionary = TMap; + +struct DictionaryIterator +{ + explicit DictionaryIterator(const Dictionary &dict); + + Dictionary::ConstIterator Iterator; + Dictionary::ConstPair *Pair; +}; diff --git a/wadsrc/static/zscript/dictionary.zs b/wadsrc/static/zscript/dictionary.zs index f802a2faed..432cec891f 100644 --- a/wadsrc/static/zscript/dictionary.zs +++ b/wadsrc/static/zscript/dictionary.zs @@ -1,11 +1,50 @@ struct Dictionary native { native static Dictionary Create(); - native static Dictionary FromString(String s); native void Insert(String key, String value); native void Remove(String key); + + /** + * Returns the value for the specified key. + */ native String At(String key) const; + /** + * Deserializes a dictionary from a string. + * + * @param s serialized string, must be either empty or returned from ToString(). + */ + native static Dictionary FromString(String s); + + /** + * Serializes a dictionary to a string. + */ native String ToString() const; } + +struct DictionaryIterator native +{ + native static DictionaryIterator Create(Dictionary dict); + + /** + * Returns false if there are no more entries in the dictionary. + * Otherwise, returns true. + * + * While it returns true, get key and value for the current entry + * with Key() and Value() functions. + */ + native bool Next(); + + /** + * Returns the key for the current dictionary entry. + * Do not call this function before calling Next(). + */ + native String Key() const; + + /** + * Returns the value for the current dictionary entry. + * Do not call this function before calling Next(). + */ + native String Value() const; +}