Jump to content

  • Log In with Google      Sign In   
  • Create Account

Mediator Pattern Help!


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Ahl   Members   -  Reputation: 168

Like
0Likes
Like

Posted 27 May 2014 - 09:47 PM

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.



Sponsor:

#2 BitMaster   Crossbones+   -  Reputation: 4076

Like
1Likes
Like

Posted 28 May 2014 - 08:55 AM

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 the documentation 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.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS