- dictionary can also go to 'common'.
This commit is contained in:
parent
f6bd2e4f76
commit
1ce11ff02a
4 changed files with 50 additions and 46 deletions
|
|
@ -1,218 +0,0 @@
|
|||
#include "dictionary.h"
|
||||
|
||||
#include "vm.h"
|
||||
#include "serializer.h"
|
||||
|
||||
#include <cassert>
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
// DObject implementations for Dictionary and DictionaryIterator
|
||||
//
|
||||
//=====================================================================================
|
||||
|
||||
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);
|
||||
Map.TransferFrom(pointerToDeserializedDictionary->Map);
|
||||
delete pointerToDeserializedDictionary;
|
||||
}
|
||||
}
|
||||
|
||||
static Dictionary *DictCreate()
|
||||
{
|
||||
Dictionary *dict { Create<Dictionary>() };
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
static void DictInsert(Dictionary *dict, const FString &key, const FString &value)
|
||||
{
|
||||
dict->Map.Insert(key, value);
|
||||
}
|
||||
|
||||
static void DictAt(const Dictionary *dict, const FString &key, FString *result)
|
||||
{
|
||||
const FString *value = dict->Map.CheckKey(key);
|
||||
*result = value ? *value : "";
|
||||
}
|
||||
|
||||
static void DictToString(const Dictionary *dict, FString *result)
|
||||
{
|
||||
*result = DictionaryToString(*dict);
|
||||
}
|
||||
|
||||
static void DictRemove(Dictionary *dict, const FString &key)
|
||||
{
|
||||
dict->Map.Remove(key);
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
// Dictionary exports
|
||||
//
|
||||
//=====================================================================================
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Create, DictCreate)
|
||||
{
|
||||
ACTION_RETURN_POINTER(DictCreate());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, FromString, DictionaryFromString)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_STRING(string);
|
||||
ACTION_RETURN_POINTER(DictionaryFromString(string));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION_NATIVE(_Dictionary, Remove, DictRemove)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(Dictionary);
|
||||
PARAM_STRING(key);
|
||||
DictRemove(self, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=====================================================================================
|
||||
//
|
||||
// DictionaryIterator functions
|
||||
//
|
||||
//=====================================================================================
|
||||
|
||||
DictionaryIterator::DictionaryIterator()
|
||||
: Iterator(nullptr)
|
||||
, Pair(nullptr)
|
||||
, Dict(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
void DictionaryIterator::Serialize(FSerializer &arc)
|
||||
{
|
||||
if (arc.isWriting())
|
||||
{
|
||||
I_Error("Attempt to save pointer to unhandled type DictionaryIterator");
|
||||
}
|
||||
}
|
||||
|
||||
void DictionaryIterator::init(Dictionary *dict)
|
||||
{
|
||||
Iterator = std::make_unique<Dictionary::ConstIterator>(dict->Map);
|
||||
Dict = dict;
|
||||
|
||||
GC::WriteBarrier(this, Dict);
|
||||
}
|
||||
|
||||
static DictionaryIterator *DictIteratorCreate(Dictionary *dict)
|
||||
{
|
||||
DictionaryIterator *iterator = Create<DictionaryIterator>();
|
||||
iterator->init(dict);
|
||||
|
||||
return iterator;
|
||||
}
|
||||
|
||||
static int DictIteratorNext(DictionaryIterator *self)
|
||||
{
|
||||
assert(self->Iterator != nullptr);
|
||||
|
||||
const bool hasNext { self->Iterator->NextPair(self->Pair) };
|
||||
return hasNext;
|
||||
}
|
||||
|
||||
static void DictIteratorKey(const DictionaryIterator *self, FString *result)
|
||||
{
|
||||
*result = self->Pair ? self->Pair->Key : FString {};
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "tarray.h"
|
||||
#include "zstring.h"
|
||||
#include "dobject.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
/**
|
||||
* @brief The Dictionary class exists to be exported to ZScript.
|
||||
*
|
||||
* It is a string-to-string map.
|
||||
*
|
||||
* It is derived from DObject to be a part of normal GC process.
|
||||
*/
|
||||
class Dictionary final : public DObject
|
||||
{
|
||||
DECLARE_CLASS(Dictionary, DObject)
|
||||
|
||||
public:
|
||||
|
||||
using StringMap = TMap<FString, FString>;
|
||||
using ConstIterator = StringMap::ConstIterator;
|
||||
using ConstPair = StringMap::ConstPair;
|
||||
|
||||
void Serialize(FSerializer &arc) override;
|
||||
|
||||
StringMap Map;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The DictionaryIterator class exists to be exported to ZScript.
|
||||
*
|
||||
* It provides iterating over a Dictionary. The order is not specified.
|
||||
*
|
||||
* It is derived from DObject to be a part of normal GC process.
|
||||
*/
|
||||
class DictionaryIterator final : public DObject
|
||||
{
|
||||
DECLARE_CLASS(DictionaryIterator, DObject)
|
||||
HAS_OBJECT_POINTERS
|
||||
|
||||
public:
|
||||
|
||||
~DictionaryIterator() override = default;
|
||||
|
||||
/**
|
||||
* IMPLEMENT_CLASS macro needs a constructor without parameters.
|
||||
*
|
||||
* @see init().
|
||||
*/
|
||||
DictionaryIterator();
|
||||
|
||||
void Serialize(FSerializer &arc) override;
|
||||
|
||||
/**
|
||||
* @brief init function complements constructor.
|
||||
* @attention always call init after constructing DictionaryIterator.
|
||||
*/
|
||||
void init(Dictionary *dict);
|
||||
|
||||
std::unique_ptr<Dictionary::ConstIterator> Iterator;
|
||||
Dictionary::ConstPair *Pair;
|
||||
|
||||
/**
|
||||
* @brief Dictionary attribute exists for holding a pointer to iterated
|
||||
* dictionary, so it is known by GC.
|
||||
*/
|
||||
Dictionary *Dict;
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue