好的问题第一: 我需要知道我的远程“对象派遣”(穷人的RPC)MethodCall方法中的难以置信的Evil(TM)开关有什么替代方案。如何实现更多的C++友好/支持OO的联网方法调度机制?
virtual void methodCall(unsigned int method) {
bvnet::scoped_lock lock(ctx.getMutex());
bvnet::value_queue &vqueue=ctx.getSendQueue();
switch(method) {
case 0: /* GetType */
/* emit object type to output queue as string */
vqueue.push(string(getType()));
break;
}
当然有人问我想用这种方法完成什么。
我建立了一个协议(网络),实现了一个轻量级的分布式对象系统,允许一端或另一端在一端或另一端使用对象引用和方法索引进行方法调用,每个对象都是一个整数,网络(所以不能使用指针,ptr-to-method等)。此外,我有一个注册表映射在每个跟踪哪些对象引用是活着的(意味着对象id整数来自另一端的传入方法调用是有效的)。
参数与第四风格的堆栈来处理,所以你不得不进入流的东西,如:
3 5 math.plus() 7 math.multiply()
实现的(3 + 5)* 7
的vqueue相当于< > .push()和getarg <>()通过vqueue处理将vlaue放到流出流中,并通过getarg读取参数<>()与<>模板化为支持的类型通过线这个动物是基类,其目的是提供注册到特定连接会话的对象(每个端点都有自己的注册表,每当创建新对象以引用远程对象时,都插入该注册表。
/**
** @brief ABC for remotable objects.
**
** Base used for objects exchangeable via object references.
**
** Since secure referencing requires a way to
** track object lifetime a registry reference
** is required for construction.
*/
class object {
protected:
session &ctx; /**< @brief for objects to attach to the session's registry */
public:
/** @brief construction of an object @param sess reference to session to attach */
object(session &sess) :
ctx(sess) {
LOCK_COUT
cout << "object [" << this << "] ctor" << endl;
UNLOCK_COUT
ctx.register_object(this);
}
/** @brief base dtor to automatically unregister the object */
virtual ~object() {
LOCK_COUT
cout << "object [" << this << "] dtor" << endl;
UNLOCK_COUT
ctx.unregister(this);
}
/**
* @brief Get object's identity.
* @return Object identity string
*
* Overriden by superclass to announce it's identity.
*/
virtual const char *getType() {return "baseObject";}
/**
* @brief Method call switchboard.
*
* Overidden by superclass to implement methods callable
* by the remote. Currently the superclasses are using
* big switchbanks which looks plain evil but at this
* point I'm not sure of what to refactor with.
*
* @todo
* Base class to implement some sort of glue to take out the switch boilerplate?
* @todo
* some sort of static enum to get rid of the magic number
* method call #s from remote POV?
* @todo
* automatically declare the methods for method calling
* via some sort of macro or metacode?
*
*/
virtual void methodCall(unsigned int idx)=0;
};
丑陋在于实现实际接口的派生对象。这是一个在MethodCall(即开关):
class Account : public bvnet::object {
private:
s64 userId;
public:
Account(bvnet::session &sess,s64 who)
: bvnet::object(sess),userId(who) {}
virtual ~Account() {}
virtual const char *getType() {return "userAccount";}
virtual void methodCall(unsigned int method) {
bvnet::scoped_lock lock(ctx.getMutex());
bvnet::value_queue &vqueue=ctx.getSendQueue();
switch(method) {
case 0: /* GetType */
/* emit object type to output queue as string */
vqueue.push(string(getType()));
break;
}
}
};
如此反复,问题是,如果有另一种方式来实现的东西更友好的C++和这样的把戏未来某个对象的编号方法分派决定他想要做
MyFutureAccount : public Account {...}
(和恐惧的nulcear裂变 - 愤怒的电子邮件,我会从要做到这一点马克塞斯附近的盖革计数器的愤怒维护者得到...)
好像我可能需要在bvnet :: Object的构造中做一些工作并设置一些C++内部(vtable)的形式,可以使用intMethodId-to-ptrToMember的STL映射(给下游提供一种简单的方法来覆盖内容)。然而,bvnet :: Object基类成员指针在下游派生类中是否仍按预期工作?还有很多问号。不知道如果我在正确的轨道上或在这个潜在的解决方案上咆哮错误的树...
而不是粘贴更多(我无法预测别人会想看到什么,我可以指出你为嘛GitHub的,因为它是LGPL3开源:https://github.com/gau-veldt/Minetest-Blockiverse/tree/master/blockiverse
最相关的文件将是https://github.com/gau-veldt/Minetest-Blockiverse/blob/master/blockiverse/protocol.hpp而是采取了战利品在ServerRoot的在https://github.com/gau-veldt/Minetest-Blockiverse/blob/master/blockiverse/server.hpp清楚地看到邪恶的开关方法已经成为在野外...
['std :: map'](http://en.cppreference.com/w/cpp/container/map)和['std :: function'](http://en.cppreference.com/瓦特/ CPP /实用程序/功能/功能)。 – 2014-12-04 14:46:59
@CaptainObvlious你能否详细说明一下?我怀疑std :: map是设置vtables的基类wizardry,但std :: function在哪里?我想象一下,典型的用例是一个bvnet :: Object派生对象的对象,它想要写入基类的vtable中,以楔入派生类中的各种方法成员。 std :: function是否处理这种情况?你的意思是一个动物:typedef std :: map overworld_vtable; –
2014-12-04 14:52:43
我不想回答,直到我知道我的攻击计划正在工作,但是它涉及到std :: map,因为我和@CaptainObvlious都提到现在只有我错过了std :: function需要它匹配的签名作为它的模板参数(当你做成员函数调用时给出类名)。作为一个优点,新模式还将旧代码中的某些样板文件转化为单一的点,并允许为未实现的方法引发一个简单的异常。我还添加了标记方法插槽的功能(允许更好的调试信息)。现在回到疯狂的编码......:P – 2014-12-04 16:23:15