1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
|
#ifndef SCRIPTDICTIONARY_H
#define SCRIPTDICTIONARY_H
// The dictionary class relies on the script string object, thus the script
// string type must be registered with the engine before registering the
// dictionary type
#ifndef ANGELSCRIPT_H
// Avoid having to inform include path if header is already include before
#include <angelscript.h>
#endif
// By default the CScriptDictionary use the std::string for the keys.
// If the application uses a custom string type, then this typedef
// can be changed accordingly.
#include <string>
typedef std::string dictKey_t;
// Forward declare CScriptDictValue so we can typedef the internal map type
BEGIN_AS_NAMESPACE
class CScriptDictValue;
END_AS_NAMESPACE
// C++11 introduced the std::unordered_map which is a hash map which is
// is generally more performatic for lookups than the std::map which is a
// binary tree.
// TODO: memory: The map allocator should use the asAllocMem and asFreeMem
#if AS_CAN_USE_CPP11
#include <unordered_map>
typedef std::unordered_map<dictKey_t, AS_NAMESPACE_QUALIFIER CScriptDictValue> dictMap_t;
#else
#include <map>
typedef std::map<dictKey_t, AS_NAMESPACE_QUALIFIER CScriptDictValue> dictMap_t;
#endif
#ifdef _MSC_VER
// Turn off annoying warnings about truncated symbol names
#pragma warning (disable:4786)
#endif
// Sometimes it may be desired to use the same method names as used by C++ STL.
// This may for example reduce time when converting code from script to C++ or
// back.
//
// 0 = off
// 1 = on
#ifndef AS_USE_STLNAMES
#define AS_USE_STLNAMES 0
#endif
BEGIN_AS_NAMESPACE
class CScriptArray;
class CScriptDictionary;
class CScriptDictValue
{
public:
// This class must not be declared as local variable in C++, because it needs
// to receive the script engine pointer in all operations. The engine pointer
// is not kept as member in order to keep the size down
CScriptDictValue();
CScriptDictValue(asIScriptEngine *engine, void *value, int typeId);
// Destructor must not be called without first calling FreeValue, otherwise a memory leak will occur
~CScriptDictValue();
// Replace the stored value
void Set(asIScriptEngine *engine, void *value, int typeId);
void Set(asIScriptEngine *engine, const asINT64 &value);
void Set(asIScriptEngine *engine, const double &value);
void Set(asIScriptEngine *engine, CScriptDictValue &value);
// Gets the stored value. Returns false if the value isn't compatible with the informed typeId
bool Get(asIScriptEngine *engine, void *value, int typeId) const;
bool Get(asIScriptEngine *engine, asINT64 &value) const;
bool Get(asIScriptEngine *engine, double &value) const;
// Returns the address of the stored value for inspection
const void *GetAddressOfValue() const;
// Returns the type id of the stored value
int GetTypeId() const;
// Free the stored value
void FreeValue(asIScriptEngine *engine);
// GC callback
void EnumReferences(asIScriptEngine *engine);
protected:
friend class CScriptDictionary;
union
{
asINT64 m_valueInt;
double m_valueFlt;
void *m_valueObj;
};
int m_typeId;
};
class CScriptDictionary
{
public:
// Factory functions
static CScriptDictionary *Create(asIScriptEngine *engine);
// Called from the script to instantiate a dictionary from an initialization list
static CScriptDictionary *Create(asBYTE *buffer);
// Reference counting
void AddRef() const;
void Release() const;
// Reassign the dictionary
CScriptDictionary &operator =(const CScriptDictionary &other);
// Sets a key/value pair
void Set(const dictKey_t &key, void *value, int typeId);
void Set(const dictKey_t &key, const asINT64 &value);
void Set(const dictKey_t &key, const double &value);
// Gets the stored value. Returns false if the value isn't compatible with the informed typeId
bool Get(const dictKey_t &key, void *value, int typeId) const;
bool Get(const dictKey_t &key, asINT64 &value) const;
bool Get(const dictKey_t &key, double &value) const;
// Index accessors. If the dictionary is not const it inserts the value if it doesn't already exist
// If the dictionary is const then a script exception is set if it doesn't exist and a null pointer is returned
CScriptDictValue *operator[](const dictKey_t &key);
const CScriptDictValue *operator[](const dictKey_t &key) const;
// Returns the type id of the stored value, or negative if it doesn't exist
int GetTypeId(const dictKey_t &key) const;
// Returns true if the key is set
bool Exists(const dictKey_t &key) const;
// Returns true if there are no key/value pairs in the dictionary
bool IsEmpty() const;
// Returns the number of key/value pairs in the dictionary
asUINT GetSize() const;
// Deletes the key
bool Delete(const dictKey_t &key);
// Deletes all keys
void DeleteAll();
// Get an array of all keys
CScriptArray *GetKeys() const;
// STL style iterator
class CIterator
{
public:
void operator++(); // Pre-increment
void operator++(int); // Post-increment
// This is needed to support C++11 range-for
CIterator &operator*();
bool operator==(const CIterator &other) const;
bool operator!=(const CIterator &other) const;
// Accessors
const dictKey_t &GetKey() const;
int GetTypeId() const;
bool GetValue(asINT64 &value) const;
bool GetValue(double &value) const;
bool GetValue(void *value, int typeId) const;
const void * GetAddressOfValue() const;
protected:
friend class CScriptDictionary;
CIterator();
CIterator(const CScriptDictionary &dict,
dictMap_t::const_iterator it);
CIterator &operator=(const CIterator &) {return *this;} // Not used
dictMap_t::const_iterator m_it;
const CScriptDictionary &m_dict;
};
CIterator begin() const;
CIterator end() const;
CIterator find(const dictKey_t &key) const;
// Garbage collections behaviours
int GetRefCount();
void SetGCFlag();
bool GetGCFlag();
void EnumReferences(asIScriptEngine *engine);
void ReleaseAllReferences(asIScriptEngine *engine);
protected:
// Since the dictionary uses the asAllocMem and asFreeMem functions to allocate memory
// the constructors are made protected so that the application cannot allocate it
// manually in a different way
CScriptDictionary(asIScriptEngine *engine);
CScriptDictionary(asBYTE *buffer);
// We don't want anyone to call the destructor directly, it should be called through the Release method
virtual ~CScriptDictionary();
// Cache the object types needed
void Init(asIScriptEngine *engine);
// Our properties
asIScriptEngine *engine;
mutable int refCount;
mutable bool gcFlag;
dictMap_t dict;
};
// This function will determine the configuration of the engine
// and use one of the two functions below to register the dictionary object
void RegisterScriptDictionary(asIScriptEngine *engine);
// Call this function to register the math functions
// using native calling conventions
void RegisterScriptDictionary_Native(asIScriptEngine *engine);
// Use this one instead if native calling conventions
// are not supported on the target platform
void RegisterScriptDictionary_Generic(asIScriptEngine *engine);
END_AS_NAMESPACE
#endif
|