VR-Forces 4.0.4 Class Documentation
Entity List

The DtEntityList class is a Qt-based dialog/ widget class that displays all existing entities as well as their current task and, if available, their destination.


Header file:

/*******************************************************************************
** Copyright (c) 2011 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/

//\file DtEntityList.h
//\brief Contains makVrf::makVrfEntityListExample::DtEntityList class.

#pragma once

#include <vrvUtil/signalslib.h>

#include "entityListUi.hpp"

#include <vrvCoreQt/DtDockable.h>
#include <vrvCoreQt/DtPage.h>
#include <vrvCore/DtUserInterfaceAssembler.h>
#include <vrvCore/DtStateViewCollection.h>
#include <vrfGuiCore/DtVrfStateViewCollectionManager.h>
#include <vrftasks/simTask.h>

namespace makVrv
{
   class DtDe;
}

namespace makVrfEntityListExample
{

   //A widget class that displays all existing entities
   //as well as their current task and, if available, their destination.
   class DtEntityList
      : public makVrv::DtPage
      , public makVrv::DtDockable
   {
   public:
      DtEntityList( makVrv::DtDe& de, QWidget* parent = 0, Qt::WindowFlags flags = 0);

      virtual ~DtEntityList();

      //Get the icon of the page.
      virtual QIcon icon();

      //Get the title of the page.
      virtual QString title();

      //Get the class name of the page.
      virtual const std::string& pageClassName() const;

      //Called when the page is displayed.
      virtual void activate();

      //Called when the page is hidden.
      virtual void deactivate();

      static std::string thePageClassName();

      //Goes through the entire list of entities and populates the tree
      virtual void populateEntityList();

   protected:
      //Sets up the contents of the widget onto the supplied parent
      void setupUi(QWidget* p);

      //Clears out widget
      virtual void clear();


   protected:
      virtual void slot_onObjectAdded(const makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>&);
      virtual void slot_onObjectUpdated(makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>*);
      virtual void slot_onObjectAboutToBeRemoved(const makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>&);
      virtual void slot_onCurrentTaskChanged(const std::string& entityName);

      //Using the known task, fill in the destination line in the entity list
      void fillDestinationLine(DtSimTask* task,QTreeWidgetItem* displayEntityItem);

   public:
      Ui_DtEntityListUi myUi;

      //A list of all simulated entities.
      //Each State View is a collection of similar objects
      //that the VR-Forces front end knows about. This particular view
      //keeps a list of all simulated entities.
      makVrf::DtVrfSimulatedEntityStateViewCollection* mySimulatedEntityStateView;

      //This maps keeps track of each line in the target list
      std::map<const makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>*, QTreeWidgetItem*> myLineToStateViewMap;
   };

   //Create a "creator" helper class using the template.
   typedef makVrv::DtPageCreatorTemplate<DtEntityList> DtEntityListWidgetCreator;
}

Implementation:

/*******************************************************************************
** Copyright (c) 2011 MAK Technologies, Inc.
** All rights reserved.
*******************************************************************************/

//\file DtEntityList.cxx
//\brief Contains makVrf3DEntityListExample::DtEntityList class.


#include "DtEntityList.h"

#include <vrfGuiCoreQt/vrfGuiCoreQt.h>
#include <vrfGuiCoreQt/DtVrfGuiSymbolMapper.h>
#include <vrfGuiCore/DtVrfCurrentTaskManager.h>
#include <vrfGuiCore/entityMapperKey.h>
#include <vrftasks/moveToTask.h>
#include <vrftasks/moveToLocTask.h>
#include <vrftasks/radioMsgTypes.h>

#include <vlpi/appearance.h>

#include <QtGui/QPixmap>

using namespace makVrf;

namespace makVrfEntityListExample
{
   DtEntityList::DtEntityList( makVrv::DtDe& de, QWidget* parent, Qt ::WindowFlags flags)
   : DtPage(de, parent, flags)
   , makVrv::DtDockable(de, "DtEntityList")
   {
      setObjectName(tr("Entity List"));
      setupUi(this);
         

      mySimulatedEntityStateView = DtVrfStateViewCollectionManager::instance(de).simulatedEntityStateViewCollection();

      //The first thing to do is to populate my entity list with all existing entities.
      populateEntityList();

      //Set up connections
      //From now on, all new entities are called through these slots.
      mySimulatedEntityStateView->signal_stateViewAdded.connect(
         boost::bind(&DtEntityList::slot_onObjectAdded, this, _1));
      mySimulatedEntityStateView->signal_stateViewAboutToBeRemoved.connect(
         boost::bind(&DtEntityList::slot_onObjectAboutToBeRemoved, this, _1));

      DtVrfCurrentTaskManager& manager = DtVrfCurrentTaskManager::instance(de);
      manager.signal_currentTaskChanged.connect(
         boost::bind(&DtEntityList::slot_onCurrentTaskChanged, this, _1));
   }

