How to write a traffic light "get program" and "get phase" functions in traci interface? - veins

Checking in the TraCICommandInterface there are only two function for the traffic lights. The first one is setProgram and the other one is setPhaseIndex how can I write the get functions for them?

In TraCICommandInterface.h: insert the following functions definitions under traffic light methods:
// Trafficlight methods
std::string getProgram();
int getPhaseIndex();
In TraCICommandInterface.cc: insert the following functions declarations:
std::string TraCICommandInterface::Trafficlight::getProgram() {
return traci->genericGetString(CMD_GET_TL_VARIABLE, trafficLightId, TL_CURRENT_PROGRAM,RESPONSE_GET_TL_VARIABLE);
}
and
int TraCICommandInterface::Trafficlight::getPhaseIndex() {
return traci->genericGetInt(CMD_GET_TL_VARIABLE, trafficLightId, TL_CURRENT_PHASE,RESPONSE_GET_TL_VARIABLE);
}

Related

How would you cleanly follow the Stepdown rule in C/C++?

The Stepdown rule encourages to read the code like a top-down narrative. It suggests every class/function to be followed by those at the next level of abstraction so we can read the code descending in the level of abstraction.
In C/C++ you need to declare classes/functions before you use them. So how would cleanly apply the Stepdown rule here? What are some pros and cons of the following approach? Any better one?
void makeBreakfast();
void addEggs();
void cook();
void serve();
int main()
{
makeBreakfast();
}
void makeBreakfast()
{
addEggs();
cook();
serve();
}
void addEggs()
{
// Add eggs.
}
void cook()
{
// Cook.
}
void serve()
{
// Serve.
}
My approach is like yours but with either making a class so the declaration can come after use, or put declarations in a header file.

Styling non member class related functions

When it comes to defining your non member class related functions, should you typically have them in the header file or source file? Which is generally the best practice? Or is it all personal preference?
Always try to minimize visibility. If you need your function only in the source file you can put it into an unnamed namespace:
// Your .cpp
namespace
{
void yourHelperFunction( void ) // only visible in the translation unit
{
...
}
}
//
I wanted to comment because I'm currently on my way home but I need a higher reputation... maybe I will refine my answer later.
I generally choose one of four strategies for helper functions in C++, depending on re-use requirements.
1. Is the function large, and only used in one source file?
If this is a function that is only required in a single .cpp file, and it is going to be used in multiple places, put it into a anonymous namespace at the top of your .ccp file:
namespace
{
int myHelperFunc()
{
int result = 0;
....
return result;
}
}
...
bool MyClass::someMethod()
{
return 0 != myHelperFunc();
}
void MyClass::someOtherMethod()
{
if (0 == myHelperFunc())
{
for (int i = 0; i < 10; ++i)
std::cout << i << std::endl;
}
}
This allows re-use of the helper function, but avoids any potential naming conflicts.
Advantages
Scope limited to a single file.
No chance of naming conflicts with other helper functions in other files with the same name.
Disadvantages
Large numbers of helper functions dropped at the top of a source file can pollute the file with functions of limited scope.
2. Does the function require access to class state?
If the helper function requires access to your internal class state, make it a private method.
int MyClass::myStatefulHelperFunc()
{
int result = 0;
if (IsInitialized())
{
....
}
return result;
}
...
bool MyClass::someMethod()
{
return 0 != myStatefulHelperFunc();
}
void MyClass::someOtherMethod()
{
if (0 == myStatefulHelperFunc())
{
for (int i = 0; i < 10; ++i)
std::cout << i << std::endl;
}
}
Advantages
Scope limited to a single class.
Access to class state.
Can be made virtual allowing derived classes to override the helper with an alternative implementation.
Disadvantages
Must be declared in the header file.
3. Is the function helpful in multiple source files?
If the helper function might be used in multiple places in your codebase, extract it into it's own file inside it's own namespace:
HelperFunction.h
namespace ProjectHelpers
{
/**
* \brief Do helpful thing.
*
* \return a helpful integer.
*/
int myHelperFunc();
}
Advantages
Easily accessible from anywhere in the codebase.
Disadvantages
Large numbers of helper functions shared across multiple classes/translation units could be indicative of a code smell.
4. Is the helper function limited to a single function, and very small?
If the helper function is very small, and the usage is limited to a single function, you could create a lambda function and use it like you would any other function using the C++ algorithm function (e.g. std::for_each()).
Advantages
Scope limited to a single function.
Can be used in multiple places within the function by assigning to a variable.
Disadvantages
C++11 and later only.
5. ... Other options
Other options for helper functions include static class functions and copy/pasting code. Each of the above strategies has it's own benefits and drawbacks as well, so it is up to you to decide the best approach for your own codebase.

