recording service events now working
authorAndreas Monzner <andreas.monzner@multimedia-labs.de>
Wed, 22 Nov 2006 15:09:29 +0000 (15:09 +0000)
committerAndreas Monzner <andreas.monzner@multimedia-labs.de>
Wed, 22 Nov 2006 15:09:29 +0000 (15:09 +0000)
TODO: add record specific events like diskfull, demux errors, a.o.

Navigation.py
RecordTimer.py
lib/nav/core.cpp
lib/nav/core.h
lib/nav/pcore.cpp
lib/nav/pcore.h
lib/python/enigma_python.i
lib/service/iservice.h
lib/service/servicedvbrecord.cpp

index 7c1cdd426131d1d5343a82ce379395fa74f5c61e..53e9ed426153516466b627d147e2aeadd7fd17b7 100644 (file)
@@ -22,19 +22,26 @@ class Navigation:
                Nav.navcore = self
                
                self.pnav = pNavigation()
-               self.pnav.m_event.get().append(self.callEvent)
+               self.pnav.m_event.get().append(self.dispatchEvent)
+               self.pnav.m_record_event.get().append(self.dispatchRecordEvent)
                self.event = [ ]
+               self.record_event = [ ]
                self.currentlyPlayingServiceReference = None
                self.currentlyPlayingService = None
                self.state = 0
                self.RecordTimer = RecordTimer.RecordTimer()
                self.SleepTimer = SleepTimer.SleepTimer()
-               
-       def callEvent(self, i):
+
+       def dispatchEvent(self, i):
                self.state = i != 1
                for x in self.event:
                        x(i)
 
+       def dispatchRecordEvent(self, rec_service, event):
+#              print "record_event", rec_service, event
+               for x in self.record_event:
+                       x(rec_service, event)
+
        def playService(self, ref, checkParentalControl = True):
                print "playing", ref and ref.toString()
                self.currentlyPlayingServiceReference = None
@@ -66,6 +73,13 @@ class Navigation:
                else:
                        return service
 
+       def stopRecordService(self, service):
+               ret = self.pnav and self.pnav.stopRecordService(service)
+               return ret
+
+       def getRecordings(self):
+               return self.pnav and self.pnav.getRecordings()
+
        def getCurrentService(self):
                if self.state:
                        if not self.currentlyPlayingService:
index b438910e5570580ff25c663493348b4fe4bcf7e1..21ad99d904b4dd226b8a05894fae7f147cf141bf 100644 (file)
@@ -198,7 +198,7 @@ class RecordTimerEntry(timer.TimerEntry):
                elif next_state == self.StateEnded:
                        self.log(12, "stop recording")
                        if not self.justplay:
-                               self.record_service.stop()
+                               NavigationInstance.instance.stopRecordService(self.record_service)
                                self.record_service = None
                        if self.afterEvent == AFTEREVENT.STANDBY:
                                if self.session is not None:
index edc63c1881d9fa84f96ea3777a586509fc8053e5..7f76fa3f87dfb0199130bcfece2875d17f3a36a7 100644 (file)
@@ -1,5 +1,6 @@
 #include <lib/nav/core.h>
 #include <lib/base/eerror.h>
+#include <Python.h>
 
 void eNavigation::serviceEvent(iPlayableService* service, int event)
 {
@@ -8,8 +9,17 @@ void eNavigation::serviceEvent(iPlayableService* service, int event)
                eDebug("nav: event for other service");
                return;
        }
+       m_event(event);
+}
 
-       m_event(this, event);
+void eNavigation::recordEvent(iRecordableService* service, int event)
+{
+       if (m_recordings.find(service) == m_recordings.end())
+       {
+               eDebug("nav: event for non registered recording service");
+               return;
+       }
+       m_record_event(service, event);
 }
 
 RESULT eNavigation::playService(const eServiceReference &service)
@@ -26,12 +36,18 @@ RESULT eNavigation::playService(const eServiceReference &service)
        return res;
 }
 
-RESULT eNavigation::connectEvent(const Slot2<void,eNavigation*,int> &event, ePtr<eConnection> &connection)
+RESULT eNavigation::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
 {
        connection = new eConnection(this, m_event.connect(event));
        return 0;
 }
 
