xref: /haiku/src/apps/debugger/user_interface/gui/value/ValueHandlerRoster.cpp (revision 5d0fd0e4220b461e2021d5768ebaa936c13417f8)
1 /*
2  * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Distributed under the terms of the MIT License.
4  */
5 
6 
7 #include "ValueHandlerRoster.h"
8 
9 #include <new>
10 
11 #include <AutoDeleter.h>
12 #include <AutoLocker.h>
13 
14 #include "AddressValueHandler.h"
15 #include "BoolValueHandler.h"
16 #include "EnumerationValueHandler.h"
17 #include "FloatValueHandler.h"
18 #include "StringValueHandler.h"
19 #include "Value.h"
20 
21 
22 /*static*/ ValueHandlerRoster* ValueHandlerRoster::sDefaultInstance = NULL;
23 
24 
25 ValueHandlerRoster::ValueHandlerRoster()
26 	:
27 	fLock("value handler roster"),
28 	fValueHandlers(20, false)
29 {
30 }
31 
32 
33 ValueHandlerRoster::~ValueHandlerRoster()
34 {
35 	for(int32 i = 0; ValueHandler* handler = fValueHandlers.ItemAt(i); i++)
36 		handler->ReleaseReference();
37 }
38 
39 /*static*/ ValueHandlerRoster*
40 ValueHandlerRoster::Default()
41 {
42 	return sDefaultInstance;
43 }
44 
45 
46 /*static*/ status_t
47 ValueHandlerRoster::CreateDefault()
48 {
49 	if (sDefaultInstance != NULL)
50 		return B_OK;
51 
52 	ValueHandlerRoster* roster = new(std::nothrow) ValueHandlerRoster;
53 	if (roster == NULL)
54 		return B_NO_MEMORY;
55 	ObjectDeleter<ValueHandlerRoster> rosterDeleter(roster);
56 
57 	status_t error = roster->Init();
58 	if (error != B_OK)
59 		return error;
60 
61 	error = roster->RegisterDefaultHandlers();
62 	if (error != B_OK)
63 		return error;
64 
65 	sDefaultInstance = rosterDeleter.Detach();
66 	return B_OK;
67 }
68 
69 
70 /*static*/ void
71 ValueHandlerRoster::DeleteDefault()
72 {
73 	ValueHandlerRoster* roster = sDefaultInstance;
74 	sDefaultInstance = NULL;
75 	delete roster;
76 }
77 
78 
79 status_t
80 ValueHandlerRoster::Init()
81 {
82 	return fLock.InitCheck();
83 }
84 
85 
86 status_t
87 ValueHandlerRoster::RegisterDefaultHandlers()
88 {
89 	status_t error;
90 
91 	#undef REGISTER_HANDLER
92 	#define REGISTER_HANDLER(name)											\
93 		{																	\
94 			name##ValueHandler* handler										\
95 				= new(std::nothrow) name##ValueHandler;						\
96 			if (handler == NULL)											\
97 				return B_NO_MEMORY;											\
98 			BReference<name##ValueHandler> handlerReference(handler, true);	\
99 																			\
100 			error = handler->Init();										\
101 			if (error != B_OK)												\
102 				return error;												\
103 																			\
104 			if (!RegisterHandler(handler))									\
105 				return B_NO_MEMORY;											\
106 		}
107 
108 	REGISTER_HANDLER(Address)
109 	REGISTER_HANDLER(Bool)
110 	REGISTER_HANDLER(Enumeration)
111 	REGISTER_HANDLER(Float)
112 	REGISTER_HANDLER(Integer)
113 	REGISTER_HANDLER(String)
114 
115 	return B_OK;
116 }
117 
118 
119 status_t
120 ValueHandlerRoster::FindValueHandler(Value* value, ValueHandler*& _handler)
121 {
122 	// find the best-supporting handler
123 	AutoLocker<BLocker> locker(fLock);
124 
125 	ValueHandler* bestHandler = NULL;
126 	float bestSupport = 0;
127 
128 	for (int32 i = 0; ValueHandler* handler = fValueHandlers.ItemAt(i); i++) {
129 		float support = handler->SupportsValue(value);
130 		if (support > 0 && support > bestSupport) {
131 			bestHandler = handler;
132 			bestSupport = support;
133 		}
134 	}
135 
136 	if (bestHandler == NULL)
137 		return B_ENTRY_NOT_FOUND;
138 
139 	bestHandler->AcquireReference();
140 	_handler = bestHandler;
141 	return B_OK;
142 }
143 
144 
145 status_t
146 ValueHandlerRoster::GetValueFormatter(Value* value,
147 	ValueFormatter*& _formatter)
148 {
149 	// get the best supporting value handler
150 	ValueHandler* handler;
151 	status_t error = FindValueHandler(value, handler);
152 	if (error != B_OK)
153 		return error;
154 	BReference<ValueHandler> handlerReference(handler, true);
155 
156 	// create the formatter
157 	return handler->GetValueFormatter(value, _formatter);
158 }
159 
160 
161 status_t
162 ValueHandlerRoster::GetTableCellValueRenderer(Value* value,
163 	TableCellValueRenderer*& _renderer)
164 {
165 	// get the best supporting value handler
166 	ValueHandler* handler;
167 	status_t error = FindValueHandler(value, handler);
168 	if (error != B_OK)
169 		return error;
170 	BReference<ValueHandler> handlerReference(handler, true);
171 
172 	// create the renderer
173 	return handler->GetTableCellValueRenderer(value, _renderer);
174 }
175 
176 
177 bool
178 ValueHandlerRoster::RegisterHandler(ValueHandler* handler)
179 {
180 	if (!fValueHandlers.AddItem(handler))
181 		return false;
182 
183 	handler->AcquireReference();
184 	return true;
185 }
186 
187 
188 void
189 ValueHandlerRoster::UnregisterHandler(ValueHandler* handler)
190 {
191 	if (fValueHandlers.RemoveItem(handler))
192 		handler->ReleaseReference();
193 }
194