eris  1.4.0
A WorldForge client library.
EntityRouter.cpp
1 #ifdef HAVE_CONFIG_H
2  #include "config.h"
3 #endif
4 
5 #include "EntityRouter.h"
6 #include "LogStream.h"
7 #include "ViewEntity.h"
8 #include "TypeService.h"
9 #include "Avatar.h"
10 #include "TypeInfo.h"
11 #include "View.h"
12 #include "Connection.h"
13 #include "TypeBoundRedispatch.h"
14 
15 #include <Atlas/Objects/Operation.h>
16 #include <Atlas/Objects/Entity.h>
17 
18 using namespace Atlas::Objects::Operation;
19 using Atlas::Objects::Root;
20 using Atlas::Objects::smart_dynamic_cast;
21 
22 namespace Eris {
23 
24 EntityRouter::EntityRouter(Entity& ent, View& view) :
25  m_entity(ent),
26  m_view(view)
27 {
28  m_view.getConnection().registerRouterForFrom(this, m_entity.getId());
29 }
30 
31 EntityRouter::~EntityRouter() {
32  m_view.getConnection().unregisterRouterForFrom(m_entity.getId());
33 }
34 
35 Router::RouterResult EntityRouter::handleOperation(const RootOperation& op)
36 {
37  assert(op->getFrom() == m_entity.getId());
38  const std::vector<Root>& args = op->getArgs();
39 
40  // note it's important we match exactly on sight here, and not derived ops
41  // like appearance and disappearance
42  if (op->getClassNo() == SIGHT_NO) {
43  for (const auto& arg : args) {
44  RootOperation sop = smart_dynamic_cast<RootOperation>(arg);
45  if (sop.isValid()) {
46  return handleSightOp(sop);
47  }
48  }
49  }
50 
51  if (op->getClassNo() == SOUND_NO) {
52  for (const auto& arg : args) {
53  if (arg->getClassNo() == TALK_NO)
54  {
55  RootOperation talk = smart_dynamic_cast<RootOperation>(arg);
56  m_entity.onTalk(talk);
57  } else {
58  if (!arg->isDefaultParent()) {
59  auto ty = m_view.getTypeService().getTypeForAtlas(arg);
60  if (!ty->isBound()) {
61  new TypeBoundRedispatch(m_view.getConnection(), op, ty);
62  } else if (ty->isA(m_view.getTypeService().getTypeByName("action"))) {
63  // sound of action
64  RootOperation act = smart_dynamic_cast<RootOperation>(arg);
65  m_entity.onSoundAction(act, *ty);
66  } else {
67  warning() << "entity " << m_entity.getId() << " emitted sound with strange argument: " << op;
68  }
69  } else {
70  warning() << "entity " << m_entity.getId() << " emitted sound with strange argument: " << op;
71  }
72  }
73  }
74 
75  return HANDLED;
76  // other sounds !
77  }
78 
79  return IGNORED;
80 }
81 
82 Router::RouterResult EntityRouter::handleSightOp(const RootOperation& op)
83 {
84  const std::vector<Root>& args = op->getArgs();
85 
86 // if (op->getClassNo() == SET_NO) {
87 //
88 // //If we get a SET op for an entity that's not visible, it means that the entity has moved
89 // //within our field of vision without sending an Appear op first. We should treat this as a
90 // //regular Appear op and issue a Look op back, to get more info.
91 // if (!m_entity.isVisible()) {
92 // m_entity.getView()->sendLookAt(m_entity.getId());
93 // }
94 //
95 // for (const auto& arg : args) {
96 // if (arg->hasAttr("loc")) {
97 // m_entity.setLocationFromAtlas(arg->getAttr("loc").asString());
98 // }
99 //
100 // m_entity.setFromRoot(arg, true /* movement allowed */);
101 // }
102 //
103 // return HANDLED;
104 // }
105 
106  if (op->instanceOf(IMAGINARY_NO)) {
107  if (args.empty()) {
108  error() << "entity " << m_entity.getId() << " sent imaginary with no args: " << op;
109  } else {
110  for (const auto& arg : args) {
111  m_entity.onImaginary(arg);
112  }
113  }
114  return HANDLED;
115  }
116 
117  // explicitly do NOT handle set ops here, since they can
118  // validly change multiple entities - handled by the IGRouter
119 
120  return IGNORED;
121 }
122 
123 
124 } // of namespace Eris
Definition: Account.cpp:33