[SCM] kodi-pvr-hts/master: factored out channels, tags, recordings, timers, events and schedules to separate files, deriving from an Entity base class which provides the "dirty" functionality

tiber-guest at users.alioth.debian.org tiber-guest at users.alioth.debian.org
Wed Mar 2 23:01:42 UTC 2016


The following commit has been merged in the master branch:
commit c8b2bead3dee783c8b8e4d74ea9ef0751ed26c01
Author: Sam Stenvall <neggelandia at gmail.com>
Date:   Thu Jul 23 14:32:47 2015 +0300

    factored out channels, tags, recordings, timers, events and
    schedules to separate files, deriving from an Entity base class
    which provides the "dirty" functionality

diff --git a/CMakeLists.txt b/CMakeLists.txt
index e46301a..8318881 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,7 +23,6 @@ set(HTS_SOURCES src/AsyncState.cpp
                 src/HTSPConnection.cpp
                 src/HTSPDemuxer.cpp
                 src/HTSPTypes.h
-                src/HTSPTypes.cpp
                 src/HTSPVFS.cpp
                 src/Settings.h
                 src/Tvheadend.cpp
@@ -33,8 +32,25 @@ set(HTS_SOURCES src/AsyncState.cpp
                 src/AutoRecordings.cpp
                 src/AutoRecordings.h
                 src/xbmc_codec_descriptor.hpp)
+
+set(HTS_SOURCES_TVHEADEND_ENTITY
+                src/tvheadend/entity/AutoRecording.h
+                src/tvheadend/entity/AutoRecording.cpp
+                src/tvheadend/entity/Channel.h
+                src/tvheadend/entity/Entity.h
+                src/tvheadend/entity/Event.h
+                src/tvheadend/entity/Recording.h
+                src/tvheadend/entity/RecordingBase.h
+                src/tvheadend/entity/RecordingBase.cpp
+                src/tvheadend/entity/Schedule.h
+                src/tvheadend/entity/Schedule.cpp
+                src/tvheadend/entity/Tag.h
+                src/tvheadend/entity/Tag.cpp
+                src/tvheadend/entity/TimeRecording.h
+                src/tvheadend/entity/TimeRecording.cpp)
                 
 source_group("Source Files" FILES ${HTS_SOURCES})
+source_group("Source Files\\tvheadend\\entity" FILES ${HTS_SOURCES_TVHEADEND_ENTITY})
 
 # Resource files
 set(HTS_RESOURCES 
@@ -49,6 +65,7 @@ source_group("Resource Files" FILES ${HTS_RESOURCES})
 
 # Combine the file lists
 list(APPEND HTS_SOURCES
+            ${HTS_SOURCES_TVHEADEND_ENTITY}
             ${HTS_RESOURCES})
 
 add_subdirectory(lib/libhts)
diff --git a/src/AutoRecordings.cpp b/src/AutoRecordings.cpp
index 92c670d..65d60c3 100644
--- a/src/AutoRecordings.cpp
+++ b/src/AutoRecordings.cpp
@@ -24,6 +24,7 @@
 #include "Tvheadend.h"
 
 using namespace PLATFORM;
+using namespace tvheadend::entity;
 
 AutoRecordings::AutoRecordings(CHTSPConnection &conn) :
   m_conn(conn)
@@ -320,7 +321,7 @@ bool AutoRecordings::ParseAutorecAddOrUpdate(htsmsg_t *msg, bool bAdd)
   }
 
   /* Locate/create entry */
-  htsp::AutoRecording &rec = m_autoRecordings[std::string(str)];
+  AutoRecording &rec = m_autoRecordings[std::string(str)];
   rec.SetStringId(std::string(str));
   rec.SetDirty(false);
 
diff --git a/src/AutoRecordings.h b/src/AutoRecordings.h
index 30ba9cf..f3d06b3 100644
--- a/src/AutoRecordings.h
+++ b/src/AutoRecordings.h
@@ -30,7 +30,7 @@ extern "C"
 }
 
 #include "kodi/libXBMC_pvr.h"
-#include "HTSPTypes.h"
+#include "tvheadend/entity/AutoRecording.h"
 
 class CHTSPConnection;
 
@@ -60,6 +60,6 @@ public:
   bool ParseAutorecDelete(htsmsg_t *msg);
 
 private:
-  CHTSPConnection         &m_conn;
-  htsp::AutoRecordingsMap  m_autoRecordings;
+  CHTSPConnection                      &m_conn;
+  tvheadend::entity::AutoRecordingsMap  m_autoRecordings;
 };
diff --git a/src/HTSPTypes.cpp b/src/HTSPTypes.cpp
deleted file mode 100644
index 8f63944..0000000
--- a/src/HTSPTypes.cpp
+++ /dev/null
@@ -1,469 +0,0 @@
-/*
- *      Copyright (C) 2005-2015 Team Kodi
- *      http://kodi.tv
- *
- *  This Program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2, or (at your option)
- *  any later version.
- *
- *  This Program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with XBMC; see the file COPYING.  If not, write to
- *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
- *  http://www.gnu.org/copyleft/gpl.html
- *
- */
-
-#include <time.h>
-#include "Tvheadend.h"
-
-#include "HTSPTypes.h"
-
-namespace htsp
-{
-
-Tag::Tag(uint32_t id /*= 0*/) :
-  m_dirty(false),
-  m_id   (id),
-  m_index(0)
-{
-}
-
-bool Tag::operator==(const Tag &right)
-{
-  return m_id       == right.m_id &&
-         m_index    == right.m_index &&
-         m_name     == right.m_name &&
-         m_icon     == right.m_icon &&
-         m_channels == right.m_channels;
-}
-
-bool Tag::operator!=(const Tag &right)
-{
-  return !(*this == right);
-}
-
-bool Tag::IsDirty() const
-{
-  return m_dirty;
-}
-
-void Tag::SetDirty(bool bDirty)
-{
-  m_dirty = bDirty;
-}
-
-uint32_t Tag::GetId() const
-{
-   return m_id;
-}
-
-uint32_t Tag::GetIndex() const
-{
-  return m_index;
-}
-
-void Tag::SetIndex(uint32_t index)
-{
-  m_index = index;
-}
-
-const std::string& Tag::GetName() const
-{
-  return m_name;
-}
-
-void Tag::SetName(const std::string& name)
-{
-  m_name = name;
-}
-
-void Tag::SetIcon(const std::string& icon)
-{
-  m_icon = icon;
-}
-
-const std::vector<uint32_t>& Tag::GetChannels() const
-{
-  return m_channels;
-}
-
-std::vector<uint32_t>& Tag::GetChannels()
-{
-  return m_channels;
-}
-
-bool Tag::ContainsChannelType(bool bRadio) const
-{
-  std::vector<uint32_t>::const_iterator it;
-  SChannels::const_iterator cit;
-  const SChannels& channels = tvh->GetChannels();
-
-  for (it = m_channels.begin(); it != m_channels.end(); ++it)
-  {
-    if ((cit = channels.find(*it)) != channels.end())
-    {
-      if (bRadio == cit->second.radio)
-        return true;
-    }
-  }
-  return false;
-}
-
-/* **************************************************************************
- * RecordingBase
- * *************************************************************************/
-
-RecordingBase::RecordingBase(const std::string &id /*= ""*/) :
-  m_iId(GetNextIntId()),
-  m_dirty(false),
-  m_id(id),
-  m_enabled(0),
-  m_daysOfWeek(0),
-  m_retention(0),
-  m_priority(0),
-  m_channel(0)
-{
-}
-
-bool RecordingBase::operator==(const RecordingBase &right)
-{
-  return m_iId         == right.m_iId         &&
-         m_id          == right.m_id          &&
-         m_enabled     == right.m_enabled     &&
-         m_daysOfWeek  == right.m_daysOfWeek  &&
-         m_retention   == right.m_retention   &&
-         m_priority    == right.m_priority    &&
-         m_title       == right.m_title       &&
-         m_name        == right.m_name        &&
-         m_directory   == right.m_directory   &&
-         m_owner       == right.m_owner       &&
-         m_creator     == right.m_creator     &&
-         m_channel     == right.m_channel;
-}
-
-bool RecordingBase::operator!=(const RecordingBase &right)
-{
-  return !(*this == right);
-}
-
-unsigned int RecordingBase::GetIntId() const
-{
-  return m_iId;
-}
-
-bool RecordingBase::IsDirty() const
-{
-  return m_dirty;
-}
-
-void RecordingBase::SetDirty(bool bDirty)
-{
-  m_dirty = bDirty;
-}
-
-std::string RecordingBase::GetStringId() const
-{
-  return m_id;
-}
-
-void RecordingBase::SetStringId(const std::string &id)
-{
-  m_id = id;
-}
-
-bool RecordingBase::IsEnabled() const
-{
-  return m_enabled != 0;
-}
-
-void RecordingBase::SetEnabled(uint32_t enabled)
-{
-  m_enabled = enabled;
-}
-
-int RecordingBase::GetDaysOfWeek() const
-{
-  return m_daysOfWeek;
-}
-
-void RecordingBase::SetDaysOfWeek(uint32_t daysOfWeek)
-{
-  m_daysOfWeek = daysOfWeek;
-}
-
-uint32_t RecordingBase::GetRetention() const
-{
-  return m_retention;
-}
-
-void RecordingBase::SetRetention(uint32_t retention)
-{
-  m_retention = retention;
-}
-
-uint32_t RecordingBase::GetPriority() const
-{
-  return m_priority;
-}
-
-void RecordingBase::SetPriority(uint32_t priority)
-{
-  m_priority = priority;
-}
-
-const std::string& RecordingBase::GetTitle() const
-{
-  return m_title;
-}
-
-void RecordingBase::SetTitle(const std::string &title)
-{
-  m_title = title;
-}
-
-const std::string& RecordingBase::GetName() const
-{
-  return m_name;
-}
-
-void RecordingBase::SetName(const std::string &name)
-{
-  m_name = name;
-}
-
-const std::string& RecordingBase::GetDirectory() const
-{
-  return m_directory;
-}
-
-void RecordingBase::SetDirectory(const std::string &directory)
-{
-  m_directory = directory;
-}
-
-void RecordingBase::SetOwner(const std::string &owner)
-{
-  m_owner = owner;
-}
-
-void RecordingBase::SetCreator(const std::string &creator)
-{
-  m_creator = creator;
-}
-
-uint32_t RecordingBase::GetChannel() const
-{
-  return m_channel;
-}
-
-void RecordingBase::SetChannel(uint32_t channel)
-{
-  m_channel = channel;
-}
-
-// static
-time_t RecordingBase::LocaltimeToUTC(int32_t lctime)
-{
-  /* Note: lctime contains minutes from midnight (up to 24*60) as local time. */
-
-  /* complete lctime with current year, month, day, ... */
-  time_t t = time(NULL);
-  struct tm *tm_time = localtime(&t);
-
-  tm_time->tm_hour  = lctime / 60;
-  tm_time->tm_min   = lctime % 60;
-  tm_time->tm_sec   = 0;
-
-  return mktime(tm_time);
-}
-
-// static
-int RecordingBase::GetNextIntId()
-{
-  static unsigned int intId = 0;
-  return ++intId;
-}
-
-/* **************************************************************************
- * TimeRecording
- * *************************************************************************/
-
-TimeRecording::TimeRecording(const std::string &id /*= ""*/) :
-  RecordingBase(id),
-  m_start(0),
-  m_stop(0)
-{
-}
-
-bool TimeRecording::operator==(const TimeRecording &right)
-{
-  return RecordingBase::operator==(right) &&
-         m_start       == right.m_start   &&
-         m_stop        == right.m_stop;
-}
-
-bool TimeRecording::operator!=(const TimeRecording &right)
-{
-  return !(*this == right);
-}
-
-time_t TimeRecording::GetStart() const
-{
-  if (m_start == int32_t(-1)) // "any time"
-    return 0;
-
-  return LocaltimeToUTC(m_start);
-}
-
-void TimeRecording::SetStart(int32_t start)
-{
-  m_start = start;
-}
-
-time_t TimeRecording::GetStop() const
-{
-  if (m_stop == int32_t(-1)) // "any time"
-    return 0;
-
-  return LocaltimeToUTC(m_stop);
-}
-
-void TimeRecording::SetStop(int32_t stop)
-{
-  m_stop = stop;
-}
-
-/* **************************************************************************
- * AutoRecording
- * *************************************************************************/
-
-AutoRecording::AutoRecording(const std::string &id /*= ""*/) :
-  RecordingBase(id),
-  m_startWindowBegin(0),
-  m_startWindowEnd(0),
-  m_startExtra(0),
-  m_stopExtra(0),
-  m_dupDetect(0),
-  m_fulltext(0)
-{
-}
-
-bool AutoRecording::operator==(const AutoRecording &right)
-{
-  return RecordingBase::operator==(right)               &&
-         m_startWindowBegin == right.m_startWindowBegin &&
-         m_startWindowEnd   == right.m_startWindowEnd   &&
-         m_startExtra       == right.m_startExtra       &&
-         m_stopExtra        == right.m_stopExtra        &&
-         m_dupDetect        == right.m_dupDetect        &&
-         m_fulltext         == right.m_fulltext;
-}
-
-bool AutoRecording::operator!=(const AutoRecording &right)
-{
-  return !(*this == right);
-}
-
-time_t AutoRecording::GetStart() const
-{
-  if (tvh->GetSettings().bAutorecApproxTime)
-  {
-    /* Calculate the approximate start time from the starting window */
-    if ((m_startWindowBegin == int32_t(-1)) || (m_startWindowEnd == int32_t(-1))) // no starting window set => "any time"
-      return 0;
-    else if (m_startWindowEnd < m_startWindowBegin)
-    {
-      /* End of start window is a day in the future */
-      int32_t newEnd  = m_startWindowEnd + (24 * 60);
-      int32_t newStart = m_startWindowBegin + (newEnd - m_startWindowBegin) / 2;
-
-      if (newStart > (24 * 60))
-        newStart -= (24 * 60);
-
-      return LocaltimeToUTC(newStart);
-    }
-    else
-      return LocaltimeToUTC(m_startWindowBegin + (m_startWindowEnd - m_startWindowBegin) / 2);
-  }
-  else
-  {
-    if (m_startWindowBegin == int32_t(-1)) // "any time"
-      return 0;
-
-    return LocaltimeToUTC(m_startWindowBegin);
-  }
-}
-
-void AutoRecording::SetStartWindowBegin(int32_t begin)
-{
-  m_startWindowBegin = begin;
-}
-
-time_t AutoRecording::GetStop() const
-{
-  if (tvh->GetSettings().bAutorecApproxTime)
-  {
-    /* Tvh doesn't have an approximate stop time => "any time" */
-    return 0;
-  }
-  else
-  {
-    if (m_startWindowEnd == int32_t(-1)) // "any time"
-      return 0;
-
-    return LocaltimeToUTC(m_startWindowEnd);
-  }
-}
-
-void AutoRecording::SetStartWindowEnd(int32_t end)
-{
-  m_startWindowEnd = end;
-}
-
-int64_t AutoRecording::GetMarginStart() const
-{
-  return m_startExtra;
-}
-
-void AutoRecording::SetMarginStart(int64_t startExtra)
-{
-  m_startExtra = startExtra;
-}
-
-int64_t AutoRecording::GetMarginEnd() const
-{
-  return m_stopExtra;
-}
-
-void AutoRecording::SetMarginEnd(int64_t stopExtra)
-{
-  m_stopExtra = stopExtra;
-}
-
-uint32_t AutoRecording::GetDupDetect() const
-{
-  return m_dupDetect;
-}
-
-void AutoRecording::SetDupDetect(uint32_t dupDetect)
-{
-  m_dupDetect = dupDetect;
-}
-
-bool AutoRecording::GetFulltext() const
-{
-  return m_fulltext > 0;
-}
-
-void AutoRecording::SetFulltext(uint32_t fulltext)
-{
-  m_fulltext = fulltext;
-}
-
-} // namespace htsp
diff --git a/src/HTSPTypes.h b/src/HTSPTypes.h
index 58a32b6..385b0d4 100644
--- a/src/HTSPTypes.h
+++ b/src/HTSPTypes.h
@@ -73,314 +73,6 @@ enum eSubscriptionWeight {
   SUBSCRIPTION_WEIGHT_SERVERCONF = 0,
 };
 
