#ifndef PACPUS_EVENT_H #define PACPUS_EVENT_H #include #include #include #include #include namespace pacpus { // registerEventType // TODO // FIXME: move to another header file enum PacpusEventType { TYPED_EVENT = 1000, GENERIC_EVENT = 2000, GENERIC_EVENT2 = 2002, GENERIC_EVENT3 = 2003, CONFIG_EVENT = 3000 }; class PACPUSLIB_API PacpusEvent : public QEvent { Q_GADGET // permits to use signals and slots (using Q_SIGNAL, Q_SLOT) without inheriting from QObject public: PacpusEvent(PacpusEventType type, road_time_t t = road_time(), road_timerange_t tr = 0) : QEvent(QEvent::Type(type)) , m_time(t) , m_timerange(tr) {} virtual ~PacpusEvent() {} // TODO: should we make it virtual pure ??? virtual QDataStream & streamOut(QDataStream & out) { return out; } // TODO: should we make it virtual pure ??? virtual QDataStream& streamIn(QDataStream& in) { return in; } road_time_t& time() { return m_time; } road_time_t const& time() const { return m_time; } road_timerange_t& timerange() { return m_timerange; } road_timerange_t const& timerange() const { return m_timerange; } protected: road_time_t m_time; road_timerange_t m_timerange; }; template class /*PACPUSLIB_API*/ TypedData { public: TypedData(const T & data) : m_data(data) { } ~TypedData() { } T & data() { return m_data; } const T & data() const { return m_data; } std::size_t size() const { return sizeof(T); } private: T m_data; }; template class /*PACPUSLIB_API*/ PacpusTypedEvent : public PacpusEvent , public TypedData { public: // FIXME: why we need `data = T()` ??? PacpusTypedEvent(PacpusEventType type, const T & data/* = T()*/, road_time_t t = road_time(), road_timerange_t tr = 0) : PacpusEvent(type, t, tr) , TypedData(data) { } /// Conversion constructor from another PacpusTypedEvent, /// when T is convertible to S template PacpusTypedEvent(PacpusTypedEvent const& other) : PacpusEvent(static_cast(other.type()), other.time(), other.timerange()) , TypedData(other.data()) { } ~PacpusTypedEvent() { } QDataStream & streamOut(QDataStream & out) { // FIXME Stream Data errors return out << (quint64) time() << timerange() /*<< m_data*/; } QDataStream & streamIn(QDataStream & in) { return in >> (quint64&) time() >> timerange() /*>> m_data*/; } }; class PACPUSLIB_API GenericData { public: GenericData(char const* data, size_t size) : m_data(NULL) , m_dataSize(size) { m_data = new char[m_dataSize]; ::std::copy(data, data + m_dataSize, // source #ifdef _MSC_VER ::stdext::checked_array_iterator(m_data, m_dataSize) // destination #else m_data // destination #endif ); } ~GenericData() { delete[] m_data; } char * data() { return m_data; } const char * data() const { return m_data; } std::size_t size() const { return m_dataSize; } private: char * m_data; std::size_t m_dataSize; }; class PACPUSLIB_API PacpusGenericEvent : public PacpusEvent , public GenericData { public: PacpusGenericEvent(PacpusEventType type, const char * data, size_t size) : PacpusEvent(type) , GenericData(data, size) { } virtual ~PacpusGenericEvent() { } }; } // namespace pacpus PACPUSLIB_API inline QDataStream & operator<<(QDataStream & out, pacpus::PacpusEvent & ev) { /*return ev.streamOut(out);*/ return out; } PACPUSLIB_API inline QDataStream & operator>>(QDataStream & in, pacpus::PacpusEvent & ev) { /*return ev.streamIn(in);*/ return in; } #endif // PACPUS_EVENT_H