+RESULT eNavigation::connectRecordEvent(const Slot2<void,ePtr<iRecordableService>,int> &event, ePtr<eConnection> &connection)
+{
+       connection = new eConnection(this, m_record_event.connect(event));
+       return 0;
+}
+
 RESULT eNavigation::getCurrentService(ePtr<iPlayableService> &service)
 {
        service = m_runningService;
@@ -44,7 +60,7 @@ RESULT eNavigation::stopService(void)
        if (!m_runningService)
                return 1;
                        /* send stop event */
-       m_event(this, iPlayableService::evEnd);
+       m_event(iPlayableService::evEnd);
 
        m_runningService->stop();
                /* kill service. */
@@ -60,9 +76,40 @@ RESULT eNavigation::recordService(const eServiceReference &ref, ePtr<iRecordable
        eDebug("record: %d", res);
        if (res)
                service = 0;
+       else
+       {
+               ePtr<eConnection> conn;
+               service->connectEvent(slot(*this, &eNavigation::recordEvent), conn);
+               m_recordings[service]=conn;
+       }
        return res;
 }
 
+RESULT eNavigation::stopRecordService(ePtr<iRecordableService> &service)
+{
+       service->stop();
+       std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it =
+               m_recordings.find(service);
+       if (it != m_recordings.end())
+       {
+               m_recordings.erase(it);
+               return 0;
+       }
+       eDebug("try to stop non running recording!!");  // this should not happen
+       return -1;
+}
+
+extern PyObject *New_iRecordableServicePtr(const ePtr<iRecordableService> &ref); // defined in enigma_python.i
+
+PyObject *eNavigation::getRecordings(void)
+{
+       PyObject *result = PyList_New(m_recordings.size());
+       int pos=0;
+       for (std::map<ePtr<iRecordableService>, ePtr<eConnection> >::iterator it(m_recordings.begin()); it != m_recordings.end(); ++it)
+               PyList_SET_ITEM(result, pos++, New_iRecordableServicePtr(it->first)); 
+       return result;
+}
+
 RESULT eNavigation::pause(int dop)
 {
        if (!m_runningService)
index fbcd566d16e3b73c3e5c957ef03a86aa37feaa42..b82d2fbd4e00c8b3076c917c885cc1311487ca4a 100644 (file)
@@ -4,26 +4,34 @@
 #include <lib/base/object.h>
 #include <lib/service/iservice.h>
 #include <connection.h>
+#include <map>
 
 class eNavigation: public iObject, public Object
 {
        DECLARE_REF(eNavigation);
 private:
-       ePtr<iPlayableService> m_runningService;
-       
        ePtr<iServiceHandler> m_servicehandler;
-       Signal2<void,eNavigation*,int> m_event;
+
+       ePtr<iPlayableService> m_runningService;
+       Signal1<void,int> m_event;
        ePtr<eConnection> m_service_event_conn;
        void serviceEvent(iPlayableService* service, int event);
+
+       std::map<ePtr<iRecordableService>, ePtr<eConnection>, std::less<iRecordableService*> > m_recordings;
+       Signal2<void,ePtr<iRecordableService>,int> m_record_event;
+       void recordEvent(iRecordableService* service, int event);
 public:
        
        RESULT playService(const eServiceReference &service);
-       RESULT connectEvent(const Slot2<void,eNavigation*,int> &event, ePtr<eConnection> &connection);
+       RESULT connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection);
+       RESULT connectRecordEvent(const Slot2<void,ePtr<iRecordableService>,int> &event, ePtr<eConnection> &connection);
 /*     int connectServiceEvent(const Slot1<void,iPlayableService*,int> &event, ePtr<eConnection> &connection); */
        RESULT getCurrentService(ePtr<iPlayableService> &service);
        RESULT stopService(void);
        
        RESULT recordService(const eServiceReference &ref, ePtr<iRecordableService> &service);
+       RESULT stopRecordService(ePtr<iRecordableService> &service);
+       PyObject *getRecordings(void);
        
        RESULT pause(int p);
        eNavigation(iServiceHandler *serviceHandler);
index fdcb385e283567621a4179612c43c90e700c05b2..a6ed35f66480b99808ecb0afb697ce6dae672137 100644 (file)
@@ -14,6 +14,7 @@ pNavigation::pNavigation()
        m_core = new eNavigation(service_center);
        
        m_core->connectEvent(slot(*this, &pNavigation::navEvent), m_nav_event_connection);
+       m_core->connectRecordEvent(slot(*this, &pNavigation::navRecordEvent), m_nav_record_event_connection);
 }
 
 RESULT pNavigation::playService(const eServiceReference &service)
@@ -21,11 +22,6 @@ RESULT pNavigation::playService(const eServiceReference &service)
        return m_core->playService(service);
 }
 
-RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
-{
-       return m_core->recordService(ref, service);
-}
-
 RESULT pNavigation::getCurrentService(ePtr<iPlayableService> &service)
 {
        return m_core->getCurrentService(service);
@@ -41,8 +37,29 @@ RESULT pNavigation::stopService()
        return m_core->stopService();
 }
 
-void pNavigation::navEvent(eNavigation *nav, int event)
+RESULT pNavigation::recordService(const eServiceReference &ref, ePtr<iRecordableService> &service)
+{
+       return m_core->recordService(ref, service);
+}
+
+RESULT pNavigation::stopRecordService(ePtr<iRecordableService> &service)
+{
+       return m_core->stopRecordService(service);
+}
+
+PyObject *pNavigation::getRecordings(void)
+{
+       return m_core->getRecordings();
+}
+
+void pNavigation::navEvent(int event)
 {
                /* just relay the events here. */
        m_event(event);
 }
+
+void pNavigation::navRecordEvent(ePtr<iRecordableService> service, int event)
+{
+               /* just relay the events here. */
+       m_record_event(service, event);
+}
index e9a06403e5715d51bb263074bb1f875ef069d3ff..c485f7d01460d7eacf1fad26f914a32f789e49c4 100644 (file)
@@ -11,20 +11,24 @@ class pNavigation: public iObject, public Object
 DECLARE_REF(pNavigation);
 public:
        PSignal1<void, int> m_event;
-       
+       PSignal2<void, ePtr<iRecordableService>&, int> m_record_event;
+
        pNavigation();
        
        RESULT playService(const eServiceReference &service);
-       SWIG_VOID(RESULT) recordService(const eServiceReference &ref, ePtr<iRecordableService> &SWIG_OUTPUT);
-       
-       SWIG_VOID(RESULT) getCurrentService(ePtr<iPlayableService> &SWIG_OUTPUT);
        RESULT stopService();
-       
        RESULT pause(int p);
+       SWIG_VOID(RESULT) getCurrentService(ePtr<iPlayableService> &SWIG_OUTPUT);
+
+       SWIG_VOID(RESULT) recordService(const eServiceReference &ref, ePtr<iRecordableService> &SWIG_OUTPUT);
+       RESULT stopRecordService(ePtr<iRecordableService> &service);
+       PyObject *getRecordings(void);
+
 private:
        ePtr<eNavigation> m_core;
-       ePtr<eConnection> m_nav_event_connection;
-       void navEvent(eNavigation *nav, int event);
+       ePtr<eConnection> m_nav_event_connection, m_nav_record_event_connection;
+       void navEvent(int event);
+       void navRecordEvent(ePtr<iRecordableService>, int event);
 };
 
 #endif
index 3772a23dc8d9680fb0f77e0bc82761896e89a3b0..21c0664a9c2aa4c08cb4a9e0b6aad66dbcd90948 100644 (file)
@@ -155,6 +155,7 @@ typedef long time_t;
 %immutable eComponentScan::statusChanged;
 %immutable eComponentScan::newService;
 %immutable pNavigation::m_event;
+%immutable pNavigation::m_record_event;
 %immutable eListbox::selectionChanged;
 %immutable eDVBCI_UI::ciStateChanged;
 %immutable eDVBResourceManager::frontendUseMaskChanged;
@@ -252,6 +253,12 @@ public:
        PyObject *get();
 };
 
