Honestly, it's problematic -- passing callbacks around like this can easily
violate the invariants that make Actors work.  (In particular, if the
callback closes over any state in a different Actor, you're kind of begging
for trouble.)  By and large, any time you use the word "synchronization" in
the context of Actors it's a bit of a red flag.  This comes up a lot in the
context of gaming, and it's not easy to change one's thinking to not be
sync-oriented, but you'll get safer and more correct code if you can manage
it.

I recommend thinking about the problem, and whether there is a way to
restructure it in such a way that everything is based on requests,
responses, and fallbacks if something fails.  Every bit of state is
encapsulated and owned by exactly one Actor, and everybody else makes
requests on that.  (Note that this is pretty similar to how you usually
have to think anyway if you want to make a game scalable to multiple
servers.)

For example, have a single Actor who is the arbiter for a chunk of Space;
when players try to move into the Space, they *ask* that arbiter to let
them move in.  And if something happens to them at that point, the arbiter
sends them a message telling them what happens to them.

Etc.  I won't claim that it's easy, but you're likely to get more solid
code by thinking it through this way.

On Wed, Nov 2, 2016 at 9:18 AM, Steve Winfield <[email protected]
> wrote:

> Hey,
>
> I got a question regarding a project I'm working on.
>
> There are player actors that can be managed by a "player director" actor
> which belongs to a virtual room and supervises the players. A player
> maintains its current position and name as a mutable state.
>
> The director looks like this:
>
> class PlayerDirector extends Actor {
>      ....
>      private val players = mutable.Map[Int, ActorRef]() // Id, Player ref
>      ....
>      override def receive = {
>           case SpawnPlayer(playerReference) => players +=
> (incrementAndGetId() -> context.actorOf(Player.props(playerReference)))
>           case RemovePlayer(id) => ...
>      }
> }
>
>
> Now I'd like to execute some operations on all players which are
> positioned at x, y
>
> My first attempt:
>
> class PlayerDirector ...
>    receive = {
>           ....
>           case ExecuteOnPlayersByPosition(position, callback) => {
>                 for ((id, player) <- players) {
>                    player ! ExecuteIfPositionMatches(position, callback)
>                 }
>           }
>           ....
>
>
> Then, the player would check its position and execute the callback from
> its context. I don't like this implementation because it forces me to have
> the callback executed on the player's actor, but It's the only way to
> guarantee synchronization (I guess).
>
> Do you have any advice for me?
>
> Cheers!
>
> --
> >>>>>>>>>> Read the docs: http://akka.io/docs/
> >>>>>>>>>> Check the FAQ: http://doc.akka.io/docs/akka/
> current/additional/faq.html
> >>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
> ---
> You received this message because you are subscribed to the Google Groups
> "Akka User List" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> To post to this group, send email to [email protected].
> Visit this group at https://groups.google.com/group/akka-user.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
>>>>>>>>>>      Read the docs: http://akka.io/docs/
>>>>>>>>>>      Check the FAQ: 
>>>>>>>>>> http://doc.akka.io/docs/akka/current/additional/faq.html
>>>>>>>>>>      Search the archives: https://groups.google.com/group/akka-user
--- 
You received this message because you are subscribed to the Google Groups "Akka 
User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/d/optout.

Reply via email to