JeuWeb - Crée ton jeu par navigateur
[Scala] Exemple d'Acteur - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : [Scala] Exemple d'Acteur (/showthread.php?tid=5010)



[Scala] Exemple d'Acteur - srm - 23-07-2010

Bonjour,

Alors voici un petit exemple en Scala sur l'utilisation des Acteurs ce qui permet en gros d'avoir une utilisation des Threads très performante en terme de ressource et de puissance.

Code PHP :
<?php 
package test

import scala
.actors.Actor
import scala
.actors.Actor._

/**
* Alors "case object" c'est une notion pas facile à expliquer et que je ne
* maîtrise pas encore parfaitement
* Dans le contexte utilisé ici c'est en gros comme trois variables de leur
* propre type :
* - une variable Ping du type Ping
* - une variable Pong du type Pong
* - une variable Stop du type Stop
* C'est en soit des "singleton object"
*/
case object Ping
case object Pong
case object Stop

/**
* Ping pong example.
*
* @author Philipp Haller
* @version 1.1
*/

/**
* Il s'agit simplement du programme principal qui va appeler les deux acteurs
* Pong et Ping et qui vont s'échanger des "Ping" "Pong"
*/
object Main extends Application {
val pong = new Pong
val ping
= new Ping(5, pong)

ping.start
pong
.start

}

/**
* La définition de mon premier acteur "Ping""
*/
class Ping(count: Int, pong: Actor) extends Actor {
/**
* Pour définir un acteur, on définit son comportement dans la méthode "act"
*/
def act() {
var
pingsLeft = count - 1
/**
* C'est la syntaxe pour envoyer un message "Ping" à l'acteur "Pong"
*/
pong ! Ping
loop
{
/**
* A chaque message envoyé à l'acteur Ping la méthode react
* est appelé avec comme argument le message
*
* Note : techniquement le principe est bien plus compliqué, car
* la boucle loop ne tourne pas à l'infini, une itération de loop
* est appelé à chaque fois par le système Actor, donc la boucle loop
* "est en attente" dans les autres cas et ne consomme aucune ressource
*/
react {
case
Pong =>
/**
* Si le message reçu est "Pong" on envoie le message "Ping" à l'acteur "Pong"
* et décrémente le nombre de ping restant
*/
if (pingsLeft > 0) {
println("Ping: pong")
pong ! Ping
pingsLeft
-= 1

/**
* Si il n'y a plus de pingsLeft alors on envoie le message "Stop" à l'acteur "Pong"
* et on quitte la boucle loop et donc termine l'acteur
*/
} else {
println("Ping: stop")
pong ! Stop
exit()
}
}
}
}
}

class
Pong extends Actor {
def act() {
var
pongCount = 0
loop
{
react {
case
Ping =>
/**
* On reçoit le message "Ping" on répond donc à l'émetteur (sender) le message "Pong"
*/
println("Pong: ping "+pongCount)
sender ! Pong
pongCount
+= 1
case Stop =>
/**
* On reçoit le message "Stop", la séquence de "Ping/Pong" est terminée on termine l'acteur
*/
println("Pong: stop")
exit()
}
}
}
}

Un article qui explique l'intérêt du système Acteur par rapport au système Thread simple :
http://java.dzone.com/articles/scala-threadless-concurrent


RE: [Scala] Exemple d'Acteur - srm - 27-04-2012

Il y a une discussion dans les topics Erlang concernant les acteurs, Scala a copié le principe des Acteurs du langage Erlang.
Voici un exemple des acteurs en Erlang : http://www.jeuweb.org/showthread.php?tid=7929&pid=107529#pid107529
Voici l'équivalent en Scala :

import scala.actors.Actor
import scala.actors.Actor._

class Character extends Actor
{

def act
{

loop {

react {
case (sender: Actor, "introduce") =>
println(self + " received introduce message from " + sender)
sender ! "reply"
case "reply" =>
println(self + " received reply message.")
case _ =>
println(self + " received other kind of message. Stop listening.")
exit
}

}

}

}


object Test extends App {

val character1 = new Character
val character2 = new Character

character1.start
character2.start

character1 ! (character2, "introduce")
character1 ! (character2, "introduce")
character2 ! (character1, "introduce")

}

On peut constater que ça reste très semblable, mais qu'il y a tout de même des grosses différences.
Par exemple en Scala on n'a pas à relancer l'acteur une fois qu'il a traité un message, c'est fait automatiquement, si on veut que l'acteur se termine on lui demande explicitement avec exit.