From eede6646dd548b5fe56d9305f1d6fb2b650e26c3 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Sun, 4 Dec 2016 14:19:42 -0500 Subject: [PATCH] Debugger: Add connection config handler framework. ConnectionConfigHandler: - Abstract base class for the different types of connection that allows one to retrieve an appropriate configuration view based on the target host interface type. This will allow the configuration window to switch dynamically between network, USB, etc. without having to know the details of any of those. Initially only a network subclass has been implemented though. ConnectionConfigHandlerRoster: - Keeps track of the list of available config handlers, and handles mapping a request for a given interface info to the appropriate type of handler. ConnectionConfigView: - Abstract base class for the actual configuration views returned by the config handlers. This exposes a listener interface via which the view can notify an interested party that the configuration has been changed. Correspondingly, the configuration window will use this to determine if the configuration is complete enough to allow a connection attempt. --- src/apps/debugger/Jamfile | 12 ++ .../ConnectionConfigHandler.cpp | 17 +++ .../ConnectionConfigHandler.h | 32 +++++ .../ConnectionConfigHandlerRoster.cpp | 135 ++++++++++++++++++ .../ConnectionConfigHandlerRoster.h | 55 +++++++ .../ConnectionConfigView.cpp | 42 ++++++ .../connection_config/ConnectionConfigView.h | 45 ++++++ .../NetworkConnectionConfigHandler.cpp | 44 ++++++ .../NetworkConnectionConfigHandler.h | 22 +++ .../NetworkConnectionConfigView.cpp | 87 +++++++++++ .../NetworkConnectionConfigView.h | 33 +++++ 11 files changed, 524 insertions(+) create mode 100644 src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.cpp create mode 100644 src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.h create mode 100644 src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.cpp create mode 100644 src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.h create mode 100644 src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.cpp create mode 100644 src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.h create mode 100644 src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.cpp create mode 100644 src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.h create mode 100644 src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.cpp create mode 100644 src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index e7cb812426..f218e26f62 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -38,6 +38,9 @@ SEARCH_SOURCE += [ FDirName $(SUBDIR) settings ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface cli ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface cli commands ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui connection_config ] ; +SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui connection_config + config_handlers ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui expression_eval_window ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui inspector_window ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) user_interface gui model ] ; @@ -85,6 +88,15 @@ local sources = # user_interface/gui GraphicalUserInterface.cpp + # user_interface/gui/connection_config + ConnectionConfigHandler.cpp + ConnectionConfigHandlerRoster.cpp + ConnectionConfigView.cpp + + # user_interface/gui/connection_config/config_handlers + NetworkConnectionConfigHandler.cpp + NetworkConnectionConfigView.cpp + # user_interface/gui/model VariablesViewState.cpp VariablesViewStateHistory.cpp diff --git a/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.cpp b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.cpp new file mode 100644 index 0000000000..d6380a8313 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.cpp @@ -0,0 +1,17 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "ConnectionConfigHandler.h" + + +ConnectionConfigHandler::ConnectionConfigHandler(const char* name) + : + fName(name) +{ +} + + +ConnectionConfigHandler::~ConnectionConfigHandler() +{ +} diff --git a/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.h b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.h new file mode 100644 index 0000000000..adbb6a839a --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandler.h @@ -0,0 +1,32 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef CONNECTION_CONFIG_HANDLER_H +#define CONNECTION_CONFIG_HANDLER_H + +#include +#include + +#include "ConnectionConfigView.h" + + +class TargetHostInterfaceInfo; + + +class ConnectionConfigHandler { +public: + ConnectionConfigHandler(const char* name); + virtual ~ConnectionConfigHandler(); + + const BString& Name() const { return fName; } + + virtual status_t CreateView(TargetHostInterfaceInfo* info, + ConnectionConfigView::Listener* listener, + ConnectionConfigView*& _view) = 0; +private: + BString fName; +}; + + +#endif // CONNECTION_CONFIG_HANDLER_H diff --git a/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.cpp b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.cpp new file mode 100644 index 0000000000..fbd2f7a67a --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.cpp @@ -0,0 +1,135 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "ConnectionConfigHandlerRoster.h" + +#include + +#include "NetworkConnectionConfigHandler.h" +#include "TargetHostInterfaceInfo.h" + + +/*static*/ ConnectionConfigHandlerRoster* + ConnectionConfigHandlerRoster::sDefaultInstance = NULL; + + +ConnectionConfigHandlerRoster::ConnectionConfigHandlerRoster() + : + fLock("config handler roster lock"), + fConfigHandlers(10, true) +{ +} + + +ConnectionConfigHandlerRoster::~ConnectionConfigHandlerRoster() +{ +} + + +/*static*/ ConnectionConfigHandlerRoster* +ConnectionConfigHandlerRoster::Default() +{ + return sDefaultInstance; +} + + +/*static*/ status_t +ConnectionConfigHandlerRoster::CreateDefault() +{ + if (sDefaultInstance != NULL) + return B_OK; + + ConnectionConfigHandlerRoster* roster + = new(std::nothrow) ConnectionConfigHandlerRoster; + if (roster == NULL) + return B_NO_MEMORY; + + ObjectDeleter rosterDeleter(roster); + + status_t error = roster->Init(); + if (error != B_OK) + return error; + + sDefaultInstance = roster; + rosterDeleter.Detach(); + return B_OK; +} + + +/*static*/ void +ConnectionConfigHandlerRoster::DeleteDefault() +{ + ConnectionConfigHandlerRoster* roster = sDefaultInstance; + sDefaultInstance = NULL; + delete roster; +} + + +status_t +ConnectionConfigHandlerRoster::Init() +{ + return _RegisterHandlers(); +} + + +bool +ConnectionConfigHandlerRoster::HasHandlerFor(TargetHostInterfaceInfo* info) + const +{ + ConnectionConfigHandler* handler = NULL; + return _GetHandler(info->Name(), handler); +} + + +status_t +ConnectionConfigHandlerRoster::CreateConfigView(TargetHostInterfaceInfo* info, + ConnectionConfigView::Listener* listener, + ConnectionConfigView*& _view) const +{ + ConnectionConfigHandler* handler = NULL; + + if (!_GetHandler(info->Name(), handler)) + return B_NOT_SUPPORTED; + + return handler->CreateView(info, listener, _view); +} + + +bool +ConnectionConfigHandlerRoster::_GetHandler(const BString& name, + ConnectionConfigHandler*& _handler) const +{ + ConnectionConfigHandler* handler = NULL; + for (int32 i = 0; i < fConfigHandlers.CountItems(); i++) { + handler = fConfigHandlers.ItemAt(i); + if (handler->Name() == name) { + _handler = handler; + return true; + } + } + + return false; +} + + +status_t +ConnectionConfigHandlerRoster::_RegisterHandlers() +{ + ConnectionConfigHandler* handler = NULL; + ObjectDeleter handlerDeleter; + + #undef REGISTER_HANDLER_INFO + #define REGISTER_HANDLER_INFO(type) \ + handler = new(std::nothrow) type##ConnectionConfigHandler; \ + if (handler == NULL) \ + return B_NO_MEMORY; \ + handlerDeleter.SetTo(handler); \ + if (!fConfigHandlers.AddItem(handler)) \ + return B_NO_MEMORY; \ + handlerDeleter.Detach(); \ + + REGISTER_HANDLER_INFO(Network) + + return B_OK; +} diff --git a/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.h b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.h new file mode 100644 index 0000000000..524ffe70f4 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigHandlerRoster.h @@ -0,0 +1,55 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef CONNECTION_CONFIG_HANDLER_ROSTER_H +#define CONNECTION_CONFIG_HANDLER_ROSTER_H + +#include +#include +#include + +#include "ConnectionConfigView.h" + + +class ConnectionConfigHandler; +class TargetHostInterfaceInfo; + + +class ConnectionConfigHandlerRoster { +public: + ConnectionConfigHandlerRoster(); + virtual ~ConnectionConfigHandlerRoster(); + + static ConnectionConfigHandlerRoster* Default(); + static status_t CreateDefault(); + static void DeleteDefault(); + + bool Lock() { return fLock.Lock(); } + void Unlock() { fLock.Unlock(); } + + status_t Init(); + + bool HasHandlerFor(TargetHostInterfaceInfo* info) + const; + + status_t CreateConfigView(TargetHostInterfaceInfo* info, + ConnectionConfigView::Listener* listener, + ConnectionConfigView*& _view) const; + +private: + typedef BObjectList HandlerList; + +private: + bool _GetHandler(const BString& name, + ConnectionConfigHandler*& _handler) const; + status_t _RegisterHandlers(); + +private: + BLocker fLock; + static ConnectionConfigHandlerRoster* sDefaultInstance; + + HandlerList fConfigHandlers; +}; + +#endif // CONNECTION_CONFIG_HANDLER_ROSTER_H diff --git a/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.cpp b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.cpp new file mode 100644 index 0000000000..b3e220f837 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.cpp @@ -0,0 +1,42 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "ConnectionConfigView.h" + + +ConnectionConfigView::ConnectionConfigView(const char* name) + : + BView(name, B_WILL_DRAW) +{ +} + + +ConnectionConfigView::~ConnectionConfigView() +{ +} + + +status_t +ConnectionConfigView::Init(TargetHostInterfaceInfo* info, Listener* listener) +{ + fInfo = info; + fListener = listener; + + return InitSpecific(); +} + + +void +ConnectionConfigView::NotifyConfigurationChanged(Settings* settings) +{ + fListener->ConfigurationChanged(settings); +} + + +// #pragma mark - ConnectionConfigView::Listener + + +ConnectionConfigView::Listener::~Listener() +{ +} diff --git a/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.h b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.h new file mode 100644 index 0000000000..431a62f013 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/ConnectionConfigView.h @@ -0,0 +1,45 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef CONNECTION_CONFIG_VIEW_H +#define CONNECTION_CONFIG_VIEW_H + +#include + + +class Settings; +class TargetHostInterfaceInfo; + + +class ConnectionConfigView : public BView { +public: + class Listener; + ConnectionConfigView(const char* name); + virtual ~ConnectionConfigView(); + + status_t Init(TargetHostInterfaceInfo* info, + Listener* listener); + +protected: + TargetHostInterfaceInfo* InterfaceInfo() const + { return fInfo; } + void NotifyConfigurationChanged(Settings* settings); + + virtual status_t InitSpecific() = 0; + +private: + TargetHostInterfaceInfo* fInfo; + Listener* fListener; +}; + + +class ConnectionConfigView::Listener { +public: + virtual ~Listener(); + + virtual void ConfigurationChanged(Settings* settings) = 0; +}; + + +#endif // CONNECTION_CONFIG_VIEW_H diff --git a/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.cpp b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.cpp new file mode 100644 index 0000000000..e488f4b26a --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "NetworkConnectionConfigHandler.h" + +#include + +#include "NetworkConnectionConfigView.h" +#include "TargetHostInterfaceInfo.h" + + + +NetworkConnectionConfigHandler::NetworkConnectionConfigHandler() + : + ConnectionConfigHandler("Network") +{ +} + + +NetworkConnectionConfigHandler::~NetworkConnectionConfigHandler() +{ +} + + +status_t +NetworkConnectionConfigHandler::CreateView(TargetHostInterfaceInfo* info, + ConnectionConfigView::Listener* listener, ConnectionConfigView*& _view) +{ + NetworkConnectionConfigView* view = NULL; + try { + view = new NetworkConnectionConfigView; + ObjectDeleter viewDeleter(view); + status_t error = view->Init(info, listener); + if (error != B_OK) + return error; + viewDeleter.Detach(); + } catch (...) { + return B_NO_MEMORY; + } + + _view = view; + return B_OK; +} diff --git a/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.h b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.h new file mode 100644 index 0000000000..8dad20dc86 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigHandler.h @@ -0,0 +1,22 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef NETWORK_CONNECTION_CONFIG_HANDLER_H +#define NETWORK_CONNECTION_CONFIG_HANDLER_H + +#include "ConnectionConfigHandler.h" + + +class NetworkConnectionConfigHandler : public ConnectionConfigHandler { +public: + NetworkConnectionConfigHandler(); + virtual ~NetworkConnectionConfigHandler(); + + virtual status_t CreateView(TargetHostInterfaceInfo* info, + ConnectionConfigView::Listener* listener, + ConnectionConfigView*& _view); +}; + + +#endif // NETWORK_CONNECTION_CONFIG_HANDLER_H diff --git a/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.cpp b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.cpp new file mode 100644 index 0000000000..2ad736499a --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.cpp @@ -0,0 +1,87 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#include "NetworkConnectionConfigView.h" + +#include +#include +#include + + +enum { + MSG_NET_CONFIG_INPUT_CHANGED = 'ncic' +}; + + +NetworkConnectionConfigView::NetworkConnectionConfigView() + : + ConnectionConfigView("NetworkConnectionConfig"), + fProtocolField(NULL), + fHostInput(NULL), + fPortInput(NULL) +{ +} + + +NetworkConnectionConfigView::~NetworkConnectionConfigView() +{ +} + + +void +NetworkConnectionConfigView::AttachedToWindow() +{ + ConnectionConfigView::AttachedToWindow(); + + fHostInput->SetTarget(this); + fPortInput->SetTarget(this); +} + + +void +NetworkConnectionConfigView::MessageReceived(BMessage* message) +{ + switch (message->what) { + case MSG_NET_CONFIG_INPUT_CHANGED: + { + // TODO: implement + break; + } + + default: + { + ConnectionConfigView::MessageReceived(message); + break; + } + } +} + + +status_t +NetworkConnectionConfigView::InitSpecific() +{ + fPortInput = new BTextControl("port_input", "Port:", "", + new BMessage(MSG_NET_CONFIG_INPUT_CHANGED)); + + BLayoutBuilder::Group<>(this, B_VERTICAL) + .AddGroup(B_HORIZONTAL) + .Add((fHostInput = new BTextControl("host_input", "Host:", "", + new BMessage(MSG_NET_CONFIG_INPUT_CHANGED)))) + .Add(fPortInput->CreateLabelLayoutItem()) + .Add(fPortInput->CreateTextViewLayoutItem()) + .End() + .End(); + + // since port numbers are limited to 5 digits, there's no need for + // the port input to expand farther than that. Instead, let the + // host field take the extra space. + fPortInput->CreateTextViewLayoutItem()->SetExplicitMaxSize(BSize( + be_plain_font->StringWidth("999999"), B_SIZE_UNSET)); + + // TODO: init settings and protocol input + + return B_OK; +} + + diff --git a/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.h b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.h new file mode 100644 index 0000000000..fd0e11b5b1 --- /dev/null +++ b/src/apps/debugger/user_interface/gui/connection_config/config_handlers/NetworkConnectionConfigView.h @@ -0,0 +1,33 @@ +/* + * Copyright 2016, Rene Gollent, rene@gollent.com. + * Distributed under the terms of the MIT License. + */ +#ifndef NETWORK_CONNECTION_CONFIG_VIEW_H +#define NETWORK_CONNECTION_CONFIG_VIEW_H + +#include "ConnectionConfigView.h" + + +class BMenuField; +class BTextControl; + + +class NetworkConnectionConfigView : public ConnectionConfigView{ +public: + NetworkConnectionConfigView(); + virtual ~NetworkConnectionConfigView(); + + virtual void AttachedToWindow(); + virtual void MessageReceived(BMessage* message); + +protected: + virtual status_t InitSpecific(); + +private: + BMenuField* fProtocolField; + BTextControl* fHostInput; + BTextControl* fPortInput; +}; + + +#endif // NETWORK_CONNECTION_CONFIG_VIEW_H