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
18using namespace Atlas::Objects::Operation;
19using Atlas::Objects::Root;
20using Atlas::Objects::smart_dynamic_cast;
21
22namespace Eris {
23
24EntityRouter::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
31EntityRouter::~EntityRouter() {
32 m_view.getConnection().unregisterRouterForFrom(m_entity.getId());
33}
34
35Router::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
82Router::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