LCOV - code coverage report
Current view: top level - source/simulation2/components - CCmpCinemaManager.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 68 198 34.3 %
Date: 2023-01-19 00:18:29 Functions: 21 33 63.6 %

          Line data    Source code
       1             : /* Copyright (C) 2022 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "simulation2/system/Component.h"
      21             : #include "ICmpCinemaManager.h"
      22             : 
      23             : #include "ps/CLogger.h"
      24             : #include "simulation2/components/ICmpOverlayRenderer.h"
      25             : #include "simulation2/components/ICmpRangeManager.h"
      26             : #include "simulation2/components/ICmpSelectable.h"
      27             : #include "simulation2/components/ICmpTerritoryManager.h"
      28             : #include "simulation2/MessageTypes.h"
      29             : #include "simulation2/Simulation2.h"
      30             : 
      31             : 
      32          12 : class CCmpCinemaManager final : public ICmpCinemaManager
      33             : {
      34             : public:
      35         116 :     static void ClassInit(CComponentManager& componentManager)
      36             :     {
      37         116 :         componentManager.SubscribeToMessageType(MT_Update);
      38         116 :     }
      39             : 
      40           8 :     DEFAULT_COMPONENT_ALLOCATOR(CinemaManager)
      41             : 
      42         116 :     static std::string GetSchema()
      43             :     {
      44         116 :         return "<a:component type='system'/><empty/>";
      45             :     }
      46             : 
      47           4 :     void Init(const CParamNode& UNUSED(paramNode)) override
      48             :     {
      49           4 :         m_Enabled = false;
      50           4 :         m_MapRevealed = false;
      51           4 :         m_ElapsedTime = fixed::Zero();
      52           4 :         m_TotalTime = fixed::Zero();
      53           4 :         m_CurrentPathElapsedTime = fixed::Zero();
      54           4 :     }
      55             : 
      56           4 :     void Deinit() override
      57             :     {
      58           4 :     }
      59             : 
      60           0 :     void Serialize(ISerializer& serializer) override
      61             :     {
      62           0 :         serializer.Bool("Enabled", m_Enabled);
      63           0 :         serializer.NumberFixed_Unbounded("ElapsedTime", m_ElapsedTime);
      64           0 :         serializer.NumberFixed_Unbounded("CurrentPathElapsedTime", m_CurrentPathElapsedTime);
      65           0 :         serializer.Bool("MapRevealed", m_MapRevealed);
      66             : 
      67           0 :         serializer.NumberU32_Unbounded("NumberOfPaths", m_Paths.size());
      68           0 :         for (const std::pair<const CStrW, CCinemaPath>& it : m_Paths)
      69           0 :             SerializePath(it.second, serializer);
      70             : 
      71           0 :         serializer.NumberU32_Unbounded("NumberOfQueuedPaths", m_PathQueue.size());
      72           0 :         for (const CCinemaPath& path : m_PathQueue)
      73           0 :             serializer.String("PathName", path.GetName(), 1, 128);
      74           0 :     }
      75             : 
      76           0 :     void Deserialize(const CParamNode& UNUSED(paramNode), IDeserializer& deserializer) override
      77             :     {
      78           0 :         deserializer.Bool("Enabled", m_Enabled);
      79           0 :         deserializer.NumberFixed_Unbounded("ElapsedTime", m_ElapsedTime);
      80           0 :         deserializer.NumberFixed_Unbounded("CurrentPathElapsedTime", m_CurrentPathElapsedTime);
      81           0 :         deserializer.Bool("MapRevealed", m_MapRevealed);
      82             : 
      83           0 :         uint32_t numberOfPaths = 0;
      84           0 :         deserializer.NumberU32_Unbounded("NumberOfPaths", numberOfPaths);
      85           0 :         for (uint32_t i = 0; i < numberOfPaths; ++i)
      86             :         {
      87           0 :             CCinemaPath path = DeserializePath(deserializer);
      88           0 :             m_Paths[path.GetName()] = path;
      89             :         }
      90             : 
      91           0 :         uint32_t numberOfQueuedPaths = 0;
      92           0 :         deserializer.NumberU32_Unbounded("NumberOfQueuedPaths", numberOfQueuedPaths);
      93           0 :         for (uint32_t i = 0; i < numberOfQueuedPaths; ++i)
      94             :         {
      95           0 :             CStrW pathName;
      96           0 :             deserializer.String("PathName", pathName, 1, 128);
      97           0 :             ENSURE(HasPath(pathName));
      98           0 :             AddCinemaPathToQueue(pathName);
      99             :         }
     100             : 
     101           0 :         if (!m_PathQueue.empty())
     102             :         {
     103           0 :             m_PathQueue.front().m_TimeElapsed = m_CurrentPathElapsedTime.ToFloat();
     104           0 :             m_PathQueue.front().Validate();
     105             :         }
     106             : 
     107           0 :         SetEnabled(m_Enabled);
     108           0 :     }
     109             : 
     110         100 :     void HandleMessage(const CMessage& msg, bool UNUSED(global)) override
     111             :     {
     112         100 :         switch (msg.GetType())
     113             :         {
     114         100 :         case MT_Update:
     115             :         {
     116         100 :             const CMessageUpdate &msgData = static_cast<const CMessageUpdate&>(msg);
     117         100 :             if (!m_Enabled)
     118           0 :                 break;
     119             : 
     120         100 :             m_ElapsedTime += msgData.turnLength;
     121         100 :             m_CurrentPathElapsedTime += msgData.turnLength;
     122         100 :             if (m_CurrentPathElapsedTime >= m_PathQueue.front().GetDuration())
     123             :             {
     124           2 :                 CMessageCinemaPathEnded msgCinemaPathEnded(m_PathQueue.front().GetName());
     125           1 :                 m_PathQueue.pop_front();
     126           1 :                 GetSimContext().GetComponentManager().PostMessage(SYSTEM_ENTITY, msgCinemaPathEnded);
     127           1 :                 m_CurrentPathElapsedTime = fixed::Zero();
     128             : 
     129           1 :                 if (!m_PathQueue.empty())
     130           0 :                     m_PathQueue.front().Reset();
     131             :             }
     132             : 
     133         100 :             if (m_ElapsedTime >= m_TotalTime)
     134             :             {
     135           1 :                 m_CurrentPathElapsedTime = fixed::Zero();
     136           1 :                 m_ElapsedTime = fixed::Zero();
     137           1 :                 m_TotalTime = fixed::Zero();
     138           1 :                 SetEnabled(false);
     139           1 :                 GetSimContext().GetComponentManager().PostMessage(SYSTEM_ENTITY, CMessageCinemaQueueEnded());
     140             :             }
     141             : 
     142         100 :             break;
     143             :         }
     144           0 :         default:
     145           0 :             break;
     146             :         }
     147         100 :     }
     148             : 
     149           2 :     void AddPath(const CCinemaPath& path) override
     150             :     {
     151           2 :         if (m_Paths.find(path.GetName()) != m_Paths.end())
     152             :         {
     153           0 :             LOGWARNING("Path with name '%s' already exists", path.GetName().ToUTF8());
     154           0 :             return;
     155             :         }
     156           2 :         m_Paths[path.GetName()] = path;
     157             :     }
     158             : 
     159           1 :     void AddCinemaPathToQueue(const CStrW& name) override
     160             :     {
     161           1 :         if (!HasPath(name))
     162             :         {
     163           0 :             LOGWARNING("Path with name '%s' doesn't exist", name.ToUTF8());
     164           0 :             return;
     165             :         }
     166           1 :         m_PathQueue.push_back(m_Paths[name]);
     167             : 
     168           1 :         if (m_PathQueue.size() == 1)
     169           1 :             m_PathQueue.front().Reset();
     170           1 :         m_TotalTime += m_Paths[name].GetDuration();
     171             :     }
     172             : 
     173           1 :     void Play() override
     174             :     {
     175           1 :         SetEnabled(true);
     176           1 :     }
     177             : 
     178           0 :     void Stop() override
     179             :     {
     180           0 :         SetEnabled(false);
     181           0 :     }
     182             : 
     183           6 :     bool HasPath(const CStrW& name) const override
     184             :     {
     185           6 :         return m_Paths.find(name) != m_Paths.end();
     186             :     }
     187             : 
     188           0 :     void ClearQueue() override
     189             :     {
     190           0 :         m_PathQueue.clear();
     191           0 :     }
     192             : 
     193           1 :     void DeletePath(const CStrW& name) override
     194             :     {
     195           1 :         if (!HasPath(name))
     196             :         {
     197           0 :             LOGWARNING("Path with name '%s' doesn't exist", name.ToUTF8());
     198           0 :             return;
     199             :         }
     200           2 :         m_PathQueue.remove_if([name](const CCinemaPath& path) { return path.GetName() == name; });
     201           1 :         m_Paths.erase(name);
     202             :     }
     203             : 
     204           0 :     const std::map<CStrW, CCinemaPath>& GetPaths() const override
     205             :     {
     206           0 :         return m_Paths;
     207             :     }
     208             : 
     209           0 :     void SetPaths(const std::map<CStrW, CCinemaPath>& newPaths) override
     210             :     {
     211           0 :         m_Paths = newPaths;
     212           0 :     }
     213             : 
     214           0 :     const std::list<CCinemaPath>& GetQueue() const override
     215             :     {
     216           0 :         return m_PathQueue;
     217             :     }
     218             : 
     219         102 :     bool IsEnabled() const override
     220             :     {
     221         102 :         return m_Enabled;
     222             :     }
     223             : 
     224           2 :     void SetEnabled(bool enabled) override
     225             :     {
     226           2 :         if (m_PathQueue.empty() && enabled)
     227           0 :             enabled = false;
     228             : 
     229           2 :         if (m_Enabled == enabled)
     230           0 :             return;
     231             : 
     232           2 :         CmpPtr<ICmpRangeManager> cmpRangeManager(GetSimContext().GetSystemEntity());
     233           2 :         CmpPtr<ICmpTerritoryManager> cmpTerritoryManager(GetSimContext().GetSystemEntity());
     234           2 :         if (cmpRangeManager)
     235             :         {
     236           0 :             if (enabled)
     237           0 :                 m_MapRevealed = cmpRangeManager->GetLosRevealAll(-1);
     238             :             // TODO: improve m_MapRevealed state and without fade in
     239           0 :             cmpRangeManager->SetLosRevealAll(-1, enabled);
     240             :         }
     241           2 :         if (cmpTerritoryManager)
     242           0 :             cmpTerritoryManager->SetVisibility(!enabled);
     243           2 :         ICmpSelectable::SetOverrideVisibility(!enabled);
     244           2 :         ICmpOverlayRenderer::SetOverrideVisibility(!enabled);
     245             : 
     246           2 :         m_Enabled = enabled;
     247             :     }
     248             : 
     249           0 :     void PlayQueue(const float deltaRealTime, CCamera* camera) override
     250             :     {
     251           0 :         if (m_PathQueue.empty())
     252           0 :             return;
     253           0 :         m_PathQueue.front().Play(deltaRealTime, camera);
     254             :     }
     255             : 
     256             : private:
     257             : 
     258           0 :     void SerializePath(const CCinemaPath& path, ISerializer& serializer)
     259             :     {
     260           0 :         const CCinemaData* data = path.GetData();
     261             : 
     262           0 :         serializer.String("PathName", data->m_Name, 1, 128);
     263           0 :         serializer.String("PathOrientation", data->m_Orientation, 1, 128);
     264           0 :         serializer.String("PathMode", data->m_Mode, 1, 128);
     265           0 :         serializer.String("PathStyle", data->m_Style, 1, 128);
     266           0 :         serializer.NumberFixed_Unbounded("PathTimescale", data->m_Timescale);
     267           0 :         serializer.Bool("LookAtTarget", data->m_LookAtTarget);
     268             : 
     269           0 :         serializer.NumberU32("NumberOfNodes", path.GetAllNodes().size(), 1, MAX_SPLINE_NODES);
     270           0 :         const std::vector<SplineData>& nodes = path.GetAllNodes();
     271           0 :         for (size_t i = 0; i < nodes.size(); ++i)
     272             :         {
     273           0 :             if (i > 0)
     274           0 :                 serializer.NumberFixed_Unbounded("NodeDeltaTime", nodes[i - 1].Distance);
     275             :             else
     276           0 :                 serializer.NumberFixed_Unbounded("NodeDeltaTime", fixed::Zero());
     277             : 
     278           0 :             serializer.NumberFixed_Unbounded("PositionX", nodes[i].Position.X);
     279           0 :             serializer.NumberFixed_Unbounded("PositionY", nodes[i].Position.Y);
     280           0 :             serializer.NumberFixed_Unbounded("PositionZ", nodes[i].Position.Z);
     281             : 
     282           0 :             serializer.NumberFixed_Unbounded("RotationX", nodes[i].Rotation.X);
     283           0 :             serializer.NumberFixed_Unbounded("RotationY", nodes[i].Rotation.Y);
     284           0 :             serializer.NumberFixed_Unbounded("RotationZ", nodes[i].Rotation.Z);
     285             :         }
     286             : 
     287           0 :         if (!data->m_LookAtTarget)
     288           0 :             return;
     289             : 
     290           0 :         const std::vector<SplineData>& targetNodes = path.GetTargetSpline().GetAllNodes();
     291           0 :         serializer.NumberU32("NumberOfTargetNodes", targetNodes.size(), 1, MAX_SPLINE_NODES);
     292           0 :         for (size_t i = 0; i < targetNodes.size(); ++i)
     293             :         {
     294           0 :             if (i > 0)
     295           0 :                 serializer.NumberFixed_Unbounded("NodeDeltaTime", targetNodes[i - 1].Distance);
     296             :             else
     297           0 :                 serializer.NumberFixed_Unbounded("NodeDeltaTime", fixed::Zero());
     298           0 :             serializer.NumberFixed_Unbounded("PositionX", targetNodes[i].Position.X);
     299           0 :             serializer.NumberFixed_Unbounded("PositionY", targetNodes[i].Position.Y);
     300           0 :             serializer.NumberFixed_Unbounded("PositionZ", targetNodes[i].Position.Z);
     301             :         }
     302             :     }
     303             : 
     304           0 :     CCinemaPath DeserializePath(IDeserializer& deserializer)
     305             :     {
     306           0 :         CCinemaData data;
     307             : 
     308           0 :         deserializer.String("PathName", data.m_Name, 1, 128);
     309           0 :         deserializer.String("PathOrientation", data.m_Orientation, 1, 128);
     310           0 :         deserializer.String("PathMode", data.m_Mode, 1, 128);
     311           0 :         deserializer.String("PathStyle", data.m_Style, 1, 128);
     312           0 :         deserializer.NumberFixed_Unbounded("PathTimescale", data.m_Timescale);
     313           0 :         deserializer.Bool("LookAtTarget", data.m_LookAtTarget);
     314             : 
     315           0 :         TNSpline pathSpline, targetSpline;
     316           0 :         uint32_t numberOfNodes = 0;
     317           0 :         deserializer.NumberU32("NumberOfNodes", numberOfNodes, 1, MAX_SPLINE_NODES);
     318           0 :         for (uint32_t j = 0; j < numberOfNodes; ++j)
     319             :         {
     320           0 :             SplineData node;
     321           0 :             deserializer.NumberFixed_Unbounded("NodeDeltaTime", node.Distance);
     322             : 
     323           0 :             deserializer.NumberFixed_Unbounded("PositionX", node.Position.X);
     324           0 :             deserializer.NumberFixed_Unbounded("PositionY", node.Position.Y);
     325           0 :             deserializer.NumberFixed_Unbounded("PositionZ", node.Position.Z);
     326             : 
     327           0 :             deserializer.NumberFixed_Unbounded("RotationX", node.Rotation.X);
     328           0 :             deserializer.NumberFixed_Unbounded("RotationY", node.Rotation.Y);
     329           0 :             deserializer.NumberFixed_Unbounded("RotationZ", node.Rotation.Z);
     330             : 
     331           0 :             pathSpline.AddNode(node.Position, node.Rotation, node.Distance);
     332             :         }
     333             : 
     334           0 :         if (data.m_LookAtTarget)
     335             :         {
     336           0 :             uint32_t numberOfTargetNodes = 0;
     337           0 :             deserializer.NumberU32("NumberOfTargetNodes", numberOfTargetNodes, 1, MAX_SPLINE_NODES);
     338           0 :             for (uint32_t j = 0; j < numberOfTargetNodes; ++j)
     339             :             {
     340           0 :                 SplineData node;
     341           0 :                 deserializer.NumberFixed_Unbounded("NodeDeltaTime", node.Distance);
     342             : 
     343           0 :                 deserializer.NumberFixed_Unbounded("PositionX", node.Position.X);
     344           0 :                 deserializer.NumberFixed_Unbounded("PositionY", node.Position.Y);
     345           0 :                 deserializer.NumberFixed_Unbounded("PositionZ", node.Position.Z);
     346             : 
     347           0 :                 targetSpline.AddNode(node.Position, CFixedVector3D(), node.Distance);
     348             :             }
     349             :         }
     350             : 
     351           0 :         return CCinemaPath(data, pathSpline, targetSpline);
     352             :     }
     353             : 
     354             :     bool m_Enabled;
     355             :     std::map<CStrW, CCinemaPath> m_Paths;
     356             :     std::list<CCinemaPath> m_PathQueue;
     357             : 
     358             :     // States before playing
     359             :     bool m_MapRevealed;
     360             : 
     361             :     fixed m_ElapsedTime;
     362             :     fixed m_TotalTime;
     363             :     fixed m_CurrentPathElapsedTime;
     364             : };
     365             : 
     366         119 : REGISTER_COMPONENT_TYPE(CinemaManager)

Generated by: LCOV version 1.13