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.
This commit is contained in:
Rene Gollent
2016-12-05 18:18:09 -05:00
parent 445f00371c
commit eede6646dd
11 changed files with 524 additions and 0 deletions
+12
View File
@@ -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
@@ -0,0 +1,17 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "ConnectionConfigHandler.h"
ConnectionConfigHandler::ConnectionConfigHandler(const char* name)
:
fName(name)
{
}
ConnectionConfigHandler::~ConnectionConfigHandler()
{
}
@@ -0,0 +1,32 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef CONNECTION_CONFIG_HANDLER_H
#define CONNECTION_CONFIG_HANDLER_H
#include <String.h>
#include <SupportDefs.h>
#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
@@ -0,0 +1,135 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "ConnectionConfigHandlerRoster.h"
#include <AutoDeleter.h>
#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<ConnectionConfigHandlerRoster> 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<ConnectionConfigHandler> 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;
}
@@ -0,0 +1,55 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef CONNECTION_CONFIG_HANDLER_ROSTER_H
#define CONNECTION_CONFIG_HANDLER_ROSTER_H
#include <Locker.h>
#include <ObjectList.h>
#include <String.h>
#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<ConnectionConfigHandler> 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
@@ -0,0 +1,42 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* 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()
{
}
@@ -0,0 +1,45 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef CONNECTION_CONFIG_VIEW_H
#define CONNECTION_CONFIG_VIEW_H
#include <View.h>
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
@@ -0,0 +1,44 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "NetworkConnectionConfigHandler.h"
#include <AutoDeleter.h>
#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<BView> 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;
}
@@ -0,0 +1,22 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* 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
@@ -0,0 +1,87 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* Distributed under the terms of the MIT License.
*/
#include "NetworkConnectionConfigView.h"
#include <LayoutBuilder.h>
#include <MenuField.h>
#include <TextControl.h>
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;
}
@@ -0,0 +1,33 @@
/*
* Copyright 2016, Rene Gollent, [email protected].
* 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