Am I violating an OOP design guideline here? Couple of interesting design pickles - c++

I'm designing a new power-up system for a game I'm creating. It's a side scroller, the power ups appear as circular objects and the player has to touch / move through them to pick up their power. The power up then becomes activated, and deactivates itself a few seconds later. Each power-up has its own duration defined. For simplicity's sake the power ups are spawned (placed on the screen) every X seconds.
I created a PowerUpManager, a singleton whose job is to decide when to create new power ups and then where to place them.
I then created the Powerup base class, and a class that inherits from that base class for every new Powerup. Every Power-up can be in one of three states: Disabled, placed on the screen, and picked up by the player. If the player did not pick up the power up but moved on, the power up will exit the screen and should go back from the placed state to the disabled state, so it can be placed again.
One of the requirements (that I) put in place is that there should be minimal code changes when I code up a new Power up class. The best I could do was one piece of code: The PowerUpManager's constructor, where you must add the new power-up to the to the container that holds all power-ups:
PowerupManager::PowerupManager()
{
available = {
new PowerupSpeed(),
new PowerupAltWeapon(),
...
};
}
The PowerUpManager, in more details (Question is coming up!):
Holds a vector of pointers to PowerUp (The base class) called available. This is the initial container that holds one copy of each power up in the game.
To handle the different states, it has a couple of lists: One that holds pointers to currently placed power ups, and another list that holds pointers to currently active power ups.
It also has a method that gets called every game tick that decides if and where to place a new power up and clean up power ups that weren't picked up. Finally it has a method that gets called when the player runs into a power up, that activates the power up (Moves it from the placed to the active list, and calls the power up's activate method).
Finally, once you understand the full picture, the question:
I needed a way for client code to ask if a particular power-up is currently active. For example: The player has a weapon, but there is a power up that replaces that weapon temporarily. Where I poll for input and recognize that the player wants to fire his weapon, I need to call the correct fire method - The alternative weapon power up fire method, and not the regular weapon fire method.
I thought of this particular demand for a while and came up with this:
template <typename T>
T* isActivated() // Returns a pointer to the derived Powerup if it exists in the activated list, or nullptr if it doesn't
{
for(Powerup *i : active) // Active is a list of currently active power ups
{
T *result = dynamic_cast<T*>(i);
if(result)
return result;
}
return nullptr;
}
So client code looks like this:
PowerUpAltWeapon *weapon = powerUpManager->isActivated<PowerUpAltWeapon>();
if(weapon)
...
I thought the solution is elegant and kind of neat, but essentially what it is is trying to convert a base type to a derived type. If that doesn't work, you try the next derived type... A long chain of if / else if, it's just disguised in a loop. Does this violate the guideline that I just described? Not casting a base type to all of its derived types in a long chain of if / else if until you get a hit? Is there another solution?
A secondary question is: Is there a way to get rid of the need to construct all the different power ups in the PowerupManager constructor? That is currently the only place you need to make a change if you want to introduce a new power up. If I can get rid of that, that'd be interesting...

This is based on your design, but if it was me I choose an ID for each PowerUp and a set of IDs in the client, and each time a user posses a PowerUp that ID will be added to its set and ... you know the rest. Using this technique I can do fast look up for every PowerUp and avoid dynamic_cast:
std::set<PowerUp::ID> my_powerUps;
template< class T > bool isActivated() {
return my_powerUps.find( T::id() ) != my_powerUps.end();
}
And about your second question, I have a similar program that load some plugins instead of PowerUp, I have a pure virtual base class that contain all methods that required by that plugin and implement it in shared modules and then at startup I load them from an specific folder. For example each shared module contain a create_object that return a plugin* (in your case PowerUp* of course) and then I iterate the folder, load modules and call create_object to create my plugins from them and register them in my plugin_manager

Related

OOP for global system/task monitoring class

