File: RegisterDictionary.h

package info (click to toggle)
jazz2-native 3.5.0-1
  • links: PTS, VCS
  • area: contrib
  • in suites:
  • size: 16,836 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (200 lines) | stat: -rw-r--r-- 6,030 bytes parent folder | download | duplicates (3)
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
#pragma once

#if defined(WITH_ANGELSCRIPT) || defined(DOXYGEN_GENERATING_OUTPUT)

#include "../../nCine/Base/HashMap.h"

#include <angelscript.h>

#include <Containers/String.h>

using namespace Death::Containers;
using namespace nCine;

namespace Jazz2::Scripting
{
	class CScriptArray;
	class CScriptDictionary;
	class CScriptDictValue;

	typedef String dictKey_t;
	typedef HashMap<dictKey_t, CScriptDictValue> dictMap_t;

	/** @brief **AngelScript** dictionary value */
	class CScriptDictValue
	{
		friend class CScriptDictionary;

	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, std::int32_t 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, std::int32_t typeId);
		void Set(asIScriptEngine* engine, const std::int64_t& 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, std::int32_t typeId) const;
		bool Get(asIScriptEngine* engine, std::int64_t& 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
		std::int32_t GetTypeId() const;

		// Free the stored value
		void FreeValue(asIScriptEngine* engine);

		// GC callback
		void EnumReferences(asIScriptEngine* engine);

	protected:
#ifndef DOXYGEN_GENERATING_OUTPUT
		union
		{
			asINT64 m_valueInt;
			double  m_valueFlt;
			void* m_valueObj;
		};
		std::int32_t m_typeId;
#endif
	};

	/** @brief **AngelScript** dictionary */
	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, std::int32_t typeId);
		void Set(const dictKey_t& key, const std::int64_t& 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, std::int32_t typeId) const;
		bool Get(const dictKey_t& key, std::int64_t& 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
		std::int32_t 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;

		/** @brief **AngelScript** dictionary iterator */
		class CIterator
		{
			friend class CScriptDictionary;

		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;
			std::int32_t GetTypeId() const;
			bool GetValue(std::int64_t& value) const;
			bool GetValue(double& value) const;
			bool GetValue(void* value, std::int32_t typeId) const;
			const void* GetAddressOfValue() const;

		protected:
			CIterator();
			CIterator(const CScriptDictionary& dict, dictMap_t::const_iterator it);

			CIterator& operator=(const CIterator&) { return *this; } // Not used

#ifndef DOXYGEN_GENERATING_OUTPUT
			dictMap_t::const_iterator m_it;
			const CScriptDictionary& m_dict;
#endif
		};

		CIterator begin() const;
		CIterator end() const;
		CIterator find(const dictKey_t& key) const;

		// Garbage collections behaviours
		std::int32_t 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);

#ifndef DOXYGEN_GENERATING_OUTPUT
		// Our properties
		asIScriptEngine* engine;
		mutable std::int32_t refCount;
		mutable bool gcFlag;
		dictMap_t dict;
#endif
	};

	/** @relatesalso CScriptDictionary
		@brief Registers `dictionary` type to **AngelScript** engine
	*/
	void RegisterDictionary(asIScriptEngine* engine);
}

#endif