DynaMix  1.3.7
A new take on polymorphism in C++
message_macros.hpp File Reference
#include "message.hpp"
#include "preprocessor.hpp"
#include "exception.hpp"
#include "domain.hpp"

Classes

struct  dynamix::internal::msg_caller< Ret, Args >
 
struct  dynamix::internal::msg_unicast< Derived, Object, Ret, Args >
 
struct  dynamix::internal::msg_multicast< Derived, Object, Ret, Args >
 

Macros

#define I_DYNAMIX_MESSAGE_STRUCT_NAME(message_name)   I_DYNAMIX_PP_CAT(dynamix_msg_, message_name)
 
#define I_DYNAMIX_MESSAGE_TAG(message_name)   I_DYNAMIX_PP_CAT(message_name, _msg)
 
#define I_DYNAMIX_MESSAGE_CALLER_STRUCT(mechanism)   I_DYNAMIX_PP_CAT(msg_, mechanism)
 
#define DYNAMIX_DEFAULT_IMPL_STRUCT(message_name)   I_DYNAMIX_PP_CAT(message_name, _default_impl_t)
 
#define I_DYNAMIX_MESSAGE_ARG_ERROR   static_assert(false, "DynaMix macro called with a bad number of arguments")
 
#define I_DYNAMIX_VA_ARGS_PROXY(MACRO, args)   MACRO args
 
#define I_DYNAMIX_GET_MIXIN_DATA(obj, id)   reinterpret_cast<char*>(const_cast<void*>(obj._mixin_data[obj._type_info->_mixin_indices[id]].mixin()))
 
#define DYNAMIX_MESSAGE_N(return_type, message, args)
 
#define DYNAMIX_DEFINE_MESSAGE_N_WITH_DEFAULT_IMPL(return_type, message_name, args)
 
#define DYNAMIX_DEFINE_MESSAGE(message_name)
 

Detailed Description

Macros used to declare and define messages.

Macro Definition Documentation

#define DYNAMIX_MESSAGE_N (   return_type,
  message,
  args 
)

Macro that declares a message

This generates the stand-alone function which is users should use to call messages.

The calls will throw the exception bad_message_call if none of the mixins from which the object is composed handles this message. To prevent the message calls from Throwing exceptions you can define DYNAMIX_NO_MSG_THROW before including the library's headers.

Variants:
1 DYNAMIX_MESSAGE_N(return_type, message, args)
2 DYNAMIX_CONST_MESSAGE_N(return_type, message, args)
3 DYNAMIX_MULTICAST_MESSAGE_N(return_type, message, args)
4 DYNAMIX_CONST_MULTICAST_MESSAGE_N(return_type, message, args)
5 DYNAMIX_EXPORTED_MESSAGE_N(export, return_type, message, args)
6 DYNAMIX_EXPORTED_CONST_MESSAGE_N(export, return_type, message, args)
7 DYNAMIX_EXPORTED_MULTICAST_MESSAGE_N(export, return_type, message, args)
8 DYNAMIX_EXPORTED_CONST_MULTICAST_MESSAGE_N(export, return_type, message, args)
9 DYNAMIX_MESSAGE_N_OVERLOAD(message_name, return_type, method_name, args)
10 DYNAMIX_CONST_MESSAGE_N_OVERLOAD(message_name, return_type, method_name, args)
11 DYNAMIX_MULTICAST_MESSAGE_N_OVERLOAD(message_name, return_type, method_name, args)
12 DYNAMIX_CONST_MULTICAST_MESSAGE_N_OVERLOAD(message_name, return_type, method_name, args)
13 DYNAMIX_EXPORTED_MESSAGE_N_OVERLOAD(export, message_name, return_type, method_name, args)
14 DYNAMIX_EXPORTED_CONST_MESSAGE_N_OVERLOAD(export, message_name, return_type, method_name, args)
15 DYNAMIX_EXPORTED_MULTICAST_MESSAGE_N_OVERLOAD(export, message_name, return_type, method_name, args)
16 DYNAMIX_EXPORTED_CONST_MULTICAST_MESSAGE_N_OVERLOAD(export, message_name, return_type, method_name, args)
Legend:
  • N in those variant names is a number that indicates how many parameters the message takes. If N is 0, then args is omitted.
  • args is a coma-separated list of the argument types and argument names of the message's arguments
  • If MULTICAST is a part of a macro, it declares a multicast message. Otherwise it declares a unicast message.
  • If CONST is part of a macro, then the message works with const object& and should be bound to const methods of a mixin class. Otherwise it works with simply object& and should be bound no non-const methods of the mixin class.
  • If EXPORTED is part of a macro, then it's used to declare a message that is exported from a dynamic library. The export parameter should be the appropriate export/import symbols for the particular compiler (i.e. __declspec(dllexport))
  • If OVERLOAD is part of a macro, it defines a message overload. It splits the ways of referring to the message in two. The first - message_name - should be used when referring to the message - in mixin feature lists, in object::implements, and in DYNAMIX_DEFINE_MESSAGE. The second - method_name - is the name of the method in the mixin class, and will be the name of the message function generated by the macro.
Examples:
1 // A basic non-const unicast message with no arguments.
2 // Should be bound to: void mixin_class::foo()
3 DYNAMIX_MESSAGE_0(void, foo);
4 
5 // A const multicast message with two arguments
6 // Should be bound to: void mixin_class::serialize(archive& ar, int flags) const
7 DYNAMIX_CONST_MULTICAST_MESSAGE_2(void, serialize, archive&, ar, int, flags);
8 
9 // Assuming MY_LIB_API is a macro that expands accordingly to the
10 // export/import symbols for the compiler you're using, this is
11 // a const unicast message with one argument exported from a dynamic library
12 // Should be bound to: float mixin_class::size(int dimension) const
13 DYNAMIX_EXPORTED_CONST_MESSAGE_1(MY_LIB_API, int, size, int, dimension);
14 
15 // Two message overloads, that should be bound to:
16 // void mixin_class::scale(float uniform);
17 // void mixin_class::scale(const vector3& vec);
18 // respectively.
19 // The macros will generate two functions named scale with the
20 // appropriate arguments. In order to bind them to a mixin,
21 // you should use scale_uniform_msg and scale_vector_msg
22 // in the mixin feature list.
23 DYNAMIX_MESSAGE_1_OVERLOAD(scale_uniform, void, scale, float, uniform);
24 DYNAMIX_MESSAGE_1_OVERLOAD(scale_vector, void, scale, const vector3&, vec);
#define DYNAMIX_DEFINE_MESSAGE_N_WITH_DEFAULT_IMPL (   return_type,
  message_name,
  args 
)

Macro that defines a message by also providing a default implementation

Use it once per message in a compilation unit (.cpp file)

A default implementation lets the user provide code to be executed if a message is called for an object which has no mixin implementing it.

Legend:
  • N is a number that indicates how many parameters the message takes. If N is 0, then args is omitted.
  • args is a coma-separated list of the argument types and argument names of the message's arguments
  • message_name - is the name of the message
Notes:
  • As is the case with the mutation rules, an empty object won't implement default message implementations. You'll need at least one mutation to make it do so
  • A default implementation can be treated the same way as your implementation in the method for a regular message: ie dm_this is valid
  • If any of the mixins in an object implements this message, the default implementation will be unreachable. Multicasts won't feature it.
#define DYNAMIX_DEFINE_MESSAGE (   message_name)

The macro for defining a message. Use it once per message in a compilation unit (.cpp file)