Replace UpdateObserver with UpdateController class which uses signal/slot notifications using the sigslot library.

This commit is contained in:
Robert Knight 2012-05-04 16:04:19 +01:00
parent 932cddfb77
commit d69b8288ee
15 changed files with 2608 additions and 48 deletions

View File

@ -12,6 +12,7 @@ option(SIGN_UPDATER OFF)
include_directories(external) include_directories(external)
include_directories(external/TinyThread/source) include_directories(external/TinyThread/source)
include_directories(external/sigslot/)
if (WIN32) if (WIN32)
include_directories(external/zlib/) include_directories(external/zlib/)

2507
external/sigslot/sigslot.h vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -31,6 +31,7 @@ set (SOURCES
Log.cpp Log.cpp
ProcessUtils.cpp ProcessUtils.cpp
StandardDirs.cpp StandardDirs.cpp
UpdateController.cpp
UpdateInstaller.cpp UpdateInstaller.cpp
UpdateScript.cpp UpdateScript.cpp
UpdaterOptions.cpp UpdaterOptions.cpp
@ -65,6 +66,7 @@ set (HEADERS
Log.h Log.h
ProcessUtils.h ProcessUtils.h
StandardDirs.h StandardDirs.h
UpdateController.h
UpdateInstaller.h UpdateInstaller.h
UpdateScript.h UpdateScript.h
UpdaterOptions.h UpdaterOptions.h

6
src/UpdateController.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "UpdateController.h"
UpdateController::UpdateController()
{
}

23
src/UpdateController.h Normal file
View File

@ -0,0 +1,23 @@
#pragma once
#include <sigslot.h>
/** Controller used by the UI to drive the installation
* and monitor the status of the install.
*/
class UpdateController
{
public:
UpdateController();
/** Emitted to indicate progress of update installation. */
sigslot::signal1<int> installProgress;
/** Emitted when installation fails for any reason. */
sigslot::signal1<const std::string&> installError;
/** Emitted when installation completes, whether successfully or
* following an unrecoverable error.
*/
sigslot::signal0<> finished;
};

View File

@ -1,22 +1,23 @@
#pragma once #pragma once
#include "UpdateObserver.h" #include <sigslot.h>
class UpdateDialogPrivate; class UpdateDialogPrivate;
class UpdateController;
class UpdateDialogCocoa : public UpdateObserver class UpdateDialogCocoa : public sigslot::has_slots<>
{ {
public: public:
UpdateDialogCocoa(); UpdateDialogCocoa(UpdateController* controller);
~UpdateDialogCocoa(); ~UpdateDialogCocoa();
void init(); void init();
void exec(); void exec();
// implements UpdateObserver // slots for update notifications
virtual void updateError(const std::string& errorMessage); void updateError(const std::string& errorMessage);
virtual void updateProgress(int percentage); void updateProgress(int percentage);
virtual void updateFinished(); void updateFinished();
static void* createAutoreleasePool(); static void* createAutoreleasePool();
static void releaseAutoreleasePool(void* data); static void releaseAutoreleasePool(void* data);

View File

@ -6,6 +6,7 @@
#include "AppInfo.h" #include "AppInfo.h"
#include "Log.h" #include "Log.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "UpdateController.h"
@interface UpdateDialogDelegate : NSObject @interface UpdateDialogDelegate : NSObject
{ {
@ -78,9 +79,13 @@ class UpdateDialogPrivate
} }
@end @end
UpdateDialogCocoa::UpdateDialogCocoa() UpdateDialogCocoa::UpdateDialogCocoa(UpdateController* controller)
: d(new UpdateDialogPrivate) : d(new UpdateDialogPrivate)
{ {
controller->installProgress.connect(this, &UpdateDialogCocoa::updateProgress);
controller->installError.connect(this, &UpdateDialogCocoa::updateError);
controller->finished.connect(this, &UpdateDialogCocoa::updateFinished);
[NSApplication sharedApplication]; [NSApplication sharedApplication];
d->pool = [[NSAutoreleasePool alloc] init]; d->pool = [[NSAutoreleasePool alloc] init];
} }

View File

@ -1,11 +1,10 @@
#pragma once #pragma once
#include "UpdateMessage.h" #include "UpdateMessage.h"
#include "UpdateObserver.h"
#include <gtk/gtk.h> #include <gtk/gtk.h>
class UpdateDialogGtk : public UpdateObserver class UpdateDialogGtk
{ {
public: public:
UpdateDialogGtk(); UpdateDialogGtk();
@ -15,9 +14,9 @@ class UpdateDialogGtk : public UpdateObserver
// observer callbacks - these may be called // observer callbacks - these may be called
// from a background thread // from a background thread
virtual void updateError(const std::string& errorMessage); void updateError(const std::string& errorMessage);
virtual void updateProgress(int percentage); void updateProgress(int percentage);
virtual void updateFinished(); void updateFinished();
private: private:
static void finish(GtkWidget* widget, gpointer dialog); static void finish(GtkWidget* widget, gpointer dialog);

View File

@ -2,6 +2,7 @@
#include "Log.h" #include "Log.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "UpdateController.h"
#include <dlfcn.h> #include <dlfcn.h>
#include <errno.h> #include <errno.h>
@ -41,9 +42,12 @@ bool extractFileFromBinary(const char* path, const void* buffer, size_t length)
return true; return true;
} }
UpdateDialogGtkWrapper::UpdateDialogGtkWrapper() UpdateDialogGtkWrapper::UpdateDialogGtkWrapper(UpdateController* controller)
: m_dialog(0) : m_dialog(0)
{ {
controller->installProgress.connect(this, &UpdateDialogGtkWrapper::updateProgress);
controller->installError.connect(this, &UpdateDialogGtkWrapper::updateError);
controller->finished.connect(this, &UpdateDialogGtkWrapper::updateFinished);
} }
bool UpdateDialogGtkWrapper::init(int argc, char** argv) bool UpdateDialogGtkWrapper::init(int argc, char** argv)

View File

@ -1,14 +1,15 @@
#pragma once #pragma once
#include "UpdateObserver.h" #include <sigslot.h>
class UpdateDialogGtk; class UpdateDialogGtk;
class UpdateController;
/** A wrapper around UpdateDialogGtk which allows the GTK UI to /** A wrapper around UpdateDialogGtk which allows the GTK UI to
* be loaded dynamically at runtime if the GTK libraries are * be loaded dynamically at runtime if the GTK libraries are
* available. * available.
*/ */
class UpdateDialogGtkWrapper : public UpdateObserver class UpdateDialogGtkWrapper : public sigslot::has_slots<>
{ {
public: public:
UpdateDialogGtkWrapper(); UpdateDialogGtkWrapper();
@ -20,9 +21,9 @@ class UpdateDialogGtkWrapper : public UpdateObserver
bool init(int argc, char** argv); bool init(int argc, char** argv);
void exec(); void exec();
virtual void updateError(const std::string& errorMessage); void updateError(const std::string& errorMessage);
virtual void updateProgress(int percentage); void updateProgress(int percentage);
virtual void updateFinished(); void updateFinished();
private: private:
UpdateDialogGtk* m_dialog; UpdateDialogGtk* m_dialog;

View File

@ -1,5 +1,6 @@
#include "UpdateDialogWin32.h" #include "UpdateDialogWin32.h"
#include "UpdateController.h"
#include "AppInfo.h" #include "AppInfo.h"
#include "Log.h" #include "Log.h"
@ -58,9 +59,13 @@ void registerWindowClass()
RegisterClassEx(&wcex); RegisterClassEx(&wcex);
} }
UpdateDialogWin32::UpdateDialogWin32() UpdateDialogWin32::UpdateDialogWin32(UpdateController* controller)
: m_hadError(false) : m_hadError(false)
{ {
controller->installProgress.connect(this, &UpdateDialogWin32::updateProgress);
controller->installError.connect(this, &UpdateDialogWin32::updateError);
controller->finished.connect(this, &UpdateDialogWin32::updateFinished);
registerWindowClass(); registerWindowClass();
} }

View File

@ -2,25 +2,28 @@
#include "Platform.h" #include "Platform.h"
#include "UpdateMessage.h" #include "UpdateMessage.h"
#include "UpdateObserver.h"
#include "wincore.h" #include "wincore.h"
#include "controls.h" #include "controls.h"
#include "stdcontrols.h" #include "stdcontrols.h"
class UpdateDialogWin32 : public UpdateObserver #include <sigslot.h>
class UpdateController;
class UpdateDialogWin32 : public has_slots<>
{ {
public: public:
UpdateDialogWin32(); UpdateDialogWin32(UpdateController* controller);
~UpdateDialogWin32(); ~UpdateDialogWin32();
void init(); void init();
void exec(); void exec();
// implements UpdateObserver // implements UpdateObserver
virtual void updateError(const std::string& errorMessage); void updateError(const std::string& errorMessage);
virtual void updateProgress(int percentage); void updateProgress(int percentage);
virtual void updateFinished(); void updateFinished();
LRESULT WINAPI windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam); LRESULT WINAPI windowProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam);

View File

@ -4,13 +4,13 @@
#include "FileUtils.h" #include "FileUtils.h"
#include "Log.h" #include "Log.h"
#include "ProcessUtils.h" #include "ProcessUtils.h"
#include "UpdateObserver.h" #include "UpdateController.h"
UpdateInstaller::UpdateInstaller() UpdateInstaller::UpdateInstaller()
: m_mode(Setup) : m_mode(Setup)
, m_waitPid(0) , m_waitPid(0)
, m_script(0) , m_script(0)
, m_observer(0) , m_controller(0)
, m_forceElevated(false) , m_forceElevated(false)
{ {
} }
@ -64,10 +64,10 @@ std::list<std::string> UpdateInstaller::updaterArgs() const
void UpdateInstaller::reportError(const std::string& error) void UpdateInstaller::reportError(const std::string& error)
{ {
if (m_observer) if (m_controller)
{ {
m_observer->updateError(error); m_controller->installError.emit(error);
m_observer->updateFinished(); m_controller->finished.emit();
} }
} }
@ -213,19 +213,19 @@ void UpdateInstaller::run() throw ()
LOG(Error,"Error reverting partial update " + std::string(exception.what())); LOG(Error,"Error reverting partial update " + std::string(exception.what()));
} }
if (m_observer) if (m_controller)
{ {
if (friendlyError.empty()) if (friendlyError.empty())
{ {
friendlyError = error; friendlyError = error;
} }
m_observer->updateError(friendlyError); m_controller->installError.emit(friendlyError);
} }
} }
if (m_observer) if (m_controller)
{ {
m_observer->updateFinished(); m_controller->finished.emit();
} }
} }
} }
@ -319,11 +319,11 @@ void UpdateInstaller::installFiles()
{ {
installFile(*iter); installFile(*iter);
++filesInstalled; ++filesInstalled;
if (m_observer) if (m_controller)
{ {
int toInstallCount = static_cast<int>(m_script->filesToInstall().size()); int toInstallCount = static_cast<int>(m_script->filesToInstall().size());
double percentage = ((1.0 * filesInstalled) / toInstallCount) * 100.0; double percentage = ((1.0 * filesInstalled) / toInstallCount) * 100.0;
m_observer->updateProgress(static_cast<int>(percentage)); m_controller->installProgress.emit(static_cast<int>(percentage));
} }
} }
} }
@ -395,9 +395,9 @@ bool UpdateInstaller::checkAccess()
} }
} }
void UpdateInstaller::setObserver(UpdateObserver* observer) void UpdateInstaller::setController(UpdateController* controller)
{ {
m_observer = observer; m_controller = controller;
} }
void UpdateInstaller::restartMainApp() void UpdateInstaller::restartMainApp()