   DtEntityList::~DtEntityList()
   {
      //remove connections
      mySimulatedEntityStateView->signal_stateViewAdded.disconnect(
         boost::bind(&DtEntityList::slot_onObjectAdded, this, _1));
      mySimulatedEntityStateView->signal_stateViewAboutToBeRemoved.disconnect(
         boost::bind(&DtEntityList::slot_onObjectAboutToBeRemoved, this, _1));

      DtVrfCurrentTaskManager& manager = DtVrfCurrentTaskManager::instance(DtPage::myDe);
      manager.signal_currentTaskChanged.disconnect(
         boost::bind(&DtEntityList::slot_onCurrentTaskChanged, this, _1));
   }

   QIcon DtEntityList::icon()
   {
      return QIcon(QString::fromStdString(DtPage::myDe.dePathConfiguration().dataPath() +"/Icons/?.svg"));
   }

   QString DtEntityList::title()
   {
      return tr("Entity List");
   }

   const std::string& DtEntityList::pageClassName() const
   {
      return myClassName;
   }

   void DtEntityList::activate()
   {
   }

   void DtEntityList::deactivate()
   {
   }

   std::string DtEntityList::thePageClassName()
   {
      return "DtEntityList";
   }

   void DtEntityList::setupUi(QWidget* p)
   {
      myUi.setupUi(this);
   }

   void DtEntityList::clear()
   {
      myUi.myEntityTree->clear();
   }

   void DtEntityList::populateEntityList()
   {
      //The list from the DtVrfStateViewCollectionManager will contain
      //all the entities that are currently on the network. Initially,
      //this function populates our list, but it gets updated by using the
      //callback functions below
      DtVrfSimulatedEntityStateViewCollection::StateViewMap::const_iterator iter =
         mySimulatedEntityStateView->stateViewMap().begin();
      while (iter != mySimulatedEntityStateView->stateViewMap().end())
      {
         //Add the entity to my list
         makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>* entityState = iter->second;
         slot_onObjectAdded(*entityState);
         ++iter;
      }

   }

   void DtEntityList::slot_onObjectAdded(const makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>& entityState)
   {
      makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>* nonConstStateView =
         const_cast<makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>*>(&entityState);

      if(myLineToStateViewMap[nonConstStateView] != 0)
      {
         return; //This object has already been added.
      }

      QTreeWidgetItem* displayEntityItem = new QTreeWidgetItem(0);

      //Subscribe to object updates so we can grab the name of an entity when it updates.
      //Note that it is possible that at this point the entity name is blank which is why
      //we need to wait for an update.
      nonConstStateView->signal_stateViewUpdated.connect(
         boost::bind(&DtEntityList::slot_onObjectUpdated, this, _1));

      //Set to update on any updates.  Need to set update rate on state view in
      //order to get state view information
      nonConstStateView->setUpdateRate(makVrv::DtSimEntryUpdater::AnyUpdates);

      //Force the initial update. Note that it is possible that this initial update is incomplete
      myLineToStateViewMap[nonConstStateView] = displayEntityItem;
      nonConstStateView->forceUpdate();
      
      myUi.myEntityTree->addTopLevelItem(displayEntityItem);
   }

   void DtEntityList::slot_onObjectAboutToBeRemoved(const makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>& entityState)
   {
      //Remove all callbacks
      makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>* nonConstStateView =
         const_cast<makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>*>(&entityState);
      nonConstStateView->signal_stateViewUpdated.disconnect(
         boost::bind(&DtEntityList::slot_onObjectUpdated, this, _1));

      //Remove deleted entity from gui.
      QTreeWidgetItem* displayEntityItem = myLineToStateViewMap[nonConstStateView];
      if(displayEntityItem)
      {
         myUi.myEntityTree->takeTopLevelItem(
            myUi.myEntityTree->indexOfTopLevelItem(displayEntityItem));
         myLineToStateViewMap[nonConstStateView] = 0;
      }
   }

