1 /* 2 * Copyright (C) 2012-2018 Team Kodi 3 * This file is part of Kodi - https://kodi.tv 4 * 5 * SPDX-License-Identifier: GPL-2.0-or-later 6 * See LICENSES/README.md for more information. 7 */ 8 9 #pragma once 10 11 #include "XBDateTime.h" 12 13 #include <functional> 14 #include <map> 15 #include <memory> 16 #include <unordered_map> 17 #include <utility> 18 #include <vector> 19 20 class CFileItem; 21 class CFileItemList; 22 23 namespace PVR 24 { 25 struct GridItem 26 { GridItemGridItem27 GridItem(const std::shared_ptr<CFileItem>& _item, float _width, int _startBlock, int _endBlock) 28 : item(_item), 29 originWidth(_width), 30 width(_width), 31 startBlock(_startBlock), 32 endBlock(_endBlock) 33 { 34 } 35 36 bool operator==(const GridItem& other) const 37 { 38 return (startBlock == other.startBlock && endBlock == other.endBlock); 39 } 40 41 std::shared_ptr<CFileItem> item; 42 float originWidth = 0.0f; 43 float width = 0.0f; 44 int startBlock = 0; 45 int endBlock = 0; 46 }; 47 48 class CPVREpgInfoTag; 49 50 class CGUIEPGGridContainerModel 51 { 52 public: 53 static constexpr int MINSPERBLOCK = 5; // minutes 54 55 CGUIEPGGridContainerModel() = default; 56 virtual ~CGUIEPGGridContainerModel() = default; 57 58 void Initialize(const std::unique_ptr<CFileItemList>& items, 59 const CDateTime& gridStart, 60 const CDateTime& gridEnd, 61 int iFirstChannel, 62 int iChannelsPerPage, 63 int iFirstBlock, 64 int iBlocksPerPage, 65 int iRulerUnit, 66 float fBlockSize); 67 void SetInvalid(); 68 69 static const int INVALID_INDEX = -1; 70 void FindChannelAndBlockIndex(int channelUid, unsigned int broadcastUid, int eventOffset, int& newChannelIndex, int& newBlockIndex) const; 71 72 void FreeChannelMemory(int keepStart, int keepEnd); 73 bool FreeProgrammeMemory(int firstChannel, int lastChannel, int firstBlock, int lastBlock); 74 void FreeRulerMemory(int keepStart, int keepEnd); 75 GetChannelItem(int iIndex)76 std::shared_ptr<CFileItem> GetChannelItem(int iIndex) const { return m_channelItems[iIndex]; } HasChannelItems()77 bool HasChannelItems() const { return !m_channelItems.empty(); } ChannelItemsSize()78 int ChannelItemsSize() const { return static_cast<int>(m_channelItems.size()); } GetLastChannel()79 int GetLastChannel() const 80 { 81 return m_channelItems.empty() ? -1 : static_cast<int>(m_channelItems.size()) - 1; 82 } 83 GetRulerItem(int iIndex)84 std::shared_ptr<CFileItem> GetRulerItem(int iIndex) const { return m_rulerItems[iIndex]; } RulerItemsSize()85 int RulerItemsSize() const { return static_cast<int>(m_rulerItems.size()); } 86 GridItemsSize()87 int GridItemsSize() const { return m_blocks; } 88 bool IsSameGridItem(int iChannel, int iBlock1, int iBlock2) const; 89 std::shared_ptr<CFileItem> GetGridItem(int iChannel, int iBlock) const; 90 int GetGridItemStartBlock(int iChannel, int iBlock) const; 91 int GetGridItemEndBlock(int iChannel, int iBlock) const; 92 CDateTime GetGridItemEndTime(int iChannel, int iBlock) const; 93 float GetGridItemWidth(int iChannel, int iBlock) const; 94 float GetGridItemOriginWidth(int iChannel, int iBlock) const; 95 void DecreaseGridItemWidth(int iChannel, int iBlock, float fSize); 96 IsZeroGridDuration()97 bool IsZeroGridDuration() const { return (m_gridEnd - m_gridStart) == CDateTimeSpan(0, 0, 0, 0); } GetGridStart()98 const CDateTime& GetGridStart() const { return m_gridStart; } GetGridEnd()99 const CDateTime& GetGridEnd() const { return m_gridEnd; } 100 unsigned int GetGridStartPadding() const; 101 102 unsigned int GetPageNowOffset() const; 103 int GetNowBlock() const; GetLastBlock()104 int GetLastBlock() const { return m_blocks - 1; } 105 106 CDateTime GetStartTimeForBlock(int block) const; 107 int GetBlock(const CDateTime& datetime) const; 108 int GetFirstEventBlock(const std::shared_ptr<CPVREpgInfoTag>& event) const; 109 int GetLastEventBlock(const std::shared_ptr<CPVREpgInfoTag>& event) const; 110 bool IsEventMemberOfBlock(const std::shared_ptr<CPVREpgInfoTag>& event, int iBlock) const; 111 112 std::unique_ptr<CFileItemList> GetCurrentTimeLineItems() const; 113 114 private: 115 GridItem* GetGridItemPtr(int iChannel, int iBlock) const; 116 std::shared_ptr<CFileItem> CreateGapItem(int iChannel) const; 117 std::shared_ptr<CFileItem> GetItem(int iChannel, int iBlock) const; 118 119 std::vector<std::shared_ptr<CPVREpgInfoTag>> GetEPGTimeline( 120 int iChannel, const CDateTime& minEventEnd, const CDateTime& maxEventStart) const; 121 122 struct EpgTags 123 { 124 std::vector<std::shared_ptr<CFileItem>> tags; 125 int firstBlock = -1; 126 int lastBlock = -1; 127 }; 128 129 using EpgTagsMap = std::unordered_map<int, EpgTags>; 130 131 std::shared_ptr<CFileItem> CreateEpgTags(int iChannel, int iBlock) const; 132 std::shared_ptr<CFileItem> GetEpgTags(EpgTagsMap::iterator& itEpg, 133 int iChannel, 134 int iBlock) const; 135 std::shared_ptr<CFileItem> GetEpgTagsBefore(EpgTags& epgTags, int iChannel, int iBlock) const; 136 std::shared_ptr<CFileItem> GetEpgTagsAfter(EpgTags& epgTags, int iChannel, int iBlock) const; 137 138 mutable EpgTagsMap m_epgItems; 139 140 CDateTime m_gridStart; 141 CDateTime m_gridEnd; 142 143 std::vector<std::shared_ptr<CFileItem>> m_channelItems; 144 std::vector<std::shared_ptr<CFileItem>> m_rulerItems; 145 146 struct GridCoordinates 147 { GridCoordinatesGridCoordinates148 GridCoordinates(int _channel, int _block) : channel(_channel), block(_block) {} 149 150 bool operator==(const GridCoordinates& other) const 151 { 152 return (channel == other.channel && block == other.block); 153 } 154 155 int channel = 0; 156 int block = 0; 157 }; 158 159 struct GridCoordinatesHash 160 { operatorGridCoordinatesHash161 std::size_t operator()(const GridCoordinates& coordinates) const 162 { 163 return std::hash<int>()(coordinates.channel) ^ std::hash<int>()(coordinates.block); 164 } 165 }; 166 167 mutable std::unordered_map<GridCoordinates, GridItem, GridCoordinatesHash> m_gridIndex; 168 169 int m_blocks = 0; 170 float m_fBlockSize = 0.0f; 171 172 int m_firstActiveChannel = 0; 173 int m_lastActiveChannel = 0; 174 int m_firstActiveBlock = 0; 175 int m_lastActiveBlock = 0; 176 }; 177 } 178