+%template(PSignal2VoidIRecordableServiceInt) PSignal2<void,ePtr<iRecordableService>&,int>;
+
+%typemap(out) PSignal2VoidIRecordableServiceInt {
+       $1 = $input->get();
+}
+
 /************** temp *****************/
 
        /* need a better place for this, i agree. */
@@ -290,4 +297,9 @@ PyObject *New_eServiceReference(const eServiceReference &ref)
     eServiceReference *result = new eServiceReference(ref);
     return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_eServiceReference, 1);
 }
+PyObject *New_iRecordableServicePtr(const ePtr<iRecordableService> &ptr)
+{
+    ePtr<iRecordableService> *result = new ePtr<iRecordableService>(ptr);
+    return SWIG_NewPointerObj((void*)(result), SWIGTYPE_p_ePtrTiRecordableService_t, 1);
+}
 %}
index 73a0f4ef3aa77e82b786a583058ce4fa2d8c397d..1dd419c1680ffe8e23d043831bf2b42b74bd6acf 100644 (file)
@@ -512,7 +512,9 @@ public:
 
                evUpdatedRadioText
        };
+#ifndef SWIG
        virtual RESULT connectEvent(const Slot2<void,iPlayableService*,int> &event, ePtr<eConnection> &connection)=0;
+#endif
        virtual RESULT start()=0;
        virtual RESULT stop()=0;
                        /* might have to be changed... */
@@ -547,6 +549,7 @@ public:
                evTunedIn,
                evTuneFailed,
                evRecordRunning,
+               evRecordStopped,
                evNewProgramInfo,
                evRecordFailed
 //             evDiskFull
@@ -560,8 +563,10 @@ public:
                errDiskFull=-4,
                errTuneFailed=-255
        };
-       virtual RESULT getError(int &)=0;
+#ifndef SWIG
        virtual RESULT connectEvent(const Slot2<void,iRecordableService*,int> &event, ePtr<eConnection> &connection)=0;
+#endif
+       virtual RESULT getError(int &)=0;
        virtual RESULT prepare(const char *filename, time_t begTime=-1, time_t endTime=-1, int eit_event_id=-1)=0;
        virtual RESULT start()=0;
        virtual RESULT stop()=0;
@@ -570,6 +575,8 @@ public:
 
 TEMPLATE_TYPEDEF(ePtr<iRecordableService>, iRecordableServicePtr);
 
+PyObject *PyFrom(ePtr<iRecordableService>&);  // implemented in servicedvbrecord.cpp
+
 // TEMPLATE_TYPEDEF(std::list<eServiceReference>, eServiceReferenceList);
 
 class iMutableServiceList: public iObject
index fb3ae2bad3d819f8eadc9df6afbf95a6086c05c2..6164ca171a7f23845696dfaf894218d3edfa8f09 100644 (file)
@@ -1,11 +1,17 @@
 #include <lib/service/servicedvbrecord.h>
 #include <lib/base/eerror.h>
 #include <lib/dvb/epgcache.h>
-
 #include <fcntl.h>
 
 DEFINE_REF(eDVBServiceRecord);
 
+extern PyObject *New_iRecordableServicePtr(const ePtr<iRecordableService> &ref); // defined in enigma_python.i
+
+PyObject *PyFrom(ePtr<iRecordableService> &c)
+{
+       return New_iRecordableServicePtr(c);
+}
+
 eDVBServiceRecord::eDVBServiceRecord(const eServiceReferenceDVB &ref): m_ref(ref)
 {
        CONNECT(m_service_handler.serviceEvent, eDVBServiceRecord::serviceEvent);
@@ -115,6 +121,7 @@ RESULT eDVBServiceRecord::start()
 RESULT eDVBServiceRecord::stop()
 {
        eDebug("stop recording!!");
+       m_event((iRecordableService*)this, evStop);
        if (m_state == stateRecording)
        {
                if (m_record)
@@ -132,7 +139,7 @@ RESULT eDVBServiceRecord::stop()
                m_record = 0;
                m_state = stateIdle;
        }
-       m_event((iRecordableService*)this, evStop);
+       m_event((iRecordableService*)this, evRecordStopped);
        return 0;
 }