调度自动化
dispatch automation
我自己不太确定我在这里要求什么,所以请耐心等待我一秒钟。
基本上,我有一个应用程序,除其他外,它必须能够处理从某个外部源(例如套接字)接收的命令。
每个命令都使用特定于此命令的两个数据结构 - 一个结构包含一组与此命令的处理相关的参数,另一个结构接收一些结果数据。
当然,数据传输处理程序类不知道哪个命令使用哪些结构,因此在收到命令后调用的第一件事如下所示:
CSocketHandler::ReceiveCommand(int CommandCode, const TBuffer& Args, TBuffer& Result);
最后一个看起来像这样:
CClassBar::ProcessCommandFoo(const TFooArgs& Args, TFooResult& Result);
现在,缺少的只是将 TBuffer 转换为 TFooArgs 的部分,调用正确的方法,然后将 TFooResult 转换回 TBuffer 的部分(转换是微不足道的)。
不同的处理程序类和命令的数量有望相当大,所以我在这里看到的是一个三英里长的方法,它对不同的数据类型做同样的事情,然后一遍又一遍地调用不同的函数。
所以我的问题 - 是否有可能自动化这个乏味且容易出错的任务?最好只是定义一个新的消息处理方法就足够了,但我愿意妥协。
通用代码很好。
- 创建两种转换方法,一种从
TBuffer
转换为XArgs
,另一种从XResult
转换为TBuffer
- 创建自动命令包装器
- 实现自动调度到这些包装器的
map
您可以通过指向函数的指针或继承来做到这一点,我想继承会更容易......
class BaseCommand {
public:
virtual ~BaseCommand() {}
virtual TBuffer invoke(TBuffer const& tb) = 0;
};
template <typename Args, typename Result>
class CommandT: public BaseCommand {
public:
virtual TBuffer invoke(TBuffer const& tb) {
Args const a = from_buffer(tb, &a); // free function
Result const r = this->invoke(a);
return to_buffer(r); // free function
}
private:
virtual Result invoke(Args const&) = 0;
};
注意:作为作弊,我们将&a
传递给from_buffer
以获得自动参数扣除,预计指针未使用。
因此,让我们假设我们有我们的论点和结果(两者都int
更容易):
int from_buffer(TBuffer const& tb, int const*) {
return tb.asInt();
}
TBuffer to_buffer(int i) {
return TBuffer(i);
}
然后我们可以实现一个处理int
的命令:
class IntCommand: public CommandT<int, int> {
virtual int invoke(int const& i) override { return i; }
};
好的,让我们继续调度。这个想法是将每个命令注册到其 ID。
template <typename T>
std::unique_ptr<BaseCommand> make_command() { return std::unique_ptr<T>(new T()); }
static std::map<int, std::unique_ptr<BaseCommand>> Commands;
int main() {
Commands.insert(std::make_pair(1, make_command<IntCommand>()));
// lots of them...
// starts processing
}
在SocketHandler
我们有:
void SocketHandler::ReceiveCommand(int code, TBuffer const& a, TBuffer& r) {
typedef std::map<int, std::unique_ptr<BaseCommand>>::const_iterator const_it;
const_it it = Commands.find(code);
if (it == Commands.end()) {
std::cerr << "Unknown command: " << code << "n";
throw std::runtime_error("Unknown command");
}
r = it->second->invoke(a);
}
相关文章:
- 如何在c++中实现处理器调度模拟器
- 如何在 C++17 STL 并行算法中处理调度?
- 无法使用迭代器标记调度实例化模板
- Qt QML桌面应用程序自动化测试
- 在 c++11 中为 pthread 设置调度参数
- 如何在 assert() 和 static_assert() 之间调度,如果在 constexpr 上下文中依赖?
- 如何使用从处理程序调度的最终回调将响应异步返回给调用方on_read?
- C++双重调度
- 动态调度到模板函数C++
- 正确调度消息 UART
- 在 C++ 中使用枚举而不是结构进行标记调度
- 如何实现从 Windows 脚本主机到脚本的事件调度
- C++内置类型的基于类型的调度
- 用于GPU上的瓦片度量和调度的Halide
- SFINAE和标签调度之间的差异
- C++ 如何按标签调度到不同的模板函数
- 在 boost::asio 中发布和调度有什么区别?
- 根据应用程序是否已自动化显示不同的 QML 文件
- 5 CPU的任务调度N进程
- 调度自动化