serialization system can now search for serializer methods on objects
This commit is contained in:
parent
a77442327f
commit
2457458aca
4
main.cpp
4
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);
|
||||
|
@ -32,8 +32,8 @@ namespace metacall {
|
||||
// Macros
|
||||
//
|
||||
|
||||
#define IS_TRUE(x) ((x) != 0)
|
||||
#define ASSERT assert
|
||||
#define FPARAM(x) #x, x
|
||||
|
||||
|
||||
//
|
||||
|
@ -34,6 +34,7 @@ namespace metacall {
|
||||
|
||||
class IFunctor {
|
||||
public:
|
||||
virtual ~IFunctor() { }
|
||||
virtual bool call(Deserializer* args, Serializer* ret) const = 0;
|
||||
};
|
||||
|
||||
|
57
mc_meta.hpp
57
mc_meta.hpp
@ -32,30 +32,63 @@ namespace metacall {
|
||||
// Meta
|
||||
//
|
||||
|
||||
qword serialize (class Serializer*, ...);
|
||||
qword deserialize (class Deserializer*, ...);
|
||||
qword serialize(class Serializer*, ...);
|
||||
|
||||
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)
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
namespace metacall {
|
||||
|
||||
|
||||
//
|
||||
// Token
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user