• Advertisement
Sign in to follow this  

Mediator Pattern Help!

This topic is 1333 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

Hey all,

 

I'm writing a Mediator class in C++ and am having trouble with a part of it.  I've done this before in C# (which was really easy) and trying to do the same thing in C++ is kicking my butt.  I have a std::map that contains a std::string for the key and a std::vector<> for the value.  The idea being any number of functions/methods can be registered under any number of keys and all said functions/methods can be invoked with one call.

 

I'm having two primary problems:  1, I can't figure out how to get both functions AND class methods into the std::map.  Currently I'm using:

typedef std::function<void(void* Object)> FunctionDef;

I have a Register method in my Mediator class that takes a std::string for the key and a FunctionDef for the value.  So far this works fine for functions but I can't get it to work with class methods.

 

And 2;  I have an Unregister method in my Mediator class that takes the same inputs and removes the appropriate function from the appropriate key.  Or, at least, it's supposed too. 

template<class T>
static void Unregister(std::string Key, T Function)
{
		if (MediatorMap.count(Key) != 0)
		 {
			FunctionDef Func = Function;
			for (std::vector<FunctionDef>::iterator It = MediatorMap[Key].begin();
				It != MediatorMap[Key].end();
				++It)
			 {
				 if ((*It).target_type().name() == Func.target_type().name())
				{
					std::cout << "1" << std::endl;

					std::cout << (*It).target<T>() << " == " << Func.target<T>() << " ?? \n";
					if ((*It).target<T>() == Func.target<T>())
					{
						std::cout << "2" << std::endl;
					}
				}
			}

			if (MediatorMap[Key].size() == 0)
			{
				MediatorMap.erase(MediatorMap.find(Key));
			}
		}
	}

This is basicaly just testing code ATM.  The problem seems to be, and mind you I can only test this with functions, that whatever info is provided by .target<T>() (I'm guessing the pointer) never matches, even when sending the same function.

 

I admit to not really being sure of what I'm doing.  This is new territory for me and my C++ is a little rusty.  Any help would be appreciated.

Share this post


Link to post
Share on other sites
Advertisement

Regarding 1):

Instead of trying to assign a member function pointer (which will obviously not work because member functions have a different signature), assign a lambda:

MyObject obj;
//...
FunctionDef myFunction = [&] () { obj.memberFunctionToCall(); };

Warning: there are a lot of caveats regarding what to capture in the lambda and how to do it regarding the lifetime of the objects involved. Unless you know what you are doing exactly I would strongly recommend you post some use case examples and how you intend to use this.

 

Regarding 2):

That is impossible. As [url=http://en.cppreference.com/w/cpp/utility/functional/function/operator_cmp]the documentation[/url] says: any non-empty std::function objects will always compare non-equal. Even if they were created using the same source-function. Even if they are copies of each other.

The typical way to solve this is returning some kind of Connection-object which uniquely identifies that particular connection. See for example how boost::signals2 works.

Share this post


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

  • Advertisement