1/*
2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6
7#include "VariablesViewState.h"
8
9#include <new>
10
11#include "FunctionID.h"
12#include "StackFrameValues.h"
13#include "TypeComponentPath.h"
14
15
16// #pragma mark - VariablesViewNodeInfo
17
18
19VariablesViewNodeInfo::VariablesViewNodeInfo()
20	:
21	fNodeExpanded(false)
22{
23}
24
25
26VariablesViewNodeInfo::VariablesViewNodeInfo(const VariablesViewNodeInfo& other)
27	:
28	fNodeExpanded(other.fNodeExpanded)
29{
30}
31
32
33VariablesViewNodeInfo&
34VariablesViewNodeInfo::operator=(const VariablesViewNodeInfo& other)
35{
36	fNodeExpanded = other.fNodeExpanded;
37	return *this;
38}
39
40
41void
42VariablesViewNodeInfo::SetNodeExpanded(bool expanded)
43{
44	fNodeExpanded = expanded;
45}
46
47
48// #pragma mark - Key
49
50
51struct VariablesViewState::Key {
52	ObjectID*			variable;
53	TypeComponentPath*	path;
54
55	Key(ObjectID* variable, TypeComponentPath* path)
56		:
57		variable(variable),
58		path(path)
59	{
60	}
61
62	uint32 HashValue() const
63	{
64		return variable->HashValue() ^ path->HashValue();
65	}
66
67	bool operator==(const Key& other) const
68	{
69		return *variable == *other.variable && *path == *other.path;
70	}
71};
72
73
74// #pragma mark - InfoEntry
75
76
77struct VariablesViewState::InfoEntry : Key, VariablesViewNodeInfo {
78	InfoEntry*	next;
79
80	InfoEntry(ObjectID* variable, TypeComponentPath* path)
81		:
82		Key(variable, path)
83	{
84		variable->AcquireReference();
85		path->AcquireReference();
86	}
87
88	~InfoEntry()
89	{
90		variable->ReleaseReference();
91		path->ReleaseReference();
92	}
93
94	void SetInfo(const VariablesViewNodeInfo& info)
95	{
96		VariablesViewNodeInfo::operator=(info);
97	}
98};
99
100
101struct VariablesViewState::InfoEntryHashDefinition {
102	typedef Key			KeyType;
103	typedef	InfoEntry	ValueType;
104
105	size_t HashKey(const Key& key) const
106	{
107		return key.HashValue();
108	}
109
110	size_t Hash(const InfoEntry* value) const
111	{
112		return value->HashValue();
113	}
114
115	bool Compare(const Key& key, const InfoEntry* value) const
116	{
117		return key == *value;
118	}
119
120	InfoEntry*& GetLink(InfoEntry* value) const
121	{
122		return value->next;
123	}
124};
125
126
127VariablesViewState::VariablesViewState()
128	:
129	fNodeInfos(NULL),
130	fValues(NULL)
131{
132}
133
134
135VariablesViewState::~VariablesViewState()
136{
137	_Cleanup();
138}
139
140
141status_t
142VariablesViewState::Init()
143{
144	fNodeInfos = new(std::nothrow) NodeInfoTable;
145	if (fNodeInfos == NULL)
146		return B_NO_MEMORY;
147
148	return fNodeInfos->Init();
149}
150
151void
152VariablesViewState::SetValues(StackFrameValues* values)
153{
154	if (fValues == values)
155		return;
156
157	if (fValues != NULL)
158		fValues->ReleaseReference();
159
160	fValues = values;
161
162	if (fValues != NULL)
163		fValues->AcquireReference();
164}
165
166
167const VariablesViewNodeInfo*
168VariablesViewState::GetNodeInfo(ObjectID* variable,
169	const TypeComponentPath* path) const
170{
171	return fNodeInfos->Lookup(Key(variable, (TypeComponentPath*)path));
172}
173
174
175status_t
176VariablesViewState::SetNodeInfo(ObjectID* variable, TypeComponentPath* path,
177	const VariablesViewNodeInfo& info)
178{
179	InfoEntry* entry = fNodeInfos->Lookup(Key(variable, path));
180	if (entry == NULL) {
181		entry = new(std::nothrow) InfoEntry(variable, path);
182		if (entry == NULL)
183			return B_NO_MEMORY;
184		fNodeInfos->Insert(entry);
185	}
186
187	entry->SetInfo(info);
188	return B_OK;
189}
190
191
192void
193VariablesViewState::_Cleanup()
194{
195	if (fNodeInfos != NULL) {
196		InfoEntry* entry = fNodeInfos->Clear(true);
197
198		while (entry != NULL) {
199			InfoEntry* next = entry->next;
200			delete entry;
201			entry = next;
202		}
203
204		delete fNodeInfos;
205		fNodeInfos = NULL;
206	}
207
208	SetValues(NULL);
209}
210