Chapter 2.2.1 - The Factory
The strategy factory is a class whose solely purpose is to create the client
states, the server states and repositories when the framework wants it to do so. Only the
strategy factory knows the names of the concrete server and client states / repositories.
It has to determine the initial server state, the initial client state and the token that
is used by this strategy to end the server tip sequence (a string that is never used as
a [LINK:server tip]). The strategy factory is registered in the
initcomponents()
void in the framework with its name. It will be automatically
selected by the framework if the user of the robot has specified it in the
[LINK:configuration file].
A factory must be derivated from [LINK:Strategies::StrategyFactory]. The factory has
three functions: createServerStateData()
,
createClientStateData()
and getFinishingString()
.
The createServerStateData()
creates all server state objects for one
single server coordinator (a finite state machine) as an array in the master server. The
first element of that array indicates the initial state object. Furthermore, the returned
server state data object contains the InternalServerSpecificRepository and a reference to
the SharedServerSpecificRepository.
The createClientStateData()
creates all client states objects for the
client coordinator (a finite state machine) in an array. The first position in the array
indicates the initial state object that will be the first current state in the client
coordinator. Furthermore, the returned client state data object contains the
InternalClientSpecificRepository.
Both functions, createServerStateData()
and
createClientStateData()
get a pointer to the GameOptionsRepository.
It's in their responsibility to pass it to the different state objects.
The getFinishingString()
function returns a token that is used to end
the [LINK:server tip sequence]. This string must not be used as a server tip itself by any
of the strategy's server states.
All strategies were registered in the framework by the
registrateStrategyFactory()
of the Master Resource Control in
initomponents.cpp. The user chooses the strategy he wants to play in the robot's config
file. The framework takes that definition and starts the robot with the defined
strategy.
That was the theory, so let's have a look on our sample strategy "Brotfrucht".
The first thing we have to do is to initialize the strategy in
initcomponents()
. In the end of that method we have to add the line:
// register brotfrucht strategy mrc->registrateStrategyFactory("Brotfrucht",auto_ptr<Strategies::StrategyFactory>(new BFFactory()));
Now, the strategy is calls "Brotfrucht" (first parameter) and its factory is the class
BFFactory()
.
The second thing was to complete the three described methods.
As you remember, the Brotfrucht strategy has two client and two server states Rotate and NoRotate state for the server and ShootHalf and ShootTwice state for the client.
In the createServerStateData()
function of the factory, the server states
and the server repositories must be created. These repositories were created by the
lines
BFInternalServerSpecificRepository* bfssppointer; auto_ptr<InternalServerSpecificRepository> bfssp(bfssppointer=new BFInternalServerSpecificRepository()); BFSharedServerSpecificRepository* bfsharedssp(BFSharedServerSpecificRepository::Instance());
Then, we create a list for all states
auto_ptr<pvector<ServerState> > states(new pvector<ServerState>());
and push a new instance of all states onto the list:
states->push_back(new BFServerNoRotateState(serverCoordinator,bfssppointer,bfsharedssp)); states->push_back(new BFServerRotateState(serverCoordinator,bfssppointer,bfsharedssp));
Finally, we return that list:
return auto_ptr<ServerStateData> (new ServerStateData(states,bfssp,bfsharedssp));
For createClientStateData()
we have to do nearly the same for the client
states, so we do not explain all that again.
The last thing to do is to set the getFinishingString()
function. In
Brotfrucht, it just returns the string "BFE". It might be a good idea not to
make it too long, so you can save time in parsing it.
After these changes, the factory is ready to use.