View File

@ -8,7 +8,7 @@
#include <string> #include <string>
#include <map> #include <map>
class UpdateObserver; class UpdateController;
/** Central class responsible for installing updates, /** Central class responsible for installing updates,
* launching an elevated copy of the updater if required * launching an elevated copy of the updater if required
@ -33,7 +33,7 @@ class UpdateInstaller
void setWaitPid(PLATFORM_PID pid); void setWaitPid(PLATFORM_PID pid);
void setForceElevated(bool elevated); void setForceElevated(bool elevated);
void setObserver(UpdateObserver* observer); void setController(UpdateController* controller);
void run() throw (); void run() throw ();
@ -61,7 +61,7 @@ class UpdateInstaller
std::string m_backupDir; std::string m_backupDir;
PLATFORM_PID m_waitPid; PLATFORM_PID m_waitPid;
UpdateScript* m_script; UpdateScript* m_script;
UpdateObserver* m_observer; UpdateController* m_controller;
std::map<std::string,std::string> m_backups; std::map<std::string,std::string> m_backups;
bool m_forceElevated; bool m_forceElevated;
}; };

View File

@ -4,6 +4,7 @@
#include "Platform.h" #include "Platform.h"
#include "ProcessUtils.h" #include "ProcessUtils.h"
#include "StringUtils.h" #include "StringUtils.h"
#include "UpdateController.h"
#include "UpdateScript.h" #include "UpdateScript.h"
#include "UpdaterOptions.h" #include "UpdaterOptions.h"
@ -164,17 +165,18 @@ int main(int argc, char** argv)
#ifdef PLATFORM_LINUX #ifdef PLATFORM_LINUX
void runWithUi(int argc, char** argv, UpdateInstaller* installer) void runWithUi(int argc, char** argv, UpdateInstaller* installer)
{ {
UpdateDialogAscii asciiDialog; UpdateController updateController;
UpdateDialogGtkWrapper dialog; UpdateDialogAscii asciiDialog(&updateController);
UpdateDialogGtkWrapper dialog(&updateController);
bool useGtk = dialog.init(argc,argv); bool useGtk = dialog.init(argc,argv);
if (useGtk) if (useGtk)
{ {
installer->setObserver(&dialog); installer->setController(&dialog);
} }
else else
{ {
asciiDialog.init(); asciiDialog.init();
installer->setObserver(&asciiDialog); installer->setController(&asciiDialog);
} }
tthread::thread updaterThread(runUpdaterThread,installer); tthread::thread updaterThread(runUpdaterThread,installer);
if (useGtk) if (useGtk)
@ -188,8 +190,9 @@ void runWithUi(int argc, char** argv, UpdateInstaller* installer)
#ifdef PLATFORM_MAC #ifdef PLATFORM_MAC
void runWithUi(int argc, char** argv, UpdateInstaller* installer) void runWithUi(int argc, char** argv, UpdateInstaller* installer)
{ {
UpdateDialogCocoa dialog; UpdateController updateController;
installer->setObserver(&dialog); UpdateDialogCocoa dialog(&updateController);
installer->setController(&updateController);
dialog.init(); dialog.init();
tthread::thread updaterThread(runUpdaterThread,installer); tthread::thread updaterThread(runUpdaterThread,installer);
dialog.exec(); dialog.exec();