zoukankan      html  css  js  c++  java
  • CAF(C++ actor framework)(序列化之结构体,任意嵌套STL)(一)

    User-Defined Data Types in Messages(用户自定义类型)
    All user-defined types must be explicitly “announced” so that CAF can (de)serialize them correctly.

    之前干活,一开始不知道CAF自带序列化,都用boost库来做序列化,就是变string 类型发送,发现很多STL有些搞搞比较麻烦,发现诶?CAF居然比boost库好使!

    那么就来搞一下看看.

    先看一个例子(也是usermanual 里唯一的一个例子,呵呵呵~)其他的例子在github官网里https://github.com/actor-framework/actor-framework/tree/master/examples/type_system (就五个收益很大)

    没看错就是那么简单的使用,announce函数。第一个参数是一个string那么之后就是他的所有成员。怎么实现我也不是很懂,上图

    大致就是TS 就是参数的类型,可以是可变长度,然后检查他们的类型,我第一看到Is_pod 查了一下(pod类型 是plain old data)就是完全兼容C语言的编程的。(涨姿势了~)

    还有uniform_type_info是CAF自己的一个关于类型什么的(没深究,只知道与RTTI有关)。还有一个重要的地方就是你必须写明你要发送的结构体的比较函数 ==(下面代码上有)

    进入正题。(announce1.cpp)代码有一点点小长但是信息量很大。

    // POD struct
    struct foo {
      std::vector<int> a;
      int b;
    };
    
    // announce requires foo to have the equal operator implemented
    bool operator==(const foo& lhs, const foo& rhs) {
      return lhs.a == rhs.a && lhs.b == rhs.b;
    }
    
    // a pair of two ints
    using foo_pair = std::pair<int, int>;
    
    // another pair of two ints
    using foo_pair2 = std::pair<int, int>;
    
    // a struct with member vector<vector<...>>
    struct foo2 {
      int a;
      vector<vector<double>> b;
    };
    
    bool operator==(const foo2& lhs, const foo2& rhs) {
      return lhs.a == rhs.a && lhs.b == rhs.b;
    }
    
    // receives `remaining` messages
    void testee(event_based_actor* self, size_t remaining) {
      auto set_next_behavior = [=] {
        if (remaining > 1) testee(self, remaining - 1);
        else self->quit();
      };
      self->become (
        // note: we sent a foo_pair2, but match on foo_pair
        // that's safe because both are aliases for std::pair<int, int>
        [=](const foo_pair& val) {
          cout << "foo_pair("
             << val.first << ", "
             << val.second << ")"
             << endl;
          set_next_behavior();
        },
        [=](const foo& val) {
          cout << "foo({";
          auto i = val.a.begin();
          auto end = val.a.end();
          if (i != end) {
            cout << *i;
            while (++i != end) {
              cout << ", " << *i;
            }
          }
          cout << "}, " << val.b << ")" << endl;
          set_next_behavior();
        }
      );
    }
    
    int main(int, char**) {
      // announces foo to the libcaf type system;
      // the function expects member pointers to all elements of foo
      announce<foo>("foo", &foo::a, &foo::b);
      // announce foo2 to the libcaf type system,
      // note that recursive containers are managed automatically by libcaf
      announce<foo2>("foo2", &foo2::a, &foo2::b);
      // serialization can throw if types are not announced properly
      try {
        // init some test data
        foo2 vd;
        vd.a = 5;
        vd.b.resize(1);
        vd.b.back().push_back(42);
        // serialize test data
        vector<char> buf;
        binary_serializer bs(std::back_inserter(buf));
        bs << vd;
        // deserialize written test data from buffer
        binary_deserializer bd(buf.data(), buf.size());
        foo2 vd2;
        uniform_typeid<foo2>()->deserialize(&vd2, &bd);
        // deserialized data must be equal to original input
        assert(vd == vd2);
        // announce std::pair<int, int> to the type system
        announce<foo_pair>("foo_pair", &foo_pair::first, &foo_pair::second);
        // libcaf returns the same uniform_type_info
        // instance for the type aliases foo_pair and foo_pair2
        assert(uniform_typeid<foo_pair>() == uniform_typeid<foo_pair2>());
      }
      catch (std::exception& e) {
        cerr << "error during type (de)serialization: " << e.what() << endl;
        return -1;
      }
      // spawn a testee that receives two messages of user-defined type
      auto t = spawn(testee, size_t{2});
      { // lifetime scope of self
        scoped_actor self;
        // send t a foo
        self->send(t, foo{std::vector<int>{1, 2, 3, 4}, 5});
        // send t a foo_pair2
        self->send(t, foo_pair2{3, 4});
      }
      await_all_actors_done();
      shutdown();
    }

    一开始看,就是声明了两种结构体。foo 和foo2,foo2里面有vector<vector<double>> b(其实这里就告诉我们,它不但支持STL,还支持嵌套,而且我亲测pair,map都是可以的。其他应该也没问题吧。)

    然后testee里定义了接受两种类型的消息一种是<int,int>(不管别名),一种是结构体foo 是的没看错,都不用序列化了,直接传(// note that recursive containers are managed automatically by libcaf)。

    真心方便,然后是main函数里,使用了二进制去序列化类,再使用反序列化,整个过程就像用读文件非常的方便(注意捕获异常)。那么在最后的scoped_actor send也直接把类传过去非常的方便。

    为了证明好用,支持remote actor我写了一个很难看的代码。

    #include <vector>
    #include <iostream>
    #include "caf/all.hpp"
    #include "caf/io/all.hpp"
    using std::cout;
    using std::endl;
    using std::vector;
    using std::map;
    using std::pair;
    using namespace caf;
    
    struct foo {
      std::vector<vector<map<int,pair<int,int>>>> a;
      int b;
    };
    bool operator==(const foo& lhs, const foo& rhs) {
      return lhs.a == rhs.a && lhs.b == rhs.b;
    }
    // receives `remaining` messages
    void testee(event_based_actor* self) {
      self->become (
        [=](const foo& val) {
            aout(self)<<"get it"<<endl;
        }
      );
    }
    int main(int, char**) {
    //  announce<foo2>("foo2", &foo2::a, &foo2::b);
      announce<foo>("foo", &foo::a, &foo::b);
      auto actor = spawn(testee);
      caf::io::publish(actor,10000);
      { // lifetime scope of self
        scoped_actor self;
        auto remoter = caf::io::remote_actor("localhost", 10000);
        self->send(remoter, foo{std::vector<vector<map<int,pair<int,int>>>>{},1,});
      }
      await_all_actors_done();
      shutdown();
    }

    结果为

    不得不服还是很方便的!

    码字不容易,求粉丝~互粉呀~

  • 相关阅读:
    《P3953 [NOIP2017 提高组] 逛公园》
    《P4180 [BJWC2010]严格次小生成树》
    《济南icpc补题》
    《levil的因子和》
    《洛谷P2704 [NOI2001]炮兵阵地》
    《Codeforces Round #689 (Div. 2, based on Zed Code Competition)》
    《2174: Leapin' Lizards》
    《3820: Revenge of Fibonacci 》
    马拉车求最长回文子串
    二分训练
  • 原文地址:https://www.cnblogs.com/zhejiangxiaomai/p/5259625.html
Copyright © 2011-2022 走看看