Refactoring 3 cyclic classes

I have made a big edit in attempt to clarify what help I am asking for and to try to make the question appropriate for Stack Overflow.
The problem in general: I have an existing library class which allows me to query a server for information. That library class is widely used by a large amount of legacy software, so I am somewhat limited in the changes I can make to it. Likewise, reimplementing it in a better fashion might not be time well spent.
The problem in specific: I've create a simplified "toy" model of my approach below with 3 classes. The real thing is more complex, as there are polymorphic variations, more functionality, error handling, etc.
In "toy" model code included below, Gateway is the existing library class. I've tried to show how I would like to use it, with a result set and a way to access each member of the set. The idea is similar to how a well-implemented database API might look, with a statement, result and row -- except in my case, what would be the statement class is hobbled by a poor design which includes part of the result functionality.
The toy example below will not compile as-is because of the following cyclical dependecy. The Gateway class includes the ResultSet class and depends upon it, as it returns a ResultSet object. The ResultSet class depends on the Member class, as it uses it to convert the data returned from the server into primitives (e.g. string). But the Member class refers back to the Gateway class to access that data, and so there is a cycle.
I want to find a solution which will provide the ResultSet and Member functionality.
For a simpler 2 class problem, I know a solution. It is to create a superclass that one class derives from (is-a), and which the other class is composed of (has-a), such that both original classes depend on the third, and all is right with the world. :-)
For my 3 class problem, for some reason I have been unable to wrap my head around how to refactor it to make it work.
// Gateway.h
#include "ResultSet.h"
class Gateway {
ResultSet exec(string params);
};
// Gateway.cpp
ResultSet Gateway::exec(string p) { ... }
// ResultSet.h
#include "Member.h"
class ResultSet {
ResultSet(); // ctor
int index;
bool next();
string getCurrent(Member member);
};
// ResultSet.cpp
ResultSet::ResultSet() { index = 0; }
bool ResultSet::next() { ++index < length; }
string ResultSet::getCurrent(Member member) { member.fetch(index) }
// Member.h
#include "Gateway.h"
class Member {
Gateway gateway;
string fetch(int i);
};
// Member.cpp
string Member::fetch(int i) { return gateway.sGet(i); }
// Example desired usage of the final API.
main() {
Gateway gate;
ResultSet set;
Member member;
set = gate.exec("...");
while (set.next()) {
cout << set.getCurrent(member) << endl;
}
}
The solution to your issue is to forward declare the overlapping classes in the header files, and then to include their actual .h files from your .cpp implementation files.
For instance, to get around Gateway's dependencies on ResultSet,
// Gateway.h
class ResultSet;
class Gateway {
ResultSet exec(string params);
};
This forward declares the class ResultSet.
Now in Gateway.cpp, we have to provide the actual interface to the compiler. So now we include ResultSet.h.
// Gateway.cpp
#include "ResultSet.h"
ResultSet Gateway::exec(string p) { ... }
We do this for your other cyclic relationships, and you will then have source you can compile and build.
For ResultSet, we will forward declare Member.
// ResultSet.h
class Member;
class ResultSet {
ResultSet(); // ctor
int index;
bool next();
string getCurrent(Member member);
};
And in its implementation file, we will finally include Member's header.
// ResultSet.cpp
#include "Member.h"
ResultSet::ResultSet() { index = 0; }
bool ResultSet::next() { ++index < length; }
string ResultSet::getCurrent(Member member) { member.fetch(index) }
And finally, Member...
// Member.h
class Gateway;
class Member {
Gateway gateway;
string fetch(int i);
};
And of course, Member.cpp must then include Gateway's information.
// Member.cpp
#include "Gateway.h"
string Member::fetch(int i) { return gateway.sGet(i); }
Now there are no cyclic dependencies.

Using objects and object functions through variables

