1/*
2 * Copyright 2013-2018, Rene Gollent, rene@gollent.com.
3 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
4 * Distributed under the terms of the MIT License.
5 */
6
7
8#include "VariablesViewState.h"
9
10#include <new>
11
12#include "ExpressionValues.h"
13#include "FunctionID.h"
14#include "StackFrameValues.h"
15#include "Type.h"
16#include "TypeComponentPath.h"
17#include "TypeHandler.h"
18
19
20// #pragma mark - VariablesViewNodeInfo
21
22
23VariablesViewNodeInfo::VariablesViewNodeInfo()
24	:
25	fNodeExpanded(false),
26	fCastedType(NULL),
27	fTypeHandler(NULL),
28	fRendererSettings()
29{
30}
31
32
33VariablesViewNodeInfo::VariablesViewNodeInfo(const VariablesViewNodeInfo& other)
34	:
35	fNodeExpanded(other.fNodeExpanded),
36	fCastedType(other.fCastedType),
37	fTypeHandler(other.fTypeHandler),
38	fRendererSettings(other.fRendererSettings)
39{
40	if (fCastedType != NULL)
41		fCastedType->AcquireReference();
42}
43
44
45VariablesViewNodeInfo::~VariablesViewNodeInfo()
46{
47	if (fCastedType != NULL)
48		fCastedType->ReleaseReference();
49
50	if (fTypeHandler != NULL)
51		fTypeHandler->ReleaseReference();
52}
53
54
55VariablesViewNodeInfo&
56VariablesViewNodeInfo::operator=(const VariablesViewNodeInfo& other)
57{
58	fNodeExpanded = other.fNodeExpanded;
59	SetCastedType(other.fCastedType);
60	SetTypeHandler(other.fTypeHandler);
61	fRendererSettings = other.fRendererSettings;
62
63	return *this;
64}
65
66
67void
68VariablesViewNodeInfo::SetNodeExpanded(bool expanded)
69{
70	fNodeExpanded = expanded;
71}
72
73
74void
75VariablesViewNodeInfo::SetCastedType(Type* type)
76{
77	if (fCastedType != NULL)
78		fCastedType->ReleaseReference();
79
80	fCastedType = type;
81	if (fCastedType != NULL)
82		fCastedType->AcquireReference();
83}
84
85
86void
87VariablesViewNodeInfo::SetTypeHandler(TypeHandler* handler)
88{
89	if (fTypeHandler != NULL)
90		fTypeHandler->ReleaseReference();
91
92	fTypeHandler = handler;
93	if (fTypeHandler != NULL)
94		fTypeHandler->AcquireReference();
95}
96
97
98void
99VariablesViewNodeInfo::SetRendererSettings(const BMessage& settings)
100{
101	fRendererSettings = settings;
102}
103
104
105// #pragma mark - Key
106
107
108struct VariablesViewState::Key {
109	ObjectID*			variable;
110	TypeComponentPath*	path;
111
112	Key(ObjectID* variable, TypeComponentPath* path)
113		:
114		variable(variable),
115		path(path)
116	{
117	}
118
119	uint32 HashValue() const
120	{
121		return variable->HashValue() ^ path->HashValue();
122	}
123
124	bool operator==(const Key& other) const
125	{
126		return *variable == *other.variable && *path == *other.path;
127	}
128};
129
130
131// #pragma mark - InfoEntry
132
133
134struct VariablesViewState::InfoEntry : Key, VariablesViewNodeInfo {
135	InfoEntry*	next;
136
137	InfoEntry(ObjectID* variable, TypeComponentPath* path)
138		:
139		Key(variable, path)
140	{
141		variable->AcquireReference();
142		path->AcquireReference();
143	}
144
145	~InfoEntry()
146	{
147		variable->ReleaseReference();
148		path->ReleaseReference();
149	}
150
151	void SetInfo(const VariablesViewNodeInfo& info)
152	{
153		VariablesViewNodeInfo::operator=(info);
154	}
155};
156
157
158struct VariablesViewState::InfoEntryHashDefinition {
159	typedef Key			KeyType;
160	typedef	InfoEntry	ValueType;
161
162	size_t HashKey(const Key& key) const
163	{
164		return key.HashValue();
165	}
166
167	size_t Hash(const InfoEntry* value) const
168	{
169		return value->HashValue();
170	}
171
172	bool Compare(const Key& key, const InfoEntry* value) const
173	{
174		return key == *value;
175	}
176
177	InfoEntry*& GetLink(InfoEntry* value) const
178	{
179		return value->next;
180	}
181};
182
183
184VariablesViewState::VariablesViewState()
185	:
186	fNodeInfos(NULL),
187	fValues(NULL),
188	fExpressionValues(NULL)
189{
190}
191
192
193VariablesViewState::~VariablesViewState()
194{
195	_Cleanup();
196}
197
198
199status_t
200VariablesViewState::Init()
201{
202	fNodeInfos = new(std::nothrow) NodeInfoTable;
203	if (fNodeInfos == NULL)
204		return B_NO_MEMORY;
205
206	return fNodeInfos->Init();
207}
208
209void
210VariablesViewState::SetValues(StackFrameValues* values)
211{
212	if (fValues == values)
213		return;
214
215	if (fValues != NULL)
216		fValues->ReleaseReference();
217
218	fValues = values;
219
220	if (fValues != NULL)
221		fValues->AcquireReference();
222}
223
224
225void
226VariablesViewState::SetExpressionValues(ExpressionValues* values)
227{
228	if (fExpressionValues == values)
229		return;
230
231	if (fExpressionValues != NULL)
232		fExpressionValues->ReleaseReference();
233
234	fExpressionValues = values;
235
236	if (fExpressionValues != NULL)
237		fExpressionValues->AcquireReference();
238}
239
240
241const VariablesViewNodeInfo*
242VariablesViewState::GetNodeInfo(ObjectID* variable,
243	const TypeComponentPath* path) const
244{
245	return fNodeInfos->Lookup(Key(variable, (TypeComponentPath*)path));
246}
247
248
249status_t
250VariablesViewState::SetNodeInfo(ObjectID* variable, TypeComponentPath* path,
251	const VariablesViewNodeInfo& info)
252{
253	InfoEntry* entry = fNodeInfos->Lookup(Key(variable, path));
254	if (entry == NULL) {
255		entry = new(std::nothrow) InfoEntry(variable, path);
256		if (entry == NULL)
257			return B_NO_MEMORY;
258		fNodeInfos->Insert(entry);
259	}
260
261	entry->SetInfo(info);
262	return B_OK;
263}
264
265
266void
267VariablesViewState::_Cleanup()
268{
269	if (fNodeInfos != NULL) {
270		InfoEntry* entry = fNodeInfos->Clear(true);
271
272		while (entry != NULL) {
273			InfoEntry* next = entry->next;
274			delete entry;
275			entry = next;
276		}
277
278		delete fNodeInfos;
279		fNodeInfos = NULL;
280	}
281
282	SetValues(NULL);
283	SetExpressionValues(NULL);
284}
285