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 25ValueHandlerRoster::ValueHandlerRoster() 26 : 27 fLock("value handler roster"), 28 fValueHandlers(20, false) 29{ 30} 31 32 33ValueHandlerRoster::~ValueHandlerRoster() 34{ 35 for(int32 i = 0; ValueHandler* handler = fValueHandlers.ItemAt(i); i++) 36 handler->ReleaseReference(); 37} 38 39/*static*/ ValueHandlerRoster* 40ValueHandlerRoster::Default() 41{ 42 return sDefaultInstance; 43} 44 45 46/*static*/ status_t 47ValueHandlerRoster::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 71ValueHandlerRoster::DeleteDefault() 72{ 73 ValueHandlerRoster* roster = sDefaultInstance; 74 sDefaultInstance = NULL; 75 delete roster; 76} 77 78 79status_t 80ValueHandlerRoster::Init() 81{ 82 return fLock.InitCheck(); 83} 84 85 86status_t 87ValueHandlerRoster::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 119status_t 120ValueHandlerRoster::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 145status_t 146ValueHandlerRoster::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 161status_t 162ValueHandlerRoster::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 177bool 178ValueHandlerRoster::RegisterHandler(ValueHandler* handler) 179{ 180 if (!fValueHandlers.AddItem(handler)) 181 return false; 182 183 handler->AcquireReference(); 184 return true; 185} 186 187 188void 189ValueHandlerRoster::UnregisterHandler(ValueHandler* handler) 190{ 191 if (fValueHandlers.RemoveItem(handler)) 192 handler->ReleaseReference(); 193} 194