I'm making a small generative video layering software using openframeworks and c++. To this effect I have one main class, one layer class and a lot of different types of video/simulations class. I need to make it so that when I press a key, a different simulation is loaded.
I have two questions :
I made a drawing instead of using to code brackets to have all 3 blocks on the same horizontal level (actual code is underneath).
Here's the main.cpp and the layer.cpp in code for clarity :
// main.cpp
void ofApp::setup(){
layer1.setup();
layer2.setup();
layer3.setup();
}
void ofApp::update(){
layer1.update();
layer2.update();
layer3.update();
}
void ofApp::draw(){
layer1.draw();
layer2.draw();
layer3.draw();
}
void ofApp::keyPressed(int key){
switch (key)
{
case '1':
// get first class from list of classes
layer1.changeSim(); // input first class from list of simulation classes
break;
default:
break;
}
}
and the layer.cpp
void layer::setup(){
simulation = new Simulation(); // how do i initialize the Simulation variable if I dont know what type itll be ?
}
void layer::update(){
simulation.update();
}
void layer::draw(){
simulation.draw();
}
void layer::changeSim(){
simulation = new Simulation(); // destroy old simulation and create new one, but will be of a different class
}
Best method to do this is to use something called the factory pattern.
Basically, define a function that takes an argument of some defined type that can be used to figure out what kind of simulation you want, and then create that simulation and return a pointer to it.
A simple version of it might look like this:
enum SimulationType
{
Simulation_None,
Simulation_Basic,
Simulation_Complex,
...
};
Simulation* CreateSimulation(SimulationType Type)
{
switch(Type)
{
case Simulation_None:
default:
return nullptr;
case Simulation_Basic:
return new BasicSimulation();
case Simulation_Complex:
return new ComplexSimulation();
...
}
}
...
void ofApp::keyPressed(int key){
switch (key)
{
case '1':
// get first class from list of classes
layer1.changeSim(Simulation_Basic); // input first class from list of simulation classes
break;
default:
break;
}
}
...
void layer::setup(){
simulation = CreateSimulation(Simulation_None);
}
void layer::changeSim(SimulationType Type){
if(simulation) delete simulation;
simulation = CreateSimulation(Type);
}
This is a simple example - you could also use a table indexed by SimulationType
, an ordered map of SimulationType
that references static constructor functions for each type, basically anything that associates an identifier with a constructor function.