Skip to content

Commit

Permalink
Debugger: Refactor SettingsManager.
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
anevilyak committed Jun 4, 2016
1 parent 0957c82 commit 5c8ba74
Show file tree
Hide file tree
Showing 9 changed files with 342 additions and 240 deletions.
15 changes: 3 additions & 12 deletions src/apps/debugger/Debugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -295,7 +295,7 @@ class Debugger : public BApplication,
status_t _HandleOptions(const Options& options);

private:
SettingsManager fSettingsManager;
DebuggerSettingsManager fSettingsManager;
TeamsWindow* fTeamsWindow;
StartTeamWindow* fStartTeamWindow;
};
Expand Down Expand Up @@ -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: "
Expand Down Expand Up @@ -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);
Expand All @@ -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;
Expand Down
2 changes: 2 additions & 0 deletions src/apps/debugger/Jamfile
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,8 @@ local sources =

# settings
BreakpointSetting.cpp
DebuggerSettingsManager.cpp
NoOpSettingsManager.cpp
SettingsManager.cpp
TeamFileManagerSettings.cpp
TeamSettings.cpp
Expand Down
9 changes: 9 additions & 0 deletions src/apps/debugger/controllers/TeamDebugger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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();
Expand Down
212 changes: 212 additions & 0 deletions src/apps/debugger/settings/DebuggerSettingsManager.cpp
Original file line number Diff line number Diff line change
@@ -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;
}
50 changes: 50 additions & 0 deletions src/apps/debugger/settings/DebuggerSettingsManager.h
Original file line number Diff line number Diff line change
@@ -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
36 changes: 36 additions & 0 deletions src/apps/debugger/settings/NoOpSettingsManager.cpp
Original file line number Diff line number Diff line change
@@ -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 comments on commit 5c8ba74

Please sign in to comment.