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