Files
pip/libs/main/core/piobject_macros.h
2026-03-12 14:46:57 +03:00

859 lines
50 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! \~\ingroup Core
//! \~\file piobject_macros.h
//! \~\brief
//! \~english PIObject macros for event system and object introspection
//! \~russian Макросы PIObject для событийной системы и интроспекции объектов
//! \~\details
//! \~english
//! This file declares the macro layer used by %PIObject-based classes:
//! class registration, event declaration, event handler declaration,
//! connection helpers and event raising helpers.
//! \~russian
//! Этот файл объявляет макросный слой для классов на базе %PIObject:
//! регистрацию класса, объявление событий, объявление обработчиков,
//! макросы соединения и макросы вызова событий.
/*
PIP - Platform Independent Primitives
Macros for PIObject
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PIOBJECT_MACROS_H
#define PIOBJECT_MACROS_H
#ifdef DOXYGEN
//! \relatesalso PIObject
//! \~\brief
//! \~english Put this macro inside a direct %PIObject subclass definition to enable registered events, event handlers and class metadata.
//! \~russian Поместите этот макрос внутрь объявления прямого наследника %PIObject, чтобы включить регистрацию событий, обработчиков и
//! метаданных класса.
# define PIOBJECT(name)
//! \relatesalso PIObject
//! \~\brief
//! \~english Put this macro inside a %PIObject subclass definition to inherit registered methods and class scope from "parent".
//! \~russian Поместите этот макрос внутрь объявления наследника %PIObject, чтобы унаследовать зарегистрированные методы и цепочку
//! классов от "parent".
# define PIOBJECT_SUBCLASS(name, parent)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a registered event handler method with signature `ret name()`.
//! \~russian Объявляет зарегистрированный метод-обработчик событий с сигнатурой `ret name()`.
# define EVENT_HANDLER0(ret, name) ret name()
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a registered event handler method with one argument.
//! \~russian Объявляет зарегистрированный метод-обработчик событий с одним аргументом.
# define EVENT_HANDLER1(ret, name, type0, var0) ret name(type0 var0)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a registered event handler method with two arguments.
//! \~russian Объявляет зарегистрированный метод-обработчик событий с двумя аргументами.
# define EVENT_HANDLER2(ret, name, type0, var0, type1, var1) ret name(type0 var0, type1 var1)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a registered event handler method with three arguments.
//! \~russian Объявляет зарегистрированный метод-обработчик событий с тремя аргументами.
# define EVENT_HANDLER3(ret, name, type0, var0, type1, var1, type2, var2) ret name(type0 var0, type1 var1, type2 var2)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a registered event handler method with four arguments.
//! \~russian Объявляет зарегистрированный метод-обработчик событий с четырьмя аргументами.
# define EVENT_HANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) \
ret name(type0 var0, type1 var1, type2 var2, type3 var3)
//! \relatesalso PIObject
//! \~\brief
//! \~english Synonym of EVENT_HANDLER0
//! \~russian Аналог EVENT_HANDLER0
# define EVENT_HANDLER EVENT_HANDLER0
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a virtual registered event handler method with signature `virtual ret name()`.
//! \~russian Объявляет виртуальный зарегистрированный метод-обработчик с сигнатурой `virtual ret name()`.
# define EVENT_VHANDLER0(ret, name) virtual ret name()
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a virtual registered event handler method with one argument.
//! \~russian Объявляет виртуальный зарегистрированный метод-обработчик с одним аргументом.
# define EVENT_VHANDLER1(ret, name, type0, var0) virtual ret name(type0 var0)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a virtual registered event handler method with two arguments.
//! \~russian Объявляет виртуальный зарегистрированный метод-обработчик с двумя аргументами.
# define EVENT_VHANDLER2(ret, name, type0, var0, type1, var1) virtual ret name(type0 var0, type1 var1)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a virtual registered event handler method with three arguments.
//! \~russian Объявляет виртуальный зарегистрированный метод-обработчик с тремя аргументами.
# define EVENT_VHANDLER3(ret, name, type0, var0, type1, var1, type2, var2) virtual ret name(type0 var0, type1 var1, type2 var2)
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare a virtual registered event handler method with four arguments.
//! \~russian Объявляет виртуальный зарегистрированный метод-обработчик с четырьмя аргументами.
# define EVENT_VHANDLER4(ret, name, type0, var0, type1, var1, type2, var2, type3, var3) \
virtual ret name(type0 var0, type1 var1, type2 var2, type3 var3)
//! \relatesalso PIObject
//! \~\brief
//! \~english Synonym of EVENT_VHANDLER0
//! \~russian Аналог EVENT_VHANDLER0
# define EVENT_VHANDLER EVENT_VHANDLER0
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare an event method with no arguments.
//! \~russian Объявляет метод-событие без аргументов.
# define EVENT0(name) void name();
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare an event method with one argument.
//! \~russian Объявляет метод-событие с одним аргументом.
# define EVENT1(name, type0, var0) void name(type0 var0);
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare an event method with two arguments.
//! \~russian Объявляет метод-событие с двумя аргументами.
# define EVENT2(name, type0, var0, type1, var1) void name(type0 var0, type1 var1);
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare an event method with three arguments.
//! \~russian Объявляет метод-событие с тремя аргументами.
# define EVENT3(name, type0, var0, type1, var1, type2, var2) void name(type0 var0, type1 var1, type2 var2);
//! \relatesalso PIObject
//! \~\brief
//! \~english Declare an event method with four arguments.
//! \~russian Объявляет метод-событие с четырьмя аргументами.
# define EVENT4(name, type0, var0, type1, var1, type2, var2, type3, var3) void name(type0 var0, type1 var1, type2 var2, type3 var3);
//! \relatesalso PIObject
//! \~\brief
//! \~english Synonym of EVENT0
//! \~russian Аналог EVENT0
# define EVENT EVENT0
//! \relatesalso PIObject
//! \~\brief
//! \~english Compatibility helper that raises event "event" on source object "src".
//! \~russian Совместимый вспомогательный макрос, вызывающий событие "event" у объекта-источника "src".
# define RAISE_EVENT0(src, event)
//! \relatesalso PIObject
//! \~english Compatibility helper that raises event "event" with one argument.
//! \~russian Совместимый вспомогательный макрос, вызывающий событие "event" с одним аргументом.
# define RAISE_EVENT1(src, event, v0)
//! \relatesalso PIObject
//! \~english Compatibility helper that raises event "event" with two arguments.
//! \~russian Совместимый вспомогательный макрос, вызывающий событие "event" с двумя аргументами.
# define RAISE_EVENT2(src, event, v0, v1)
//! \relatesalso PIObject
//! \~english Compatibility helper that raises event "event" with three arguments.
//! \~russian Совместимый вспомогательный макрос, вызывающий событие "event" с тремя аргументами.
# define RAISE_EVENT3(src, event, v0, v1, v2)
//! \relatesalso PIObject
//! \~english Compatibility helper that raises event "event" with four arguments.
//! \~russian Совместимый вспомогательный макрос, вызывающий событие "event" с четырьмя аргументами.
# define RAISE_EVENT4(src, event, v0, v1, v2, v3)
# define RAISE_EVENT RAISE_EVENT0
//! \relatesalso PIObject
//! \~\brief
//! \~english Connect event \"event\" from object \"src\" to event handler or event \"handler\" of object \"dest\".
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" объекта \"dest\".
//! \~\details
//! \~english
//! \"handler\" can accept a prefix of \"event\" arguments.
//! This macro resolves registered methods by name at run time and returns \a PIObject::Connection.
//! \~russian
//! \"handler\" может принимать только начальную часть аргументов \"event\".
//! Макрос ищет зарегистрированные методы по имени во время выполнения и возвращает \a PIObject::Connection.
# define CONNECTU(src, event, dest, handler)
//! \relatesalso PIObject
//! \~\brief
//! \~english Connect event \"event\" from object \"src\" to event handler or event \"handler\" of object \"dest\".
//! \~russian Соединяет событие \"event\" объекта \"src\" к обработчику или событию \"handler\" объекта \"dest\".
//! \~\details
//! \~english
//! \"handler\" can accept a prefix of \"event\" arguments.
//! Delivery is queued on the performer object and runs only when that object calls
//! \a PIObject::callQueuedEvents() or \a PIObject::maybeCallQueuedEvents().
//! All argument types should be registered by \a REGISTER_VARIANT() macro, but many
//! common and PIP types already done.
//! Returns \a PIObject::Connection.
//! \~russian
//! \"handler\" может принимать только начальную часть аргументов \"event\".
//! Доставка ставится в очередь объекта \"performer\" и выполняется только когда этот объект
//! вызывает \a PIObject::callQueuedEvents() или \a PIObject::maybeCallQueuedEvents().
//! Все типы аргументов должны быть зарегистрированы с помощью макроса \a REGISTER_VARIANT(),
//! однако многие стандартные и PIP типы уже там.
//! Возвращает \a PIObject::Connection.
# define CONNECTU_QUEUED(src, event, dest, handler, performer)
//! \relatesalso PIObject
//! \~\brief
//! \~english Connect event \"event\" from object \"src\" to lambda-expression \"functor\".
//! \~russian Соединяет событие \"event\" объекта \"src\" к лямбда-функции \"functor\".
//! \~\details
//! \~english
//! \"event\" and \"functor\" must have the same argument list.
//! Wrap \"functor\" in () when the lambda expression is complex.
//! Returns \a PIObject::Connection.
//! \~russian
//! \"event\" и \"functor\" должны иметь одинаковый список аргументов.
//! В случае сложной лямбда-функции оберните её в ().
//! Возвращает \a PIObject::Connection.
# define CONNECTL(src, event, functor)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper that connects an event to a registered handler with compile-time signature spelling.
//! \~russian Устаревший совместимый макрос, который соединяет событие с зарегистрированным обработчиком через явное указание сигнатуры.
//! \~\details
//! \~english Prefer \a CONNECTU() for new code.
//! \~russian Для нового кода предпочитайте \a CONNECTU().
# define CONNECT0(ret, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper for a one-argument registered event or handler.
//! \~russian Устаревший совместимый макрос для зарегистрированного события или обработчика с одним аргументом.
# define CONNECT1(ret, type0, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper for a two-argument registered event or handler.
//! \~russian Устаревший совместимый макрос для зарегистрированного события или обработчика с двумя аргументами.
# define CONNECT2(ret, type0, type1, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper for a three-argument registered event or handler.
//! \~russian Устаревший совместимый макрос для зарегистрированного события или обработчика с тремя аргументами.
# define CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper for a four-argument registered event or handler.
//! \~russian Устаревший совместимый макрос для зарегистрированного события или обработчика с четырьмя аргументами.
# define CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Synonym of \a CONNECT0
//! \~russian Аналог \a CONNECT0
# define CONNECT CONNECT0
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper that skips source method verification.
//! \~russian Устаревший совместимый макрос, который пропускает проверку исходного метода.
# define WEAK_CONNECT0(ret, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper that skips source method verification for one argument.
//! \~russian Устаревший совместимый макрос, который пропускает проверку исходного метода для случая с одним аргументом.
# define WEAK_CONNECT1(ret, type0, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper that skips source method verification for two arguments.
//! \~russian Устаревший совместимый макрос, который пропускает проверку исходного метода для случая с двумя аргументами.
# define WEAK_CONNECT2(ret, type0, type1, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper that skips source method verification for three arguments.
//! \~russian Устаревший совместимый макрос, который пропускает проверку исходного метода для случая с тремя аргументами.
# define WEAK_CONNECT3(ret, type0, type1, type2, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Legacy compatibility helper that skips source method verification for four arguments.
//! \~russian Устаревший совместимый макрос, который пропускает проверку исходного метода для случая с четырьмя аргументами.
# define WEAK_CONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
//! \relatesalso PIObject
//! \deprecated
//! \~english Use \a CONNECTU() instead
//! \~russian Используйте \a CONNECTU()
//! \~\brief
//! \~english Synonym of \a WEAK_CONNECT0
//! \~russian Аналог \a WEAK_CONNECT0
# define WEAK_CONNECT WEAK_CONNECT0
//! \relatesalso PIObject
//! \~\brief
//! \~english Disconnect a registered event from a registered event handler.
//! \~russian Разрывает соединение зарегистрированного события с зарегистрированным обработчиком.
# define DISCONNECT0(ret, src, event, dest, handler)
//! \relatesalso PIObject
//! \~\brief
//! \~english Disconnect a one-argument registered event from a registered event handler.
//! \~russian Разрывает соединение зарегистрированного события с одним аргументом и зарегистрированного обработчика.
# define DISCONNECT1(ret, type0, src, event, dest, handler)
//! \relatesalso PIObject
//! \~\brief
//! \~english Disconnect a two-argument registered event from a registered event handler.
//! \~russian Разрывает соединение зарегистрированного события с двумя аргументами и зарегистрированного обработчика.
# define DISCONNECT2(ret, type0, type1, src, event, dest, handler)
//! \relatesalso PIObject
//! \~\brief
//! \~english Disconnect a three-argument registered event from a registered event handler.
//! \~russian Разрывает соединение зарегистрированного события с тремя аргументами и зарегистрированного обработчика.
# define DISCONNECT3(ret, type0, type1, type2, src, event, dest, handler)
//! \relatesalso PIObject
//! \~\brief
//! \~english Disconnect a four-argument registered event from a registered event handler.
//! \~russian Разрывает соединение зарегистрированного события с четырьмя аргументами и зарегистрированного обработчика.
# define DISCONNECT4(ret, type0, type1, type2, type3, src, event, dest, handler)
//! \relatesalso PIObject
//! \~\brief
//! \~english Synonym of \a DISCONNECT0
//! \~russian Аналог \a DISCONNECT0
# define DISCONNECT DISCONNECT0
//! \relatesalso PIObject
//! \~\brief
//! \~english Low-level helper that expands to the registered handler entry point.
//! \~russian Низкоуровневый вспомогательный макрос, который разворачивается в точку входа зарегистрированного обработчика.
# define HANDLER(handler)
#else
# define _PI_STR(x) #x
# define _PI_SSTR(x) _PI_STR(x)
# define LOCATION __FILE__ ":" _PI_SSTR(__LINE__)
# ifdef CC_GCC
# define __PTYPE(t) typename __PIVariantTypeInfo__<t>::PureType
# else
# define __PTYPE(t) __PIVariantTypeInfo__<t>::PureType
# endif
# define __VVALUE(t, v) v.value<__PTYPE(t)>()
# define __PIOBJECT_MAX_ARGS__ 4
# define PIOBJECT(name) \
\
protected: \
typedef name __PIObject__; \
\
public: \
static const char * __classNameCC() { \
return #name; \
} \
static uint __classNameIDS() { \
static uint ret = PIStringAscii(#name).hash(); \
return ret; \
} \
const char * className() const override { \
return #name; \
} \
uint classNameID() const override { \
static uint ret = PIStringAscii(#name).hash(); \
return ret; \
} \
\
private: \
int ptrOffset() const override { \
name * o = (name *)100; \
return int(llong((PIObject *)o) - llong(o)); \
} \
class __BaseInitializer__ { \
public: \
__BaseInitializer__() { \
uint pid = PIObject::__classNameIDS(); \
if (pid == 0) return; \
uint id = __classNameIDS(); \
PIMutexLocker ml(__meta_mutex()); \
if (__meta_data().contains(id)) return; \
__meta_data()[pid]; \
__meta_data()[id]; \
__MetaData & ehp(__meta_data()[pid]); \
__MetaData & eh(__meta_data()[id]); \
eh.eh_set << ehp.eh_set; \
eh.eh_func << ehp.eh_func; \
eh.addScope(__classNameCC(), id); \
} \
}; \
__BaseInitializer__ __base_init__;
# define PIOBJECT_PARENT(name) \
class __ParentInitializer__ { \
public: \
__ParentInitializer__() { \
uint pid = name::__classNameIDS(); \
if (pid == 0) return; \
uint id = __classNameIDS(); \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[id]); \
if (eh.scope_id.contains(pid)) return; \
__MetaData ehp(__meta_data().value(pid)); \
eh.eh_set << ehp.eh_set; \
eh.eh_func << ehp.eh_func; \
eh.scope_id = ehp.scope_id; \
eh.scope_list = ehp.scope_list; \
eh.addScope(__classNameCC(), id); \
} \
}; \
__ParentInitializer__ __parent_init__; \
\
public: \
const char * parentClassName() const override { \
return #name; \
} \
typedef name __Parent__; \
\
private:
# define PIOBJECT_SUBCLASS(name, parent) PIOBJECT(name) PIOBJECT_PARENT(parent)
# define __EH_INIT_BASE__(ret, name) \
PIMutexLocker ml(__meta_mutex()); \
__MetaData & eh(__meta_data()[__classNameIDS()]); \
if (eh.eh_set[fp]) return; \
eh.eh_set << fp; \
__MetaFunc & f(eh.eh_func[fp]); \
f.scope = __classNameCC(); \
f.__setFuncName(#name); \
f.addr = fp; \
f.addrV = fpV; \
f.type_ret = #ret;
# define EH_INIT0(ret, name) \
STATIC_INITIALIZER_BEGIN \
void * fp = (void *)(ret(*)(void *))__stat_eh_##name##__; \
void * fpV = fp; \
__EH_INIT_BASE__(ret, name) \
STATIC_INITIALIZER_END
# define EH_INIT1(ret, name, a0, n0) \
STATIC_INITIALIZER_BEGIN \
void * fp = (void *)(ret(*)(void *, a0))__stat_eh_##name##__; \
void * fpV = (void *)(ret(*)(void *, const PIVariantSimple &))__stat_eh_v_##name##__; \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
STATIC_INITIALIZER_END
# define EH_INIT2(ret, name, a0, n0, a1, n1) \
STATIC_INITIALIZER_BEGIN \
void * fp = (void *)(ret(*)(void *, a0, a1))__stat_eh_##name##__; \
void * fpV = (void *)(ret(*)(void *, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
f.__addArgument(#a1, #n1); \
STATIC_INITIALIZER_END
# define EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
STATIC_INITIALIZER_BEGIN \
void * fp = (void *)(ret(*)(void *, a0, a1, a2))__stat_eh_##name##__; \
void * fpV = \
(void *)(ret(*)(void *, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &))__stat_eh_v_##name##__; \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
f.__addArgument(#a1, #n1); \
f.__addArgument(#a2, #n2); \
STATIC_INITIALIZER_END
# define EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
STATIC_INITIALIZER_BEGIN \
void * fp = (void *)(ret(*)(void *, a0, a1, a2, a3))__stat_eh_##name##__; \
void * fpV = \
(void *)(ret(*)(void *, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &, const PIVariantSimple &)) \
__stat_eh_v_##name##__; \
__EH_INIT_BASE__(ret, name) \
f.__addArgument(#a0, #n0); \
f.__addArgument(#a1, #n1); \
f.__addArgument(#a2, #n2); \
f.__addArgument(#a3, #n3); \
STATIC_INITIALIZER_END
# define EVENT_HANDLER0(ret, name) \
EH_INIT0(ret, name) \
static ret __stat_eh_##name##__(void * __o__) { \
return ((__PIObject__ *)__o__)->name(); \
} \
ret name()
# define EVENT_HANDLER1(ret, name, a0, n0) \
EH_INIT1(ret, name, a0, n0) \
static ret __stat_eh_##name##__(void * __o__, a0 n0) { \
return ((__PIObject__ *)__o__)->name(n0); \
} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
return ((__PIObject__ *)__o__)->name(tv0); \
} \
ret name(a0 n0)
# define EVENT_HANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(ret, name, a0, n0, a1, n1) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) { \
return ((__PIObject__ *)__o__)->name(n0, n1); \
} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
return ((__PIObject__ *)__o__)->name(tv0, tv1); \
} \
ret name(a0 n0, a1 n1)
# define EVENT_HANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) { \
return ((__PIObject__ *)__o__)->name(n0, n1, n2); \
} \
static ret __stat_eh_v_##name##__(void * __o__, \
const PIVariantSimple & v0, \
const PIVariantSimple & v1, \
const PIVariantSimple & v2) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \
return ((__PIObject__ *)__o__)->name(tv0, tv1, tv2); \
} \
ret name(a0 n0, a1 n1, a2 n2)
# define EVENT_HANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) { \
return ((__PIObject__ *)__o__)->name(n0, n1, n2, n3); \
} \
static ret __stat_eh_v_##name##__(void * __o__, \
const PIVariantSimple & v0, \
const PIVariantSimple & v1, \
const PIVariantSimple & v2, \
const PIVariantSimple & v3) { \
__PTYPE(a0) tv0 = __VVALUE(a0, v0); \
__PTYPE(a1) tv1 = __VVALUE(a1, v1); \
__PTYPE(a2) tv2 = __VVALUE(a2, v2); \
__PTYPE(a3) tv3 = __VVALUE(a3, v3); \
return ((__PIObject__ *)__o__)->name(tv0, tv1, tv2, tv3); \
} \
ret name(a0 n0, a1 n1, a2 n2, a3 n3)
# define EVENT_HANDLER EVENT_HANDLER0
# define EVENT_VHANDLER0(ret, name) \
EH_INIT0(ret, name) \
static ret __stat_eh_##name##__(void * __o__) { \
return ((__PIObject__ *)__o__)->name(); \
} \
virtual ret name()
# define EVENT_VHANDLER1(ret, name, a0, n0) \
EH_INIT1(ret, name, a0, n0) \
static ret __stat_eh_##name##__(void * __o__, a0 n0) { \
return ((__PIObject__ *)__o__)->name(n0); \
} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0) { \
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0)); \
} \
virtual ret name(a0 n0)
# define EVENT_VHANDLER2(ret, name, a0, n0, a1, n1) \
EH_INIT2(ret, name, a0, n0, a1, n1) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1) { \
return ((__PIObject__ *)__o__)->name(n0, n1); \
} \
static ret __stat_eh_v_##name##__(void * __o__, const PIVariantSimple & v0, const PIVariantSimple & v1) { \
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1)); \
} \
virtual ret name(a0 n0, a1 n1)
# define EVENT_VHANDLER3(ret, name, a0, n0, a1, n1, a2, n2) \
EH_INIT3(ret, name, a0, n0, a1, n1, a2, n2) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2) { \
return ((__PIObject__ *)__o__)->name(n0, n1, n2); \
} \
static ret __stat_eh_v_##name##__(void * __o__, \
const PIVariantSimple & v0, \
const PIVariantSimple & v1, \
const PIVariantSimple & v2) { \
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2)); \
} \
virtual ret name(a0 n0, a1 n1, a2 n2)
# define EVENT_VHANDLER4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
EH_INIT4(ret, name, a0, n0, a1, n1, a2, n2, a3, n3) \
static ret __stat_eh_##name##__(void * __o__, a0 n0, a1 n1, a2 n2, a3 n3) { \
return ((__PIObject__ *)__o__)->name(n0, n1, n2, n3); \
} \
static ret __stat_eh_v_##name##__(void * __o__, \
const PIVariantSimple & v0, \
const PIVariantSimple & v1, \
const PIVariantSimple & v2, \
const PIVariantSimple & v3) { \
return ((__PIObject__ *)__o__)->name(__VVALUE(a0, v0), __VVALUE(a1, v1), __VVALUE(a2, v2), __VVALUE(a3, v3)); \
} \
virtual ret name(a0 n0, a1 n1, a2 n2, a3 n3)
# define EVENT_VHANDLER EVENT_VHANDLER0
# define EVENT0(name) \
EVENT_HANDLER0(void, name) { \
static uint eid = PIStringAscii(#name).hash(); \
PIObject::raiseEvent(this, eid); \
}
# define EVENT1(name, a0, n0) \
EVENT_HANDLER1(void, name, a0, n0) { \
static uint eid = PIStringAscii(#name).hash(); \
PIObject::raiseEvent(this, eid, n0); \
}
# define EVENT2(name, a0, n0, a1, n1) \
EVENT_HANDLER2(void, name, a0, n0, a1, n1) { \
static uint eid = PIStringAscii(#name).hash(); \
PIObject::raiseEvent(this, eid, n0, n1); \
}
# define EVENT3(name, a0, n0, a1, n1, a2, n2) \
EVENT_HANDLER3(void, name, a0, n0, a1, n1, a2, n2) { \
static uint eid = PIStringAscii(#name).hash(); \
PIObject::raiseEvent(this, eid, n0, n1, n2); \
}
# define EVENT4(name, a0, n0, a1, n1, a2, n2, a3, n3) \
EVENT_HANDLER4(void, name, a0, n0, a1, n1, a2, n2, a3, n3) { \
static uint eid = PIStringAscii(#name).hash(); \
PIObject::raiseEvent(this, eid, n0, n1, n2, n3); \
}
# define EVENT EVENT0
# define RAISE_EVENT0(src, event) (src)->event();
# define RAISE_EVENT1(src, event, v0) (src)->event(v0);
# define RAISE_EVENT2(src, event, v0, v1) (src)->event(v0, v1);
# define RAISE_EVENT3(src, event, v0, v1, v2) (src)->event(v0, v1, v2);
# define RAISE_EVENT4(src, event, v0, v1, v2, v3) (src)->event(v0, v1, v2, v3);
# define RAISE_EVENT RAISE_EVENT0
# define CONNECTU(src, event, dest, handler) \
PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION);
# define CONNECTU_QUEUED(src, event, dest, handler, performer) \
PIObject::piConnectU(src, PIStringAscii(#event), dest, dest, PIStringAscii(#handler), LOCATION, performer);
# define CONNECTL(src, event, functor) \
PIObject::piConnectLS(src, PIStringAscii(#event), PIObject::__newFunctor(&(src)->__stat_eh_##event##__, functor), LOCATION);
# define CONNECT0(ret, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *))(&(dest)->__stat_eh_##handler##__), \
(void *)(void (*)(void *))(&(src)->__stat_eh_##event##__), \
0, \
LOCATION);
# define CONNECT1(ret, a0, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0))(&(dest)->__stat_eh_##handler##__), \
(void *)(void (*)(void *, a0))(&(src)->__stat_eh_##event##__), \
1, \
LOCATION);
# define CONNECT2(ret, a0, a1, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0, a1))(&(dest)->__stat_eh_##handler##__), \
(void *)(void (*)(void *, a0, a1))(&(src)->__stat_eh_##event##__), \
2, \
LOCATION);
# define CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \
(void *)(void (*)(void *, a0, a1, a2))(&(src)->__stat_eh_##event##__), \
3, \
LOCATION);
# define CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \
(void *)(void (*)(void *, a0, a1, a2, a3))(&(src)->__stat_eh_##event##__), \
4, \
LOCATION);
# define CONNECT CONNECT0
# define WEAK_CONNECT0(ret, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *))(&(dest)->__stat_eh_##handler##__), \
0, \
0, \
LOCATION);
# define WEAK_CONNECT1(ret, a0, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0))(&(dest)->__stat_eh_##handler##__), \
0, \
1, \
LOCATION);
# define WEAK_CONNECT2(ret, a0, a1, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0, a1))(&(dest)->__stat_eh_##handler##__), \
0, \
2, \
LOCATION);
# define WEAK_CONNECT3(ret, a0, a1, a2, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0, a1, a2))(&(dest)->__stat_eh_##handler##__), \
0, \
3, \
LOCATION);
# define WEAK_CONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \
PIObject::piConnect(src, \
PIStringAscii(#event), \
dest, \
dest, \
(void *)(ret(*)(void *, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__), \
0, \
4, \
LOCATION);
# define WEAK_CONNECT WEAK_CONNECT0
# define DISCONNECT0(ret, src, event, dest, handler) \
PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void *)(ret(*)(void *))(&(dest)->__stat_eh_##handler##__));
# define DISCONNECT1(ret, a0, src, event, dest, handler) \
PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void *)(ret(*)(void *, a0))(&(dest)->__stat_eh_##handler##__));
# define DISCONNECT2(ret, a0, a1, src, event, dest, handler) \
PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void *)(ret(*)(void *, a0, a1))(&(dest)->__stat_eh_##handler##__));
# define DISCONNECT3(ret, a0, a1, a2, src, event, dest, handler) \
PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void *)(ret(*)(void *, a0, a1, a2))(&(dest)->__stat_eh_##handler##__));
# define DISCONNECT4(ret, a0, a1, a2, a3, src, event, dest, handler) \
PIObject::piDisconnect(src, PIStringAscii(#event), dest, (void *)(ret(*)(void *, a0, a1, a2, a3))(&(dest)->__stat_eh_##handler##__));
# define DISCONNECT DISCONNECT0
# define HANDLER(handler) __stat_eh_##handler##__
# define __PIOBJECT_SIGNATURE__ 0xabcdbadc
#endif
#endif // PIOBJECT_MACROS_H