All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ShapeViewController.h
1 #pragma once
2 
3 #include "Types.h"
4 #include "ShapeEventTypes.h"
5 #include "ICallback.h"
6 #include "Positioning.h"
7 #include "IPositioningViewComponent.h"
8 #include "IShapeView.h"
9 #include "ShapeHelpers.h"
10 #include "InteriorInteractionModel.h"
11 
12 #include <unordered_set>
13 
14 
15 namespace Eegeo
16 {
17  namespace Shapes
18  {
19 
20 
21  template <typename TArgs>
23  {
24  public:
26 
27  TShapeViewController(typename TArgs::ShapeViewFactoryType& viewFactory,
28  typename TArgs::ShapeViewRepositoryType& viewRepository,
29  const Eegeo::Positioning::IPositioningViewComponent& positioningViewComponent,
30  typename TArgs::ShapeModelAddedEventType& shapeModelAddedEvent,
31  typename TArgs::ShapeModelRemovedEventType& shapeModelRemovedEvent,
32  typename TArgs::ShapeModelChangedEventType& shapeModelChangedEvent,
33  const Resources::Interiors::InteriorInteractionModel& interiorInteractionModel)
34  : m_viewFactory(viewFactory)
35  , m_viewRepository(viewRepository)
36  , m_positioningViewComponent(positioningViewComponent)
37  , m_shapeModelAddedEvent(shapeModelAddedEvent)
38  , m_shapeModelRemovedEvent(shapeModelRemovedEvent)
39  , m_shapeModelChangedEvent(shapeModelChangedEvent)
40  , m_shapeModelAddedHandler(this, &ThisType::OnShapeModelAdded)
41  , m_shapeModelRemovedHandler(this, &ThisType::OnShapeModelRemoved)
42  , m_shapeModelChangedHandler(this, &ThisType::OnShapeModelChanged)
43  , m_positioningViewComponentChangedHandler(this, &ThisType::OnPositioningViewComponentChanged)
44  , m_positioningViewComponentChanged(true)
45  , m_interiorInteractionModel(interiorInteractionModel)
46  {
47  m_shapeModelAddedEvent.Register(m_shapeModelAddedHandler);
48  m_shapeModelRemovedEvent.Register(m_shapeModelRemovedHandler);
49  m_shapeModelChangedEvent.Register(m_shapeModelChangedHandler);
50  m_positioningViewComponent.GetPositioningViewComponentChangedEvent().Register(m_positioningViewComponentChangedHandler);
51  }
52 
53  virtual ~TShapeViewController()
54  {
55  m_shapeModelAddedEvent.Unregister(m_shapeModelAddedHandler);
56  m_shapeModelRemovedEvent.Unregister(m_shapeModelRemovedHandler);
57  m_shapeModelChangedEvent.Unregister(m_shapeModelChangedHandler);
58  m_positioningViewComponent.GetPositioningViewComponentChangedEvent().Unregister(m_positioningViewComponentChangedHandler);
59  }
60 
61  void Update()
62  {
63  for (auto pShapeModel : m_modelsNeedingViewRebind)
64  {
65  UnbindView(*pShapeModel);
66  BindView(*pShapeModel);
67  }
68  m_modelsNeedingViewRebind.clear();
69 
70  if (m_positioningViewComponentChanged)
71  {
72  std::vector<typename TArgs::ShapeViewType*> views;
73  m_viewRepository.AllItems(views);
74 
75  for (auto view : views)
76  {
77  UpdateView(*view);
78  }
79  m_positioningViewComponentChanged = false;
80  }
81  }
82 
83  private:
84  void BindView(const typename TArgs::ShapeModelType& shapeModel)
85  {
86  auto pView = m_viewFactory.CreateView(shapeModel);
87  m_viewRepository.Add(shapeModel.GetId(), pView);
88 
89  UpdateView(*pView);
90  }
91 
92  void UnbindView(const typename TArgs::ShapeModelType& shapeModel)
93  {
94  auto pView = m_viewRepository.Get(shapeModel.GetId());
95  m_viewRepository.Remove(shapeModel.GetId());
96  Eegeo_DELETE pView;
97  }
98 
99  void OnShapeModelAdded(const typename TArgs::ShapeModelType& shapeModel)
100  {
101  BindView(shapeModel);
102  }
103 
104  void OnShapeModelRemoved(const typename TArgs::ShapeModelType& shapeModel)
105  {
106  m_modelsNeedingViewRebind.erase(&shapeModel);
107  UnbindView(shapeModel);
108  }
109 
110  void OnShapeModelChanged(const typename TArgs::ShapeModelChangedMessageType& message)
111  {
112  if (message.GeometryChanged)
113  {
114  m_modelsNeedingViewRebind.insert(&message.ShapeModel);
115  }
116  else
117  {
118  auto& view = *m_viewRepository.Get(message.ShapeModel.GetId());
119  UpdateView(view);
120  }
121  }
122 
123  void OnPositioningViewComponentChanged()
124  {
125  m_positioningViewComponentChanged = true;
126 
127  }
128 
129  void UpdateView(IShapeView& view) const
130  {
131  const bool show = ShouldShowView(view);
132  view.SetHidden(!show);
133  view.Update();
134  }
135 
136  bool ShouldShowView(const IShapeView& view) const
137  {
138  const auto& model = view.GetShapeModel();
139  bool isExpanded = m_interiorInteractionModel.IsFullyExpanded() || m_interiorInteractionModel.IsEnteringExpanded();
140  return ShapeHelpers::ShouldDisplayShape(model, m_positioningViewComponent, isExpanded);
141  }
142 
143  typename TArgs::ShapeViewFactoryType& m_viewFactory;
144  typename TArgs::ShapeViewRepositoryType& m_viewRepository;
145  const Eegeo::Positioning::IPositioningViewComponent& m_positioningViewComponent;
146  typename TArgs::ShapeModelAddedEventType& m_shapeModelAddedEvent;
147  typename TArgs::ShapeModelRemovedEventType& m_shapeModelRemovedEvent;
148  typename TArgs::ShapeModelChangedEventType& m_shapeModelChangedEvent;
149 
153  Helpers::TCallback0<TShapeViewController> m_positioningViewComponentChangedHandler;
154 
155  std::unordered_set<const typename TArgs::ShapeModelType*> m_modelsNeedingViewRebind;
156  bool m_positioningViewComponentChanged;
157 
158  const Resources::Interiors::InteriorInteractionModel& m_interiorInteractionModel;
159  };
160  }
161 }
162 
163