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
|
// Constants
|
||||||
//
|
//
|
||||||
|
|
||||||
static const int SERVER_PORT = 1338;
|
static const int SERVER_PORT = 1337;
|
||||||
static const int SERVER_MAX_CLIENTS = 1;
|
static const int SERVER_MAX_CLIENTS = 1;
|
||||||
|
|
||||||
|
|
||||||
@ -58,7 +58,7 @@ int main(int argc, char **argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.binding()->bind("serverTest", serverTest);
|
server.binding()->bind(FPARAM(serverTest));
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
printf("[S] Connecting to server on port %d\n", SERVER_PORT);
|
printf("[S] Connecting to server on port %d\n", SERVER_PORT);
|
||||||
|
@ -32,8 +32,8 @@ namespace metacall {
|
|||||||
// Macros
|
// Macros
|
||||||
//
|
//
|
||||||
|
|
||||||
#define IS_TRUE(x) ((x) != 0)
|
|
||||||
#define ASSERT assert
|
#define ASSERT assert
|
||||||
|
#define FPARAM(x) #x, x
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -34,6 +34,7 @@ namespace metacall {
|
|||||||
|
|
||||||
class IFunctor {
|
class IFunctor {
|
||||||
public:
|
public:
|
||||||
|
virtual ~IFunctor() { }
|
||||||
virtual bool call(Deserializer* args, Serializer* ret) const = 0;
|
virtual bool call(Deserializer* args, Serializer* ret) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
55
mc_meta.hpp
55
mc_meta.hpp
@ -33,29 +33,62 @@ namespace metacall {
|
|||||||
//
|
//
|
||||||
|
|
||||||
qword serialize(class Serializer*, ...);
|
qword serialize(class Serializer*, ...);
|
||||||
qword deserialize (class Deserializer*, ...);
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct IsSerializable {
|
struct HasGlobalSerializer {
|
||||||
enum {
|
enum {
|
||||||
Value = sizeof(bool) == sizeof(
|
Value = sizeof(bool) == sizeof(
|
||||||
serialize(
|
serialize(
|
||||||
static_cast<Serializer*>(0),
|
static_cast<Serializer*>(NULL),
|
||||||
*static_cast<T*>(0)
|
*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>
|
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 {
|
enum {
|
||||||
Value = sizeof(bool) == sizeof(
|
Value = sizeof(Test<T>(NULL)) == sizeof(dword)
|
||||||
deserialize(
|
};
|
||||||
static_cast<Deserializer*>(0),
|
};
|
||||||
static_cast<T*>(0)
|
|
||||||
)
|
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 {
|
else {
|
||||||
const bool error =
|
const bool error =
|
||||||
IS_TRUE(packetReply.flags & PacketInvokeReply::FLAG_UNBOUND_FUNC) ||
|
(packetReply.flags & PacketInvokeReply::FLAG_UNBOUND_FUNC) ||
|
||||||
IS_TRUE(packetReply.flags & PacketInvokeReply::FLAG_INVALID_ARGS);
|
(packetReply.flags & PacketInvokeReply::FLAG_INVALID_ARGS);
|
||||||
|
|
||||||
iter->second.state = error ? TASK_STATE_ERROR : TASK_STATE_READY;
|
iter->second.state = error ? TASK_STATE_ERROR : TASK_STATE_READY;
|
||||||
iter->second.data = packetReply.data;
|
iter->second.data = packetReply.data;
|
||||||
|
@ -30,27 +30,42 @@ namespace metacall {
|
|||||||
// TypeReader
|
// TypeReader
|
||||||
//
|
//
|
||||||
|
|
||||||
template <typename T, bool G>
|
template <typename T, bool L, bool G>
|
||||||
struct TypeReader {
|
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) {
|
static bool read(Deserializer* deserializer, T* data) {
|
||||||
return deserialize(deserializer, data);
|
return deserialize(deserializer, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TypeReader<T, false> {
|
struct TypeReader<T, false, false> {
|
||||||
static bool read(Deserializer* deserializer, T* data) {
|
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) {
|
if (temp != NULL) {
|
||||||
*data = *temp;
|
*data = *temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp != NULL;
|
return temp != NULL;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Deserializer::read(T* data) {
|
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
|
// TypeWriter
|
||||||
//
|
//
|
||||||
|
|
||||||
template <typename T, bool G>
|
template <typename T, bool L, bool G>
|
||||||
struct TypeWriter {
|
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) {
|
static bool write(Serializer* serializer, const T& data) {
|
||||||
return serialize(serializer, data);
|
return serialize(serializer, data);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct TypeWriter<T, false> {
|
struct TypeWriter<T, false, false> {
|
||||||
static bool write(Serializer* serializer, const T& data) {
|
static bool write(Serializer* serializer, const T& data) {
|
||||||
return serializer->writeRaw(&data, sizeof(T));
|
return serializer->writeRaw(&data, sizeof(T));
|
||||||
}
|
}
|
||||||
@ -74,7 +96,11 @@ struct TypeWriter<T, false> {
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool Serializer::write(const T& data) {
|
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(push)
|
||||||
#pragma warning(disable:4127)
|
#pragma warning(disable:4127)
|
||||||
#endif
|
#endif
|
||||||
if (IS_TRUE(mask & MASK_READ)) {
|
if (mask & MASK_READ) {
|
||||||
readSetUse = &readSet;
|
readSetUse = &readSet;
|
||||||
FD_ZERO(readSetUse);
|
FD_ZERO(readSetUse);
|
||||||
FD_SET(socket_, readSetUse);
|
FD_SET(socket_, readSetUse);
|
||||||
}
|
}
|
||||||
if (IS_TRUE(mask & MASK_WRITE)) {
|
if (mask & MASK_WRITE) {
|
||||||
writeSetUse = &writeSet;
|
writeSetUse = &writeSet;
|
||||||
FD_ZERO(writeSetUse);
|
FD_ZERO(writeSetUse);
|
||||||
FD_SET(socket_, writeSetUse);
|
FD_SET(socket_, writeSetUse);
|
||||||
}
|
}
|
||||||
if (IS_TRUE(mask & MASK_EXCEPT)) {
|
if (mask & MASK_EXCEPT) {
|
||||||
exceptSetUse = &exceptSet;
|
exceptSetUse = &exceptSet;
|
||||||
FD_ZERO(exceptSetUse);
|
FD_ZERO(exceptSetUse);
|
||||||
FD_SET(socket_, exceptSetUse);
|
FD_SET(socket_, exceptSetUse);
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
namespace metacall {
|
namespace metacall {
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Stream::State Stream::send(const T& packet) {
|
Stream::State Stream::send(const T& packet) {
|
||||||
if (!socket_->connected()) {
|
if (!socket_->connected()) {
|
||||||
@ -69,4 +70,5 @@ Stream::State Stream::receive(T* packet) {
|
|||||||
return success ? STATE_READY : STATE_ERROR_PROTOCOL;
|
return success ? STATE_READY : STATE_ERROR_PROTOCOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
|
|
||||||
namespace metacall {
|
namespace metacall {
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Token
|
// Token
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user