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