/* * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. * Distributed under the terms of the MIT License. */ #include "ValueHandlerRoster.h" #include #include #include #include "AddressValueHandler.h" #include "BoolValueHandler.h" #include "EnumerationValueHandler.h" #include "FloatValueHandler.h" #include "StringValueHandler.h" #include "Value.h" /*static*/ ValueHandlerRoster* ValueHandlerRoster::sDefaultInstance = NULL; ValueHandlerRoster::ValueHandlerRoster() : fLock("value handler roster"), fValueHandlers(20, false) { } ValueHandlerRoster::~ValueHandlerRoster() { for(int32 i = 0; ValueHandler* handler = fValueHandlers.ItemAt(i); i++) handler->ReleaseReference(); } /*static*/ ValueHandlerRoster* ValueHandlerRoster::Default() { return sDefaultInstance; } /*static*/ status_t ValueHandlerRoster::CreateDefault() { if (sDefaultInstance != NULL) return B_OK; ValueHandlerRoster* roster = new(std::nothrow) ValueHandlerRoster; if (roster == NULL) return B_NO_MEMORY; ObjectDeleter rosterDeleter(roster); status_t error = roster->Init(); if (error != B_OK) return error; error = roster->RegisterDefaultHandlers(); if (error != B_OK) return error; sDefaultInstance = rosterDeleter.Detach(); return B_OK; } /*static*/ void ValueHandlerRoster::DeleteDefault() { ValueHandlerRoster* roster = sDefaultInstance; sDefaultInstance = NULL; delete roster; } status_t ValueHandlerRoster::Init() { return fLock.InitCheck(); } status_t ValueHandlerRoster::RegisterDefaultHandlers() { status_t error; #undef REGISTER_HANDLER #define REGISTER_HANDLER(name) \ { \ name##ValueHandler* handler \ = new(std::nothrow) name##ValueHandler; \ if (handler == NULL) \ return B_NO_MEMORY; \ BReference handlerReference(handler, true); \ \ error = handler->Init(); \ if (error != B_OK) \ return error; \ \ if (!RegisterHandler(handler)) \ return B_NO_MEMORY; \ } REGISTER_HANDLER(Address) REGISTER_HANDLER(Bool) REGISTER_HANDLER(Enumeration) REGISTER_HANDLER(Float) REGISTER_HANDLER(Integer) REGISTER_HANDLER(String) return B_OK; } status_t ValueHandlerRoster::FindValueHandler(Value* value, ValueHandler*& _handler) { // find the best-supporting handler AutoLocker locker(fLock); ValueHandler* bestHandler = NULL; float bestSupport = 0; for (int32 i = 0; ValueHandler* handler = fValueHandlers.ItemAt(i); i++) { float support = handler->SupportsValue(value); if (support > 0 && support > bestSupport) { bestHandler = handler; bestSupport = support; } } if (bestHandler == NULL) return B_ENTRY_NOT_FOUND; bestHandler->AcquireReference(); _handler = bestHandler; return B_OK; } status_t ValueHandlerRoster::GetValueFormatter(Value* value, ValueFormatter*& _formatter) { // get the best supporting value handler ValueHandler* handler; status_t error = FindValueHandler(value, handler); if (error != B_OK) return error; BReference handlerReference(handler, true); // create the formatter return handler->GetValueFormatter(value, _formatter); } status_t ValueHandlerRoster::GetTableCellValueRenderer(Value* value, TableCellValueRenderer*& _renderer) { // get the best supporting value handler ValueHandler* handler; status_t error = FindValueHandler(value, handler); if (error != B_OK) return error; BReference handlerReference(handler, true); // create the renderer return handler->GetTableCellValueRenderer(value, _renderer); } bool ValueHandlerRoster::RegisterHandler(ValueHandler* handler) { if (!fValueHandlers.AddItem(handler)) return false; handler->AcquireReference(); return true; } void ValueHandlerRoster::UnregisterHandler(ValueHandler* handler) { if (fValueHandlers.RemoveItem(handler)) handler->ReleaseReference(); }