From 4a3582ec10235efea2a2973773e6c33b900fd46c Mon Sep 17 00:00:00 2001 From: Sascha Volkenandt Date: Tue, 16 Jan 2007 18:34:31 +0000 Subject: - rewritten task manager to make it more general --- live.cpp | 4 +-- tasks.cpp | 86 +++++++++++++++++++++++++++++++++------------------------------ tasks.h | 78 +++++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 101 insertions(+), 67 deletions(-) diff --git a/live.cpp b/live.cpp index 9cd5eb1..9058080 100644 --- a/live.cpp +++ b/live.cpp @@ -3,7 +3,7 @@ * * See the README file for copyright information and how to reach the author. * - * $Id: live.cpp,v 1.11 2007/01/13 18:37:21 lordjaxom Exp $ + * $Id: live.cpp,v 1.12 2007/01/16 18:34:31 lordjaxom Exp $ */ #include @@ -56,7 +56,7 @@ void Plugin::Stop(void) void Plugin::MainThreadHook(void) { LiveTimerManager().DoPendingWork(); - LiveTaskManager().DoScheduledWork(); + LiveTaskManager().DoScheduledTasks(); } cString Plugin::Active(void) diff --git a/tasks.cpp b/tasks.cpp index 07275e5..feaf6aa 100644 --- a/tasks.cpp +++ b/tasks.cpp @@ -1,69 +1,73 @@ #include +#include #include #include +#include "exception.h" #include "tasks.h" +#include "tools.h" + +using namespace std; namespace vdrlive { -TaskManager::TaskManager(): - m_switchChannel( 0, false ), - m_replayRecording( "", false ) +void SwitchChannelTask::Action() { -} + ReadLock lock( Channels ); + cChannel* channel = Channels.GetByChannelID( m_channel ); + if ( channel == 0 ) { + SetError( tr("Couldn't find channel or no channels available. Maybe you mistyped your request?") ); + return; + } -bool TaskManager::SwitchChannel( int number ) -{ - return ScheduleCommand( m_switchChannel, number ); - //cMutexLock lock( this ); - //m_switchChannel.first = number; - //m_scheduleWait.Wait( *this ); - //return m_switchChannel.second; + if ( !Channels.SwitchTo( channel->Number() ) ) + SetError( tr("Couldn't switch channels") ); } -bool TaskManager::ReplayRecording( std::string const& fileName ) +TaskManager::TaskManager() { - return ScheduleCommand( m_replayRecording, fileName ); - //cMutexLock lock( this ); - //m_replayFileName = fileName; - //m_scheduleWait.Wait( *this ); - //return m_replayResult; } -void TaskManager::DoScheduledWork() +bool TaskManager::Execute( Task* task, string& error ) { - if ( m_switchChannel.first == 0 && m_replayRecording.first.empty() ) - return; - + auto_ptr< Task > reaper( task ); cMutexLock lock( this ); - if ( m_switchChannel.first != 0 ) - DoSwitchChannel(); - if ( !m_replayRecording.first.empty() ) - DoReplayRecording(); - m_scheduleWait.Broadcast(); + + m_taskQueue.push_back( task ); + m_scheduleWait.Wait( *this ); + error = task->Error(); + return task->Result(); } -void TaskManager::DoSwitchChannel() +bool TaskManager::Execute( Task* task ) { - m_switchChannel.second = Channels.SwitchTo( m_switchChannel.first ); - m_switchChannel.first = 0; + string dummyError; + return Execute( task, dummyError ); } -void TaskManager::DoReplayRecording() +void TaskManager::DoScheduledTasks() { - bool result = false; - cThreadLock lock( &Recordings ); + if ( m_taskQueue.empty() ) + return; - cRecording* recording = Recordings.GetByName( m_replayRecording.first.c_str() ); - if ( recording ) { - cReplayControl::SetRecording( 0, 0 ); - cControl::Shutdown(); - cReplayControl::SetRecording( recording->FileName(), recording->Title() ); - cControl::Launch( new cReplayControl ); - cControl::Attach(); - result = true; + cMutexLock lock( this ); + while ( !m_taskQueue.empty() ) { + Task* current = m_taskQueue.front(); + current->Action(); + m_taskQueue.pop_front(); } - m_replayRecording.first.clear(); + m_scheduleWait.Broadcast(); +} + +/* +bool TaskManager::ReplayRecording( std::string const& fileName ) +{ + return ScheduleCommand( m_replayRecording, fileName ); + //cMutexLock lock( this ); + //m_replayFileName = fileName; + //m_scheduleWait.Wait( *this ); + //return m_replayResult; } +*/ TaskManager& LiveTaskManager() { diff --git a/tasks.h b/tasks.h index 3ae63da..c90f9e1 100644 --- a/tasks.h +++ b/tasks.h @@ -1,52 +1,82 @@ #ifndef VDR_LIVE_TASKS_H #define VDR_LIVE_TASKS_H +#include +#include #include -#include +#include #include namespace vdrlive { +class Task; + class TaskManager: public cMutex { friend TaskManager& LiveTaskManager(); + typedef std::deque< Task* > TaskQueue; + public: - bool SwitchChannel( int number ); - bool ReplayRecording( std::string const& fileName ); + bool Execute( Task* task, std::string& error ); + bool Execute( Task* task ); // may only be called from Plugin::MainThreadHook - void DoScheduledWork(); - -private: - template< typename Type > - struct Task: std::pair< Type, bool > - { - Task( Type const& first, bool second ): std::pair< Type, bool >( first, second ) {} - }; + void DoScheduledTasks(); +private: TaskManager(); TaskManager( TaskManager const& ); - Task< int > m_switchChannel; - Task< std::string > m_replayRecording; + TaskQueue m_taskQueue; cCondVar m_scheduleWait; +}; + +class Task +{ + friend void TaskManager::DoScheduledTasks(); + +public: + virtual ~Task() {} + + bool Result() const { return m_result; } + std::string const& Error() const { return m_error; } - template< typename Type > - bool ScheduleCommand( Task< Type >& member, Type const& param ); +protected: + Task(): m_result( true ) {} + Task( Task const& ); - void DoSwitchChannel(); - void DoReplayRecording(); + void SetError( std::string const& error ) { m_result = false; m_error = error; } + + virtual void Action() = 0; + +private: + bool m_result; + std::string m_error; }; + +class SwitchChannelTask: public Task +{ +public: + SwitchChannelTask( tChannelID channel ): m_channel( channel ) {} -template< typename Type > -inline bool TaskManager::ScheduleCommand( Task< Type >& member, Type const& param ) +private: + tChannelID m_channel; + + virtual void Action(); +}; + +class ReplayRecordingTask: public Task { - cMutexLock lock( this ); - member.first = param; - m_scheduleWait.Wait( *this ); - return member.second; -} +public: + ReplayRecordingTask( std::string const& recording ): m_recording( recording ) {} + +private: + std::string m_recording; + + virtual void Action() {} +}; + TaskManager& LiveTaskManager(); -- cgit v1.2.3