1package main
2
3import (
4	"fmt"
5
6	"github.com/Arceliar/phony"
7)
8
9// Structs can embed the Inbox type to fulfill the Actor interface.
10type printer struct {
11	phony.Inbox
12}
13
14// Functions can be defined to send messages to an Actor from another Actor.
15func (p *printer) Println(from phony.Actor, msg ...interface{}) {
16	p.Act(from, func() { fmt.Println(msg...) })
17}
18
19// It's useful to embed an Actor in a struct whose fields the Actor is responsible for.
20type counter struct {
21	phony.Inbox
22	count   int
23	printer *printer
24}
25
26// Act with a nil sender is useful for asking an Actor to do something from non-Actor code.
27func (c *counter) Increment() {
28	c.Act(nil, func() { c.count++ })
29}
30
31// Block waits until after a message has been processed before returning.
32// This can be used to interrogate an Actor from an outside goroutine.
33// Note that Actors shouldn't use this on eachother, since it blocks, it's just meant for convenience when interfacing with outside code.
34func (c *counter) Get() int {
35	var n int
36	phony.Block(c, func() { n = c.count })
37	return n
38}
39
40// Print sends a message to the counter, telling to to call c.printer.Println
41// Calling Println sends a message to the printer, telling it to print
42// So message sends become function calls.
43func (c *counter) Print() {
44	c.Act(nil, func() {
45		c.printer.Println(c, "The count is:", c.count)
46	})
47}
48
49func main() {
50	c := &counter{printer: new(printer)} // Create an actor
51	for idx := 0; idx < 10; idx++ {
52		c.Increment() // Ask the Actor to do some work
53		c.Print()     // And ask it to send a message to another Actor, which handles them asynchronously
54	}
55	n := c.Get()                      // Inspect the Actor's internal state
56	fmt.Println("Value from Get:", n) // This likely prints before the Print() lines above have finished -- Actors work asynchronously.
57	phony.Block(c.printer, func() {}) // Wait for an Actor to handle a message, in this case just to finish printing
58	fmt.Println("Exiting")
59}
60