Background of the program: the user is able to input a string of two words only - a verb and a noun. I tokenize this string into a vector and compare tokens[0] with a vector of allowed verbs, and tokens[1] with a vector of allowed nouns.
Now, I'm trying to find a way to allow only certain verbs to be performed on certain nouns. For example, writing "take book" will give a message (or whatever) saying it's allowed, but writing "take door" would not be. I have so far created a class Object with bool values for each possible verb (eg. within the class Object, I can create an Object book for which m_take = true, or false for an Object door).
However, I'm having trouble associating these objects with the user input. For example, I would like to be able to do something like this:
1) User inputs "verb noun", which go into the tokens vector as tokens[0] and tokens[1].
2) Program checks if the input contains acceptable words (individually).
3) Considering getstat() to be the function to retreive the bool value of the possible action doable on an object, the program retrieves tokens[1].getstat(tokens[0]) and, if true, executes tokens[0].tokens[1]() (eg. book.take()). This way I could have only one if cycle in my main(), which can be used by all legal verbs and nouns, without making an infinite list of if, else if, etc, considering every single option manually.
Sorry if this is at all confusing. I know it is not possible to use a variable as an object name, but I'm sure there's a better way to do this than doing cycles within cycles of considering every single mix and match of verb and noun. I'm experimenting with like 3 each at the moment, but once I get this working I plan on expanding it and it would be a nightmare to keep track of every change if I have to hard-code every possible verb and noun multiple times within the source code. (Also, sorry for not posting the whole source - it's a really long file just now!)
Thanks for any help/hint in the right direction!
You could use runtime polymorphism for this kind of stuff, either with virtual methods or C++11 std::function and lambdas.
You will obviously have to redesign your "token" system.
Virtual methods example:
struct Object
{
virtual void onTake() { }
virtual void onOpen() { }
};
struct Door : public Object
{
bool open{false};
void onTake() override { say("I can't take the door!"); }
void onOpen() override { say("The door is now open."); open = true; }
};
struct Book : public Object
{
void onTake() override { say("I put the book in my backpack."); }
void onOpen() override { say("I open the book. All the pages are blank."); }
};
C++11 lambdas example:
struct Object
{
std::function<void()> onTake, onOpen;
};
struct Door : public Object
{
bool open{false};
Door()
{
onTake = []{ say("I can't take the door!"); };
onOpen = []{ say("The door is now open."); open = true; };
}
};
struct Book : public Object
{
Book()
{
onTake = []{ say("I put the book in my backpack."); };
onOpen = []{ say("I open the book. All the pages are blank."); };
}
};
// You can also avoid creating new classes
Object bananaPrototype;
bool eaten{false};
bananaPrototype.onTake = []{ say("I put the banana in my backpack."); };
bananaPrototype.onOpen = [eaten] mutable
{ say("I eat the banana. Yum."); eaten = true; };
It's hard to give an advice in such a non trivial case not seeing the code, but, as far as I understand, you'd better consider dropping the hardcode approach, i.e.
book.take().
Try writing more generic code, at least something like book.action(actions::kTake).
As you say, tokens[0].tokens[1]() does not do what you want it to - the names of functions and variables are not available when the program is being run.
You could try using maps. objects could be a map with keys of the object names. The values (objects[token[0]]) would in turn be other maps which would be functions to do what you want (objects[token[0]][token[1]]).
Here is an example:
#include <unordered_map>
#include <string>
#include <iostream>
using namespace std;
void read_fn()
{
cout << "You read the book";
}
int main()
{
unordered_map <string, unordered_map <string, void (*)()>> lookup;
unordered_map <string, void (*)()> book_lookup;
book_lookup["read"] = read_fn;
lookup["book"] = book_lookup;
lookup["book"]["read"]();
}

std::vector::push_back fails to add data to my vector

I have these two pieces of code that are messing up without throwing any errors:
The first piece is from a custom class which I am trying to push into an array.
class idRect {
public:
sf::FloatRect rect;
int id;
idRect(int _id, sf::FloatRect _rect) : id(_id), rect(_rect) {}
};
The second piece is where the function gets called.
if((deltaX + deltaY) < 500) { //Taxi distance calculation
cout << endl << "Passed check" << endl;
gloAreas.push_back(idRect(id, entity.getGlobalBounds()));
}
gloAreas is a globally defined vector which contains idRect objects.
As said earlier I have observed from the console that "Passed check" outputs and that the size of my vector doesn't increase EDIT: globally.
Edit: The error also seems rather random and only happens for 1 in 6 instances of the objects calling the push_back functions.
I'm using SFML for the sf::FloatRect which is basically just a vector of 4 floats. getGlobalBounds() is another function from SFML that returns the bounding rectangle of a sprite in sf::FloatRect format.
Any ideas of what is going wrong?
Sincerely,
BarrensZeppelin
EDIT 2:
The error seems to have erupted due to a mix between my own incompetence and std::multiset's sorting, maybe I'll come back for that in another thread ^^ (With a sscce ofc)
Thank you guys for you time and help.
If gloAreas is defined as static, it won't be a true global. It will have global scope, but a copy of it will be created for each translation unit.
For a global, you need to declare it with extern and define it in a single implementation file.
Disclaimer: answer is just a guess, my crystal ball might be off today...
My crystal ball answer: You have redefined gloAreas in an interior scope, like this:
vector<idRect> gloAreas; // defines global
void F( vector<idRect> gloAreas ) // defines local instance
{
gloAreas.push_back(); // affects local instance
return; // destroys local instance
}
int main() {
F(gloAreas); // Copies global instance to parameter
// global remains unchanged.
}