Enterprise Resource Planning

ERP Journal on Ulitzer

Subscribe to ERP Journal on Ulitzer: eMailAlertsEmail Alerts newslettersWeekly Newsletters
Get ERP Journal on Ulitzer: homepageHomepage mobileMobile rssRSS facebookFacebook twitterTwitter linkedinLinkedIn


ERP Journal Authors: Steve Mordue, Elizabeth White, Automic Blog, Louis Nauges, Progress Blog

Related Topics: ERP Journal on Ulitzer

ERP Journal: Article

Get the most out of each of your CPU's ticks!

Multithread programming in Macromedia Director Xtras

No matter how powerful a computer you or your end user has, faster software is always desirable. For one, we live in an era where time is very valuable and technology is here to empower us, not to set limits on what we can or wish to do. Furthermore, the responsiveness of an application to its user is a crucial benefit and increasingly important differentiator between ordinary software and superior software. Responsiveness of software is generally defined as its ability to react fast, to provide guidance and feedback and to allow users to cancel or redirect time-consuming operations. Conversely, an application that temporarily freezes and does not provide progress information while it is processing tasks that take as little as a few seconds, does not convey the sense of responsiveness, care and respect users expect, and in addition interrupts the user's concentration when performing tasks such as learning, selecting a product from an electronic catalog, or just playing a game.

Modern operating systems, Windows and Mac OS alike, implement a mechanism called multithreading that allows multiple tasks to take place simultaneously , thus interacting with users while processing other CPU or network intensive tasks.

This article will show how you can improve the responsiveness of your Director based applications, through the use of multithreaded Director Xtras. Implementing multithreading in a Director Xtra has been a commonly asked question for the seven years I have been on Macromedia's XDK forum.

To quote Albert Einstein "For every problem there is a solution which is simple, obvious, and wrong". Time and again, I've seen poor solutions suggested on the XDK forum to address the multithreading issue. These solutions aren't the best and in some cases, will even crash your project. This is what h as inspired me to write this article.

Example 1: A Board Game Application
Let's assume you are building a board game such as chess, or Othello-Reversi, or any other board game that requires your opponent (the computer) to "forward think" multiple scenarios. Such an application typically requires CPU-intensive and time-consuming dynamic programming or backtracking algorithms. Let's further assume you want your game to stand out from the crowd: it must provide an animated progress indicator providing the user with feedback on how long it will take before the computer's next move. Ultimately, you may also want to give users the ability to force the computer to "Play Now" with the best move it has at the moment. To do so, your best bet is to code the game's "intelligence" in a multithreaded Xtra. Better yet, assuming that you can reuse an existing game engine (a library or application) that implements the required intelligence, you only need to bridge your Director user interface with the engine using a multithreaded Xtra.

Any time-consuming computation problem can be addressed in the same way as the game example. A few similar scenarios could be:

  • Scientific calculations involving large matrices or complex algorithms
  • Optimization problems in logistics, manufacturing, transportation and other areas
  • Visualization applications with intensive graphic processing
  • Real-time data compression / decompression
Example 2: Networking in Macromedia Director
Another context where multithreading plays a key role is networking in Macromedia Director. Assume that your Director movie must asynchronously send and receive information from a remote server, say your corporate ERP. Asynchronous means that the said process can accept a request, return control to the caller and then notify the caller again when it completes. In contrast, in a synchronous call, the said process would hold the calling request, perform its processing, get the result and send it back to the originator by way of the calling function. The user interface would look frozen in the meantime.

Although NetLingo is able to perform asynchronous network operations, your Director code must keep looping and checking the status of such an operation so it can provide the user with feedback and perform an action once the operation has been completed. The code would also need to properly handle error and timeout scenarios. This mechanism is called polling. It is further discussed below.

Any task that can be delegated to an external CPU falls in this category:

  • Reading and writing data to a corporate server, such as an ERP, CRM, LMS, etc.
  • Tapping into custom-made enterprise servers built with Java, .NET, etc.
  • Integrating your project to a chat server, a database server, a web service, etc.
What is Multithreading?
One can easily understand how a computer linearly executes a sequence of instructions, one after another. Any commercial-grade CPU can only sequentially process one such instruction at a time. However, multithreading implies that multiple actions simultaneously take place on the same computer. How can this be?

Both of the above statements are true as long as you agree to abstract the concept of time. In the wonderful world of multithreading, your application and the CPU have different concepts of time. Your program only deals with the Operating System and thus assumes that its threads are executed simultaneously. However, while the Operating System makes you believe this is true, down under, it juggles with setting priorities on threads and has the CPU process short sequences of each so they appear to be simultaneous to you.

Polling: Simple but Inefficient
A simple solution to providing users with an interface that remains active while performing other tasks is to have your Lingo code continuously poll the status of the external tasks, possibly displaying progress information, and performing a completion action in due time.

For example, if the computer must calculate the next move of a board game, your Lingo code would call your Xtra, which would create a new thread (let's call it the "secondary thread"), and call the game engine with the appropriate parameters. Your Xtra would immediately resume in the main thread and return control to Director. Then, your Lingo code would need to continuously loop On EnterFrame (or On Idle, or something similar) and check a status method (let's call it GameBusy()). As long as GameBusy() returns true, your Lingo keeps looping, updating progress information, managing timeouts and error conditions, and trying to respond to any other user requests. In the mean time, the secondary thread provides enough CPU time to the game engine to compute the next move. Whenever GameBusy() returns FALSE, you exit the loop, call another method to retrieve the computer's next move and display it to the user.

Although polling works fine in simple projects, it has two major drawbacks:

  1. ) It wastes valuable CPU time
  2. ) It makes your code harder to write, to read, to debug, to update and to reuse in future projects
Thus, the polling solution is detrimental to both your users (who experience slower software execution) and you (who has to spend more time coding and debugging).

Brutal Multithreading: Simple but Wrong
An obvious way to optimize the above-mentioned polling mechanism is to replace it by a notification mechanism.

More Stories By Laurent Brigaut

Laurent 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.

Comments (1) View Comments

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.


Most Recent Comments
Sunil Gupta 08/31/05 11:50:24 AM EDT

Excellent article. This can be used to communicate with any previously written code in C/C++. Exactly what I was interested in. Great Job!!!