2020-04-11 10:24:39 +00:00
|
|
|
#include "dictionary.h"
|
2019-12-29 10:35:06 +00:00
|
|
|
|
|
|
|
#include "scripting/vm/vm.h"
|
|
|
|
#include "serializer.h"
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
#include <cassert>
|
|
|
|
|
2019-12-29 10:35:06 +00:00
|
|
|
//=====================================================================================
|
|
|
|
//
|
2020-01-29 17:10:07 +00:00
|
|
|
// DObject implementations for Dictionary and DictionaryIterator
|
2019-12-29 10:35:06 +00:00
|
|
|
//
|
|
|
|
//=====================================================================================
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
IMPLEMENT_CLASS(Dictionary, false, false);
|
|
|
|
|
|
|
|
IMPLEMENT_CLASS(DictionaryIterator, false, true);
|
|
|
|
|
|
|
|
IMPLEMENT_POINTERS_START(DictionaryIterator)
|
|
|
|
IMPLEMENT_POINTER(Dict)
|
|
|
|
IMPLEMENT_POINTERS_END
|
|
|
|
|
|
|
|
//=====================================================================================
|
|
|
|
//
|
|
|
|
// Dictionary functions
|
|
|
|
//
|
|
|
|
//=====================================================================================
|
|
|
|
|
|
|
|
void Dictionary::Serialize(FSerializer &arc)
|
|
|
|
{
|
|
|
|
Super::Serialize(arc);
|
|
|
|
|
|
|
|
constexpr char key[] { "dictionary" };
|
|
|
|
|
|
|
|
if (arc.isWriting())
|
|
|
|
{
|
|
|
|
// Pass this instance to serializer.
|
|
|
|
Dictionary *pointerToThis = this;
|
|
|
|
arc(key, pointerToThis);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Receive new Dictionary, copy contents, clean up.
|
|
|
|
Dictionary *pointerToDeserializedDictionary;
|
|
|
|
arc(key, pointerToDeserializedDictionary);
|
2020-02-06 14:20:33 +00:00
|
|
|
Map.TransferFrom(pointerToDeserializedDictionary->Map);
|
2020-01-29 17:10:07 +00:00
|
|
|
delete pointerToDeserializedDictionary;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static Dictionary *DictCreate()
|
2019-12-29 10:35:06 +00:00
|
|
|
{
|
2020-01-29 17:10:07 +00:00
|
|
|
Dictionary *dict { Create<Dictionary>() };
|
|
|
|
|
|
|
|
return dict;
|
2019-12-29 10:35:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void DictInsert(Dictionary *dict, const FString &key, const FString &value)
|
|
|
|
{
|
2020-02-06 14:20:33 +00:00
|
|
|
dict->Map.Insert(key, value);
|
2019-12-29 10:35:06 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
static void DictAt(const Dictionary *dict, const FString &key, FString *result)
|
|
|
|
{
|
2020-02-06 14:20:33 +00:00
|
|
|
const FString *value = dict->Map.CheckKey(key);
|
2020-01-29 17:10:07 +00:00
|
|
|
*result = value ? *value : "";
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DictToString(const Dictionary *dict, FString *result)
|
|
|
|
{
|
|
|
|
*result = DictionaryToString(*dict);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void DictRemove(Dictionary *dict, const FString &key)
|
|
|
|
{
|
2020-02-06 14:20:33 +00:00
|
|
|
dict->Map.Remove(key);
|
2020-01-29 17:10:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================================
|
|
|
|
//
|
|
|
|
// Dictionary exports
|
|
|
|
//
|
|
|
|
//=====================================================================================
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Create, DictCreate)
|
|
|
|
{
|
|
|
|
ACTION_RETURN_POINTER(DictCreate());
|
|
|
|
}
|
|
|
|
|
2019-12-29 10:35:06 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Insert, DictInsert)
|
|
|
|
{
|
|
|
|
PARAM_SELF_STRUCT_PROLOGUE(Dictionary);
|
|
|
|
PARAM_STRING(key);
|
|
|
|
PARAM_STRING(value);
|
|
|
|
DictInsert(self, key, value);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, ToString, DictToString)
|
|
|
|
{
|
|
|
|
PARAM_SELF_STRUCT_PROLOGUE(Dictionary);
|
|
|
|
FString result;
|
|
|
|
DictToString(self, &result);
|
|
|
|
ACTION_RETURN_STRING(result);
|
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, FromString, DictionaryFromString)
|
2019-12-29 10:35:06 +00:00
|
|
|
{
|
|
|
|
PARAM_PROLOGUE;
|
|
|
|
PARAM_STRING(string);
|
2020-01-29 17:10:07 +00:00
|
|
|
ACTION_RETURN_POINTER(DictionaryFromString(string));
|
2019-12-30 13:33:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Remove, DictRemove)
|
|
|
|
{
|
|
|
|
PARAM_SELF_STRUCT_PROLOGUE(Dictionary);
|
|
|
|
PARAM_STRING(key);
|
|
|
|
DictRemove(self, key);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-12-31 15:26:52 +00:00
|
|
|
|
|
|
|
//=====================================================================================
|
|
|
|
//
|
2020-01-29 17:10:07 +00:00
|
|
|
// DictionaryIterator functions
|
2019-12-31 15:26:52 +00:00
|
|
|
//
|
|
|
|
//=====================================================================================
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
DictionaryIterator::DictionaryIterator()
|
|
|
|
: Iterator(nullptr)
|
2019-12-31 15:26:52 +00:00
|
|
|
, Pair(nullptr)
|
2020-01-29 17:10:07 +00:00
|
|
|
, Dict(nullptr)
|
2019-12-31 15:26:52 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
void DictionaryIterator::Serialize(FSerializer &arc)
|
2019-12-31 15:26:52 +00:00
|
|
|
{
|
2020-01-29 17:10:07 +00:00
|
|
|
if (arc.isWriting())
|
|
|
|
{
|
|
|
|
I_Error("Attempt to save pointer to unhandled type DictionaryIterator");
|
|
|
|
}
|
2019-12-31 15:26:52 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
void DictionaryIterator::init(Dictionary *dict)
|
2019-12-31 15:26:52 +00:00
|
|
|
{
|
2020-02-06 14:20:33 +00:00
|
|
|
Iterator = std::make_unique<Dictionary::ConstIterator>(dict->Map);
|
2020-01-29 17:10:07 +00:00
|
|
|
Dict = dict;
|
|
|
|
|
|
|
|
GC::WriteBarrier(this, Dict);
|
2019-12-31 15:26:52 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
static DictionaryIterator *DictIteratorCreate(Dictionary *dict)
|
2019-12-31 15:26:52 +00:00
|
|
|
{
|
2020-01-29 17:10:07 +00:00
|
|
|
DictionaryIterator *iterator = Create<DictionaryIterator>();
|
|
|
|
iterator->init(dict);
|
|
|
|
|
|
|
|
return iterator;
|
2019-12-31 15:26:52 +00:00
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
static int DictIteratorNext(DictionaryIterator *self)
|
2019-12-31 15:26:52 +00:00
|
|
|
{
|
2020-01-29 17:10:07 +00:00
|
|
|
assert(self->Iterator != nullptr);
|
|
|
|
|
|
|
|
const bool hasNext { self->Iterator->NextPair(self->Pair) };
|
|
|
|
return hasNext;
|
2019-12-31 15:26:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void DictIteratorKey(const DictionaryIterator *self, FString *result)
|
|
|
|
{
|
|
|
|
*result = self->Pair ? self->Pair->Key : FString {};
|
|
|
|
}
|
|
|
|
|
2020-01-29 17:10:07 +00:00
|
|
|
static void DictIteratorValue(const DictionaryIterator *self, FString *result)
|
|
|
|
{
|
|
|
|
*result = self->Pair ? self->Pair->Value : FString {};
|
|
|
|
}
|
|
|
|
|
|
|
|
//=====================================================================================
|
|
|
|
//
|
|
|
|
// DictionaryIterator exports
|
|
|
|
//
|
|
|
|
//=====================================================================================
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Create, DictIteratorCreate)
|
|
|
|
{
|
|
|
|
PARAM_PROLOGUE;
|
|
|
|
PARAM_POINTER(dict, Dictionary);
|
|
|
|
ACTION_RETURN_POINTER(DictIteratorCreate(dict));
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Next, DictIteratorNext)
|
|
|
|
{
|
|
|
|
PARAM_SELF_STRUCT_PROLOGUE(DictionaryIterator);
|
|
|
|
ACTION_RETURN_BOOL(DictIteratorNext(self));
|
|
|
|
}
|
|
|
|
|
2019-12-31 15:26:52 +00:00
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Key, DictIteratorKey)
|
|
|
|
{
|
|
|
|
PARAM_SELF_STRUCT_PROLOGUE(DictionaryIterator);
|
|
|
|
FString result;
|
|
|
|
DictIteratorKey(self, &result);
|
|
|
|
ACTION_RETURN_STRING(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
DEFINE_ACTION_FUNCTION_NATIVE(_DictionaryIterator, Value, DictIteratorValue)
|
|
|
|
{
|
|
|
|
PARAM_SELF_STRUCT_PROLOGUE(DictionaryIterator);
|
|
|
|
FString result;
|
|
|
|
DictIteratorValue(self, &result);
|
|
|
|
ACTION_RETURN_STRING(result);
|
|
|
|
}
|