-namespace htsp
-{
-
-class Tag
-{
-public:
-  Tag(uint32_t id = 0);
-
-  bool operator==(const Tag &right);
-  bool operator!=(const Tag &right);
-
-  bool IsDirty() const;
-  void SetDirty(bool bDirty);
-
-  uint32_t GetId() const;
-
-  uint32_t GetIndex() const;
-  void SetIndex(uint32_t index);
-
-  const std::string& GetName() const;
-  void SetName(const std::string& name);
-
-  void SetIcon(const std::string& icon);
-
-  const std::vector<uint32_t>& GetChannels() const;
-  std::vector<uint32_t>& GetChannels();
-
-  bool ContainsChannelType(bool bRadio) const;
-
-private:
-  bool                  m_dirty;
-
-  uint32_t              m_id;
-  uint32_t              m_index;
-  std::string           m_name;
-  std::string           m_icon;
-  std::vector<uint32_t> m_channels;
-};
-
-typedef std::map<uint32_t, Tag> Tags;
-
-class RecordingBase
-{
-protected:
-  RecordingBase(const std::string &id = "");
-
-  bool operator==(const RecordingBase &right);
-  bool operator!=(const RecordingBase &right);
-
-public:
-  unsigned int GetIntId() const;
-
-  bool IsDirty() const;
-  void SetDirty(bool bDirty);
-
-  std::string GetStringId() const;
-  void SetStringId(const std::string &id);
-
-  bool IsEnabled() const;
-  void SetEnabled(uint32_t enabled);
-
-  int GetDaysOfWeek() const;
-  void SetDaysOfWeek(uint32_t daysOfWeek);
-
-  uint32_t GetRetention() const;
-  void SetRetention(uint32_t retention);
-
-  uint32_t GetPriority() const;
-  void SetPriority(uint32_t priority);
-
-  const std::string& GetTitle() const;
-  void SetTitle(const std::string &title);
-
-  const std::string& GetName() const;
-  void SetName(const std::string &name);
-
-  const std::string& GetDirectory() const;
-  void SetDirectory(const std::string &directory);
-
-  void SetOwner(const std::string &owner);
-
-  void SetCreator(const std::string &creator);
-
-  uint32_t GetChannel() const;
-  void SetChannel(uint32_t channel);
-
-protected:
-  static time_t LocaltimeToUTC(int32_t lctime);
-
-private:
-  static int    GetNextIntId();
-
-  const unsigned int m_iId;
-  bool               m_dirty;
-
-  std::string m_id;         // ID (string!) of dvr[Time|Auto]recEntry.
-  uint32_t    m_enabled;    // If [time|auto]rec entry is enabled (activated).
-  uint32_t    m_daysOfWeek; // Bitmask - Days of week (0x01 = Monday, 0x40 = Sunday, 0x7f = Whole Week, 0 = Not set).
-  uint32_t    m_retention;  // Retention time (in days).
-  uint32_t    m_priority;   // Priority (0 = Important, 1 = High, 2 = Normal, 3 = Low, 4 = Unimportant).
-  std::string m_title;      // Title (pattern) for the recording files.
-  std::string m_name;       // Name.
-  std::string m_directory;  // Directory for the recording files.
-  std::string m_owner;      // Owner.
-  std::string m_creator;    // Creator.
-  uint32_t    m_channel;    // Channel ID.
-};
-
-class TimeRecording : public RecordingBase
-{
-public:
-  TimeRecording(const std::string &id = "");
-
-  bool operator==(const TimeRecording &right);
-  bool operator!=(const TimeRecording &right);
-
-  time_t GetStart() const;
-  void SetStart(int32_t start);
-
-  time_t GetStop() const;
-  void SetStop(int32_t stop);
-
-private:
-  int32_t m_start; // Start time in minutes from midnight (up to 24*60).
-  int32_t m_stop;  // Stop time in minutes from midnight (up to 24*60).
-};
-
-typedef std::map<std::string, TimeRecording> TimeRecordingsMap;
-
-class AutoRecording : public RecordingBase
-{
-public:
-  AutoRecording(const std::string &id = "");
-
-  bool operator==(const AutoRecording &right);
-  bool operator!=(const AutoRecording &right);
-
-  time_t GetStart() const;
-  void SetStartWindowBegin(int32_t begin);
-
-  time_t GetStop() const;
-  void SetStartWindowEnd(int32_t end);
-
-  int64_t GetMarginStart() const;
-  void SetMarginStart(int64_t startExtra);
-
-  int64_t GetMarginEnd() const;
-  void SetMarginEnd(int64_t stopExtra);
-
-  uint32_t GetDupDetect() const;
-  void SetDupDetect(uint32_t dupDetect);
-
-  bool GetFulltext() const;
-  void SetFulltext(uint32_t fulltext);
-
-private:
-  int32_t  m_startWindowBegin; // Begin of the starting window (minutes from midnight).
-  int32_t  m_startWindowEnd;   // End of the starting window (minutes from midnight).
-  int64_t  m_startExtra;  // Extra start minutes (pre-time).
-  int64_t  m_stopExtra;   // Extra stop minutes (post-time).
-  uint32_t m_dupDetect;   // duplicate episode detect (record: 0 = all, 1 = different episode number,
-                          //                                   2 = different subtitle, 3 = different description,
-                          //                                   4 = once per week, 5 = once per day).
-  uint32_t m_fulltext;    // Fulltext epg search.
-};
-
-typedef std::map<std::string, AutoRecording> AutoRecordingsMap;
-
-} // namespace htsp
-
-struct SChannel
-{
-  bool             del;
-  uint32_t         id;
-  uint32_t         num;
-  uint32_t         numMinor;
-  bool             radio;
-  uint32_t         caid;
-  std::string      name;
-  std::string      icon;
-
-  SChannel() :
-    del     (false),
-    id      (0),
-    num     (0),
-    numMinor(0),
-    radio   (false),
-    caid    (0)
-  {
-  }
-
-  bool operator<(const SChannel &right) const
-  {
-    return num < right.num;
-  }
-};
-
-struct SRecording
-{
-  bool             del;
-  uint32_t         id;
-  uint32_t         channel;
-  uint32_t         eventId;
-  int64_t          start;
-  int64_t          stop;
-  int64_t          startExtra;
-  int64_t          stopExtra;
-  std::string      title;
-  std::string      subtitle; /* episode name */
-  std::string      path;
-  std::string      description;
-  std::string      timerecId;
-  std::string      autorecId;
-  PVR_TIMER_STATE  state;
-  std::string      error;
-  uint32_t         retention;
-  uint32_t         priority;
-
-  SRecording() :
-    del       (false),
-    id        (0),
-    channel   (0),
-    eventId   (0),
-    start     (0),
-    stop      (0),
-    startExtra(0),
-    stopExtra (0),
-    state     (PVR_TIMER_STATE_ERROR),
-    retention (99), // Kodi default - "99 days"
-    priority  (DVR_PRIO_NORMAL)
-  {
-  }
-
-  bool IsRecording () const
-  {
-    return state == PVR_TIMER_STATE_COMPLETED ||
-           state == PVR_TIMER_STATE_ABORTED   ||
-           state == PVR_TIMER_STATE_RECORDING;
-  }
-
-  bool IsTimer () const
-  {
-    return state == PVR_TIMER_STATE_SCHEDULED ||
-           state == PVR_TIMER_STATE_RECORDING ||
-           state == PVR_TIMER_STATE_DISABLED;
-  }
-};
-
-struct SEvent
-{
-  bool        del;
-  uint32_t    id;
-  uint32_t    next;
-  uint32_t    channel;
-  uint32_t    content;
-  time_t      start;
-  time_t      stop;
-  uint32_t    stars; /* 1 - 5 */
-  uint32_t    age;   /* years */
-  time_t      aired;
-  uint32_t    season;
-  uint32_t    episode;
-  uint32_t    part;
-  std::string title;
-  std::string subtitle; /* episode name */
-  std::string desc;
-  std::string summary;
-  std::string image;
-  uint32_t    recordingId;
-
-  SEvent() :
-    del        (false),
-    id         (0),
-    next       (0),
-    channel    (0),
-    content    (0),
-    start      (0),
-    stop       (0),
-    stars      (0),
-    age        (0),
-    aired      (0),
-    season     (0),
-    episode    (0),
-    part       (0),
-    recordingId(0)
-  {
-  }
-};
-
-typedef std::map<uint32_t, SChannel>   SChannels;
-typedef std::map<uint32_t, SEvent>     SEvents;
-typedef std::map<uint32_t, SRecording> SRecordings;
-
-struct SSchedule
-{
-  bool     del;
-  uint32_t channel;
-  SEvents  events;
-
-  SSchedule() :
-    del    (false),
-    channel(0)
-  {
-  }
-};
-
-typedef std::map<int, SSchedule>  SSchedules;
-
 struct SQueueStatus
 {
   uint32_t packets; // Number of data packets in queue.
diff --git a/src/TimeRecordings.cpp b/src/TimeRecordings.cpp
index 0fe536e..545a4e4 100644
--- a/src/TimeRecordings.cpp
+++ b/src/TimeRecordings.cpp
@@ -24,6 +24,7 @@
 #include "Tvheadend.h"
 
 using namespace PLATFORM;
+using namespace tvheadend::entity;
 
 TimeRecordings::TimeRecordings(CHTSPConnection &conn) :
   m_conn(conn)
@@ -239,7 +240,7 @@ bool TimeRecordings::ParseTimerecAddOrUpdate(htsmsg_t *msg, bool bAdd)
   }
 
   /* Locate/create entry */
