I am using OIS for handling my input with Ogre and currently, on KeyPress/Release a Message object like the following will be constructed and distributed among subscribers.
class Message
{
public:
Message();
~Message();
inline void SetKeyEvent(const OIS::KeyEvent& keyEvent) { _keyEvent = keyEvent; }
const OIS::KeyEvent& GetKeyEvent() const { return _keyEvent; }
private:
OIS::KeyEvent _keyEvent;
};
Since this object will be constructed/destroyed whenever input is received via keyboard, I am trying to store a pre-constructed Message object and then simply update the _keyEvent field with the new data, before distributing.
The problem is that the OIS::KeyEvent object has a const member which is preventing me from using the assignment operator. The SetKeyEvent method gives me the following syntax error:
function "OIS::KeyEvent::operator=(const OIS::KeyEvent &)" (declared implicitly) cannot be referenced -- it is a deleted function
I was wondering what the best way to achieve this functionality would be?
Thanks in advance
EDIT: Just to clarify, I already use initializer lists when possible. My intention is to have the Message object pre-constructed and then update the _keyEvent field with the new event data from the KeyPress event which OIS fires, using the SetKeyEvent method. I would like to know if this is possible and if so, what the best way to do it would be.
The copy operator is deleted, so you must work with pointers.
class Message
{
public:
Message();
~Message();
inline void SetKeyEvent(OIS::KeyEvent* keyEvent) { _keyEvent = keyEvent; }
const OIS::KeyEvent& GetKeyEvent() const { return _keyEvent; }
private:
OIS::KeyEvent* _keyEvent;
};
And now it's better to check if the argument in the setter isn't nullptr.
inline void SetKeyEvent(OIS::KeyEvent* keyEvent)
{
assert(keyEvent != nullptr);
_keyEvent = keyEvent;
}
assert() needs #include <assert.h>
EDIT:
Sorry, forgot the getter method. You must use pointers, too.
const OIS::KeyEvent* keyEvent = &Message.GetKeyEvent();
Where Message is your class instance.
It is possible by using placement new and an explicit destructor call, things you normally should never do:
inline void SetKeyEvent(const OIS::KeyEvent& keyEvent)
{
_keyEvent.~KeyEvent();
new (&_keyEvent) OIS::KeyEvent(keyEvent);
}
This is bad ugly horrible code, use at your own risk.
Related
I don't know whether I don't get the logic behind adding a function to eclipse/omnet++:
Tried to simply add a new function "init_func" to the VeinsInetSampleApplication.h Header file
#pragma once
#include "veins_inet.h"
#include "VeinsInetApplicationBase.h"
class VEINS_INET_API VeinsInetSampleApplication : public veins::VeinsInetApplicationBase {
protected:
bool haveForwarded = false;
protected:
virtual bool startApplication() override;
virtual bool stopApplication() override;
virtual void processPacket(std::shared_ptr<inet::Packet> pk) override;
// ADAPTION 2022/05/28
virtual void init_func();
public:
VeinsInetSampleApplication();
~VeinsInetSampleApplication();
};
However when I simply copy the initialization code of the startApplication() function into "init_func()" in VeinsInetSampleApplication.cc "init_func()" is simply ignored by my simulation.
Here's the code snippet which basically shall send a message to all my simulation nodes at time t=5 sec. The only difference to the startApplication() function is that the message sending is triggered at t=5sec. and not at t=10sec.
The startApplication() function does its job correctly and even if i comment it out and only make my init_func() function run it is also ignored. (I tried this in order to rule out any issues with the "this" pointer etc. which would suggest there is a "bad interaction" between both functions). So it really seems like my init_func() is not registered. But I don't know. Does anybody have an idea why "init_func()" might be ignored here by Omnet++?
Code of init_func():
void VeinsInetSampleApplication::init_func()
{
// host[0] should stop at t=5s, change in timerManger.create(...)
if (getParentModule()->getIndex() == 0) {
auto callback = [this]() {
getParentModule()->getDisplayString().setTagArg("i", 1, "red");
traciVehicle->setSpeed(0);
auto payload = makeShared<VeinsInetSampleMessage>();
timestampPayload(payload);
payload->setChunkLength(B(100));
payload->setRoadId(traciVehicle->getRoadId().c_str());
auto packet = createPacket("accident");
packet->insertAtBack(payload);
sendPacket(std::move(packet));
};
timerManager.create(veins::TimerSpecification(callback).oneshotAt(SimTime(5, SIMTIME_S)));
}
}
(I also changed return type of "init_func" to bool to further increase similarity. But that of course was also not successful)
Best regards,
Lukas
init_func() is ignored because it is not called neither by initialize() nor by any other method. You decided to create a new method, so you have to add calling of that method somewhere in the code.
As you can see by my code, I'm trying to create a onClick event for a button that invoke a function from another class (I'm trying to make my custom button class instead of using win32 default ones for testing).
But even if this does not throw any error, it just doesn't invoke the given method.
This is the function signature inside Button.hpp
void onClick(POINT pt, void (ButtonsHandler::*clicked)(void));
This is the implementation inside Button.cpp (Using clicked() throws C++ expression preceding parentheses of apparent call must have pointer-to function type)
void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void))
{
if (PtInRect(&textRect, pt) != 0)
{
clicked;
}
}
And this is where I actually call it
mainMenu.getPlay().onClick(pt, &ButtonsHandler::onPlay);
EDIT: solved thank you guys
I was just not creating a ButtonsHandler object to execute the non-static function
Here's the correct code I was missing.
void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void)) {
if (PtInRect(&textRect, pt) != 0) {
ButtonsHandler bh;
(bh.*clicked)();
}
}
It just doesn't invoke the given method!
The passed pointer to member function has to be called to get in effect.
I assume that the Button is inherited from the ButtonsHandler. Then, for instance, you can call with the pointer to member function with this pointer as follows:
void Button::onClick(POINT pt, void (ButtonsHandler::*clicked)(void))
{
if (PtInRect(&textRect, pt) != 0) {
(this->*clicked)();
//^^^^^^^^^^^^^^^^^^
// or
// std::invoke(clicked, this) // need to include <functional> header(Since C++17)
}
}
If both classes are unrelated, you required an instance of ButtonsHandler to call the member function. For example:
ButtonsHandler obj;
(obj.*clicked)();
// or
// std::invoke(clicked, obj) // need to include <functional> header
I am trying to test a function like below within Provider.cpp,
SomeType::Data Provider::getData()
{
const Param param();
SomeType wanted_data = SomeType::Data(Creator{}(param));
return wanted_data;
}
But that Creator creation in getData() makes testing this function difficult.
FYI, Provider.h is like
class Provider {
public:
SomeType::Data getData();
// constructor/destructor
Provider(System& system);
~Provider();
private:
System& m_system;
};
While Creator has the following in Creator.h
class Creator {
public:
//operator function overload?
virtual SomeType::Data operator()(Param param) {
SomeType::Data data = ...;//create data
return data;
}
// constructor/destructor
Creator();
virtual ~Creator(){};
};
I looked up for hours, and it seems like mocking a creation of an object within a function seems not possible. If I still wanna test this function and create an the DataCreator object whenever I call getData(), how can I get it done? (if it's possible...)
I read on google saying something like you can use pointer or reference in the constructor in such case, but I am not sure what it means... :'(
I am currently trying to implement an event system where layers can subscribe to certain event types. I am struggling with function pointers for the callback methods. In the layer.h file I have the OnEvent function and a function pointer which looks like this:
void OnEvent(const Event& e);
void(Engine::Layer::*m_EventCallback)(const Event& e);
In the constructor of a layer I simply do this:
m_EventCallback = OnEvent;
To keep track of which layer subscribed to which EventType I have defined a struct as folling:
struct CallbackData {
EventType type;
void(Engine::Layer::*OnEvent)(const Event& e);
int layerID;
bool isActive;
};
I have an EventDispatcher and its dispatch function looks something like this:
bool EventDispatcher::Dispatch(const Event& e)
{
for (CallbackData& calldata : m_Callbacks) {
if (calldata.type == e.GetEventType() && calldata.isActive) {
calldata.OnEvent(e);
}
}
//TODO work on this so it only returns true if the event has been properly dispatched
return true;
}
There is also a subscribe function which creates an instance of CallbackData and pushes it into a vector which looks like this:
void EventDispatcher::Subscribe(EventType type, void(Engine::Layer::*OnEvent)
(const Event& e), int layerID)
{
CallbackData temp = { type, OnEvent, layerID, true };
m_CallbackInsert = m_Callbacks.emplace(m_CallbackInsert, temp);
}
So if the type is of callback data is the same as the event references type the OnEvent function should get called via the function pointer.
The function pointer defintion needs to have Engine:: which is just a namespace and Layer which is the class where the OnEvent lies. I dont know why it needs the namespace because everything I do here is defined in the namespace.
But the main question is how do I properly define the function pointer and then call it the way showcased here?
The exact error message is this:
expression preceding parentheses of apparent call must have(pointer-to-)function type
Please dont link sites with already implemented event systems. I have already looked at those and didnt really understand much. Thats why I want to do it myself so I do understand it.
Thanks in advance!
Assuming I understand what you're doing...
You have an EventDispatcher, and he needs to keep a registry of possible callbacks to make. I'm going to cut & paste a little code I use then explain it.
First, this is the relevant portion of my Route object.
class Route {
public:
typedef std::function<void(const HTTPServerRequest &, HTTPServerResponse &)> Callback;
Callback callback;
};
class Router {
public:
void addRoute(const std::string &method, const std::string &path, Route::Callback callback);
};
That part works about how you would expect and doesn't require anything special. This creates an array of Route objects, with the callback method being given the callback passed into addRoute(). When I want to dispatch on this particular route:
route->callback(request, response);
You probably know that part, too.
For my code, I'm making method calls into an object. To pass that, you have two choices. The first is to use std::bind() -- which I really dislike.
So I use lambdas.
addRoute("GET", "/ping", [=](const HTTPServerRequest &request, HTTPServerResponse &response) { ping(request, response); } );
Is this absolutely the most efficient? I have no idea. But performance isn't ultra-sucky, so this is what I do.
Basically, I keep std::function<> pointers, and those are really easy to use. You can pass a lambda as a std::function<> as long as the signature matches.
The other choice is to use std::bind -- which, as I said, I don't like, mostly because I think it's uglier than using a lambda. But that's definitely an opinion, not a fact. Using std::bind may be a better way, but I don't have any code to show you doing it that way.
I'm not entirely sure this actually solves the confusion you're having, but if it's close, just comment, and I'll try to clarify.
I have a very simple class definition as follows:
#include "../bshttp/controllers.h"
#include <iostream>
#include <string>
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this)
{
m_urlRules["print"] = REG_NAME &DerivedController::print;
//regController(REG_NAME &DerivedController::print,"print");
regController(REG_NAME &DerivedController::printView,"printView");
}
void * print()
{
return NULL;
}
void * printView()
{
cout<<"Print view!"<<endl;
return NULL;
}
};
where either
m_urlRules["print"] = REG_NAME &DerivedController::print;
or
regController(REG_NAME &DerivedController::printView,"printView");
has to be called for all of the member functions. What it does it that it takes the member function pointer of the class and maps with a string, so later on the function can be identified with a string.
Everything is all well and working, but when the class structure gets bigger, the programmer will have to repetitively call this function for every single member function. Is there anyway to use the preprocessor, or any preprocessing library such as the boost-wave, so that the programmer doesn't have to do these repetitive calling?
EDIT:
Sorry for the confusion, I clearly did not describe the problem well enough here.
I am mapping strings to member function pointer;
m_urlRules is a std::map with string as the key, and member function pointer as value
regController is basically a setter function for m_urlRules, so both statements effectively does the same thing, which maps a string to a member function.
REG_NAME is a macro to replace a very ugly typecast.
what I am trying to do is that, if the class where to have the following structure,
class DerivedController : public BS_Controllers
{
public:
DerivedController():BS_Controllers(this);
void * print();
void * print2();
void * print3();
void * print4();
};
I dont have to do the following in the constructor:
m_urlRules["print"] = REG_NAME &DerivedController::print;
m_urlRules["print1"] = REG_NAME &DerivedController::print1;
m_urlRules["print2"] = REG_NAME &DerivedController::print2;
m_urlRules["print3"] = REG_NAME &DerivedController::print3;
m_urlRules["print4"] = REG_NAME &DerivedController::print4;
Well, you're trying to build the runtime type information (RTTI) on your own, so no there is no preprocessor macro for this. Mainly because preprocessor macros expand to a single place, and the place where you declare, and the place, where you register your functions are different.
Qt and qmake, does something like this, it finds the functions marked signals/slots, and builds a moc object for RTTI. That's about the best you can get with c++. Other languages like java, and delphi, has more RTTI, than c++, and makes it possible to query functions at runtime.
I am not exactly sure I understood completely your problem, but why don't use the built-in data structure, such as map, in which you can map it to a key (your string).
Here some examples
I would first work on removing the ugly typecast (even in macro form). This can be done by moving the m_urlRules out of BS_Controllers and into an intermediate (or proxy) template class. The template is used to resolve the map to the right derived type. (I didn't know how you defined BS_Controllers, so I made one up.)
class BS_Controllers {
protected:
virtual ~BS_Controllers () {}
public:
virtual void * invokeRule (const std::string &) = 0;
};
template <typename D>
class BS_Proxy : public BS_Controllers {
typedef std::map<std::string, void *(D::*)()> UrlRuleMap;
static UrlRuleMap & urlRules () {
static UrlRuleMap urlRules_;
return urlRules_;
}
void * invokeRule (const std::string &s) {
typename UrlRuleMap::iterator i = urlRules().find(s);
if (i == urlRules().end()) return 0;
return (dynamic_cast<D *>(this)->*(i->second))();
}
protected:
static void regController (void *(D::*m)(), const std::string &s) {
urlRules()[s] = m;
}
};
Now, the DerivedController can be initialized fairly easily, by invoking the regController method of the proxy class.
#define REG_RULE(D, x) BS_Proxy<D>::regController(&D::x, #x)
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
REG_RULE(DerivedController, print);
REG_RULE(DerivedController, printView);
}
};
public:
DerivedController() {
static Populate populate_;
}
void * print() { return NULL; }
void * printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
};
You can view a demo of the above code.
If you want to make the population semi-automatic, you still have to define the list of methods somewhere. You could list them out in a file.
// DerivedController rules
DERIVED_RULE_INC(print)
DERIVED_RULE_INC(printView)
//...
And then change your DerivedController class to use this file:
class DerivedController : public BS_Proxy<DerivedController> {
struct Populate {
Populate () {
#define DERIVED_RULE_INC(x) REG_RULE(DerivedController, x);
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
}
};
public:
DerivedController() {
static Populate populate_;
}
#define DERIVED_RULE_INC(x) void * x ();
#include "derived_controller_rules.inc"
#undef DERIVED_RULE_INC
};
void * DerivedController::print() { return NULL; }
void * DerivedController::printView() {
std::cout<<"Print view!"<<std::endl;
return NULL;
}
Now, if you add another rule to the file, the registration code and the method declaration is automatic. But the definition of the method needs to be implemented, or a linker error will be generated about the missing method definition.
I believe you want to use this feature for logging reasons, to see where problems appear.
I think you're searching for something like:
urlRules ("<function name>");
regController("<function name>");
Instead of
m_urlRules["<function name>"] = REG_NAME &DerivedController::print;
regController(REG_NAME &DerivedController::printView,"<function name>");
You can define such makros like so:
#define urlRules(x) { m_urlRules[(x)] = REG_NAME &DerivedController::print; }
#define regController(x) { regController(REG_NAME &DerivedController::printView,(x)); }
Attention: I have not tested it, it might not work but in my understanding it should.
EDIT:
Ah now I understand, you want calls for every function within the constructor.
Actually, the constructor is the wrong place, because it gets called for every object you create, but you only have to assign this pointers once. (on startup for example)
See, the functions of a class only exist once in memory, and the thing that is connected to the pointer is the yield data, so all member variables.
There is no simple way to get all class members by name and then run over them, sorry.
At least not as I know of.
But you should keep in mind that the function pointers won't change for any given object.
An external function which does the work would be more intelligent. Called on startup.