Director
Get the most out of each of your CPU's ticks!
Multithread programming in Macromedia Director Xtras
Aug. 11, 2005 11:00 AM
Adding a message to the queue:
// Make sure that the queue did not reach its maximum size
// This call will block until the queue has some space available
WaitForSingleObject(mSemaphore, INFINITE);
// Request exclusive access to the queue
// This call will block if the queue is already being accessed elsewhere
EnterCriticalSection(&mCriticalSection);
// Add the event to the queue
mEventQueue.push(theEvent);
// Signal that we no longer require exclusive access
LeaveCriticalSection(&mCriticalSection);
Retrieving a message from the queue:
// Make sure that nobody else is accessing the queue
// This call will block if the queue is already being accessed elsewhere
EnterCriticalSection(&mCriticalSection);
// Pop the event
CEvent* event = 0;
if (!mEventQueue.empty()) // Check if the queue contains at least one item
{
event = mEventQueue.front();
mEventQueue.pop();
}
// Signal that we no longer require exclusive access
LeaveCriticalSection(&mCriticalSection);
// Release the Semaphore acquired during the push
// This call will eventually unblock a waiting push
ReleaseSemaphore(mSemaphore, 1, 0);
The Producer thread part is very simple. It will only call the message adding method shown above when it needs to communicate with the Consumer.
The Consumer thread will poll the queue manager on idle time and call Lingo every time it finds a message to process. It would do this with MOA's notification mechanism, more precisely through the IMoaNotificationClient interface. Briefly stated, your Xtra would register to this interface so it can be notified of events of type NID_DrNIdle (which are just plain idle events).
PIMoaNotificationClient pNotificationClient;
PIMoaNotification pMmNotification;
// Acquire MOA notification interface
pObj->pCallback->QueryInterface(&IID_IMoaNotification, (PPMoaVoid)
&This->pMmNotification);
if (pObj->pMmNotification != 0)
{
// Instantiate a notification client object
pObj->pCallback->MoaCreateInstance(&CLSID(CScript),
&IID(IMoaNotificationClient), (PPMoaVoid)&pObj->pNotificationClient);
if (pObj->pNotificationClient)
{
// Register the notification client object to receive IDLE events
pObj->pMmNotification->RegisterNotificationClient(pObj->
pNotificationClient, &NID_CustomNotificationID , 0, this);
}
}
The Notify function below is the core of the code
STDMETHODIMP CScript_IMoaNotificationClient::Notify
(ConstPMoaNotifyID nid, PMoaVoid pNData, PMoaVoid pRefCon)
{
/* variable declarations */
MoaError err = kMoaErr_NoErr;
// We ask the notification interface to pass a pointer to our CScript interface along
with the notification
CScript_IMoaMmXScript* pThis = (CScript_IMoaMmXScript*)pRefCon;
// Pop the event from the queue manager
CEvent* event = (CEvent*)pThis->pObj->pEventManager->PopEvent();
if (0 != event)
{
// Get the value of the counter pushed by the Producer
MoaLong tick;
event->GetEvent(tick);
// Call Lingo
MoaMmSymbol LingoHandlerSym;
MoaMmValue TickValue;
// Set the name of the Lingo handler to be called as a Symbol
pThis ->pObj->pMmUtils->StringToSymbol("ThreadSampleEvt", & LingoHandlerSym);
// Convert the counter vaue to a MoaValue
pThis ->pObj->pMmUtils->IntegerToValue(tick, & TickValue);
// Call the Lingo Handler
pThis ->pObj->pDrMovie->CallHandler(LingoHandlerSym, 1, & TickValue, 0);
// Release the MoaValue
pThis ->pObj->pMmUtils->ValueRelease(&TickValue);
// Free the memory used by the event
delete event;
}
return(err);
}
If you would like to see the complete script, it can be downloaded from:
www.INM.com/services/xtras/sample/
About Laurent BrigautLaurent Brigaut - Director of Operations, Integration New Media (INM)
Laurent has been the Director of Operations at Integration New Media (INM) for 5 years. During this time, he has developed and worked on several custom Xtras for clients and was the brainchild behind INM's SecureNet Xtra and Moka Xtra, two of INM's more specialized commercial Xtras. Laurent has an engineering degree in Computer Science from the Université de Technologie de Compiègne in France (equivalent to a Masters Degree) as well as twelve years experience in software R&D. Among the organizations he has worked for are CERN (European fundamental particles research center), FIRST (integrator and trainers of software for the disabled) and INM. Laurent is an expert in object based methods and technologies.