Jump to content
  • Advertisement
Sign in to follow this  
moeron

member function recursion guard on a per instance basis

This topic is 4426 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I don't know if I worded the title in the best fashion - but this is basically what I'm working on doing. I'm trying to prevent recursion in a member function for each instance of that class individually. Meaning a simple static local member variable is not going to do the trick because I don't want it applying to all instances of the class. So this is essentially the direction I was going...
class RecursionGuardEx{
    public:
        RecursionGuardEx( void const* this_addr,
                          void const* func_addr );
        virtual ~RecursionGuardEx( );
    public:
         bool Inside( )const;
    private:
         typedef std::multimap< void const*, 
                                void const* >        RecursionGuardExMap;
         typedef RecursionGuardExMap::iterator       RecursionGuardExItr;
         typedef RecursionGuardExMap::const_iterator RecursionGuardExConstItr;
    private:
         static RecursionGuardExMap     recursion_map;
    private:
         void const* guard_this; //the object "this" recursion guard is watching
         void const* guard_func; // the member func "this" guard is watching
    private: // not implemented
        RecursionGuardEx( RecursionGuardEx const &){}
        RecursionGuardEx& operator=( RecursionGuardEx const &){ return *this;}
};
RecursionGuardEx::RecursionGuardEx( void const *this_addr,
                                    void const *func_addr )
         : guard_this( this_addr ), guard_func( func_addr ){
   recursion_map.insert( std::make_pair( guard_this, guard_func ) );
}
RecursionGuardEx::~RecursionGuardEx( ){
    RecursionGuardEx itr = recursion_map.lower_bound(guard_this);
    RecursionGuardEx const upper = recursion_map.upper_bound(guard_this );
    while( upper != itr ){
        if( guard_func == itr->second ){
           recursion_map.erase( itr );
           break;
        }
        ++itr;
    }
}
bool RecursionGuardEx::Inside( )const{
    RecursionGuardEx itr = recursion_map.lower_bound(guard_this);
    RecursionGuardEx const upper = recursion_map.upper_bound(guard_this );
    size_t found_count = 0;

    while( upper != itr ){
       if( guard_func == itr->second ) ++found_count;
       ++itr;
    }
    return( found_count > 1u );
}

The basic idea is that it could be used like this for a member function
void foo::func( ){
    RecursionGuardEx guard( this, &foo::func );
    if( guard.Inside( ) )return;
}
Or like this for just regular old functions
void func( ){
    RecursionGuardEx guard( 0, func );
    if( guard.Inside( ) )return;
}
The problem of course is the whole member function to void* conversion which is illegal. So my question to all of those who know much more about things of this nature than myself - how can I get some kind of a unique id for a member function and regular function if I cannot just take the physical addresses? Is there some other way of doing this? -- Best Regards, moe.ron

Share this post


Link to post
Share on other sites
Advertisement
Probably not doable. Member function pointers not only aren't really pointers, but have different types depending on all aspects of the function signature - including what class they belong to.

Why do you *want* to do this?

Share this post


Link to post
Share on other sites
Why is a per-instance class data member flag not possible/desireable?

To make your RecursionGuard work, template it against the class type and member function pointer type. You can avoid having to do specify the type explicitly by defining a templated helper function, allowing you to have

if (guard(this, &foo::func))


If you're not sufficiently familiar with templates, I can probably hook you up with the necessary definitions.

EDIT: I just realised that would defeat the purpose of the RAII pattern here, so you probably need to stick with a template class.

~phil

Share this post


Link to post
Share on other sites
Quote:
Original post by Zahlman
Probably not doable. Member function pointers not only aren't really pointers, but have different types depending on all aspects of the function signature - including what class they belong to.

I realize that member function pointers can be more than just pointers. But I never really need to dereference these pointers - they are just a means of unique identification. So is there some kind of an "offsetof" that could let me differentiate one member function from another? It just seems that there must be some internal representation that I can use as a part or whole to tell one member function from another.

Quote:
Zahlman
Why do you *want* to do this?

I want to do this because I need a recursion guard for a spinner control I'm writing to prevent it from re-entering an update function. Thats why I need it to work on a per instance basis. I figured I could just write a basic recursion guard class so it could be used for regular functions as well ( non member functions ).

--
Best Regards,
moe.ron

[edit]
I'm also open for suggestions if anyone has any ideas on a better way to do this

[Edited by - moeron on July 6, 2006 8:54:09 PM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!