I'm trying to create a performance monitor of sorts to run on a Particle board (STM32 based). I'm used to programming in c so the OOP approach is a bit new but I think it would fit well here.
For the purpose of this question let's assume I have two types of monitors:
Frequency. The application can call a "tick" method of the monitor to calculate the time since it last ran and store it.
Period- call a "start" and "stop" method of the monitor to calculate how long a process takes to run and store it.
What I would like to do is to create instances of these monitors throughout my application and be able to report on the stats of all monitors of all types from the main module.
I've read about the singleton design pattern which seems like it might be what I need but I'm not sure and I'm also concerned about thread safety with that.
I'm thinking I will create a "StatMonitor" class and a derived class "FrequencyMonitor" and "PeriodMonitor". Monitor would be a singleton and everywhere I wanted to create a new monitor I would request an instance of "Monitor" and use that like so:
freqMonitor * task1FreqMonitor = StatMonitor::GetInstance()->Add_Freq_Monitor("Task1");
The StatMonitor would track all monitors I've added and when I wanted to print the stats I could just call the printAll method which would iterate it's array of monitors and request their results like so:
StatMonitor::GetInstance()->PrintAllStats();
Am I going down the right path?
Your path sounds good, except that FrequencyMonitor and PeriodMonitor should not derive from the class that "manages" all these monitors (let's call it MonitorPrinter).
MonitorPrinter should be a singleton and could look like this:
class MonitorPrinter
{
public:
static MonitorPrinter& getInstance()
{
static MonitorPrinter monitorPrinter;
return monitorPrinter;
}
void printAllStats()
{
for (const auto& [_, frequencyMonitor] : _frequencyMonitors)
frequencyMonitor.print();
for (const auto& [_, periodMonitor] : _periodMonitors)
periodMonitor.print();
}
FrequencyMonitor& getFrequencyMonitor(std::string name)
{ return _frequencyMonitors[name]; }
PeriodMonitor& getPeriodMonitor(std::string name)
{ return _periodMonitors[name]; }
private:
MonitorPrinter() = default;
std::map<std::string, FrequencyMonitor> _frequencyMonitors;
std::map<std::string, PeriodMonitor> _periodMonitors;
};
Demo
(The const auto& [_, frequencyMonitor] is a structured binding).
FrequencyMonitor and PeriodMonitor should not have anything to do with singletons, and from your description, they need not be part of a class hierarchy either (as they have different interfaces). If you want, you can prevent users (other than the MonitorPrinter) from instantiating these classes using other techniques, but I won't elaborate on that here.
In short, there is no need to use OOP here. Use a singleton to provide (and keep track of) the monitors, and implement the monitors to your liking. Be wary of thread safety if this is relevant (the above is not thread-safe!).

How are aggregates instantiated to test other aggregates with?

Suppose I have an aggregate that, for some operation, requires the existence of another aggregate. Let's assume I have a car and a garage. There might be a command called ParkInGarage that looks like this:
public class ParkInGarage {
#TargetAggregateIdentifier
public final UUID carId;
public final Garage garage;
//... constructor omitted
}
I've read that to validate the existence of an aggregate, it is good practice to use the loaded aggregate in commands since that already implies its existence (as opposed to passing a garageId).
Now when unit-testing the Car using Axon's fixtures, I can not simply instantiate my Garage by saying new Garage(buildGarageCmd). It will say:
java.lang.IllegalStateException: Cannot request current Scope if none is active
Because no infrastructure was set up.
How would I test such a case, or should I design the aggregate differently?
Abstracted, real-world example
The aggregate root I am working with may have a reference to itself to form a tree-structure of said aggregate root. Let's call it Node.
#Aggregate
public class Node {
private Node parentNode;
}
Upon creation, I can pass an Optional<Node> as parent, or set the parent at a later time using a separate command. Whether the parent should be defined as instance or by ID is part of the question.
public class AttachNodeCmd {
#TargetAggregateIdentifier
public final UUID nodeId;
public final Optional<Node> parentNode;
}
In the command handler, I need to check if attaching the node to given parent would introduce a cycle (the structure is supposed to be a tree, not a common graph).
#CommandHandler
public Node(AttachNodeCmd command) {
if (command.parentNode.isPresent()) {
Node currentNode = command.parentNode.get();
while (currentNode != null) {
if (currentNode.equals(this)) throw new RecursionException();
currentNode = currentNode.parentNode.orElse(null);
}
}
//Accept the command by applying() an Event
}
At some point, the parent needs to be instantiated to perform those checks. This could either be done by supplying the aggregate instance in the command (discouraged), or by supplying a Repository<Node> and the nodeId to the command handler, which is the aggregate itself and also discouraged. Currently I don't see a right way to do this and further down the road a way to test it.
I wouldn't put AR instances in commands. Command schemas should be stable and easy to serialize/reserialize as they are message contracts.
What you could do instead is resolving the dependency in the command handler.
//ParkInGarage command handler
Garage garage = garageRepository.garageOfId(command.garageId);
Car car = carRepository.carOfId(command.carId);
car.parkIn(garage);
I don't know Axon Framework at all, but that should be relatively easy to test now.
I think #plalx is putting you on the right track. Commands are part of your API/Message Contract and exposing the Aggregate in there isn't that great an idea.
Additionally I'd like to note that the AggregateFixtures in Axon are there to test a single Aggregate, not the coordination of operations between Aggregates.
Coordination between aggregates/bounded contexts is typically where you see sagas coming in to play. Now to be honest, I am a bit in doubt whether this use case justifies a Saga, but I could imagine that if the ParkCarInGarageCommand fails because the Garage Aggregate is full (for example), that you need to instruct the Car Aggregate through another command telling it it's a no-go. The Saga set up in Axon might help you with this as you can easily catch (1) the exception from handling the command or (2) handle the event notifying the operation wasn't successful.

Game NPC multi-action lua script design

I need to put scriptable NPC in my currect game project.
The project itself is developed in C++ language.
I will using Luabind to bind lua and c++.
I need to call NPC function when certain NPC clicked or timer to do something is activated.
Currently I stuck between 2 NPC script design.
Using a kind of npcname_action to differentiate every NPC.
This is kind of troublesome to give name to every different NPC.
I'm still thinking how to implement this in my project.
Example:
HotelBellboy12_Click() { .. }
HotelBellboy12_TimerAction() { .. }
Using name of function.
Every npc have it own lua file.
I'm thinking to load script into memory and when needed will be loaded into luaState using luaL_loadbuffer
Example:
OnClick() { .. }
OnTimerAction() { .. }
Which one is better and why?
You could use another design.
Take advantage of the fact that table keys and values can be any type.
Let's say npc is a table containing all NPC's. Its keys are NPC' names and its values are another table. This other table keys are the actions, and its values are the function for this actions.
So, if you want bob to jump when clicked on, and alice to cry after a timer, simply do :
npc.bob.click = function () jump() end
npc.alice.timer = function () cry() end
I've done something like this before and I used something similar to your #2 option. When the map loads I load a configuration Lua file containing all the NPC data; among that is the name of the script file used for the NPC.
When I need to load the NPC in the game I compile the Lua file. NPC's can use a 'model' NPC type to dictate most of the common behavior (for example a Merchant type or a Commoner type) which is specified in the NPC configuration. These model types provide all the basic functionality such as providing a trade window when clicked. The specific NPC's use functions like OnClick() to override their model and provide custom handlers.
This worked pretty well for me, although it ends up being a large volume of scripts if your game gets large.

C++ - Where to store a global counter?

The diagram http://www.freeimagehosting.net/uploads/2fd3f4161c.png
Here's the Minimalist-UML diagram of an app I've been working on. It's supposed to simulate the management of a bunch of sensors relating to different measurements.
Please ignore the House class, the diagram is outdated...
However, I have trouble. Each sensor (sound, contact, heat, pressure, gas - All of these inherit from sensor) has an unique ID, starting at 0 for the first one and ending at the total number of sensors - 1.
For good practices' sake, where shall I store the total number of sensors, so the classes I'm using for input/output of files (saving and loading) and insertion of new sensors can access and increment that counter?
Thank you for your time!
One option would be to create a static function in your Sensor class that increments and returns a static counter variable. The constructor for Sensor could call this function to get an ID.
// header file
class Sensor
{
...
protected:
static int getId() { return id++; }
private:
static int id;
int myId;
};
// .cpp file
int Sensor::id = 0;
Sensor::Sensor(...)
: myId(getId())
...
{}
I'm ignoring threading and persistence issues here. But hopefully this gives you a better idea.
Whatever object creates the sensors should assign the identifiers to the sensors.
If multiple objects create sensors, then they should be assigned a pointer or reference to a provider of identifiers when they are created and they should query that provider for a new unique identifier as they create new sensor objects.
Your unique ID, like a database table ID will likely have some issues.
You will probably find, eventually, that your ID needs to persist across sessions--that your window's ID is used in some other relationship.
You may, some day, also find that it needs to be unique across multiple server/client sets.
I'm just suggesting that you should consider these issues off the bat.
As for where the ID should be generated, since all your "Sensor" classes inherit from one base class, I think I'd generate it via a threadsafe method in that base class--and I'd store it there as well.
what's the problem? do you use a Vector to store your sensors? define a Vector of holding sensor-objects in the house.
can access and increment that counter
you don't have to do this, the Vector does it for you
Have a look at the Singleton pattern assuming you don't want to do it with a database of some sort.

Displaying polymorphic classes

I have an existing app with a command-line interface that I'm adding a GUI to. One situation that often comes up is that I have a list of objects that inherit from one class, and need to be displayed in a list, but each subclass has a slightly different way of being displayed.
Not wanting to have giant switch statements everywhere using reflection/RTTI to do the displaying, each class knows how to return its own summary string which then gets displayed in the list:
int position = 0;
for (vector<DisplayableObject>::const_iterator iDisp = listToDisplay.begin(); iDisp != listToDisplay.end(); ++iDisp)
cout << ++position << ". " << iDisp->GetSummary();
Similar functions are there to display different information in different contexts. This was all fine and good until we needed to add a GUI. A string is no longer sufficient - I need to create graphical controls.
I don't want to have to modify every single class to be able to display it in a GUI - especially since there is at least one more GUI platform we will want to move this to.
Is there some kind of technique I can use to separate this GUI code out of the data objects without resorting to RTTI and switch statements? It would be nice to be able to take out the GetSummary functions as well.
Ideally I'd be able to have a heierarchy of display classes that could take a data class and display it based on the runtime type instead of the compile time type:
shared_ptr<Displayer> displayer = new ConsoleDisplayer();
// or new GUIDisplayer()
for (vector<DisplayableObject>::const_iterator iDisp = listToDisplay.begin(); iDisp != listToDisplay.end(); ++iDisp)
displayer->Display(*iDisp);
I don't think this will solve your problem of not needing to write the code, but you should be able to abstract the GUI logic from the data objects.
Look at a Visitor pattern (http://en.wikipedia.org/wiki/Visitor_pattern) it will allow you to add code to an existing object without changing the object itself. You can also change the visitor based on the platform.