I have a polymorphic Behavior class that has MacroBehaviors and MicroBehaviors derived from it. I am assiging function pointers to each MicroBehavior. Each microbehavior when it executes, calls the function it is assigned. An executing macrobehavior ( which is built from a group of microbehaviors) simply loads the first microbehavior in its class . The functions live in Robot class. Each microbehavior/macrobehavior executing in turn puts the "next behavior" in the running deque. Each Behavior is "programmed" in the sense that it knows its "next_behavior" based on who called it (preceeding behavior that executed ) and wether the line of executing behaviors have been successful or has had some failure (enum run_type is F or S to designate this ) and wether this executing behavior succeeds or fails ( enum result type is f or s ). A 2x2 matrix with values for F,S,f,s decides the next_behavior. So to make things really modular, I need the function pointers to have the same signature. But in case, I need to derive some value from each Behavior to influence a succeeding Behavior, I decided to use an int over a boolean. Figuring that due to implicit cast from bool to int, If I have a zero value, it will be bool(0) which is false and a nonzero value will be bool(-5) which evaluates to true but I get additional information( -5) to pass around if I need to. This might be "bad practice", I am not sure. So, I am trying to move away from global variables in Robot class or minimize the use.
The check_rear_sonar will work in two modes: Given an input of 0 or nothing, it simply tells me that there is an obstacle with 5 inches in front of it. If I give it a distance input ( like how far the robot needs to travel ), it will tell me if there is an obstacle before getting there. I wish to use it as a Check_Sonar Behavior which will output true or false thereby influencing wether Move Behavior is called or Idle Behavior for example.
I was wondering if the following pseudo code will even work:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
typedef int(Robot::*m_behavior)(int); //the function signature
//Constructor for Check_Sonar MicroBehavior:
Check_rear_Sonar::Check_rear_Sonar(Robot &o, std::string iid) : MicroBehavior(o, &Robot::check_sonar<rear_sonar>, iid) { m_behavior=&Robot::check_sonar<rear_sonar>}; //does assigning a templated function maintain the function signature so a variable of type m_behavior * can be assigned an address ?
Check_front_Sonar::Check_front_Sonar(Robot &o, std::string iid) : MicroBehavior(o, &Robot::check_sonar<front_sonar>, iid) { m_behavior=&Robot::check_sonar<front_sonar> };
//Robot check_sonar pseudo function, it is based on the value of sonar_type, instead of its type.
template <sonar_type> int check_sonar(int){
if sonar_type == rear {
filter = Rf;
comparator = 30;
}
if sonar_type == front {
filter = Ff;
comparator = 60;
}
{
//the rest of the similar code
}
return result;
}
| |
I need to know at the creation of the Behavior object what the exact address is of the template instance that applies to Check_front_sonar and Check_rear_sonar. I cannot use the function parameter to designate if I wish to check the front sonar or the rear as I am using that input for other things. I dont want the function to depend on a global variable. But perhaps the <> can serve as another parameter and at the same time reduce code duplication?
What I am really trying to achieve is to reduce the code duplication with a template that instantiates functions based on a value instead of a type so there is only one Check_Sonar template. I dont even know if it is possible. I am still doing my research but I thought I'd ask the forum. I have learned quite a bit already from this forum within just the past couple of weeks. Ultimately, my ideas on how my project should work may change again. Truly, I have no idea if I can finish it in the manner that I envision currently. But it has served as a vehicle to keep me interested in studying cpp.
Thanks,
Chris