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 configuration file.

A factory must be derivated from 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.