serialization system can now search for serializer methods on objects

This commit is contained in:
Alex Yatskov 2011-09-04 10:19:34 -07:00
parent a77442327f
commit 2457458aca
9 changed files with 90 additions and 27 deletions

View File

@ -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);

View File

@ -32,8 +32,8 @@ namespace metacall {
// Macros
//
#define IS_TRUE(x) ((x) != 0)
#define ASSERT assert
#define FPARAM(x) #x, x
//

View File

@ -34,6 +34,7 @@ namespace metacall {
class IFunctor {
public:
virtual ~IFunctor() { }
virtual bool call(Deserializer* args, Serializer* ret) const = 0;
};

View File

@ -33,29 +33,62 @@ namespace metacall {
//
qword serialize(class Serializer*, ...);
qword deserialize (class Deserializer*, ...);
template <typename T>
struct IsSerializable {
struct HasGlobalSerializer {
enum {
Value = sizeof(bool) == sizeof(
serialize(
static_cast<Serializer*>(0),
*static_cast<T*>(0)
static_cast<Serializer*>(NULL),
*static_cast<const T*>(NULL)
)
)
};
};
qword deserialize(class Deserializer*, ...);
template <typename T>
struct HasGlobalDeserializer {
enum {
Value = sizeof(bool) == sizeof(
deserialize(
static_cast<Deserializer*>(NULL),
static_cast<T*>(NULL)
)
)
};
};
template <typename T>
struct IsDeserializable {
struct HasLocalSerializer {
template <typename U, bool (U::*)(Serializer*)>
struct Signature { };
template <typename U>
static dword Test(Signature<U, U::serialize>*);
template <typename U>
static qword Test(...);
enum {
Value = sizeof(bool) == sizeof(
deserialize(
static_cast<Deserializer*>(0),
static_cast<T*>(0)
)
)
Value = sizeof(Test<T>(NULL)) == sizeof(dword)
};
};
template <typename T>
struct HasLocalDeserializer {
template <typename U, bool (U::*)(Deserializer*)>
struct Signature { };
template <typename U>
static dword Test(Signature<U, U::deserialize>*);
template <typename U>
static qword Test(...);
enum {
Value = sizeof(Test<T>(NULL)) == sizeof(dword)
};
};

View File

@ -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;

View File

@ -30,27 +30,42 @@ namespace metacall {
// TypeReader
//
template <typename T, bool G>
template <typename T, bool L, bool G>
struct TypeReader {
static bool read(Deserializer* deserializer, T* data) {
return data->deserialize(deserializer);
}
};
template <typename T>
struct TypeReader<T, false, true> {
static bool read(Deserializer* deserializer, T* data) {
return deserialize(deserializer, data);
}
};
template <typename T>
struct TypeReader<T, false> {
struct TypeReader<T, false, false> {
static bool read(Deserializer* deserializer, T* data) {
const T* const temp = reinterpret_cast<const T*>(deserializer->readRaw(sizeof(T)));
const T* const temp = reinterpret_cast<const T*>(
deserializer->readRaw(sizeof(T))
);
if (temp != NULL) {
*data = *temp;
}
return temp != NULL;
}
};
template <typename T>
bool Deserializer::read(T* data) {
return TypeReader<T, IsDeserializable<T>::Value>::read(this, data);
return TypeReader<
T,
HasLocalDeserializer<T>::Value,
HasGlobalDeserializer<T>::Value
>::read(this, data);
}
@ -58,15 +73,22 @@ bool Deserializer::read(T* data) {
// TypeWriter
//
template <typename T, bool G>
template <typename T, bool L, bool G>
struct TypeWriter {
static bool write(Serializer* serializer, const T& data) {
return data.serialize(serializer);
}
};
template <typename T>
struct TypeWriter<T, false, true> {
static bool write(Serializer* serializer, const T& data) {
return serialize(serializer, data);
}
};
template <typename T>
struct TypeWriter<T, false> {
struct TypeWriter<T, false, false> {
static bool write(Serializer* serializer, const T& data) {
return serializer->writeRaw(&data, sizeof(T));
}
@ -74,7 +96,11 @@ struct TypeWriter<T, false> {
template <typename T>
bool Serializer::write(const T& data) {
return TypeWriter<T, IsSerializable<T>::Value>::write(this, data);
return TypeWriter<
T,
HasLocalSerializer<T>::Value,
HasGlobalSerializer<T>::Value
>::write(this, data);
}

View File

@ -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);

View File

@ -25,6 +25,7 @@
namespace metacall {
template <typename T>
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;
}
}

View File

@ -28,6 +28,7 @@
namespace metacall {
//
// Token
//