Chapter 12
[ 317 ]
Each event method takes an optional event parameter and an optional saved session
parameter. The type expected for each of these parameters is actually of the type
map, however it proved to be difficult to generate a method signature with generics
in the AST transform code, so I've used object instead which works fine.
The event method dispatches to the event handler in the current page object. It also
ensures that the session is restored first and it returns the session data as a map.
Persisting the session will be the responsibility of the game server, as we will
see later.
The GameEngineClient class will start out life in the DSL as the DSL script class.
We need to add some functionality to the class, such as the getPage method, a
restoreSession method and the session property itself. It makes our lives easier in
the AST transform if this is all packaged in a trait and we simply inject the trait into
the script class. We implement that trait here in the pattern to ensure it will work
as expected:
trait GameEngineTraits {
def session
def restoreSession(engine, sessionData = null) {
if (!session)
session = Class.forName("${engine}Session").newInstance()
if(session && sessionData) {
session.restoreSession(sessionData)
}
}
String getPage() {
session.page
}
}
You will see a lot of code in the pattern version of the engine that seems unnecessary.
We have used reflection here to create an instance of the TicTacToeEngineSession
class. That is because this is what we will need to do in the code generated by the
AST. The GameEngineTraits class needs to be generic if we want to use it for
multiple game engines so it needs to generate the session class by name dynamically:
class TicTacToeEngineSession extends PersistableSession {
def playerX
def playerO
def players
def grid = [
' ',' ',' ',