Debugger: Refactor SettingsManager.

- SettingsManager is now a pure virtual interface. The debugger core provides
  a no-op implementation of it which is used by default if no explicit manager
  is provided by the client requesting a new TeamDebugger. This allows consumers
  of the debugger core that have no need for settings persistence such as the
  report generator to not have to care about that particular detail at all.
- Add subclass DebuggerSettingsManager which is essentially the previous
  existing implementation. This one will go with the application portion
  of the Debugger once the separation of app and lib has been completed.
  Adjust callers accordingly.
This commit is contained in:
Rene Gollent
2016-06-04 13:18:35 -04:00
parent 0957c8215e
commit 5c8ba745e5
9 changed files with 342 additions and 240 deletions
+3 -12
View File
@@ -26,12 +26,12 @@
#include "CoreFileDebuggerInterface.h"
#include "CommandLineUserInterface.h"
#include "DebuggerInterface.h"
#include "DebuggerSettingsManager.h"
#include "DebuggerUiSettingsFactory.h"
#include "GraphicalUserInterface.h"
#include "ImageDebugLoadingStateHandlerRoster.h"
#include "MessageCodes.h"
#include "ReportUserInterface.h"
#include "SettingsManager.h"
#include "SignalSet.h"
#include "StartTeamWindow.h"
#include "TargetHostInterface.h"
@@ -295,7 +295,7 @@ private:
status_t _HandleOptions(const Options& options);
private:
SettingsManager fSettingsManager;
DebuggerSettingsManager fSettingsManager;
TeamsWindow* fTeamsWindow;
StartTeamWindow* fStartTeamWindow;
};
@@ -661,7 +661,7 @@ CliDebugger::Run(const Options& options)
return false;
}
SettingsManager settingsManager;
DebuggerSettingsManager settingsManager;
error = settingsManager.Init(DebuggerUiSettingsFactory::Default());
if (error != B_OK) {
fprintf(stderr, "Error: Settings manager initialization failed: "
@@ -729,14 +729,6 @@ ReportDebugger::Run(const Options& options)
return false;
}
SettingsManager settingsManager;
error = settingsManager.Init(DebuggerUiSettingsFactory::Default());
if (error != B_OK) {
fprintf(stderr, "Error: Settings manager initialization failed: "
"%s\n", strerror(error));
return false;
}
// create the report UI
ReportUserInterface* userInterface
= new(std::nothrow) ReportUserInterface(options.thread, options.reportPath);
@@ -752,7 +744,6 @@ ReportDebugger::Run(const Options& options)
TeamDebuggerOptions debuggerOptions;
set_debugger_options_from_options(debuggerOptions, options);
debuggerOptions.userInterface = userInterface;
debuggerOptions.settingsManager = &settingsManager;
error = hostInterface->StartTeamDebugger(debuggerOptions);
if (error != B_OK)
return false;
+2
View File
@@ -217,6 +217,8 @@ local sources =
# settings
BreakpointSetting.cpp
DebuggerSettingsManager.cpp
NoOpSettingsManager.cpp
SettingsManager.cpp
TeamFileManagerSettings.cpp
TeamSettings.cpp
@@ -40,6 +40,7 @@
#include "Jobs.h"
#include "LocatableFile.h"
#include "MessageCodes.h"
#include "NoOpSettingsManager.h"
#include "SettingsManager.h"
#include "SourceCode.h"
#include "SourceLanguage.h"
@@ -335,6 +336,14 @@ TeamDebugger::Init(DebuggerInterface* interface, thread_id threadID, int argc,
if (error != B_OK)
return error;
if (fSettingsManager == NULL) {
// if we have not been provided with a settings manager,
// simply use the no-op manager by default.
fSettingsManager = new(std::nothrow) NoOpSettingsManager;
if (fSettingsManager == NULL)
return B_NO_MEMORY;
}
fDebuggerInterface = interface;
fDebuggerInterface->AcquireReference();
fTeamID = interface->TeamID();
@@ -0,0 +1,212 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "DebuggerSettingsManager.h"
#include <new>
#include <Directory.h>
#include <File.h>
#include <FindDirectory.h>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include "TeamSettings.h"
static const char* const kSettingsDirPath = "Debugger";
static const char* const kGlobalSettingsName = "Global";
static const int32 kMaxRecentTeamSettings = 10;
DebuggerSettingsManager::DebuggerSettingsManager()
:
SettingsManager(),
fLock("settings manager"),
fRecentTeamSettings(kMaxRecentTeamSettings, true),
fUiSettingsFactory(NULL)
{
}
DebuggerSettingsManager::~DebuggerSettingsManager()
{
_Unset();
}
status_t
DebuggerSettingsManager::Init(TeamUiSettingsFactory* factory)
{
// check the lock
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
fUiSettingsFactory = factory;
// get and create our settings directory
if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath, true) == B_OK
&& fSettingsPath.Append(kSettingsDirPath) == B_OK
&& create_directory(fSettingsPath.Path(), 0700) == B_OK
&& fSettingsPath.Append(kGlobalSettingsName) == B_OK) {
// load the settings
_LoadSettings();
} else {
// something went wrong -- clear the path
fSettingsPath.Unset();
}
return B_OK;
}
status_t
DebuggerSettingsManager::LoadTeamSettings(const char* teamName, TeamSettings& settings)
{
AutoLocker<BLocker> locker(fLock);
int32 index = _TeamSettingsIndex(teamName);
if (index < 0)
return B_ENTRY_NOT_FOUND;
try {
settings = *fRecentTeamSettings.ItemAt(index);
return B_OK;
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
}
status_t
DebuggerSettingsManager::SaveTeamSettings(const TeamSettings& _settings)
{
AutoLocker<BLocker> locker(fLock);
TeamSettings* settings;
int32 index = _TeamSettingsIndex(_settings.TeamName());
if (index >= 0) {
settings = fRecentTeamSettings.RemoveItemAt(index);
} else {
settings = new(std::nothrow) TeamSettings;
if (settings == NULL)
return B_NO_MEMORY;
// enforce recent limit
while (fRecentTeamSettings.CountItems() >= kMaxRecentTeamSettings)
delete fRecentTeamSettings.RemoveItemAt(0);
}
ObjectDeleter<TeamSettings> settingsDeleter(settings);
try {
*settings = _settings;
if (!fRecentTeamSettings.AddItem(settings))
return B_NO_MEMORY;
settingsDeleter.Detach();
return _SaveSettings();
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
}
void
DebuggerSettingsManager::_Unset()
{
fRecentTeamSettings.MakeEmpty();
}
status_t
DebuggerSettingsManager::_LoadSettings()
{
_Unset();
if (fSettingsPath.Path() == NULL)
return B_ENTRY_NOT_FOUND;
// read the settings file
BFile file;
status_t error = file.SetTo(fSettingsPath.Path(), B_READ_ONLY);
if (error != B_OK)
return error;
BMessage archive;
error = archive.Unflatten(&file);
if (error != B_OK)
return error;
// unarchive the recent team settings
BMessage childArchive;
for (int32 i = 0; archive.FindMessage("teamSettings", i, &childArchive)
== B_OK; i++) {
TeamSettings* settings = new(std::nothrow) TeamSettings;
if (settings == NULL)
return B_NO_MEMORY;
error = settings->SetTo(childArchive, *fUiSettingsFactory);
if (error != B_OK) {
delete settings;
continue;
}
if (!fRecentTeamSettings.AddItem(settings)) {
delete settings;
return B_NO_MEMORY;
}
}
return B_OK;
}
status_t
DebuggerSettingsManager::_SaveSettings()
{
if (fSettingsPath.Path() == NULL)
return B_ENTRY_NOT_FOUND;
// archive the recent team settings
BMessage archive;
for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
i++) {
BMessage childArchive;
status_t error = settings->WriteTo(childArchive);
if (error != B_OK)
return error;
error = archive.AddMessage("teamSettings", &childArchive);
if (error != B_OK)
return error;
}
// open the settings file
BFile file;
status_t error = file.SetTo(fSettingsPath.Path(),
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (error != B_OK)
return error;
return archive.Flatten(&file);
}
int32
DebuggerSettingsManager::_TeamSettingsIndex(const char* teamName) const
{
for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
i++) {
if (settings->TeamName() == teamName)
return i;
}
return -1;
}
@@ -0,0 +1,50 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef DEBUGGER_SETTINGS_MANAGER_H
#define DEBUGGER_SETTINGS_MANAGER_H
#include "SettingsManager.h"
#include <Locker.h>
#include <Path.h>
#include <ObjectList.h>
class TeamUiSettingsFactory;
class DebuggerSettingsManager : public SettingsManager {
public:
DebuggerSettingsManager();
~DebuggerSettingsManager();
status_t Init(TeamUiSettingsFactory* factory);
virtual status_t LoadTeamSettings(const char* teamName,
TeamSettings& settings);
virtual status_t SaveTeamSettings(const TeamSettings& settings);
private:
typedef BObjectList<TeamSettings> TeamSettingsList;
private:
void _Unset();
status_t _LoadSettings();
status_t _SaveSettings();
int32 _TeamSettingsIndex(const char* teamName) const;
private:
BLocker fLock;
BPath fSettingsPath;
TeamSettingsList fRecentTeamSettings; // oldest is first
TeamUiSettingsFactory* fUiSettingsFactory;
};
#endif // DEBUGGER_SETTINGS_MANAGER_H
@@ -0,0 +1,36 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include "NoOpSettingsManager.h"
NoOpSettingsManager::NoOpSettingsManager()
:
SettingsManager()
{
}
NoOpSettingsManager::~NoOpSettingsManager()
{
}
status_t
NoOpSettingsManager::LoadTeamSettings(const char* teamName,
TeamSettings& settings)
{
return B_OK;
}
status_t
NoOpSettingsManager::SaveTeamSettings(const TeamSettings& settings)
{
return B_OK;
}
@@ -0,0 +1,23 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef NOOP_SETTINGS_MANAGER_H
#define NOOP_SETTINGS_MANAGER_H
#include "SettingsManager.h"
class NoOpSettingsManager : public SettingsManager {
public:
NoOpSettingsManager();
virtual ~NoOpSettingsManager();
virtual status_t LoadTeamSettings(const char* teamName,
TeamSettings& settings);
virtual status_t SaveTeamSettings(const TeamSettings& settings);
};
#endif // NOOP_SETTINGS_MANAGER_H
@@ -3,208 +3,9 @@
* Distributed under the terms of the MIT License.
*/
#include "SettingsManager.h"
#include <new>
#include <Directory.h>
#include <File.h>
#include <FindDirectory.h>
#include <AutoDeleter.h>
#include <AutoLocker.h>
#include "TeamSettings.h"
static const char* const kSettingsDirPath = "Debugger";
static const char* const kGlobalSettingsName = "Global";
static const int32 kMaxRecentTeamSettings = 10;
SettingsManager::SettingsManager()
:
fLock("settings manager"),
fRecentTeamSettings(kMaxRecentTeamSettings, true),
fUiSettingsFactory(NULL)
{
}
SettingsManager::~SettingsManager()
{
_Unset();
}
status_t
SettingsManager::Init(TeamUiSettingsFactory* factory)
{
// check the lock
status_t error = fLock.InitCheck();
if (error != B_OK)
return error;
fUiSettingsFactory = factory;
// get and create our settings directory
if (find_directory(B_USER_SETTINGS_DIRECTORY, &fSettingsPath, true) == B_OK
&& fSettingsPath.Append(kSettingsDirPath) == B_OK
&& create_directory(fSettingsPath.Path(), 0700) == B_OK
&& fSettingsPath.Append(kGlobalSettingsName) == B_OK) {
// load the settings
_LoadSettings();
} else {
// something went wrong -- clear the path
fSettingsPath.Unset();
}
return B_OK;
}
status_t
SettingsManager::LoadTeamSettings(const char* teamName, TeamSettings& settings)
{
AutoLocker<BLocker> locker(fLock);
int32 index = _TeamSettingsIndex(teamName);
if (index < 0)
return B_ENTRY_NOT_FOUND;
try {
settings = *fRecentTeamSettings.ItemAt(index);
return B_OK;
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
}
status_t
SettingsManager::SaveTeamSettings(const TeamSettings& _settings)
{
AutoLocker<BLocker> locker(fLock);
TeamSettings* settings;
int32 index = _TeamSettingsIndex(_settings.TeamName());
if (index >= 0) {
settings = fRecentTeamSettings.RemoveItemAt(index);
} else {
settings = new(std::nothrow) TeamSettings;
if (settings == NULL)
return B_NO_MEMORY;
// enforce recent limit
while (fRecentTeamSettings.CountItems() >= kMaxRecentTeamSettings)
delete fRecentTeamSettings.RemoveItemAt(0);
}
ObjectDeleter<TeamSettings> settingsDeleter(settings);
try {
*settings = _settings;
if (!fRecentTeamSettings.AddItem(settings))
return B_NO_MEMORY;
settingsDeleter.Detach();
return _SaveSettings();
} catch (std::bad_alloc) {
return B_NO_MEMORY;
}
}
void
SettingsManager::_Unset()
{
fRecentTeamSettings.MakeEmpty();
}
status_t
SettingsManager::_LoadSettings()
{
_Unset();
if (fSettingsPath.Path() == NULL)
return B_ENTRY_NOT_FOUND;
// read the settings file
BFile file;
status_t error = file.SetTo(fSettingsPath.Path(), B_READ_ONLY);
if (error != B_OK)
return error;
BMessage archive;
error = archive.Unflatten(&file);
if (error != B_OK)
return error;
// unarchive the recent team settings
BMessage childArchive;
for (int32 i = 0; archive.FindMessage("teamSettings", i, &childArchive)
== B_OK; i++) {
TeamSettings* settings = new(std::nothrow) TeamSettings;
if (settings == NULL)
return B_NO_MEMORY;
error = settings->SetTo(childArchive, *fUiSettingsFactory);
if (error != B_OK) {
delete settings;
continue;
}
if (!fRecentTeamSettings.AddItem(settings)) {
delete settings;
return B_NO_MEMORY;
}
}
return B_OK;
}
status_t
SettingsManager::_SaveSettings()
{
if (fSettingsPath.Path() == NULL)
return B_ENTRY_NOT_FOUND;
// archive the recent team settings
BMessage archive;
for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
i++) {
BMessage childArchive;
status_t error = settings->WriteTo(childArchive);
if (error != B_OK)
return error;
error = archive.AddMessage("teamSettings", &childArchive);
if (error != B_OK)
return error;
}
// open the settings file
BFile file;
status_t error = file.SetTo(fSettingsPath.Path(),
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (error != B_OK)
return error;
return archive.Flatten(&file);
}
int32
SettingsManager::_TeamSettingsIndex(const char* teamName) const
{
for (int32 i = 0; TeamSettings* settings = fRecentTeamSettings.ItemAt(i);
i++) {
if (settings->TeamName() == teamName)
return i;
}
return -1;
}
+7 -29
View File
@@ -1,48 +1,26 @@
/*
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
* Copyright 2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#ifndef SETTINGS_MANAGER_H
#define SETTINGS_MANAGER_H
#include <Locker.h>
#include <Path.h>
#include <ObjectList.h>
#include <SupportDefs.h>
class TeamSettings;
class TeamUiSettingsFactory;
class SettingsManager {
public:
SettingsManager();
~SettingsManager();
virtual ~SettingsManager();
status_t Init(TeamUiSettingsFactory* factory);
status_t LoadTeamSettings(const char* teamName,
TeamSettings& settings);
status_t SaveTeamSettings(const TeamSettings& settings);
private:
typedef BObjectList<TeamSettings> TeamSettingsList;
private:
void _Unset();
status_t _LoadSettings();
status_t _SaveSettings();
int32 _TeamSettingsIndex(const char* teamName) const;
private:
BLocker fLock;
BPath fSettingsPath;
TeamSettingsList fRecentTeamSettings; // oldest is first
TeamUiSettingsFactory* fUiSettingsFactory;
virtual status_t LoadTeamSettings(const char* teamName,
TeamSettings& settings) = 0;
virtual status_t SaveTeamSettings(const TeamSettings& settings)
= 0;
};