   void DtEntityList::slot_onObjectUpdated(makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>* entityState)
   {
      //If the marking text is has not updated, this entity is not ready to be updated.
      //The VR-Forces front end does not have a concept of discovery criteria so we must
      //simulate the criteria in this way.
      if(entityState->state().myMarkingText.empty())
      {
         //If marking text is empty then force an update of the state view until marking text is filled in
         entityState->forceUpdate();

         return;
      }

      QTreeWidgetItem* displayEntityItem = myLineToStateViewMap[entityState];

      if(displayEntityItem)
      {
         if(displayEntityItem->text(0).isEmpty())
         {
            slot_onCurrentTaskChanged(entityState->state().myMarkingText.c_str());

            //In order to get the task of an object we need to subscribe to the task manager
            //Note that we do this here instead of when the object is added because the 
            //DtVrfCurrentTaskManager will not work until after an update has
            //identified the object name.
            DtVrfCurrentTaskManager& manager = DtVrfCurrentTaskManager::instance(DtPage::myDe);
            manager.subscribeForTaskInformation(entityState->id());
         }

         if(displayEntityItem->text(0).toLatin1().constData() != entityState->state().myMarkingText)
         {
            displayEntityItem->setText(0,entityState->state().myMarkingText.c_str());
         }

         //Get the icon for this item.  If the serial numbers are different, then set the icon
         bool destroyed = false;

         makVrf::DtEntityMapperKey key(entityState->state().myForce, entityState->state().myEntityType.c_str());

         if (key.kind() == 11)
         {
            destroyed = (entityState->state().myAppearance == DtDamageDestroyed);
         }
         else
         {
            DtAppearance app(DtEntityType(entityState->state().myEntityType.c_str()));

            app.setAppearance(entityState->state().myAppearance);

            destroyed = (app.damageState() == DtDamageDestroyed);
         }

         QPixmap pMap = makVrf::DtVrfGuiSymbolMapper::instance(DtPage::myDe).getIcon(
            key, destroyed, 48, false, &entityState->state());

         if (pMap.serialNumber() != displayEntityItem->icon(0).serialNumber())
         {
            displayEntityItem->setIcon(0, pMap);
         }
      }
   }

   void DtEntityList::slot_onCurrentTaskChanged(const std::string& entityName)
   {
      if(entityName == "") return;

      makVrv::DtStateView<makVrv::DtVrlinkSimulatedEntityState>* entityState = 0;

      //The list from the DtVrfStateViewCollectionManager will contain
      //all the entities that are currently on the network. I use
      //this list to find the entity with the right name.
      DtVrfSimulatedEntityStateViewCollection::StateViewMap::const_iterator iter =
         mySimulatedEntityStateView->stateViewMap().begin();
      while (iter != mySimulatedEntityStateView->stateViewMap().end())
      {
         //Is this the correct state view?
         if(iter->second->state().myMarkingText == entityName)
         {
            entityState = iter->second;
            break;
         }
         ++iter;
      }

      QTreeWidgetItem* displayEntityItem = myLineToStateViewMap[entityState];

      if(displayEntityItem)
      {
         //Use the task manager to grab the current task and display it.
         DtVrfCurrentTaskManager& manager = DtVrfCurrentTaskManager::instance(DtPage::myDe);
         const DtVrfCurrentTaskManager::EntityTaskInformation* tasks = manager.tasksFor(entityState->id());

         if(!tasks || (tasks->size() == 0))
         {
            //No task
            displayEntityItem->setText(1,"");
         }
         else
         {
            int taskType = ((*tasks)[0]).first->type();
            DtString taskName;
            ((*tasks)[0]).first->getTaskNameFromTaskType(taskType,taskName);
               
            displayEntityItem->setText(1,taskName.c_str());
            fillDestinationLine(((*tasks)[0]).first.get(),displayEntityItem);
         }
      }
   }

   void DtEntityList::fillDestinationLine(DtSimTask* task,QTreeWidgetItem* displayEntityItem)
   {
      int taskType = task->type();

      switch(taskType)
      {
      case DtMoveToLocationTaskType:
         {
            //For location destinations, just display the ending point.
            DtMoveToLocationTask* locTask = (DtMoveToLocationTask*)task;
            displayEntityItem->setText(2,formatSourceToDisplay(locTask->aimingPoint()).c_str());
            break;
         }

      case DtMoveToType:
         {
            //For location destinations, display the ending point and the name of the waypoint.
            DtMoveToTask* locTask = (DtMoveToTask*)task;
            DtString controlPtName = locTask->controlPtName();

            //Go through each environmental to find the correct waypoint
            makVrf::DtEnvironmentStateViewCollection* envStateView = 
               DtVrfStateViewCollectionManager::instance(DtPage::myDe).environmentStateViewCollection();
            makVrf::DtEnvironmentStateViewCollection::StateViewMap::const_iterator iter =
               envStateView->stateViewMap().begin();
            while (iter != envStateView->stateViewMap().end())
            {
                  
               makVrv::DtStateView<makVrf::DtVrlinkSimulatedEnvironmentProcess>* waypointState = iter->second;
               if(waypointState->state().myMarkingText == controlPtName.c_str())
               {
                  //Found the named waypoint
                  DtString destinationText = waypointState->state().myPoints[0].string() + " (" + controlPtName + ")";
                  displayEntityItem->setText(2,destinationText.c_str());
                  return;
               }

               ++iter;
            }
            break;
         }
      }
   }
}

Document ID: Generated on Fri Jun 29 16:33:32 EDT 2012 from SVN revision 116588
Copyright © 2005-2012 VT MÄK Inc. All Rights Reserved (www.mak.com)