diff --git a/Firework_en.pdf b/Firework_en.pdf new file mode 100644 index 0000000..eee3afd Binary files /dev/null and b/Firework_en.pdf differ diff --git a/MVC_en.pdf b/MVC_en.pdf new file mode 100644 index 0000000..d705154 Binary files /dev/null and b/MVC_en.pdf differ diff --git a/README.md b/README.md new file mode 100644 index 0000000..34e4141 --- /dev/null +++ b/README.md @@ -0,0 +1,130 @@ +# MVC pattern + +This application follows a MVC (Model-View-Controller) pattern for the GUI communication. + +![MVC pattern applied on this project](MVC_en.pdf) + + +# Fireworks demonstration + + +The goal of this demo is to bring out some fireworks using SARL agents. +The application is composed of 4 agents. The whole structure holonic. + +![Agents organization in the fireworks demo](Firework_en.pdf| width=150px |height=300px) + +The main agent is the *LaunchingArea* which is linked with the GUI and and contains the other agents inside its inner context. +This agent creates the *RocketLauncher*, one by rocket asked by the user. It also transmits the gravity and other parameters. +This agent also registers the GUI on a dedicated OpenEventSpace for communication. + +```Scala +agent LaunchingArea { + + ... + + /* + * Get setup event from the GUI + */ + on SetupSettings { + this.rocketsQuantity = occurrence.rocketsQuantity + this.fireQuantity = occurrence.fireQuatity + this.gravity = occurrence.gravity + this.maxWidth = occurrence.maxWidth + } + + /* + * Agent initialisation when spawned by the GUI + * A communication space is opened between + * the GUI and this agent + */ + on Initialize [!occurrence.parameters.empty] { + var ctrl = occurrence.parameters.get(0) as FXMLViewerController + var ispace = defaultContext.createSpace( + OpenEventSpaceSpecification, UUID.randomUUID) + ctrl.setGUISpace(ispace) + ispace.register(asEventListener) + + ctrl.listenAndDraw(grid) + + info("Finishing initialization of Launching Area") + + } + + ... +} +``` + +![Application with the GUI](firework_screenshot.png| width=350px | height=300px) + +Then, each RocketLauncher creates a *Rocket*. When this one is destroyed, the *RocketLauncher* is going to generate another one. This allows to displace the verification of the existence of the *Rocket* out of the LaunchingArea. It also isolates the *Rocket* and avoid that emitted events disrupt the managing of the simulation. + +```Scala +agent RocketLauncher { + + ... + + /* + * A new rocket is launched when the previous + * one is destroyed + */ + on MemberLeft [!isFromMe(occurrence) && !exited] { + // wake allows to send the event at the agent itself + wake(new Launch) + } + ... +} +``` + +*Rocket* agents are the heart of this demo. Each one create a task with a fixed delay where they updates their position by writing it in a object shared with the GUI, here named *Positions*. When the *Rocket* reach the end of its lifetime, they create *Fire* agent within their inner context according to the quantity asked by the user and then wait for the destruction of every *Fire* to kill themselves. + +```Scala +agent Rocket { + + ... + + on Initialize { + + ... + + /* + * Create a new background task to update + * the agent position at a fixed delay + */ + move = atFixedDelay( + Configuration.RocketLifeCycleSchedulingRate) [ + try { + wake(new UpdateRocketPosition); + } catch (e : Exception) { + e.printStackTrace + } + ] + } + + on UpdateRocketPosition [isFromMe(occurrence) && + !frozen && !exploded] { + var vect = new Vector(2) + x = x + speedx + y = y + speedy + vect.clear() + vect.add(x) + vect.add(y) + lifetime = lifetime - 10 + + /* Updates the Position object */ + if (grid !== null) + grid.setRocketPosition(id, vect) + if (lifetime <= 0) { + exploded = true + move.cancel(true) + grid.hideHocketPosition(id) + wake(new Explode) + } + } + + ... +} + +``` +The *Fire* is the last agent of the demo. It have a list of positions and is subjected to gravity. As *Rocket* agent, the *Fire* launch a task at a fixed delay to update its actual position, add it at the end of the actual list and then update the *Positions* object. When its lifetime is over, the *Fire* is destroyed. + +When the GUI is closed, an event *Exit* is sent to the *LaunchingArea* which transmits it to the other agents she owns. It waits for their elimination to destroy the next one, until itself. \ No newline at end of file diff --git a/firework_screenshot.png b/firework_screenshot.png new file mode 100644 index 0000000..e19c02c Binary files /dev/null and b/firework_screenshot.png differ