event handling

so I have a class like:

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

class DoPick{

void clear_qty()
{
   qty = 0;
}

void enter_part()
{
   //some code that listens for F2, and will call this instance of 
   //clear_qty whenever the user hits that button on either input.
   try{
      input(&part);
   }catch(InvalidInput&){
   }
   try{
      input(&qty);
   }catch(InvalidInput&){
   }
   //cancel event
}

private:
    int part;
    int qty;

};


input is a special method I have that gets input using curses. It would throw if you tried to enter something other than an int. I want to be able to put an overal listener of some sort that will automatically call the clear_qty method of this class if F2 gets pressed at any time on either of the two inputs inside of enter_part(). Any ideas?
What part do you need help with? The input part, or the calling of clear_qty() from input()?
the calling. I guess I've never worked with any kind of even listener type construct in c++. I could maybe put the ultimate code inside of input even, but I need to declare that this event is only scoped to this method.

The problem I'm currently running into is that I tried to create a map of function pointers to call from input on an F2, but because the method I want to call is a member of a class it doesn't know which instance of the method to call. It would have to be a static method some how, but that means I have to put the method outside of the class some how and in the global namespace.
So the "problem" you're having is that you did not create an instance of the class for the program to interact with? The solution seems pretty simple to me. Or am I misunderstanding you?

but that means I have to put the method outside of the class some how and in the global namespace.

Or the application window can inherit from your class... Again I may be misunderstanding you.


so I have a main() in a .cpp. Inside of my main I create an instance of DoPick(). Inside of the .cpp for DoPick() i included a library that has functions like input which interact with curses to do io. inside of that library i have a map of key strokes and funtion pointers. However I can't add the function clear_qty to that map because which version of clear_qty I want to call is dependent of which instance of DoPick() I'm in when I hit F2. If clear_qty() was a method in my original .cpp that was called from main it would work because there could be only one version of the method and there would be no confusion on the compilers part what I wanted to call. Since clear_qty() is on the class though there could potentially be multiple versions of it and the map that's in the global namespace wouldn't know which one it was supposed to call.
So it sounds like your function DoPick() should create the object that clear_qty() is a member function of.

EDIT: Does "DoPick()" create a window or someother object you can pass a handle from?
Last edited on
Also,you realize that classes start out private? Everything in your class is completely private...
Last edited on
I just re-read your first post and I can see an issue that I don't think I know how to help with.

I don't know how to pull F2 out of the input stream on a console, I can tell you exactly how to do every other part of this project. I can tell you how to do this in Win32 but that makes this platform specific, which it very well may have to be. No doubt the Boost library has a way but that would just be a bunch of overloaded #ifndef crap to fake cross-platform compatibility.

So is this a Windows app?
LB: I mean to put public at the top. That's a typo on here.

compgeek. I could definately solve the problem by having DoPick() create the object that clear_qty() is a member of, but I don't want to do that for other reasons.

it's a linux app.
AARRRGGGHHH!!! You are presenting your problem completley different from what you have written above!!!

'DoPick' doesn't have to create an object, 'DoPick' IS the object. To call the correct instance of "clear_qty()" you simply call it as you would any other member function.

The real problem is capturing "F2" I have no idea how to do that on a *nix platform. Can anyone spare some input on this?
no that's really not a problem at all. I already have a function that will capture F2. The problem is that the function pointer I pass in is stored in the anonymous namespace so when I call it the compiler doesn't know what to call.

So if I did..

1
2
3
4
5
6
7
8
9

int main(int argc, char ** argv)
{
    DoPick pick_me_1;
    DoPick pick_me_2;

    pick_me_1.enter_part();
}


now there is a version of clear_qty() on both pick_me_1, and pick_me_2, so if the function pointer to clear_qty() is in the global namespace and a user hits F2 inside of pick_me_1.enter_part() it doesn't know which version of clear_qty() it's pointing to.
Last edited on
so in the anonymous namespace I have a map and an on_global function like

1
2
3
4
5
6
7
8

map<int, key_map_t> key_map

void on_global(int key, key_map_t cb)
{
    key_map[key] = cb;
}


so inside enter_part() i can say:
1
2
3
4
5
6
7

on_global(F2, clear_key);
try{
   input(&part);
}catch(InvalidInput&){
}


now this would work if clear_key was a stand alone function in the anonymous namespace or a static function of some sort. But the fact that it is defined inside the class and operates on the qty value that is a member of the class means that if I try and store that in the anonymous namespace it's not going to know which version of clear_qty() to call and won't compile.
Ah I think I see now, you're stuck in the same boat I am with another project. You want a member function of your class to be a pointer to an outside function is that correct?
close. I want a member function to be pointed to by an outside function. That's probably just another way of saying the same thing though.

I figured there had to be some kind of an event handler or lister type thing in c++ or boost that would mimic what java does for this type of thing. Maybe not though...
I'm reading this right now if it helps you any: http://www.newty.de/fpt/fpt.html
This author knows his stuff but I haven't finished it yet.
Last edited on
Take a look at boost function, boost bind and boost signals2.
Signals sounds like a bit of overkill.

A rough principle would be like

1
2
3
4
5
std::map<int, boost::function<void ()> > keymap;
class X { void f(); };
X x;
keymap[F2] = boost::bind(&x, &X::f);
keymap[F2](); 
kev82: ok I think this is close to what I'm looking for the one problem i'm having is that when I do
 
keymap[F2] = boost::bind(&x, &X::f);


i am actually inside of class X. Which means for the &x I have to pass &this? Except that gives me a error: non-lvalue in unary `&'
No `this' is a pointer, so you would just pass `this'.

bind(this, &X::f)

This road is a little dangerous though, as you're now assuming that the object will always exist (and not change address) during the lifetime of keymap.

This can be solved by making a functor that either has a shared_ptr or weak_ptr to x.
Topic archived. No new replies allowed.