How to build a concurrent graphical application: EiffelVision with SCOOP

How can I build a concurrent graphical application in Eiffel?

Eiffel has a great library for producing graphical applications: EiffelVision. Eiffel also has a powerful concurrency mechanism: SCOOP.

How do you make the two work together? This note gives you simple guidelines to ensure that the EiffelVision-SCOOP marriage is a harmonious and productive one.

The first question: why does the problem even exist? Let's go back to the pre-SCOOP days. Any graphical application has an "event loop", which keeps watching for graphical user events, such as a mouse click, and triggering the corresponding application responses, such as saving a file (if the user clicked OK on a File Save dialog). If you were using multithreading, the event loop would run in the main thread, also called the GUI (Graphical User Interface) thread.

Enter SCOOP. The old technique cannot work because a processor stuck in a loop cannot process any logged call! If you perform calls on a graphical widget, say the OK button, they will be logged right away, but they can only execute once the processor has exited its event loop. Not what you want.

So here is what you should do:

In a creation procedure used to initialize GUI objects, create an EV_APPLICATION object, using an instruction such as

     create my_app

with my_app of type EV_APPLICATION. (This may be a root creation procedure or a creation procedure of a separate object in case the root processor is going to be used for other operations.)

Then in the same creation procedure create all the GUI elements. They will all be in the same processor that created the EV_APPLICATION object.

After that start the application, using

     my_app.launch

In the pre-SCOOP world, launch would start the event loop. Here it only creates a separate object (of type EV_APPLICATION_HANDLER), which will run the event loop, forwarding events to the EV_APPLICATION object.

This is all the creation procedure should do. Make sure it terminates with the preceding step. Otherwise, the event loop will never run!

Now you can start using EiffelVision as you are used to, by sending GUI requests to the EV_APPLICATION object:

  • For requests coming from the same processor just use the EV_APPLICATION object directly.
  • For requests coming from another processor, you can get the access through the feature ev_separate_application of class EV_SHARED_APPLICATION.

Note that only one EV_APPLICATION object can be used, therefore all GUI objects have to be created in the region of this object.

That's all! Happy concurrent Eiffeling.