Skip to content

Commit

Permalink
libdeng2|libgui: Application subsystems and GuiApp's refresh
Browse files Browse the repository at this point in the history
Any number of subsystems can be added to an App.

GuiApp will advance clock time as often as possible (unless a larger
interval requested).
  • Loading branch information
skyjake committed Feb 17, 2013
1 parent 9ce0ca8 commit d8322f5
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 4 deletions.
29 changes: 28 additions & 1 deletion doomsday/libdeng2/include/de/core/app.h
Expand Up @@ -25,6 +25,7 @@
#include "../CommandLine"
#include "../NativePath"
#include "../LogBuffer"
#include "../System"
#include "../FS"
#include "../Module"
#include "../Config"
Expand All @@ -47,7 +48,7 @@ class Archive;
*
* @see GuiApp, TextApp
*/
class DENG2_PUBLIC App
class DENG2_PUBLIC App : DENG2_OBSERVES(Clock, TimeChange)
{
public:
/// The object or resource that was being looked for was not found. @ingroup errors
Expand Down Expand Up @@ -88,6 +89,24 @@ class DENG2_PUBLIC App
*/
void initSubsystems(SubsystemInitFlags flags = DefaultSubsystems);

/**
* Adds a system to the application. The order of systems is preserved; the
* system added last will be notified of time changes last and will receive
* input events last (if others don't eat them).
*
* @param system System. Ownership kept by caller. The caller is
* responsible for making sure the system has been
* initialized properly.
*/
void addSystem(System &system);

/**
* Removes a system from the application.
*
* @param system System to remove.
*/
void removeSystem(System &system);

/**
* Adds a native module to the set of modules that can be imported in
* scripts.
Expand Down Expand Up @@ -225,6 +244,14 @@ class DENG2_PUBLIC App
*/
void handleUncaughtException(String message);

/**
* Events received from the operating system should be passed here; the
* application will make sure all subsystems get a chance to process them.
*/
virtual bool processEvent(Event const &);

void timeChanged(Clock const &);

protected:
/**
* Returns the native path of the directory where the application can store
Expand Down
43 changes: 43 additions & 0 deletions doomsday/libdeng2/src/core/app.cpp
Expand Up @@ -57,6 +57,9 @@ DENG2_PIMPL(App), DENG2_OBSERVES(Record, Deletion)
/// Primary (wall) clock.
Clock clock;

/// Subsystems (not owned).
QList<System *> systems;

/// The file system.
FS fs;

Expand Down Expand Up @@ -91,6 +94,8 @@ DENG2_PIMPL(App), DENG2_OBSERVES(Record, Deletion)

~Instance()
{
clock.audienceForTimeChange -= &self;

DENG2_FOR_EACH(NativeModules, i, nativeModules)
{
i.value()->audienceForDeletion -= this;
Expand Down Expand Up @@ -244,6 +249,30 @@ void App::handleUncaughtException(String message)
if(d->terminateFunc) d->terminateFunc(message.toUtf8().constData());
}

bool App::processEvent(Event const &ev)
{
foreach(System *sys, d->systems)
{
if(sys->behavior() & System::ReceivesInputEvents)
{
if(sys->processEvent(ev))
return true;
}
}
return false;
}

void App::timeChanged(Clock const &clock)
{
foreach(System *sys, d->systems)
{
if(sys->behavior() & System::ObservesTime)
{
sys->timeChanged(clock);
}
}
}

NativePath App::nativePluginBinaryPath()
{
if(!d->cachedPluginBinaryPath.isEmpty()) return d->cachedPluginBinaryPath;
Expand Down Expand Up @@ -391,9 +420,23 @@ void App::initSubsystems(SubsystemInitFlags flags)
// Update the wall clock time.
d->clock.setTime(Time());

// Now we can start observing progress of time.
d->clock.audienceForTimeChange += this;

LOG_VERBOSE("libdeng2::App %s subsystems initialized.") << Version().asText();
}

void App::addSystem(System &system)
{
d->systems.removeAll(&system);
d->systems.append(&system);
}

void App::removeSystem(System &system)
{
d->systems.removeAll(&system);
}

void App::addNativeModule(String const &name, Record &module)
{
d->nativeModules.insert(name, &module);
Expand Down
3 changes: 3 additions & 0 deletions doomsday/libgui/include/de/gui/guiapp.h
Expand Up @@ -68,6 +68,9 @@ class LIBGUI_PUBLIC GuiApp : public QApplication, public App
/// Emitted when the display mode has changed.
void displayModeChanged();

protected slots:
void refresh();

private:
struct Instance;
Instance *d;
Expand Down
27 changes: 25 additions & 2 deletions doomsday/libgui/src/guiapp.cpp
Expand Up @@ -18,19 +18,28 @@

#include "de/GuiApp"
#include <de/Log>
#include <de/math.h>

#include <QTimer>
#include <QDesktopServices>

namespace de {

struct GuiApp::Instance
DENG2_PIMPL(GuiApp)
{
TimeDelta refreshInterval;
bool loopRunning;

Instance(Public *i) : Base(*i),
refreshInterval(0),
loopRunning(false)
{}
};

GuiApp::GuiApp(int &argc, char **argv)
: QApplication(argc, argv),
App(applicationFilePath(), arguments()),
d(new Instance)
d(new Instance(this))
{}

GuiApp::~GuiApp()
Expand Down Expand Up @@ -62,14 +71,28 @@ void GuiApp::notifyDisplayModeChanged()

int GuiApp::execLoop()
{
d->loopRunning = true;
return QApplication::exec();
}

void GuiApp::stopLoop(int code)
{
d->loopRunning = false;
return QApplication::exit(code);
}

void GuiApp::refresh()
{
if(!d->loopRunning) return;

// Update the clock time. App listens to this clock and will inform
// subsystems in the order they've been added in.
Clock::appClock().setTime(Time());

// Schedule the next refresh.
QTimer::singleShot(de::max(duint64(1), d->refreshInterval.asMilliSeconds()), this, SLOT(refresh()));
}

NativePath GuiApp::appDataPath() const
{
return QDesktopServices::storageLocation(QDesktopServices::DataLocation);
Expand Down
1 change: 0 additions & 1 deletion doomsday/tools/shell/shell-gui/src/qtguiapp.cpp
Expand Up @@ -65,4 +65,3 @@ bool QtGuiApp::notify(QObject *receiver, QEvent *event)
}
return false;
}

0 comments on commit d8322f5

Please sign in to comment.