aboutsummaryrefslogtreecommitdiff
path: root/common/coroutines.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/coroutines.h')
-rw-r--r--common/coroutines.h203
1 files changed, 102 insertions, 101 deletions
diff --git a/common/coroutines.h b/common/coroutines.h
index f5519902dd..3b8b1a77f9 100644
--- a/common/coroutines.h
+++ b/common/coroutines.h
@@ -23,7 +23,7 @@
#define COMMON_COROUTINES_H
#include "common/scummsys.h"
-#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION
+#include "common/util.h" // for SCUMMVM_CURRENT_FUNCTION
#include "common/list.h"
#include "common/singleton.h"
@@ -133,42 +133,43 @@ public:
/**
* End the declaration of a coroutine context.
- * @param x name of the coroutine context
+ * @param x name of the coroutine context
* @see CORO_BEGIN_CONTEXT
*/
#define CORO_END_CONTEXT(x) } *x = (CoroContextTag *)coroParam
/**
* Begin the code section of a coroutine.
- * @param x name of the coroutine context
+ * @param x name of the coroutine context
* @see CORO_BEGIN_CODE
*/
#define CORO_BEGIN_CODE(x) \
- if (&coroParam == &Common::nullContext) assert(!Common::nullContext);\
- if (!x) {coroParam = x = new CoroContextTag();}\
- Common::CoroContextHolder tmpHolder(coroParam);\
- switch (coroParam->_line) { case 0:;
+ if (&coroParam == &Common::nullContext) assert(!Common::nullContext); \
+ if (!x) { coroParam = x = new CoroContextTag(); } \
+ Common::CoroContextHolder tmpHolder(coroParam); \
+ switch (coroParam->_line) { case 0:;
/**
* End the code section of a coroutine.
* @see CORO_END_CODE
*/
#define CORO_END_CODE \
- if (&coroParam == &Common::nullContext) { \
- delete Common::nullContext; \
- Common::nullContext = NULL; \
- } \
- }
+ if (&coroParam == &Common::nullContext) { \
+ delete Common::nullContext; \
+ Common::nullContext = NULL; \
+ } \
+ }
/**
* Sleep for the specified number of scheduler cycles.
*/
-#define CORO_SLEEP(delay) do {\
- coroParam->_line = __LINE__;\
- coroParam->_sleep = delay;\
- assert(&coroParam != &Common::nullContext);\
- return; case __LINE__:;\
- } while (0)
+#define CORO_SLEEP(delay) \
+ do { \
+ coroParam->_line = __LINE__; \
+ coroParam->_sleep = delay; \
+ assert(&coroParam != &Common::nullContext); \
+ return; case __LINE__:; \
+ } while (0)
#define CORO_GIVE_WAY do { CoroScheduler.giveWay(); CORO_SLEEP(1); } while (0)
#define CORO_RESCHEDULE do { CoroScheduler.reschedule(); CORO_SLEEP(1); } while (0)
@@ -182,7 +183,7 @@ public:
* then delete the entire coroutine's state, including all subcontexts).
*/
#define CORO_KILL_SELF() \
- do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0)
+ do { if (&coroParam != &Common::nullContext) { coroParam->_sleep = -1; } return; } while (0)
/**
@@ -201,8 +202,8 @@ public:
* If the subcontext is null, the coroutine ended normally, and we can
* simply break out of the loop and continue execution.
*
- * @param subCoro name of the coroutine-enabled function to invoke
- * @param ARGS list of arguments to pass to subCoro
+ * @param subCoro name of the coroutine-enabled function to invoke
+ * @param ARGS list of arguments to pass to subCoro
*
* @note ARGS must be surrounded by parentheses, and the first argument
* in this list must always be CORO_SUBCTX. For example, the
@@ -211,18 +212,18 @@ public:
* becomes the following:
* CORO_INVOKE_ARGS(myFunc, (CORO_SUBCTX, a, b));
*/
-#define CORO_INVOKE_ARGS(subCoro, ARGS) \
- do {\
- coroParam->_line = __LINE__;\
- coroParam->_subctx = 0;\
- do {\
- subCoro ARGS;\
- if (!coroParam->_subctx) break;\
- coroParam->_sleep = coroParam->_subctx->_sleep;\
- assert(&coroParam != &Common::nullContext);\
- return; case __LINE__:;\
- } while (1);\
- } while (0)
+#define CORO_INVOKE_ARGS(subCoro, ARGS) \
+ do { \
+ coroParam->_line = __LINE__; \
+ coroParam->_subctx = 0; \
+ do { \
+ subCoro ARGS; \
+ if (!coroParam->_subctx) break; \
+ coroParam->_sleep = coroParam->_subctx->_sleep; \
+ assert(&coroParam != &Common::nullContext); \
+ return; case __LINE__:; \
+ } while (1); \
+ } while (0)
/**
* Invoke another coroutine. Similar to CORO_INVOKE_ARGS,
@@ -230,62 +231,62 @@ public:
* if invoked coroutine yields (thus causing the current
* coroutine to yield, too).
*/
-#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \
- do {\
- coroParam->_line = __LINE__;\
- coroParam->_subctx = 0;\
- do {\
- subCoro ARGS;\
- if (!coroParam->_subctx) break;\
- coroParam->_sleep = coroParam->_subctx->_sleep;\
- assert(&coroParam != &Common::nullContext);\
- return RESULT; case __LINE__:;\
- } while (1);\
- } while (0)
+#define CORO_INVOKE_ARGS_V(subCoro, RESULT, ARGS) \
+ do { \
+ coroParam->_line = __LINE__; \
+ coroParam->_subctx = 0; \
+ do { \
+ subCoro ARGS; \
+ if (!coroParam->_subctx) break; \
+ coroParam->_sleep = coroParam->_subctx->_sleep; \
+ assert(&coroParam != &Common::nullContext); \
+ return RESULT; case __LINE__:; \
+ } while (1); \
+ } while (0)
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with no parameters.
*/
#define CORO_INVOKE_0(subCoroutine) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with one parameter.
*/
#define CORO_INVOKE_1(subCoroutine, a0) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with two parameters.
*/
#define CORO_INVOKE_2(subCoroutine, a0,a1) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with three parameters.
*/
#define CORO_INVOKE_3(subCoroutine, a0,a1,a2) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2))
/**
* Convenience wrapper for CORO_INVOKE_ARGS for invoking a coroutine
* with four parameters.
*/
#define CORO_INVOKE_4(subCoroutine, a0,a1,a2,a3) \
- CORO_INVOKE_ARGS(subCoroutine,(CORO_SUBCTX,a0,a1,a2,a3))
+ CORO_INVOKE_ARGS(subCoroutine, (CORO_SUBCTX, a0, a1, a2, a3))
// the size of process specific info
-#define CORO_PARAM_SIZE 32
+#define CORO_PARAM_SIZE 32
// the maximum number of processes
-#define CORO_NUM_PROCESS 100
-#define CORO_MAX_PROCESSES 100
+#define CORO_NUM_PROCESS 100
+#define CORO_MAX_PROCESSES 100
#define CORO_MAX_PID_WAITING 5
#define CORO_INFINITE 0xffffffff
@@ -296,16 +297,16 @@ typedef void (*CORO_ADDR)(CoroContext &, const void *);
/** process structure */
struct PROCESS {
- PROCESS *pNext; ///< pointer to next process in active or free list
- PROCESS *pPrevious; ///< pointer to previous process in active or free list
+ PROCESS *pNext; ///< pointer to next process in active or free list
+ PROCESS *pPrevious; ///< pointer to previous process in active or free list
- CoroContext state; ///< the state of the coroutine
- CORO_ADDR coroAddr; ///< the entry point of the coroutine
+ CoroContext state; ///< the state of the coroutine
+ CORO_ADDR coroAddr; ///< the entry point of the coroutine
- int sleepTime; ///< number of scheduler cycles to sleep
- uint32 pid; ///< process ID
- uint32 pidWaiting[CORO_MAX_PID_WAITING]; ///< Process ID(s) process is currently waiting on
- char param[CORO_PARAM_SIZE]; ///< process specific info
+ int sleepTime; ///< number of scheduler cycles to sleep
+ uint32 pid; ///< process ID
+ uint32 pidWaiting[CORO_MAX_PID_WAITING]; ///< Process ID(s) process is currently waiting on
+ char param[CORO_PARAM_SIZE]; ///< process specific info
};
typedef PROCESS *PPROCESS;
@@ -321,7 +322,7 @@ struct EVENT {
/**
* Creates and manages "processes" (really coroutines).
*/
-class CoroutineScheduler: public Singleton<CoroutineScheduler> {
+class CoroutineScheduler : public Singleton<CoroutineScheduler> {
public:
/** Pointer to a function of the form "void function(PPROCESS)" */
typedef void (*VFPTRPP)(PROCESS *);
@@ -355,7 +356,7 @@ private:
* Checks both the active and free process list to insure all the links are valid,
* and that no processes have been lost
*/
- void CheckStack();
+ void checkStack();
#endif
/**
@@ -382,12 +383,12 @@ public:
*/
void reset();
- #ifdef DEBUG
+#ifdef DEBUG
/**
* Shows the maximum number of process used at once.
*/
void printStats();
- #endif
+#endif
/**
* Give all active processes a chance to run
@@ -408,71 +409,71 @@ public:
/**
* Moves the specified process to the end of the dispatch queue
* allowing it to run again within the current game cycle.
- * @param pGiveProc Which process
+ * @param pGiveProc Which process
*/
void giveWay(PPROCESS pReSchedProc = NULL);
/**
* Continously makes a given process wait for another process to finish or event to signal.
*
- * @param pid Process/Event identifier
- * @param duration Duration in milliseconds
- * @param expired If specified, set to true if delay period expired
+ * @param pid Process/Event identifier
+ * @param duration Duration in milliseconds
+ * @param expired If specified, set to true if delay period expired
*/
void waitForSingleObject(CORO_PARAM, int pid, uint32 duration, bool *expired = NULL);
/**
* Continously makes a given process wait for given prcesses to finished or events to be set
*
- * @param nCount Number of Id's being passed
- * @param evtList List of pids to wait for
- * @param bWaitAll Specifies whether all or any of the processes/events
- * @param duration Duration in milliseconds
- * @param expired Set to true if delay period expired
+ * @param nCount Number of Id's being passed
+ * @param evtList List of pids to wait for
+ * @param bWaitAll Specifies whether all or any of the processes/events
+ * @param duration Duration in milliseconds
+ * @param expired Set to true if delay period expired
*/
- void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
- uint32 duration, bool *expired = NULL);
+ void waitForMultipleObjects(CORO_PARAM, int nCount, uint32 *pidList, bool bWaitAll,
+ uint32 duration, bool *expired = NULL);
/**
* Make the active process sleep for the given duration in milliseconds
*
- * @param duration Duration in milliseconds
- * @remarks This duration won't be precise, since it relies on the frequency the
+ * @param duration Duration in milliseconds
+ * @remarks This duration won't be precise, since it relies on the frequency the
* scheduler is called.
*/
void sleep(CORO_PARAM, uint32 duration);
-
+
/**
* Creates a new process.
*
- * @param pid process identifier
- * @param coroAddr Coroutine start address
- * @param pParam Process specific info
- * @param sizeParam Size of process specific info
+ * @param pid process identifier
+ * @param coroAddr Coroutine start address
+ * @param pParam Process specific info
+ * @param sizeParam Size of process specific info
*/
PROCESS *createProcess(uint32 pid, CORO_ADDR coroAddr, const void *pParam, int sizeParam);
/**
* Creates a new process with an auto-incrementing Process Id.
*
- * @param coroAddr Coroutine start address
- * @param pParam Process specific info
- * @param sizeParam Size of process specific info
+ * @param coroAddr Coroutine start address
+ * @param pParam Process specific info
+ * @param sizeParam Size of process specific info
*/
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam, int sizeParam);
/**
* Creates a new process with an auto-incrementing Process Id, and a single pointer parameter.
*
- * @param coroAddr Coroutine start address
- * @param pParam Process specific info
+ * @param coroAddr Coroutine start address
+ * @param pParam Process specific info
*/
uint32 createProcess(CORO_ADDR coroAddr, const void *pParam);
/**
* Kills the specified process.
*
- * @param pKillProc Which process to kill
+ * @param pKillProc Which process to kill
*/
void killProcess(PROCESS *pKillProc);
@@ -490,9 +491,9 @@ public:
* Kills any process matching the specified PID. The current
* process cannot be killed.
*
- * @param pidKill Process identifier of process to kill
- * @param pidMask Mask to apply to process identifiers before comparison
- * @return The number of processes killed is returned.
+ * @param pidKill Process identifier of process to kill
+ * @param pidMask Mask to apply to process identifiers before comparison
+ * @return The number of processes killed is returned.
*/
int killMatchingProcess(uint32 pidKill, int pidMask = -1);
@@ -503,7 +504,7 @@ public:
* called by killProcess() to allow the resource allocator to free
* resources allocated to the dying process.
*
- * @param pFunc Function to be called by killProcess()
+ * @param pFunc Function to be called by killProcess()
*/
void setResourceCallback(VFPTRPP pFunc);
@@ -511,29 +512,29 @@ public:
/**
* Creates a new event (semaphore) object
*
- * @param bManualReset Events needs to be manually reset. Otherwise,
+ * @param bManualReset Events needs to be manually reset. Otherwise,
* events will be automatically reset after a
* process waits on the event finishes
- * @param bInitialState Specifies whether the event is signalled or not
+ * @param bInitialState Specifies whether the event is signalled or not
* initially
*/
uint32 createEvent(bool bManualReset, bool bInitialState);
/**
* Destroys the given event
- * @param pidEvent Event Process Id
+ * @param pidEvent Event Process Id
*/
void closeEvent(uint32 pidEvent);
/**
* Sets the event
- * @param pidEvent Event Process Id
+ * @param pidEvent Event Process Id
*/
void setEvent(uint32 pidEvent);
/**
* Resets the event
- * @param pidEvent Event Process Id
+ * @param pidEvent Event Process Id
*/
void resetEvent(uint32 pidEvent);
@@ -542,9 +543,9 @@ public:
* processes,allowing any processes waiting on the event to be fired. It
* then immediately resets the event again.
*
- * @param pidEvent Event Process Id
+ * @param pidEvent Event Process Id
*
- * @remarks Should not be run inside of another process
+ * @remarks Should not be run inside of another process
*/
void pulseEvent(uint32 pidEvent);
};
@@ -553,4 +554,4 @@ public:
} // end of namespace Common
-#endif // COMMON_COROUTINES_H
+#endif // COMMON_COROUTINES_H