-  htsp::TimeRecording &rec = m_timeRecordings[std::string(str)];
+  TimeRecording &rec = m_timeRecordings[std::string(str)];
   rec.SetStringId(std::string(str));
   rec.SetDirty(false);
 
diff --git a/src/TimeRecordings.h b/src/TimeRecordings.h
index d5be51d..e163ce8 100644
--- a/src/TimeRecordings.h
+++ b/src/TimeRecordings.h
@@ -30,7 +30,7 @@ extern "C"
 }
 
 #include "kodi/libXBMC_pvr.h"
-#include "HTSPTypes.h"
+#include "tvheadend/entity/TimeRecording.h"
 
 class CHTSPConnection;
 
@@ -60,6 +60,6 @@ public:
   bool ParseTimerecDelete(htsmsg_t *msg);
 
 private:
-  CHTSPConnection         &m_conn;
-  htsp::TimeRecordingsMap  m_timeRecordings;
+  CHTSPConnection                      &m_conn;
+  tvheadend::entity::TimeRecordingsMap  m_timeRecordings;
 };
diff --git a/src/Tvheadend.cpp b/src/Tvheadend.cpp
index b90dfa3..7ac559a 100644
--- a/src/Tvheadend.cpp
+++ b/src/Tvheadend.cpp
@@ -41,6 +41,7 @@ if ((x) != (y))\
 using namespace std;
 using namespace ADDON;
 using namespace PLATFORM;
+using namespace tvheadend::entity;
 
 CTvheadend::CTvheadend(tvheadend::Settings settings)
   : m_settings(settings), m_streamchange(false), m_vfs(m_conn),
