void View::create(const RootEntity& gent) { std::string eid(gent->getId()); if (m_contents.count(eid)) { // already known locally, just emit the signal EntityCreated.emit( m_contents[eid] ); return; } bool alreadyAppeared = false; PendingSightMap::iterator pending = m_pending.find(eid); if (pending != m_pending.end()) { // already being retrieved, but we have the data now alreadyAppeared = (pending->second == SACTION_QUEUED) || (pending->second == SACTION_APPEAR); pending->second = SACTION_DISCARD; // when the SIGHT turns up } Entity* ent = createEntity(gent); m_contents[eid] = ent; ent->init(gent, true); if (gent->isDefaultLoc()) setTopLevelEntity(ent); InitialSightEntity.emit(ent); // depends on relative order that sight(create) and appear are received in if (alreadyAppeared) { ent->setVisible(true); EntityCreated.emit(ent); } }
void View::sight(const RootEntity& gent) { bool visible = true; std::string eid = gent->getId(); PendingSightMap::iterator pending = m_pending.find(eid); // examine the pending map, to see what we should do with this entity if (pending != m_pending.end()) { switch (pending->second) { case SACTION_APPEAR: visible = true; break; case SACTION_DISCARD: m_pending.erase(pending); issueQueuedLook(); return; case SACTION_HIDE: visible = false; break; case SACTION_QUEUED: error() << "got sight of queued entity " << eid << " somehow"; eraseFromLookQueue(eid); break; default: throw InvalidOperation("got bad pending action for entity"); } m_pending.erase(pending); } // if we got this far, go ahead and build / update it Entity *ent = getEntity(eid); if (ent) { // existing entity, update in place ent->sight(gent); } else { ent = initialSight(gent); EntitySeen.emit(ent); } if (gent->isDefaultLoc()) { // new top level entity setTopLevelEntity(ent); } ent->setVisible(visible); issueQueuedLook(); }