From 2457458aca1dc6d0ba2c99a66e3604b3bf61091e Mon Sep 17 00:00:00 2001 From: Alex Yatskov Date: Sun, 4 Sep 2011 10:19:34 -0700 Subject: [PATCH] serialization system can now search for serializer methods on objects --- main.cpp | 4 ++-- mc_common.hpp | 2 +- mc_functor.hpp | 1 + mc_meta.hpp | 57 +++++++++++++++++++++++++++++++++++++---------- mc_protocol.cpp | 4 ++-- mc_serial-inl.hpp | 40 +++++++++++++++++++++++++++------ mc_socket.cpp | 6 ++--- mc_stream-inl.hpp | 2 ++ mc_token.cpp | 1 + 9 files changed, 90 insertions(+), 27 deletions(-) diff --git a/main.cpp b/main.cpp index 3f391ba..357cee0 100644 --- a/main.cpp +++ b/main.cpp @@ -33,7 +33,7 @@ using namespace metacall; // Constants // -static const int SERVER_PORT = 1338; +static const int SERVER_PORT = 1337; static const int SERVER_MAX_CLIENTS = 1; @@ -58,7 +58,7 @@ int main(int argc, char **argv) { return 1; } - server.binding()->bind("serverTest", serverTest); + server.binding()->bind(FPARAM(serverTest)); Client client; printf("[S] Connecting to server on port %d\n", SERVER_PORT); diff --git a/mc_common.hpp b/mc_common.hpp index 7c9c57b..c586ece 100644 --- a/mc_common.hpp +++ b/mc_common.hpp @@ -32,8 +32,8 @@ namespace metacall { // Macros // -#define IS_TRUE(x) ((x) != 0) #define ASSERT assert +#define FPARAM(x) #x, x // diff --git a/mc_functor.hpp b/mc_functor.hpp index f478e16..9b9eaa3 100644 --- a/mc_functor.hpp +++ b/mc_functor.hpp @@ -34,6 +34,7 @@ namespace metacall { class IFunctor { public: + virtual ~IFunctor() { } virtual bool call(Deserializer* args, Serializer* ret) const = 0; }; diff --git a/mc_meta.hpp b/mc_meta.hpp index 5f77594..28b920e 100644 --- a/mc_meta.hpp +++ b/mc_meta.hpp @@ -32,30 +32,63 @@ namespace metacall { // Meta // -qword serialize (class Serializer*, ...); -qword deserialize (class Deserializer*, ...); +qword serialize(class Serializer*, ...); template -struct IsSerializable { +struct HasGlobalSerializer { enum { Value = sizeof(bool) == sizeof( serialize( - static_cast(0), - *static_cast(0) + static_cast(NULL), + *static_cast(NULL) + ) + ) + }; +}; + +qword deserialize(class Deserializer*, ...); + +template +struct HasGlobalDeserializer { + enum { + Value = sizeof(bool) == sizeof( + deserialize( + static_cast(NULL), + static_cast(NULL) ) ) }; }; template -struct IsDeserializable { +struct HasLocalSerializer { + template + struct Signature { }; + + template + static dword Test(Signature*); + + template + static qword Test(...); + enum { - Value = sizeof(bool) == sizeof( - deserialize( - static_cast(0), - static_cast(0) - ) - ) + Value = sizeof(Test(NULL)) == sizeof(dword) + }; +}; + +template +struct HasLocalDeserializer { + template + struct Signature { }; + + template + static dword Test(Signature*); + + template + static qword Test(...); + + enum { + Value = sizeof(Test(NULL)) == sizeof(dword) }; }; diff --git a/mc_protocol.cpp b/mc_protocol.cpp index 9ed98a9..aa1a4bf 100644 --- a/mc_protocol.cpp +++ b/mc_protocol.cpp @@ -141,8 +141,8 @@ Stream::State Protocol::advanceInvokeReply() { } else { const bool error = - IS_TRUE(packetReply.flags & PacketInvokeReply::FLAG_UNBOUND_FUNC) || - IS_TRUE(packetReply.flags & PacketInvokeReply::FLAG_INVALID_ARGS); + (packetReply.flags & PacketInvokeReply::FLAG_UNBOUND_FUNC) || + (packetReply.flags & PacketInvokeReply::FLAG_INVALID_ARGS); iter->second.state = error ? TASK_STATE_ERROR : TASK_STATE_READY; iter->second.data = packetReply.data; diff --git a/mc_serial-inl.hpp b/mc_serial-inl.hpp index 9d8c546..ff21fb9 100644 --- a/mc_serial-inl.hpp +++ b/mc_serial-inl.hpp @@ -30,27 +30,42 @@ namespace metacall { // TypeReader // -template +template struct TypeReader { + static bool read(Deserializer* deserializer, T* data) { + return data->deserialize(deserializer); + } +}; + +template +struct TypeReader { static bool read(Deserializer* deserializer, T* data) { return deserialize(deserializer, data); } }; template -struct TypeReader { +struct TypeReader { static bool read(Deserializer* deserializer, T* data) { - const T* const temp = reinterpret_cast(deserializer->readRaw(sizeof(T))); + const T* const temp = reinterpret_cast( + deserializer->readRaw(sizeof(T)) + ); + if (temp != NULL) { *data = *temp; } + return temp != NULL; } }; template bool Deserializer::read(T* data) { - return TypeReader::Value>::read(this, data); + return TypeReader< + T, + HasLocalDeserializer::Value, + HasGlobalDeserializer::Value + >::read(this, data); } @@ -58,15 +73,22 @@ bool Deserializer::read(T* data) { // TypeWriter // -template +template struct TypeWriter { + static bool write(Serializer* serializer, const T& data) { + return data.serialize(serializer); + } +}; + +template +struct TypeWriter { static bool write(Serializer* serializer, const T& data) { return serialize(serializer, data); } }; template -struct TypeWriter { +struct TypeWriter { static bool write(Serializer* serializer, const T& data) { return serializer->writeRaw(&data, sizeof(T)); } @@ -74,7 +96,11 @@ struct TypeWriter { template bool Serializer::write(const T& data) { - return TypeWriter::Value>::write(this, data); + return TypeWriter< + T, + HasLocalSerializer::Value, + HasGlobalSerializer::Value + >::write(this, data); } diff --git a/mc_socket.cpp b/mc_socket.cpp index 4032e0b..ea2ab86 100644 --- a/mc_socket.cpp +++ b/mc_socket.cpp @@ -225,17 +225,17 @@ bool Socket::wait(unsigned mask, int seconds) const { #pragma warning(push) #pragma warning(disable:4127) #endif - if (IS_TRUE(mask & MASK_READ)) { + if (mask & MASK_READ) { readSetUse = &readSet; FD_ZERO(readSetUse); FD_SET(socket_, readSetUse); } - if (IS_TRUE(mask & MASK_WRITE)) { + if (mask & MASK_WRITE) { writeSetUse = &writeSet; FD_ZERO(writeSetUse); FD_SET(socket_, writeSetUse); } - if (IS_TRUE(mask & MASK_EXCEPT)) { + if (mask & MASK_EXCEPT) { exceptSetUse = &exceptSet; FD_ZERO(exceptSetUse); FD_SET(socket_, exceptSetUse); diff --git a/mc_stream-inl.hpp b/mc_stream-inl.hpp index c80acf4..45d62a5 100644 --- a/mc_stream-inl.hpp +++ b/mc_stream-inl.hpp @@ -25,6 +25,7 @@ namespace metacall { + template Stream::State Stream::send(const T& packet) { if (!socket_->connected()) { @@ -69,4 +70,5 @@ Stream::State Stream::receive(T* packet) { return success ? STATE_READY : STATE_ERROR_PROTOCOL; } + } diff --git a/mc_token.cpp b/mc_token.cpp index aea7eef..8026d05 100644 --- a/mc_token.cpp +++ b/mc_token.cpp @@ -28,6 +28,7 @@ namespace metacall { + // // Token //