@@ -138,22 +139,22 @@ PVR_ERROR CTvheadend::GetTags ( ADDON_HANDLE handle, bool bRadio )
   std::vector<PVR_CHANNEL_GROUP> tags;
   {
     CLockObject lock(m_mutex);
-    htsp::Tags::const_iterator it;
-    for (it = m_tags.begin(); it != m_tags.end(); ++it)
+
+    for (const auto &entry : m_tags)
     {
       /* Does group contain channels of the requested type?             */
       /* Note: tvheadend groups can contain both radio and tv channels. */
       /*       Thus, one tvheadend group can 'map' to two Kodi groups.  */
-      if (!it->second.ContainsChannelType(bRadio))
+      if (!entry.second.ContainsChannelType(bRadio))
         continue;
 
       PVR_CHANNEL_GROUP tag;
       memset(&tag, 0, sizeof(tag));
 
-      strncpy(tag.strGroupName, it->second.GetName().c_str(),
+      strncpy(tag.strGroupName, entry.second.GetName().c_str(),
               sizeof(tag.strGroupName) - 1);
       tag.bIsRadio = bRadio;
-      tag.iPosition = it->second.GetIndex();
+      tag.iPosition = entry.second.GetIndex();
       tags.push_back(tag);
     }
   }
@@ -177,33 +178,34 @@ PVR_ERROR CTvheadend::GetTagMembers
   std::vector<PVR_CHANNEL_GROUP_MEMBER> gms;
   {
     CLockObject lock(m_mutex);
-    vector<uint32_t>::const_iterator it;
-    SChannels::const_iterator cit;
-    htsp::Tags::const_iterator tit = m_tags.begin();
-    while (tit != m_tags.end())
+
+    // Find the tag
+    const auto it = std::find_if(
+      m_tags.cbegin(),
+      m_tags.cend(),
+      [group](const TagMapEntry &tag)
+    {
+      return tag.second.GetName() == group.strGroupName;
+    });
+
+    if (it != m_tags.cend())
     {
-      if (tit->second.GetName() == group.strGroupName)
+      // Find all channels in this group that are of the correct type
+      for (const auto &channelId : it->second.GetChannels())
       {
-        for (it = tit->second.GetChannels().begin();
-             it != tit->second.GetChannels().end(); ++it)
+        auto cit = m_channels.find(channelId);
+
+        if (cit != m_channels.cend() && cit->second.radio == group.bIsRadio)
         {
-          if ((cit = m_channels.find(*it)) != m_channels.end())
-          {
-            if (group.bIsRadio != cit->second.radio)
-              continue;
-
-            PVR_CHANNEL_GROUP_MEMBER gm;
-            memset(&gm, 0, sizeof(PVR_CHANNEL_GROUP_MEMBER));
-            strncpy(
-              gm.strGroupName, group.strGroupName, sizeof(gm.strGroupName) - 1);
-            gm.iChannelUniqueId = cit->second.id;
-            gm.iChannelNumber   = cit->second.num;
-            gms.push_back(gm);
-          }
+          PVR_CHANNEL_GROUP_MEMBER gm;
+          memset(&gm, 0, sizeof(PVR_CHANNEL_GROUP_MEMBER));
+          strncpy(
+            gm.strGroupName, group.strGroupName, sizeof(gm.strGroupName) - 1);
+          gm.iChannelUniqueId = cit->second.id;
+          gm.iChannelNumber = cit->second.num;
+          gms.push_back(gm);
         }
-        break;
       }
-      ++tit;
     }
   }
 
@@ -238,24 +240,26 @@ PVR_ERROR CTvheadend::GetChannels ( ADDON_HANDLE handle, bool radio )
   std::vector<PVR_CHANNEL> channels;
   {
     CLockObject lock(m_mutex);
-    SChannels::const_iterator it;
-    for (it = m_channels.begin(); it != m_channels.end(); ++it)
+    
+    for (const auto &entry : m_channels)
     {
-      if (radio != it->second.radio)
+      const auto &channel = entry.second;
+
+      if (radio != channel.radio)
         continue;
 
       PVR_CHANNEL chn;
       memset(&chn, 0 , sizeof(PVR_CHANNEL));
 
-      chn.iUniqueId         = it->second.id;
-      chn.bIsRadio          = it->second.radio;
-      chn.iChannelNumber    = it->second.num;
-      chn.iSubChannelNumber = it->second.numMinor;
-      chn.iEncryptionSystem = it->second.caid;
+      chn.iUniqueId         = channel.id;
+      chn.bIsRadio          = channel.radio;
+      chn.iChannelNumber    = channel.num;
+      chn.iSubChannelNumber = channel.numMinor;
+      chn.iEncryptionSystem = channel.caid;
       chn.bIsHidden         = false;
-      strncpy(chn.strChannelName, it->second.name.c_str(),
+      strncpy(chn.strChannelName, channel.name.c_str(),
               sizeof(chn.strChannelName) - 1);
-      strncpy(chn.strIconPath, it->second.icon.c_str(),
+      strncpy(chn.strIconPath, channel.icon.c_str(),
               sizeof(chn.strIconPath) - 1);
       channels.push_back(chn);
     }
@@ -329,14 +333,16 @@ int CTvheadend::GetRecordingCount ( void )
 {
   if (!m_asyncState.WaitForState(ASYNC_EPG))
     return 0;
-  
-  int ret = 0;
-  SRecordings::const_iterator rit;
+
   CLockObject lock(m_mutex);
-  for (rit = m_recordings.begin(); rit != m_recordings.end(); ++rit)
-    if (rit->second.IsRecording())
-      ret++;
-  return ret;
+
+  return std::count_if(
+    m_recordings.cbegin(), 
+    m_recordings.cend(), 
+    [](const RecordingMapEntry &entry)
+  {
+    return entry.second.IsRecording();
+  });
 }
 
 PVR_ERROR CTvheadend::GetRecordings ( ADDON_HANDLE handle )
@@ -347,20 +353,22 @@ PVR_ERROR CTvheadend::GetRecordings ( ADDON_HANDLE handle )
   std::vector<PVR_RECORDING> recs;
   {
     CLockObject lock(m_mutex);
-    SRecordings::const_iterator rit;
-    SChannels::const_iterator cit;
+    Channels::const_iterator cit;
     char buf[128];
 
-    for (rit = m_recordings.begin(); rit != m_recordings.end(); ++rit)
+    for (const auto &entry : m_recordings)
     {
-      if (!rit->second.IsRecording()) continue;
+      const auto &recording = entry.second;
+
+      if (!recording.IsRecording())
+        continue;
 
       /* Setup entry */
       PVR_RECORDING rec;
       memset(&rec, 0, sizeof(rec));
 
       /* Channel name and icon */
-      if ((cit = m_channels.find(rit->second.channel)) != m_channels.end())
+      if ((cit = m_channels.find(recording.channel)) != m_channels.end())
       {
         strncpy(rec.strChannelName, cit->second.name.c_str(),
                 sizeof(rec.strChannelName) - 1);
@@ -370,37 +378,37 @@ PVR_ERROR CTvheadend::GetRecordings ( ADDON_HANDLE handle )
       }
 
       /* ID */
-      snprintf(buf, sizeof(buf), "%i", rit->second.id);
+      snprintf(buf, sizeof(buf), "%i", recording.id);
       strncpy(rec.strRecordingId, buf, sizeof(rec.strRecordingId) - 1);
 
       /* Title */
-      strncpy(rec.strTitle, rit->second.title.c_str(), sizeof(rec.strTitle) - 1);
+      strncpy(rec.strTitle, recording.title.c_str(), sizeof(rec.strTitle) - 1);
 
       /* Subtitle */
       strncpy(rec.strEpisodeName, rit->second.subtitle.c_str(), sizeof(rec.strEpisodeName) - 1);
 
       /* Description */
-      strncpy(rec.strPlot, rit->second.description.c_str(), sizeof(rec.strPlot) - 1);
+      strncpy(rec.strPlot, recording.description.c_str(), sizeof(rec.strPlot) - 1);
 
       /* Time/Duration */
-      rec.recordingTime = (time_t)rit->second.start;
-      rec.iDuration     = (time_t)(rit->second.stop - rit->second.start);
+      rec.recordingTime = (time_t)recording.start;
+      rec.iDuration =     (time_t)(recording.stop - recording.start);
 
       /* Priority */
-      rec.iPriority = rit->second.priority;
+      rec.iPriority = recording.priority;
 
       /* Retention */
-      rec.iLifetime = rit->second.retention;
+      rec.iLifetime = recording.retention;
 
       /* Directory */
-      if (rit->second.path != "")
+      if (recording.path != "")
       {
-        size_t idx = rit->second.path.rfind("/");
+        size_t idx = recording.path.rfind("/");
         if (idx == 0 || idx == string::npos)
           strncpy(rec.strDirectory, "/", sizeof(rec.strDirectory) - 1);
         else
         {
-          std::string d = rit->second.path.substr(0, idx);
+          std::string d = recording.path.substr(0, idx);
           if (d[0] != '/')
             d = "/" + d;
           strncpy(rec.strDirectory, d.c_str(), sizeof(rec.strDirectory) - 1);
@@ -408,7 +416,7 @@ PVR_ERROR CTvheadend::GetRecordings ( ADDON_HANDLE handle )
       }
 
       /* EPG event id */
-      rec.iEpgEventId = rit->second.eventId;
+      rec.iEpgEventId = recording.eventId;
 
       recs.push_back(rec);
     }
@@ -745,21 +753,25 @@ int CTvheadend::GetTimerCount ( void )
   if (!m_asyncState.WaitForState(ASYNC_EPG))
     return 0;
   
-  int ret = 0;
-  SRecordings::const_iterator rit;
   CLockObject lock(m_mutex);
-  for (rit = m_recordings.begin(); rit != m_recordings.end(); ++rit)
-    if (rit->second.IsTimer())
-      ret++;
 
-  ret += m_timeRecordings.GetTimerecTimerCount();
+  // Normal timers
+  int timerCount = std::count_if(
+    m_recordings.cbegin(),
+    m_recordings.cend(),
+    [](const RecordingMapEntry &entry)
+  {
+    return entry.second.IsTimer();
+  });
 
-  ret += m_autoRecordings.GetAutorecTimerCount();
+  // Repeating timers
+  timerCount += m_timeRecordings.GetTimerecTimerCount();
+  timerCount += m_autoRecordings.GetAutorecTimerCount();
 
-  return ret;
+  return timerCount;
 }
 
-bool CTvheadend::CreateTimer ( const SRecording &tvhTmr, PVR_TIMER &tmr )
+bool CTvheadend::CreateTimer ( const Recording &tvhTmr, PVR_TIMER &tmr )
 {
   memset(&tmr, 0, sizeof(tmr));
 
@@ -816,16 +828,16 @@ PVR_ERROR CTvheadend::GetTimers ( ADDON_HANDLE handle )
     /*
      * One-shot timers
      */
-
-    SRecordings::const_iterator rit;
-    for (rit = m_recordings.begin(); rit != m_recordings.end(); ++rit)
+    for (const auto &entry : m_recordings)
     {
-      if (!rit->second.IsTimer())
+      const auto &recording = entry.second;
+
+      if (!recording.IsTimer())
         continue;
 
       /* Setup entry */
       PVR_TIMER tmr;
-      if (CreateTimer(rit->second, tmr))
+      if (CreateTimer(recording, tmr))
         timers.push_back(tmr);
     }
 
@@ -1023,7 +1035,7 @@ PVR_ERROR CTvheadend::UpdateTimer ( const PVR_TIMER &timer )
 
 /* Transfer schedule to XBMC */
 void CTvheadend::TransferEvent
-  ( ADDON_HANDLE handle, const SEvent &event )
+  ( ADDON_HANDLE handle, const Event &event )
 {
   /* Build */
   EPG_TAG epg;
@@ -1062,8 +1074,6 @@ void CTvheadend::TransferEvent
 PVR_ERROR CTvheadend::GetEpg
   ( ADDON_HANDLE handle, const PVR_CHANNEL &chn, time_t start, time_t end )
 {
-  SSchedules::const_iterator sit;
-  SEvents::const_iterator eit;
   htsmsg_field_t *f;
   int n = 0;
 
@@ -1076,30 +1086,19 @@ PVR_ERROR CTvheadend::GetEpg
     if (!m_asyncState.WaitForState(ASYNC_DONE))
       return PVR_ERROR_FAILED;
     
-    std::vector<SEvent> events;
+    // Find the relevant events
+    Segment segment;
     {
       CLockObject lock(m_mutex);
-      sit = m_schedules.find(chn.iUniqueId);
-      if (sit != m_schedules.end())
-      {
-        for (eit = sit->second.events.begin();
-            eit != sit->second.events.end(); ++eit)
-        {
-          if (eit->second.start    > end)   continue;
-          if (eit->second.stop     < start) continue;
+      auto sit = m_schedules.find(chn.iUniqueId);
 
-          events.push_back(eit->second);
-          ++n;
-        }
-      }
+      if (sit != m_schedules.cend())
+        segment = sit->second.GetSegment(start, end);
     }
 
-    std::vector<SEvent>::const_iterator it;
-    for (it = events.begin(); it != events.end(); ++it)
-    {
-      /* Callback. */
-      TransferEvent(handle, *it);
-    }
+    // Transfer
+    for (const auto &event : segment)
+      TransferEvent(handle, event);
 
   /* Synchronous transfer */
   }
@@ -1129,7 +1128,7 @@ PVR_ERROR CTvheadend::GetEpg
     }
     HTSMSG_FOREACH(f, l)
     {
-      SEvent event;
+      Event event;
       if (f->hmf_type == HMF_MAP)
       {
         if (ParseEvent(&f->hmf_msg, true, event))
@@ -1160,11 +1159,6 @@ void CTvheadend::Disconnected ( void )
 bool CTvheadend::Connected ( void )
 {
   htsmsg_t *msg;
-  htsp::Tags::iterator tit;
-  SChannels::iterator cit;
-  SRecordings::iterator rit;
-  SSchedules::iterator sit;
-  SEvents::iterator eit;
 
   /* Rebuild state */
   for (auto *dmx : m_dmx)
@@ -1172,24 +1166,19 @@ bool CTvheadend::Connected ( void )
     dmx->Connected();
   }
   m_vfs.Connected();
-
-  /* Flag all async fields in case they've been deleted */
-  for (cit = m_channels.begin(); cit != m_channels.end(); ++cit)
-    cit->second.del = true;
-  for (tit = m_tags.begin(); tit != m_tags.end(); ++tit)
-    tit->second.SetDirty(true);
-  for (rit = m_recordings.begin(); rit != m_recordings.end(); ++rit)
-    rit->second.del = true;
-  for (sit = m_schedules.begin(); sit != m_schedules.end(); ++sit)
-  {
-    sit->second.del = true;
-
-    for (eit = sit->second.events.begin(); eit != sit->second.events.end(); ++eit)
-      eit->second.del = true;
-  }
   m_timeRecordings.Connected();
   m_autoRecordings.Connected();
 
+  /* Flag all async fields in case they've been deleted */
+  for (auto &entry : m_channels)
+    entry.second.SetDirty(true);
+  for (auto &entry : m_tags)
+    entry.second.SetDirty(true);
+  for (auto &entry : m_recordings)
+    entry.second.SetDirty(true);
+  for (auto &entry : m_schedules)
+    entry.second.SetDirty(true);
+
   /* Request Async data */
   m_asyncState.SetState(ASYNC_NONE);
   
@@ -1380,8 +1369,8 @@ void CTvheadend::SyncChannelsCompleted ( void )
   if (m_asyncState.GetState() > ASYNC_CHN)
     return;
 
-  SChannels::iterator   cit = m_channels.begin();
-  htsp::Tags::iterator  tit = m_tags.begin();
+  Channels::iterator cit = m_channels.begin();
+  Tags::iterator tit = m_tags.begin();
 
   /* Tags */
   while (tit != m_tags.end())
@@ -1396,7 +1385,7 @@ void CTvheadend::SyncChannelsCompleted ( void )
   /* Channels */
   while (cit != m_channels.end())
   {
-    if (cit->second.del)
+    if (cit->second.IsDirty())
       m_channels.erase(cit++);
     else
       ++cit;
@@ -1414,13 +1403,13 @@ void CTvheadend::SyncDvrCompleted ( void )
     return;
 
   bool update;
-  SRecordings::iterator rit = m_recordings.begin();
+  Recordings::iterator rit = m_recordings.begin();
 
   /* Recordings */
   update = false;
   while (rit != m_recordings.end())
   {
-    if (rit->second.del)
+    if (rit->second.IsDirty())
     {
       update = true;
       m_recordings.erase(rit++);
@@ -1451,8 +1440,8 @@ void CTvheadend::SyncEpgCompleted ( void )
     return;
   
   bool update;
-  SSchedules::iterator  sit = m_schedules.begin();
-  SEvents::iterator     eit;
+  Schedules::iterator  sit = m_schedules.begin();
+  Events::iterator     eit;
 
   /* Events */
   update = false;
@@ -1460,7 +1449,7 @@ void CTvheadend::SyncEpgCompleted ( void )
   {
     uint32_t channelId = sit->second.channel;
     
-    if (sit->second.del)
+    if (sit->second.IsDirty())
     {
       update = true;
       m_schedules.erase(sit++);
@@ -1470,7 +1459,7 @@ void CTvheadend::SyncEpgCompleted ( void )
       eit = sit->second.events.begin();
       while (eit != sit->second.events.end())
       {
-        if (eit->second.del)
+        if (eit->second.IsDirty())
         {
           update = true;
           sit->second.events.erase(eit++);
@@ -1502,11 +1491,11 @@ void CTvheadend::ParseTagAddOrUpdate ( htsmsg_t *msg, bool bAdd )
   }
 
   /* Locate object */
-  htsp::Tag &existingTag = m_tags[u32];
+  auto &existingTag = m_tags[u32];
   existingTag.SetDirty(false);
   
   /* Create new object */
-  htsp::Tag tag(u32);
+  Tag tag(u32);
 
   /* Index */
   if (!htsmsg_get_u32(msg, "tagIndex", &u32))
@@ -1579,9 +1568,9 @@ void CTvheadend::ParseChannelAddOrUpdate ( htsmsg_t *msg, bool bAdd )
   }
 
   /* Locate channel object */
-  SChannel &channel = m_channels[u32];
+  Channel &channel = m_channels[u32];
   channel.id  = u32;
-  channel.del = false;
+  channel.SetDirty(false);
 
   /* Channel name */
   if ((str = htsmsg_get_str(msg, "channelName")) != NULL)
@@ -1713,9 +1702,9 @@ void CTvheadend::ParseRecordingAddOrUpdate ( htsmsg_t *msg, bool bAdd )
   }
 
   /* Get entry */
-  SRecording &rec = m_recordings[id];
+  Recording &rec = m_recordings[id];
   rec.id  = id;
-  rec.del = false;
+  rec.SetDirty(false);
   UPDATE(rec.start,   start);
   UPDATE(rec.stop,    stop);
 
@@ -1891,7 +1880,7 @@ void CTvheadend::ParseRecordingDelete ( htsmsg_t *msg )
   TriggerRecordingUpdate();
 }
 
-bool CTvheadend::ParseEvent ( htsmsg_t *msg, bool bAdd, SEvent &evt )
+bool CTvheadend::ParseEvent ( htsmsg_t *msg, bool bAdd, Event &evt )
 {
   const char *str;
   uint32_t u32, id, channel;
@@ -1959,14 +1948,16 @@ bool CTvheadend::ParseEvent ( htsmsg_t *msg, bool bAdd, SEvent &evt )
     evt.part    = u32;
 
   /* Add optional recording link */
-  for (SRecordings::const_iterator it = m_recordings.begin(); it != m_recordings.end(); ++it)
+  auto rit = std::find_if(
+    m_recordings.cbegin(), 
+    m_recordings.cend(), 
+    [evt](const RecordingMapEntry &entry)
   {
-    if (it->second.eventId == evt.id)
-    {
-      evt.recordingId = evt.id;
-      break;
-    }
-  }
+    return entry.second.eventId == evt.id;
+  });
+
+  if (rit != m_recordings.cend())
+    evt.recordingId = evt.id;
   
   return true;
 }
@@ -1974,18 +1965,18 @@ bool CTvheadend::ParseEvent ( htsmsg_t *msg, bool bAdd, SEvent &evt )
 void CTvheadend::ParseEventAddOrUpdate ( htsmsg_t *msg, bool bAdd )
 {
   bool update = false;
-  SEvent tmp;
+  Event tmp;
 
   /* Parse */
   if (!ParseEvent(msg, bAdd, tmp))
     return;
 
   /* Get event handle */
-  SSchedule &sched = m_schedules[tmp.channel];
-  SEvent    &evt   = sched.events[tmp.id];
+  Schedule &sched  = m_schedules[tmp.channel];
+  Event    &evt    = sched.events[tmp.id];
   sched.channel    = tmp.channel;
   evt.id           = tmp.id;
-  evt.del          = false;
+  evt.SetDirty(false);
   
   /* Store */
   UPDATE(evt.title,       tmp.title);
@@ -2031,17 +2022,19 @@ void CTvheadend::ParseEventDelete ( htsmsg_t *msg )
   tvhtrace("delete event %u", u32);
   
   /* Erase */
-  SSchedules::iterator sit;
-  for (sit = m_schedules.begin(); sit != m_schedules.end(); ++sit)
+  for (auto &entry : m_schedules)
   {
+    Schedule &schedule = entry.second;
+    Events &events = schedule.events;
+
     // Find the event so we can get the channel number
-    SEvents::iterator eit = sit->second.events.find(u32);
-    
-    if (eit != sit->second.events.end())
+    auto eit = events.find(u32);
+
+    if (eit != events.end())
     {
-      tvhtrace("deleted event %d from channel %d", u32, sit->second.channel);
-      sit->second.events.erase(eit);
-      TriggerEpgUpdate(sit->second.channel);
+      tvhtrace("deleted event %d from channel %d", u32, schedule.channel);
+      events.erase(eit);
+      TriggerEpgUpdate(schedule.channel);
       return;
     }
   }
@@ -2079,7 +2072,6 @@ void CTvheadend::TuneOnOldest( uint32_t channelId )
 
 void CTvheadend::PredictiveTune( uint32_t fromChannelId, uint32_t toChannelId )
 {
-  SChannels::const_iterator it;
   CLockObject lock(m_mutex);
   uint32_t fromNum, toNum;
 
@@ -2089,19 +2081,23 @@ void CTvheadend::PredictiveTune( uint32_t fromChannelId, uint32_t toChannelId )
   if (fromNum + 1 == toNum || toNum == 1)
   {
     /* tuning up, or to channel 1 */
-    for (it = m_channels.begin(); it != m_channels.end(); ++it)
+    for (const auto &entry : m_channels)
     {
-      if (toNum + 1 == it->second.num)
-        TuneOnOldest(it->second.id);
+      const Channel &channel = entry.second;
+
+      if (toNum + 1 == channel.num)
+        TuneOnOldest(channel.id);
     }
   }
   else if (fromNum - 1 == toNum)
   {
     /* tuning down */
-    for (it = m_channels.begin(); it != m_channels.end(); ++it)
+    for (const auto &entry : m_channels)
     {
-      if (toNum - 1 == it->second.num)
-        TuneOnOldest(it->second.id);
+      const Channel &channel = entry.second;
+
+      if (toNum - 1 == channel.num)
+        TuneOnOldest(channel.id);
     }
   }
 }
@@ -2127,7 +2123,8 @@ bool CTvheadend::DemuxOpen( const PVR_CHANNEL &chn )
     if (dmx != m_dmx_active && dmx->GetChannelId() == chn.iUniqueId)
     {
       tvhtrace("retuning channel %u on subscription %u",
-               m_channels[chn.iUniqueId].num, dmx->GetSubscriptionId());
+               m_channels[chn.iUniqueId].GetNum(), dmx->GetSubscriptionId());
+
       dmx->Weight(SUBSCRIPTION_WEIGHT_NORMAL);
       m_dmx_active->Weight(SUBSCRIPTION_WEIGHT_POSTTUNING);
       prevId = m_dmx_active->GetChannelId();
diff --git a/src/Tvheadend.h b/src/Tvheadend.h
index e418520..98334e0 100644
--- a/src/Tvheadend.h
+++ b/src/Tvheadend.h
@@ -32,6 +32,11 @@
 #include "Settings.h"
 #include "HTSPTypes.h"
 #include "AsyncState.h"
+#include "tvheadend/entity/Tag.h"
+#include "tvheadend/entity/Channel.h"
+#include "tvheadend/entity/Recording.h"
+#include "tvheadend/entity/Event.h"
+#include "tvheadend/entity/Schedule.h"
 #include "TimeRecordings.h"
 #include "AutoRecordings.h"
 #include <map>
@@ -373,7 +378,7 @@ public:
     return m_settings;
   };
 
-  inline const SChannels& GetChannels () const
+  const tvheadend::entity::Channels& GetChannels () const
   {
     return m_channels;
   }
@@ -405,7 +410,7 @@ public:
                                 time_t start, time_t end );
   
 private:
-  bool      CreateTimer       ( const SRecording &tvhTmr, PVR_TIMER &tmr );
+  bool      CreateTimer       ( const tvheadend::entity::Recording &tvhTmr, PVR_TIMER &tmr );
 
   uint32_t GetNextUnnumberedChannelNumber ( void );
   std::string GetImageURL     ( const char *str );
@@ -422,10 +427,10 @@ private:
 
   CHTSPMessageQueue           m_queue;
 
-  SChannels                   m_channels;
-  htsp::Tags                  m_tags;
-  SRecordings                 m_recordings;
-  SSchedules                  m_schedules;
+  tvheadend::entity::Channels   m_channels;
+  tvheadend::entity::Tags       m_tags;
+  tvheadend::entity::Recordings m_recordings;
+  tvheadend::entity::Schedules  m_schedules;
 
   SHTSPEventList              m_events;
 
@@ -475,7 +480,7 @@ private:
   /*
    * Epg Handling
    */
-  void        TransferEvent   ( ADDON_HANDLE handle, const SEvent &event );
+  void        TransferEvent   ( ADDON_HANDLE handle, const tvheadend::entity::Event &event );
 
   /*
    * Message sending
@@ -498,7 +503,7 @@ private:
   void ParseRecordingDelete      ( htsmsg_t *m );
   void ParseEventAddOrUpdate     ( htsmsg_t *m, bool bAdd );
   void ParseEventDelete          ( htsmsg_t *m );
-  bool ParseEvent                ( htsmsg_t *m, bool bAdd, SEvent &evt );
+  bool ParseEvent                ( htsmsg_t *msg, bool bAdd, tvheadend::entity::Event &evt );
 
 public:
   /*
diff --git a/src/tvheadend/entity/AutoRecording.cpp b/src/tvheadend/entity/AutoRecording.cpp
new file mode 100644
index 0000000..960ccf2
--- /dev/null
+++ b/src/tvheadend/entity/AutoRecording.cpp
@@ -0,0 +1,150 @@
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "AutoRecording.h"
+
+#include "../../Tvheadend.h"
+
+using namespace tvheadend::entity;
+
+AutoRecording::AutoRecording(const std::string &id /*= ""*/) :
+    RecordingBase(id),
+    m_startWindowBegin(0),
+    m_startWindowEnd(0),
+    m_startExtra(0),
+    m_stopExtra(0),
+    m_dupDetect(0),
+    m_fulltext(0)
+{
+}
+
+bool AutoRecording::operator==(const AutoRecording &right)
+{
+  return RecordingBase::operator==(right)     &&
+         m_startWindowBegin == right.m_startWindowBegin &&
+         m_startWindowEnd   == right.m_startWindowEnd   &&
+         m_startExtra       == right.m_startExtra       &&
+         m_stopExtra        == right.m_stopExtra        &&
+         m_dupDetect        == right.m_dupDetect        &&
+         m_fulltext         == right.m_fulltext;
+}
+
+bool AutoRecording::operator!=(const AutoRecording &right)
+{
+  return !(*this == right);
+}
+
+time_t AutoRecording::GetStart() const
+{
+  if (tvh->GetSettings().bAutorecApproxTime)
+  {
+    /* Calculate the approximate start time from the starting window */
+    if ((m_startWindowBegin == int32_t(-1)) ||
+        (m_startWindowEnd == int32_t(-1))) // no starting window set => "any time"
+      return 0;
+    else if (m_startWindowEnd < m_startWindowBegin)
+    {
+      /* End of start window is a day in the future */
+      int32_t newEnd = m_startWindowEnd + (24 * 60);
+      int32_t newStart = m_startWindowBegin + (newEnd - m_startWindowBegin) / 2;
+
+      if (newStart > (24 * 60))
+        newStart -= (24 * 60);
+
+      return LocaltimeToUTC(newStart);
+    }
+    else
+      return LocaltimeToUTC(m_startWindowBegin + (m_startWindowEnd - m_startWindowBegin) / 2);
+  }
+  else
+  {
+    if (m_startWindowBegin == int32_t(-1)) // "any time"
+      return 0;
+
+    return LocaltimeToUTC(m_startWindowBegin);
+  }
+}
+
+void AutoRecording::SetStartWindowBegin(int32_t start)
+{
+  m_startWindowBegin = start;
+}
+
+time_t AutoRecording::GetStop() const
+{
+  if (tvh->GetSettings().bAutorecApproxTime)
+  {
+    /* Tvh doesn't have an approximate stop time => "any time" */
+    return 0;
+  }
+  else
+  {
+    if (m_startWindowEnd == int32_t(-1)) // "any time"
+      return 0;
+
+    return LocaltimeToUTC(m_startWindowEnd);
+  }
+}
+
+void AutoRecording::SetStartWindowEnd(int32_t end)
+{
+  m_startWindowEnd = end;
+}
+
+int64_t AutoRecording::GetMarginStart() const
+{
+  return m_startExtra;
+}
+
+void AutoRecording::SetMarginStart(int64_t startExtra)
+{
+  m_startExtra = startExtra;
+}
+
+int64_t AutoRecording::GetMarginEnd() const
+{
+  return m_stopExtra;
+}
+
+void AutoRecording::SetMarginEnd(int64_t stopExtra)
+{
+  m_stopExtra = stopExtra;
+}
+
+uint32_t AutoRecording::GetDupDetect() const
+{
+  return m_dupDetect;
+}
+
+void AutoRecording::SetDupDetect(uint32_t dupDetect)
+{
+  m_dupDetect = dupDetect;
+}
+
+bool AutoRecording::GetFulltext() const
+{
+  return m_fulltext > 0;
+}
+
+void AutoRecording::SetFulltext(uint32_t fulltext)
+{
+  m_fulltext = fulltext;
+}
\ No newline at end of file
diff --git a/src/tvheadend/entity/AutoRecording.h b/src/tvheadend/entity/AutoRecording.h
new file mode 100644
index 0000000..7ae3a00
--- /dev/null
+++ b/src/tvheadend/entity/AutoRecording.h
@@ -0,0 +1,70 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "RecordingBase.h"
+#include <map>
+
+namespace tvheadend
+{
+  namespace entity
+  {
+    class AutoRecording : public RecordingBase
+    {
+    public:
+      AutoRecording(const std::string &id = "");
+
+      bool operator==(const AutoRecording &right);
+      bool operator!=(const AutoRecording &right);
+
+      time_t GetStart() const;
+      void SetStartWindowBegin(int32_t begin);
+
+      time_t GetStop() const;
+      void SetStartWindowEnd(int32_t end);
+
+      int64_t GetMarginStart() const;
+      void SetMarginStart(int64_t startExtra);
+
+      int64_t GetMarginEnd() const;
+      void SetMarginEnd(int64_t stopExtra);
+
+      uint32_t GetDupDetect() const;
+      void SetDupDetect(uint32_t dupDetect);
+
+      bool GetFulltext() const;
+      void SetFulltext(uint32_t fulltext);
+
+    private:
+      int32_t  m_startWindowBegin; // Begin of the starting window (minutes from midnight).
+      int32_t  m_startWindowEnd;   // End of the starting window (minutes from midnight).
+      int64_t  m_startExtra;  // Extra start minutes (pre-time).
+      int64_t  m_stopExtra;   // Extra stop minutes (post-time).
+      uint32_t m_dupDetect;   // duplicate episode detect (record: 0 = all, 1 = different episode number,
+                              //                                   2 = different subtitle, 3 = different description,
+                              //                                   4 = once per week, 5 = once per day).
+      uint32_t m_fulltext;    // Fulltext epg search.
+    };
+
+    typedef std::map<std::string, AutoRecording> AutoRecordingsMap;
+  }
+}
diff --git a/src/tvheadend/entity/Channel.h b/src/tvheadend/entity/Channel.h
new file mode 100644
index 0000000..3ed7676
--- /dev/null
+++ b/src/tvheadend/entity/Channel.h
@@ -0,0 +1,67 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <cstdint>
+#include <string>
+#include <map>
+#include "Entity.h"
+
+namespace tvheadend
+{
+  namespace entity
+  {
+
+    class Channel;
+    typedef std::pair<uint32_t, Channel> ChannelMapEntry;
+    typedef std::map<uint32_t, Channel> Channels;
+
+    /**
+     * Represents a channel
+     */
+    class Channel : public Entity
+    {
+    public:
+      Channel() :
+        id(0),
+        num(0),
+        numMinor(0),
+        radio(false),
+        caid(0)
+      {
+      }
+
+      bool operator<(const Channel &right) const
+      {
+        return num < right.num;
+      }
+
+      uint32_t         id;
+      uint32_t         num;
+      uint32_t         numMinor;
+      bool             radio;
+      uint32_t         caid;
+      std::string      name;
+      std::string      icon;
+    };
+  }
+}
\ No newline at end of file
diff --git a/src/AsyncState.cpp b/src/tvheadend/entity/Entity.h
similarity index 52%
copy from src/AsyncState.cpp
copy to src/tvheadend/entity/Entity.h
index 65c1d07..677faca 100644
--- a/src/AsyncState.cpp
+++ b/src/tvheadend/entity/Entity.h
@@ -1,5 +1,7 @@
+#pragma once
+
 /*
- *      Copyright (C) 2005-2014 Team XBMC
+ *      Copyright (C) 2005-2011 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -19,41 +21,39 @@
  *
  */
 
-#include "AsyncState.h"
-#include "client.h"
-
-struct Param {
-  eAsyncState state;
-  AsyncState *self;
-};
-
-using namespace PLATFORM;
-
-AsyncState::AsyncState(int timeout)
-{
-  m_state   = ASYNC_NONE;
-  m_timeout = timeout;
-}
-
-void AsyncState::SetState(eAsyncState state)
+namespace tvheadend
 {
-  CLockObject lock(m_mutex);
-  m_state = state;
-  m_condition.Broadcast();
-}
-
-bool AsyncState::PredicateCallback ( void *p )
-{
-  Param *param = (Param*)p;
-  return param->self->m_state >= param->state;
-}
-
-bool AsyncState::WaitForState(eAsyncState state)
-{
-  Param p;
-  p.state = state;
-  p.self  = this;
-
-  CLockObject lock(m_mutex);
-  return m_condition.Wait(m_mutex, AsyncState::PredicateCallback, (void*)&p, m_timeout);
+  namespace entity
+  {
+
+    /**
+     * Abstract entity. An entity can be dirty or clean
+     */
+    class Entity
+    {
+    public:
+      Entity() : m_dirty(false) {};
+      virtual ~Entity() = default;
+
+      /**
+       * @return if the entity is dirty
+       */
+      virtual bool IsDirty() const
+      {
+        return m_dirty;
+      }
+
+      /**
+       * Marks the entity as dirty or not
+       * @param dirty
+       */
+      virtual void SetDirty(bool dirty)
+      {
+        m_dirty = dirty;
+      }
+
+    private:
+      bool m_dirty;
+    };
+  }
 }
diff --git a/src/tvheadend/entity/Event.h b/src/tvheadend/entity/Event.h
new file mode 100644
index 0000000..86efe14
--- /dev/null
+++ b/src/tvheadend/entity/Event.h
@@ -0,0 +1,80 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "Entity.h"
+#include <map>
+#include <cstdint>
+#include <string>
+
+namespace tvheadend
+{
+  namespace entity
+  {
+    class Event;
+    typedef std::pair<uint32_t, Event> EventMapEntry;
+    typedef std::map<uint32_t, Event> Events;
+
+    /**
+     * Represents an event/programme
+     */
+    class Event : public Entity
+    {
+    public:
+      Event() :
+        id(0),
+        next(0),
+        channel(0),
+        content(0),
+        start(0),
+        stop(0),
+        stars(0),
+        age(0),
+        aired(0),
+        season(0),
+        episode(0),
+        part(0),
+        recordingId(0)
+      {
+      }
+
+      uint32_t    id;
+      uint32_t    next;
+      uint32_t    channel;
+      uint32_t    content;
+      time_t      start;
+      time_t      stop;
+      uint32_t    stars; /* 1 - 5 */
+      uint32_t    age;   /* years */
+      time_t      aired;
+      uint32_t    season;
+      uint32_t    episode;
+      uint32_t    part;
+      std::string title;
+      std::string subtitle; /* episode name */
+      std::string desc;
+      std::string summary;
+      std::string image;
+      uint32_t    recordingId;
+    };
+  }
+}
\ No newline at end of file
diff --git a/src/tvheadend/entity/Recording.h b/src/tvheadend/entity/Recording.h
new file mode 100644
index 0000000..f7eb147
--- /dev/null
+++ b/src/tvheadend/entity/Recording.h
@@ -0,0 +1,89 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <map>
+#include <string>
+#include "kodi/xbmc_pvr_types.h"
+#include "Entity.h"
+
+namespace tvheadend
+{
+  namespace entity
+  {
+
+    class Recording;
+    typedef std::pair<uint32_t, Recording> RecordingMapEntry;
+    typedef std::map<uint32_t, Recording> Recordings;
+
+    /**
+     * Represents a recording or a timer
+     */
+    class Recording : public Entity
+    {
+    public:
+      Recording() :
+        id(0),
+        channel(0),
+        eventId(0),
+        start(0),
+        stop(0),
+        startExtra(0),
+        stopExtra(0),
+        state(PVR_TIMER_STATE_ERROR),
+        retention(99), // Kodi default - "99 days"
+        priority(50) // Kodi default - "normal"
+      {
+      }
+
+      bool IsRecording() const
+      {
+        return state == PVR_TIMER_STATE_COMPLETED ||
+          state == PVR_TIMER_STATE_ABORTED ||
+          state == PVR_TIMER_STATE_RECORDING;
+      }
+
+      bool IsTimer() const
+      {
+        return state == PVR_TIMER_STATE_SCHEDULED ||
+          state == PVR_TIMER_STATE_RECORDING;
+      }
+
+      uint32_t         id;
+      uint32_t         channel;
+      uint32_t         eventId;
+      int64_t          start;
+      int64_t          stop;
+      int64_t          startExtra;
+      int64_t          stopExtra;
+      std::string      title;
+      std::string      path;
+      std::string      description;
+      std::string      timerecId;
+      std::string      autorecId;
+      PVR_TIMER_STATE  state;
+      std::string      error;
+      uint32_t         retention;
+      uint32_t         priority;
+    };
+  }
+}
diff --git a/src/tvheadend/entity/RecordingBase.cpp b/src/tvheadend/entity/RecordingBase.cpp
new file mode 100644
index 0000000..3002212
--- /dev/null
+++ b/src/tvheadend/entity/RecordingBase.cpp
@@ -0,0 +1,184 @@
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "RecordingBase.h"
+
+using namespace tvheadend::entity;
+
+RecordingBase::RecordingBase(const std::string &id /*= ""*/) :
+    m_iId(GetNextIntId()),
+    m_id(id),
+    m_enabled(0),
+    m_daysOfWeek(0),
+    m_retention(0),
+    m_priority(0),
+    m_channel(0)
+{
+}
+
+bool RecordingBase::operator==(const RecordingBase &right)
+{
+  return m_iId         == right.m_iId         &&
+         m_id          == right.m_id          &&
+         m_enabled     == right.m_enabled     &&
+         m_daysOfWeek  == right.m_daysOfWeek  &&
+         m_retention   == right.m_retention   &&
+         m_priority    == right.m_priority    &&
+         m_title       == right.m_title       &&
+         m_name        == right.m_name        &&
+         m_directory   == right.m_directory   &&
+         m_owner       == right.m_owner       &&
+         m_creator     == right.m_creator     &&
+         m_channel     == right.m_channel;
+}
+
+bool RecordingBase::operator!=(const RecordingBase &right)
+{
+  return !(*this == right);
+}
+
+unsigned int RecordingBase::GetIntId() const
+{
+  return m_iId;
+}
+
+std::string RecordingBase::GetStringId() const
+{
+  return m_id;
+}
+
+void RecordingBase::SetStringId(const std::string &id)
+{
+  m_id = id;
+}
+
+bool RecordingBase::IsEnabled() const
+{
+  return m_enabled != 0;
+}
+
+void RecordingBase::SetEnabled(uint32_t enabled)
+{
+  m_enabled = enabled;
+}
+
+int RecordingBase::GetDaysOfWeek() const
+{
+  return m_daysOfWeek;
+}
+
+void RecordingBase::SetDaysOfWeek(uint32_t daysOfWeek)
+{
+  m_daysOfWeek = daysOfWeek;
+}
+
+uint32_t RecordingBase::GetRetention() const
+{
+  return m_retention;
+}
+
+void RecordingBase::SetRetention(uint32_t retention)
+{
+  m_retention = retention;
+}
+
+uint32_t RecordingBase::GetPriority() const
+{
+  return m_priority;
+}
+
+void RecordingBase::SetPriority(uint32_t priority)
+{
+  m_priority = priority;
+}
+
+const std::string& RecordingBase::GetTitle() const
+{
+  return m_title;
+}
+
+void RecordingBase::SetTitle(const std::string &title)
+{
+  m_title = title;
+}
+
+const std::string& RecordingBase::GetName() const
+{
+  return m_name;
+}
+
+void RecordingBase::SetName(const std::string &name)
+{
+  m_name = name;
+}
+
+const std::string& RecordingBase::GetDirectory() const
+{
+  return m_directory;
+}
+
+void RecordingBase::SetDirectory(const std::string &directory)
+{
+  m_directory = directory;
+}
+
+void RecordingBase::SetOwner(const std::string &owner)
+{
+  m_owner = owner;
+}
+
+void RecordingBase::SetCreator(const std::string &creator)
+{
+  m_creator = creator;
+}
+
+uint32_t RecordingBase::GetChannel() const
+{
+  return m_channel;
+}
+
+void RecordingBase::SetChannel(uint32_t channel)
+{
+  m_channel = channel;
+}
+
+// static
+time_t RecordingBase::LocaltimeToUTC(int32_t lctime)
+{
+  /* Note: lctime contains minutes from midnight (up to 24*60) as local time. */
+
+  /* complete lctime with current year, month, day, ... */
+  time_t t = time(NULL);
+  struct tm *tm_time = localtime(&t);
+
+  tm_time->tm_hour  = lctime / 60;
+  tm_time->tm_min   = lctime % 60;
+  tm_time->tm_sec   = 0;
+
+  return mktime(tm_time);
+}
+
+// static
+int RecordingBase::GetNextIntId()
+{
+  static unsigned int intId = 0;
+  return ++intId;
+}
\ No newline at end of file
diff --git a/src/tvheadend/entity/RecordingBase.h b/src/tvheadend/entity/RecordingBase.h
new file mode 100644
index 0000000..94f4be8
--- /dev/null
+++ b/src/tvheadend/entity/RecordingBase.h
@@ -0,0 +1,94 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "Entity.h"
+#include <string>
+#include <cstdint>
+#include <ctime>
+
+namespace tvheadend
+{
+  namespace entity
+  {
+    class RecordingBase : public Entity
+    {
+    protected:
+      RecordingBase(const std::string &id = "");
+      bool operator==(const RecordingBase &right);
+      bool operator!=(const RecordingBase &right);
+
+    public:
+      unsigned int GetIntId() const;
+
+      std::string GetStringId() const;
+      void SetStringId(const std::string &id);
+
+      bool IsEnabled() const;
+      void SetEnabled(uint32_t enabled);
+
+      int GetDaysOfWeek() const;
+      void SetDaysOfWeek(uint32_t daysOfWeek);
+
+      uint32_t GetRetention() const;
+      void SetRetention(uint32_t retention);
+
+      uint32_t GetPriority() const;
+      void SetPriority(uint32_t priority);
+
+      const std::string &GetTitle() const;
+      void SetTitle(const std::string &title);
+
+      const std::string &GetName() const;
+      void SetName(const std::string &name);
+
+      const std::string &GetDirectory() const;
+      void SetDirectory(const std::string &directory);
+
+      void SetOwner(const std::string &owner);
+      void SetCreator(const std::string &creator);
+
+      uint32_t GetChannel() const;
+      void SetChannel(uint32_t channel);
+
+    protected:
+      static time_t LocaltimeToUTC(int32_t lctime);
+
+    private:
+      static int GetNextIntId();
+
+      const unsigned int m_iId;
+
+      std::string m_id;         // ID (string!) of dvr[Time|Auto]recEntry.
+      uint32_t m_enabled;       // If [time|auto]rec entry is enabled (activated).
+      uint32_t m_daysOfWeek;    // Bitmask - Days of week (0x01 = Monday, 0x40 = Sunday, 0x7f = Whole Week, 0 = Not set).
+      uint32_t m_retention;     // Retention time (in days).
+      uint32_t m_priority;      // Priority (0 = Important, 1 = High, 2 = Normal, 3 = Low, 4 = Unimportant).
+      std::string m_title;      // Title (pattern) for the recording files.
+      std::string m_name;       // Name.
+      std::string m_directory;  // Directory for the recording files.
+      std::string m_owner;      // Owner.
+      std::string m_creator;    // Creator.
+      uint32_t m_channel;       // Channel ID.
+    };
+  }
+}
diff --git a/src/AsyncState.cpp b/src/tvheadend/entity/Schedule.cpp
similarity index 52%
copy from src/AsyncState.cpp
copy to src/tvheadend/entity/Schedule.cpp
index 65c1d07..9b448c7 100644
--- a/src/AsyncState.cpp
+++ b/src/tvheadend/entity/Schedule.cpp
@@ -1,5 +1,5 @@
 /*
- *      Copyright (C) 2005-2014 Team XBMC
+ *      Copyright (C) 2005-2011 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -19,41 +19,30 @@
  *
  */
 
-#include "AsyncState.h"
-#include "client.h"
+#include "Schedule.h"
 
-struct Param {
-  eAsyncState state;
-  AsyncState *self;
-};
+using namespace tvheadend::entity;
 
-using namespace PLATFORM;
-
-AsyncState::AsyncState(int timeout)
+void Schedule::SetDirty(bool dirty)
 {
-  m_state   = ASYNC_NONE;
-  m_timeout = timeout;
-}
+  Entity::SetDirty(dirty);
 
-void AsyncState::SetState(eAsyncState state)
-{
-  CLockObject lock(m_mutex);
-  m_state = state;
-  m_condition.Broadcast();
+  // Mark all events as dirty too
+  for (auto &entry : events)
+    entry.second.SetDirty(dirty);
 }
 
-bool AsyncState::PredicateCallback ( void *p )
+Segment Schedule::GetSegment(time_t startTime, time_t endTime) const
 {
-  Param *param = (Param*)p;
-  return param->self->m_state >= param->state;
-}
+  Segment segment;
 
-bool AsyncState::WaitForState(eAsyncState state)
-{
-  Param p;
-  p.state = state;
-  p.self  = this;
+  for (const auto &entry : events)
+  {
+    const Event &event = entry.second;
+
+    if (event.start < endTime && event.stop > startTime)
+      segment.push_back(event);
+  }
 
-  CLockObject lock(m_mutex);
-  return m_condition.Wait(m_mutex, AsyncState::PredicateCallback, (void*)&p, m_timeout);
+  return segment;
 }
diff --git a/src/AsyncState.cpp b/src/tvheadend/entity/Schedule.h
similarity index 50%
copy from src/AsyncState.cpp
copy to src/tvheadend/entity/Schedule.h
index 65c1d07..d5e7905 100644
--- a/src/AsyncState.cpp
+++ b/src/tvheadend/entity/Schedule.h
@@ -1,5 +1,7 @@
+#pragma once
+
 /*
- *      Copyright (C) 2005-2014 Team XBMC
+ *      Copyright (C) 2005-2011 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -19,41 +21,37 @@
  *
  */
 
-#include "AsyncState.h"
-#include "client.h"
-
-struct Param {
-  eAsyncState state;
-  AsyncState *self;
-};
-
-using namespace PLATFORM;
-
-AsyncState::AsyncState(int timeout)
-{
-  m_state   = ASYNC_NONE;
-  m_timeout = timeout;
-}
-
-void AsyncState::SetState(eAsyncState state)
-{
-  CLockObject lock(m_mutex);
-  m_state = state;
-  m_condition.Broadcast();
-}
+#include <vector>
+#include "Entity.h"
+#include "Event.h"
 
-bool AsyncState::PredicateCallback ( void *p )
+namespace tvheadend
 {
-  Param *param = (Param*)p;
-  return param->self->m_state >= param->state;
-}
-
-bool AsyncState::WaitForState(eAsyncState state)
-{
-  Param p;
-  p.state = state;
-  p.self  = this;
-
-  CLockObject lock(m_mutex);
-  return m_condition.Wait(m_mutex, AsyncState::PredicateCallback, (void*)&p, m_timeout);
-}
+  namespace entity
+  {
+    class Schedule;
+    typedef std::pair<int, Schedule> ScheduleMapEntry;
+    typedef std::map<int, Schedule> Schedules;
+    typedef std::vector<Event> Segment;
+
+    /**
+     * Represents a schedule. A schedule has a channel and a bunch of events.
+     */
+    class Schedule : public Entity
+    {
+    public:
+      Schedule() : channel(0) {}
+
+      virtual void SetDirty(bool dirty);
+
+      /**
+       * @return a segment containing the events that occur within the
+       * specified times
+       */
+      Segment GetSegment(time_t startTime, time_t endTime) const;
+
+      uint32_t channel;
+      Events events;
+    };
+  }
+}
\ No newline at end of file
diff --git a/src/tvheadend/entity/Tag.cpp b/src/tvheadend/entity/Tag.cpp
new file mode 100644
index 0000000..747c181
--- /dev/null
+++ b/src/tvheadend/entity/Tag.cpp
@@ -0,0 +1,104 @@
+/*
+ *      Copyright (C) 2005-2015 Team Kodi
+ *      http://kodi.tv
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "Tag.h"
+#include "Channel.h"
+#include "../../HTSPTypes.h"
+#include "../../Tvheadend.h"
+
+using namespace tvheadend::entity;
+
+Tag::Tag(uint32_t id /*= 0*/) :
+m_id(id),
+m_index(0)
+{
+}
+
+bool Tag::operator==(const Tag &right)
+{
+  return m_id == right.m_id &&
+    m_index == right.m_index &&
+    m_name == right.m_name &&
+    m_icon == right.m_icon &&
+    m_channels == right.m_channels;
+}
+
+bool Tag::operator!=(const Tag &right)
+{
+  return !(*this == right);
+}
+
+uint32_t Tag::GetId() const
+{
+  return m_id;
+}
+
+uint32_t Tag::GetIndex() const
+{
+  return m_index;
+}
+
+void Tag::SetIndex(uint32_t index)
+{
+  m_index = index;
+}
+
+const std::string& Tag::GetName() const
+{
+  return m_name;
+}
+
+void Tag::SetName(const std::string& name)
+{
+  m_name = name;
+}
+
+void Tag::SetIcon(const std::string& icon)
+{
+  m_icon = icon;
+}
+
+const std::vector<uint32_t>& Tag::GetChannels() const
+{
+  return m_channels;
+}
+
+std::vector<uint32_t>& Tag::GetChannels()
+{
+  return m_channels;
+}
+
+bool Tag::ContainsChannelType(bool bRadio) const
+{
+  std::vector<uint32_t>::const_iterator it;
+  Channels::const_iterator cit;
+  const Channels& channels = tvh->GetChannels();
+
+  for (it = m_channels.begin(); it != m_channels.end(); ++it)
+  {
+    if ((cit = channels.find(*it)) != channels.end())
+    {
+      if (bRadio == cit->second.radio)
+        return true;
+    }
+  }
+  return false;
+}
diff --git a/src/tvheadend/entity/Tag.h b/src/tvheadend/entity/Tag.h
new file mode 100644
index 0000000..8951703
--- /dev/null
+++ b/src/tvheadend/entity/Tag.h
@@ -0,0 +1,73 @@
+#pragma once
+
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include <cstdint>
+#include <string>
+#include <map>
+#include <vector>
+#include "Entity.h"
+
+namespace tvheadend
+{
+  namespace entity
+  {
+    class Tag;
+    typedef std::pair<uint32_t, Tag> TagMapEntry;
+    typedef std::map<uint32_t, Tag> Tags;
+
+    /**
+     * Represents a channel tag
+     */
+    class Tag : public Entity
+    {
+    public:
+      Tag(uint32_t id = 0);
+
+      bool operator==(const Tag &right);
+      bool operator!=(const Tag &right);
+
+      uint32_t GetId() const;
+
+      uint32_t GetIndex() const;
+      void SetIndex(uint32_t index);
+
+      const std::string& GetName() const;
+      void SetName(const std::string& name);
+
+      void SetIcon(const std::string& icon);
+
+      const std::vector<uint32_t>& GetChannels() const;
+      std::vector<uint32_t>& GetChannels();
+
+      bool ContainsChannelType(bool bRadio) const;
+
+    private:
+      uint32_t              m_id;
+      uint32_t              m_index;
+      std::string           m_name;
+      std::string           m_icon;
+      std::vector<uint32_t> m_channels;
+    };
+  }
+}
+
diff --git a/src/tvheadend/entity/TimeRecording.cpp b/src/tvheadend/entity/TimeRecording.cpp
new file mode 100644
index 0000000..6026216
--- /dev/null
+++ b/src/tvheadend/entity/TimeRecording.cpp
@@ -0,0 +1,69 @@
+/*
+ *      Copyright (C) 2005-2011 Team XBMC
+ *      http://www.xbmc.org
+ *
+ *  This Program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This Program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with XBMC; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *  http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#include "TimeRecording.h"
+
+using namespace tvheadend::entity;
+
+TimeRecording::TimeRecording(const std::string &id /*= ""*/) :
+    RecordingBase(id),
+    m_start(0),
+    m_stop(0)
+{
+}
+
+bool TimeRecording::operator==(const TimeRecording &right)
+{
+  return RecordingBase::operator==(right) &&
+         m_start       == right.m_start   &&
+         m_stop        == right.m_stop;
+}
+
+bool TimeRecording::operator!=(const TimeRecording &right)
+{
+  return !(*this == right);
+}
+
+time_t TimeRecording::GetStart() const
+{
+  if (m_start == int32_t(-1)) // "any time"
+    return 0;
+
+  return LocaltimeToUTC(m_start);
+}
+
+void TimeRecording::SetStart(int32_t start)
+{
+  m_start = start;
+}
+
+time_t TimeRecording::GetStop() const
+{
+  if (m_stop == int32_t(-1)) // "any time"
+    return 0;
+
+  return LocaltimeToUTC(m_stop);
+}
+
+void TimeRecording::SetStop(int32_t stop)
+{
+  m_stop = stop;
+}
\ No newline at end of file
diff --git a/src/AsyncState.cpp b/src/tvheadend/entity/TimeRecording.h
similarity index 52%
copy from src/AsyncState.cpp
copy to src/tvheadend/entity/TimeRecording.h
index 65c1d07..f46ee6c 100644
--- a/src/AsyncState.cpp
+++ b/src/tvheadend/entity/TimeRecording.h
@@ -1,5 +1,7 @@
+#pragma once
+
 /*
- *      Copyright (C) 2005-2014 Team XBMC
+ *      Copyright (C) 2005-2011 Team XBMC
  *      http://www.xbmc.org
  *
  *  This Program is free software; you can redistribute it and/or modify
@@ -19,41 +21,32 @@
  *
  */
 
-#include "AsyncState.h"
-#include "client.h"
-
-struct Param {
-  eAsyncState state;
-  AsyncState *self;
-};
-
-using namespace PLATFORM;
+#include "RecordingBase.h"
+#include <map>
 
-AsyncState::AsyncState(int timeout)
+namespace tvheadend
 {
-  m_state   = ASYNC_NONE;
-  m_timeout = timeout;
-}
+  namespace entity
+  {
+    class TimeRecording : public RecordingBase
+    {
+    public:
+      TimeRecording(const std::string &id = "");
 
-void AsyncState::SetState(eAsyncState state)
-{
-  CLockObject lock(m_mutex);
-  m_state = state;
-  m_condition.Broadcast();
-}
+      bool operator==(const TimeRecording &right);
+      bool operator!=(const TimeRecording &right);
 
-bool AsyncState::PredicateCallback ( void *p )
-{
-  Param *param = (Param*)p;
-  return param->self->m_state >= param->state;
-}
+      time_t GetStart() const;
+      void SetStart(int32_t start);
 
-bool AsyncState::WaitForState(eAsyncState state)
-{
-  Param p;
-  p.state = state;
-  p.self  = this;
+      time_t GetStop() const;
+      void SetStop(int32_t stop);
+
+    private:
+      int32_t m_start; // Start time in minutes from midnight (up to 24*60).
+      int32_t m_stop;  // Stop time in minutes from midnight (up to 24*60).
+    };
 
-  CLockObject lock(m_mutex);
-  return m_condition.Wait(m_mutex, AsyncState::PredicateCallback, (void*)&p, m_timeout);
+    typedef std::map<std::string, TimeRecording> TimeRecordingsMap;
+  }
 }

-- 
kodi-pvr-hts packaging



More information about the pkg-multimedia-commits mailing list