aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-06-09 17:14:21 +1000
committerPaul Gilbert2012-06-17 17:29:20 +1000
commit269ea2f6be551f3159c1e508e28ebd2a609f5ab0 (patch)
tree56f89c54ec73fe2454d7f70042ab4fa88bed5f8c
parent06b905a218094458b1028d429956639c4a1cde7e (diff)
downloadscummvm-rg350-269ea2f6be551f3159c1e508e28ebd2a609f5ab0.tar.gz
scummvm-rg350-269ea2f6be551f3159c1e508e28ebd2a609f5ab0.tar.bz2
scummvm-rg350-269ea2f6be551f3159c1e508e28ebd2a609f5ab0.zip
COMMON: Change pulseEvent to better reflect how it works in Windows
-rw-r--r--common/coroutines.cpp58
-rw-r--r--common/coroutines.h1
2 files changed, 18 insertions, 41 deletions
diff --git a/common/coroutines.cpp b/common/coroutines.cpp
index 241d31e0d7..042b15b5d7 100644
--- a/common/coroutines.cpp
+++ b/common/coroutines.cpp
@@ -245,6 +245,15 @@ void CoroutineScheduler::schedule() {
pProc = pNext;
}
+
+ // Disable any events that were pulsed
+ Common::List<EVENT *>::iterator i;
+ for (i = _events.begin(); i != _events.end(); ++i) {
+ EVENT *evt = *i;
+ if (evt->pulsing) {
+ evt->pulsing = evt->signalled = false;
+ }
+ }
}
void CoroutineScheduler::rescheduleAll() {
@@ -678,6 +687,7 @@ uint32 CoroutineScheduler::createEvent(bool bManualReset, bool bInitialState) {
evt->pid = ++pidCounter;
evt->manualReset = bManualReset;
evt->signalled = bInitialState;
+ evt->pulsing = false;
_events.push_back(evt);
return evt->pid;
@@ -707,49 +717,15 @@ void CoroutineScheduler::pulseEvent(uint32 pidEvent) {
EVENT *evt = getEvent(pidEvent);
if (!evt)
return;
-
- // Set the event as true
+
+ // Set the event as signalled and pulsing
evt->signalled = true;
+ evt->pulsing = true;
- // start dispatching active process list for any processes that are currently waiting
- PROCESS *pOriginal = pCurrent;
- PROCESS *pNext;
- PROCESS *pProc = active->pNext;
- while (pProc != NULL) {
- pNext = pProc->pNext;
-
- // Only call processes that are currently waiting (either in waitForSingleObject or
- // waitForMultipleObjects) for the given event Pid
- for (int i = 0; i < CORO_MAX_PID_WAITING; ++i) {
- if (pProc->pidWaiting[i] == pidEvent) {
- // Dispatch the process
- pCurrent = pProc;
- pProc->coroAddr(pProc->state, pProc->param);
-
- if (!pProc->state || pProc->state->_sleep <= 0) {
- // Coroutine finished
- pCurrent = pCurrent->pPrevious;
- killProcess(pProc);
- } else {
- pProc->sleepTime = pProc->state->_sleep;
- }
-
- // pCurrent may have been changed
- pNext = pCurrent->pNext;
- pCurrent = NULL;
-
- break;
- }
- }
-
- pProc = pNext;
- }
-
- // Restore the original current process (if one was active)
- pCurrent = pOriginal;
-
- // Reset the event back to non-signalled
- evt->signalled = false;
+ // If there's an active process, and it's not the first in the queue, then reschedule all
+ // the other prcoesses in the queue to run again this frame
+ if (pCurrent && pCurrent != active->pNext)
+ rescheduleAll();
}
} // end of namespace Common
diff --git a/common/coroutines.h b/common/coroutines.h
index 64eabbf8f4..834c67f6e4 100644
--- a/common/coroutines.h
+++ b/common/coroutines.h
@@ -316,6 +316,7 @@ struct EVENT {
uint32 pid;
bool manualReset;
bool signalled;
+ bool pulsing;
};