eris  1.4.0
A WorldForge client library.
Response.cpp
1 #include "Response.h"
2 #include <Atlas/Objects/Operation.h>
3 #include <memory>
4 #include "LogStream.h"
5 
6 using namespace Atlas::Objects::Operation;
7 
8 namespace Eris
9 {
10 
11 std::string getErrorMessage(const RootOperation & err)
12 {
13  std::string msg;
14  const std::vector<Atlas::Objects::Root>& args = err->getArgs();
15  if (args.empty()) {
16  error() << "got Error error op from server without args";
17  msg = "Unknown error.";
18  } else {
19  const Atlas::Objects::Root & arg = args.front();
20  Atlas::Message::Element message;
21  if (arg->copyAttr("message", message) != 0) {
22  error() << "got Error error op from server without message";
23  msg = "Unknown error.";
24  } else {
25  if (!message.isString()) {
26  error() << "got Error error op from server with bad message";
27  msg = "Unknown error.";
28  } else {
29  msg = message.String();
30  }
31  }
32  }
33  return msg;
34 }
35 
36 ResponseBase::~ResponseBase() = default;
37 
38 ResponseTracker::~ResponseTracker() = default;
39 
40 void ResponseTracker::await(std::int64_t serial, Callback callback)
41 {
42  m_pending.emplace(serial, std::move(callback));
43 }
44 
45 
46 void ResponseTracker::await(std::int64_t serialno, std::unique_ptr<ResponseBase> resp)
47 {
48  assert(m_pending.count(serialno) == 0);
49  std::shared_ptr<ResponseBase> holder = std::move(resp);
50  await(serialno, [holder](const Atlas::Objects::Operation::RootOperation& op)->Router::RouterResult{
51  auto result = holder->responseReceived(op);
52  return result ? Router::HANDLED : Router::IGNORED;
53  });
54 }
55 
56 Router::RouterResult ResponseTracker::handleOp(const RootOperation& op)
57 {
58  if (op->isDefaultRefno()) return Router::IGNORED; // invalid refno, not a response op
59 
60  auto it = m_pending.find(op->getRefno());
61  if (it == m_pending.end()) {
62  warning() << "received op with valid refno (" << op->getRefno() <<
63  ") but no response is registered";
64  return Router::IGNORED;
65  }
66 
67 // order here is important, so the responseReceived can re-await the op
68  auto resp = it->second;
69  m_pending.erase(it);
70 
71  auto result = resp(op);
72 
73  return result;
74 }
75 
76 Router::RouterResult NullResponse::responseReceived(const Atlas::Objects::Operation::RootOperation&)
77 {
78  //debug() << "nullresponse, ignoring op with refno " << op->getRefno();
79  return Router::RouterResult::IGNORED;
80 }
81 
82 void* clearMemberResponse(void* d)
83 {
84  debug() << "clearing out member response object";
85 
86  void** objectPointer = (void**) d;
87  *objectPointer = nullptr;
88  return nullptr;
89 }
90 
91 } // of namespace
Eris
Definition: Account.cpp:33
Eris::debug
Definition: LogStream.h:46