Juce::Message


#1

Hi,

I don’t understand the class Message of JUCE (I have clone of the git repo synchronized yesterday).
The class jucemessage was in juce 1.53 including 4 members (3 ints and a pointer)
The comments in juce_message.h still say that :

[code]/** The base class for objects that can be delivered to a MessageListener.

The simplest Message object contains a few integer and pointer parameters
that the user can set, and this is enough for a lot of purposes. For passing more
complex data, subclasses of Message can also be used.

@see MessageListener, MessageManager, ActionListener, ChangeListener

*/[/code]

but I can’t see any member in the code.

Where am I wrong ?

Best,

adrien


#2

Sorry, looks like I forgot to update that comment when I changed the class, I’ll tidy it up.

I removed the old members because it was an incredibly crappy design to have them in there - just use your own subclass of Message that has appropriate fields for the data you’re passing.


#3

Ok, thank you.
Why not making it a pure interface ?

like a
public :
struct Member{
void * data;
int size;
}
Member & getMessageMembers(const int index);
private
Member mMember;
};

A template could be great to return the type we wnat, but it would make really hard to exchange messages

Moreover the callback handleMessage pass a reference to a message, how do I use it know ?

dynamic_cast(&(messagereference))); ??? that is really crap

Thanks for the answer anyway


#4

I disagree.

If you didn’t use a dynamic_cast, then you’d need to store some kind of “type” value in there, so that your handler could check that value to find out whether it can understand the data, and if so, reinterpret_cast some blob of raw memory to whatever class it actually needs.

Using a dynamic_cast achieves the same result, but uses the underlying c++ rtti system to store the type for you, and is IMHO much cleaner (and probably faster) than messing about casting raw memory blocks.


#5

dynamic_cast is the right approach for this.


#6

FYI, me and my compiler had a few problems with the reference > pointer > cast syntax. If it helps, here’s the magic snippet:

Message* inMsg = const_cast<Message*>(&message); YourMessageClass* yourMessage = dynamic_cast<YourMessageClass*>(inMsg); if (yourMessage) { etc.

Bruce


#7

If you’re 100% sure that your message object will only be of the type you’re expecting, then you can just do this:

[code]void handleMessage (const Message& message)
{
const MyMessage& myMessage = dynamic_cast <const MyMessage&> (message);

[/code]

I think the C++ standard says that if a dynamic cast of reference type fails, it throws an exception of some kind, so you could catch that to be on the safe side.


#8

Good to know. In my case there’s a number of message types. Which one is non-null determines what I do with it.

Bruce


#9

[quote=“jules”]If you’re 100% sure that your message object will only be of the type you’re expecting, then you can just do this:

I’m 99% positive that the resulting code is slower and larger since the compiler doesn’t know about your 100% assurance - it has to emit the extra code for throwing the exception and everything that entails.

You are better off in all cases using the pointer version of dynamic_cast.


#10

hi guys, i'm deeply sorry for the necromancy of this thread, however just to be clear, what is better:

const CustomMsg* msg = dynamic_cast <const CustomMsg*> (&message);

or

const CustomMsg& msg = dynamic_cast <const CustomMsg&> (message);

..cool kid card revoked.


#11

The first version will return a nullptr if the cast fails, but the second one will throw an exception.


#12

Thank you very much Jules !

Javascript engine is beyond cool !