Skip to content

Commit

Permalink
Refactor: BusyMode class in libdoomsday, BusyRunner for the client
Browse files Browse the repository at this point in the history
BusyMode handles the basic mechanics of busy mode. It optionally hands
the tasks over to a ITaskRunner object, which in the client's case
starts the worker callback in a background thread.

DoomsdayApp owns the BusyMode instance, while ClientApp owns the
BusyRunner instance. The server uses the default BusyMode behavior.

The Busy API became almost fully obsolete: only the game freezing
function remains. Other functionality is available directly via
libdoomsday.
  • Loading branch information
skyjake committed Jul 18, 2015
1 parent 68f91a3 commit b2f5d1b
Show file tree
Hide file tree
Showing 27 changed files with 873 additions and 674 deletions.
93 changes: 2 additions & 91 deletions doomsday/apps/api/api_busy.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** @file api_busy.h Public API for the Busy Mode.
/** @file api_busy.h Public API for additional Busy Mode features.
* @ingroup base
*
* @authors Copyright &copy; 2007-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright &copy; 2007-2015 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright &copy; 2007-2013 Daniel Swanson <danij@dengine.net>
*
* @par License
Expand All @@ -24,105 +24,16 @@

#include "api_base.h"

/// Busy mode worker function.
typedef int (*busyworkerfunc_t) (void* parm);

/// POD structure for defining a task processable in busy mode.
typedef struct {
busyworkerfunc_t worker; ///< Worker thread that does processing while in busy mode.
void* workerData; ///< Data context for the worker thread.

int mode; ///< Busy mode flags @ref busyModeFlags
const char* name; ///< Optional task name (drawn with the progress bar).

/// Used with task lists:
int maxProgress;
float progressStart;
float progressEnd;

// Internal state:
timespan_t _startTime;
} BusyTask;

DENG_API_TYPEDEF(Busy)
{
de_api_t api;

/// @return @c true if we are currently busy.
dd_bool (*Active)(void);

/// @return Amount of time we have been busy (if not busy, @c 0).
timespan_t (*ElapsedTime)(void);

void (*FreezeGameForBusyMode)(void);

int (*RunTask)(BusyTask* task);

/**
* Process a list of work tasks in Busy Mode, from left to right sequentially.
* Tasks are worked on one at a time and execution of a task only begins once
* all earlier tasks have completed.
*
* Caller relinquishes ownership of the task list until busy mode completes,
* (therefore it should NOT be accessed in the worker).
*
* @param tasks List of tasks.
* @param numTasks Number of tasks.
*
* @return Return value for the worker(s).
*/
int (*RunTasks)(BusyTask* tasks, int numTasks);

/**
* Convenient shortcut method for constructing and then running of a single work
* task in Busy Mode.
*
* @param flags Busy mode flags @ref busyModeFlags
* @param worker Worker thread that does processing while in busy mode.
* @param workerData Data context for the worker thread.
*
* @return Return value of the worker.
*/
int (*RunNewTask)(int flags, busyworkerfunc_t worker, void* workerData);

/**
* Convenient shortcut method for constructing and then running of a single work
* task in Busy Mode.
*
* @param flags Busy mode flags @ref busyModeFlags
* @param worker Worker thread that does processing while in busy mode.
* @param workerData Data context for the worker thread.
* @param taskName Optional task name (drawn with the progress bar).
*
* @return Return value of the worker.
*/
int (*RunNewTaskWithName)(int flags, busyworkerfunc_t worker, void* workerData, const char* taskName);

/**
* To be called by the busy worker when it has finished processing, to signal
* the end of the task.
*/
void (*WorkerEnd)(void);

/**
* To be called by the busy worker to shutdown the engine immediately.
*
* @param message Message to show. Expected to exist until the engine closes.
*/
void (*WorkerError)(const char* message);
}
DENG_API_T(Busy);

#ifndef DENG_NO_API_MACROS_BUSY
#define BusyMode_Active _api_Busy.Active
#define BusyMode_ElapsedTime _api_Busy.ElapsedTime
#define BusyMode_FreezeGameForBusyMode _api_Busy.FreezeGameForBusyMode
#define BusyMode_RunTask _api_Busy.RunTask
#define BusyMode_RunTasks _api_Busy.RunTasks
#define BusyMode_RunNewTask _api_Busy.RunNewTask
#define BusyMode_RunNewTaskWithName _api_Busy.RunNewTaskWithName
#define BusyMode_WorkerEnd _api_Busy.WorkerEnd
#define BusyMode_WorkerError _api_Busy.WorkerError
#endif

#ifdef __DOOMSDAY__
Expand Down
3 changes: 2 additions & 1 deletion doomsday/apps/api/apis.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ enum {

DE_API_BUSY_v1 = 200, // 1.10
DE_API_BUSY_v2 = 201, // 1.13
DE_API_BUSY = DE_API_BUSY_v2,
DE_API_BUSY_v3 = 202, // 2.0
DE_API_BUSY = DE_API_BUSY_v3,

DE_API_CLIENT_v1 = 300, // 1.10
DE_API_CLIENT = DE_API_CLIENT_v1,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
/**
* @file busymode.h
* Busy Mode @ingroup core
* @file busyrunner.h Runs busy tasks in a background thread. @ingroup core
*
* The Busy Mode is intended for long-running tasks that would otherwise block
* the main engine (UI) thread. During busy mode, a progress screen is shown by
Expand All @@ -14,8 +13,8 @@
* regular application event loop. During busy mode, the game loop callback
* should not be called.
*
* @authors Copyright &copy; 2009-2013 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright &copy; 2009-2013 Daniel Swanson <danij@dengine.net>
* @authors Copyright &copy; 2009-2015 Jaakko Keränen <jaakko.keranen@iki.fi>
* @authors Copyright &copy; 2009-2015 Daniel Swanson <danij@dengine.net>
*
* @par License
* GPL: http://www.gnu.org/licenses/gpl.html
Expand All @@ -32,29 +31,50 @@
* 02110-1301 USA</small>
*/

#ifndef LIBDENG_CORE_BUSYMODE_H
#define LIBDENG_CORE_BUSYMODE_H
#ifndef CLIENT_BUSYRUNNER_H
#define CLIENT_BUSYRUNNER_H

#include "dd_share.h"
#include "api_busy.h"
#include <doomsday/busymode.h>

/// Enables or disables busy mode; if disabled, work is done synchronously
/// in the main thread.
void BusyMode_SetAllowed(dd_bool allow);
/**
* Runs busy tasks in a background thread.
*/
class BusyRunner : public BusyMode::ITaskRunner
{
public:
BusyRunner();

/**
* Enables or disables the busy mode background thread; if disabled, work is done
* synchronously in the main thread.
*/
void setAllowed(bool allow);

/// @return @c true if specified thread is the current busy task worker.
dd_bool BusyMode_IsWorkerThread(uint threadId);
bool isTransitionAnimated() const;
bool isWorkerThread(uint threadId) const;
bool inWorkerThread() const;

/// @return @c true if the current thread is the busy task worker.
dd_bool BusyMode_InWorkerThread(void);
/**
* Runs an event loop in the main thread during busy mode. This keeps the UI
* responsive while the background task runs the busy task.
*/
Result runTask(BusyTask *task) override;

#ifdef __CLIENT__
dd_bool BusyMode_IsTransitionAnimated(void);
#endif
void loop();

/// @return Current busy task, else @c NULL.
BusyTask* BusyMode_CurrentTask(void);
/**
* Called when the background thread has exited.
*/
void finishTask();

void BusyMode_Loop(void);
private:
DENG2_PRIVATE(d)
};

/**
* The busy loop callback function. Called periodically in the main (UI) thread
* while the busy worker is running.
*/
void BusyMode_Loop();

#endif // LIBDENG_CORE_BUSYMODE_H
#endif // CLIENT_BUSYRUNNER_H
2 changes: 2 additions & 0 deletions doomsday/apps/client/include/clientapp.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "render/rendersystem.h"
#include "resource/resourcesystem.h"
#include "updater.h"
#include "busyrunner.h"
#include "Games"
#include "world/worldsystem.h"

Expand Down Expand Up @@ -64,6 +65,7 @@ class ClientApp : public de::BaseGuiApp, public DoomsdayApp

public:
static ClientApp &app();
static BusyRunner &busyRunner();
static Updater &updater();
static SettingsRegister &logSettings();
static SettingsRegister &networkSettings();
Expand Down
2 changes: 1 addition & 1 deletion doomsday/apps/client/include/de_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
#include "dd_main.h"
#include "dd_loop.h"
#include "library.h"
#include "busymode.h"
#include "busyrunner.h"
#include "ui/ddevent.h"
#include "ui/nativeui.h"
#include "ui/zonedebug.h"
Expand Down
3 changes: 2 additions & 1 deletion doomsday/apps/client/src/audio/s_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#ifdef __CLIENT__
# include <de/concurrency.h>
#endif
#include <doomsday/doomsdayapp.h>
#include <doomsday/audio/logical.h>
#include <doomsday/console/cmd.h>
#include <doomsday/console/var.h>
Expand Down Expand Up @@ -244,7 +245,7 @@ int S_LocalSoundAtVolumeFrom(int soundIdAndFlags, mobj_t *origin, coord_t *point
{
#ifdef __CLIENT__
// A dedicated server never starts any local sounds (only logical sounds in the LSM).
if(isDedicated || BusyMode_Active())
if(isDedicated || DoomsdayApp::app().busyMode().isActive())
return false;

int soundId = (soundIdAndFlags & ~DDSF_FLAG_MASK);
Expand Down
Loading

0 comments on commit b2f5d1b

Please sign in to comment.