mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 08:37:25 -05:00
Adds support to channel model and processing manager to auto-start
channels upon loading the playlist. Processing manager now detects channel configuration changes and restarts the channel if it is currently processing. Channel editor enable button now shows green if it is processing, or default when not processing.
This commit is contained in:
@@ -74,6 +74,8 @@ public class ChannelEditor extends JPanel
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private SourceManager mSourceManager;
|
||||
|
||||
private boolean mChannelEnableRequested = false;
|
||||
|
||||
public ChannelEditor( ChannelModel channelModel,
|
||||
PlaylistManager playlistManager,
|
||||
SourceManager sourceManager )
|
||||
@@ -108,7 +110,7 @@ public class ChannelEditor extends JPanel
|
||||
mChannelName.setText( "Channel: " + channel.getName() );
|
||||
mEnableButton.setText( channel.getEnabled() ? "Disable" : "Enable" );
|
||||
mEnableButton.setEnabled( true );
|
||||
mEnableButton.setBackground( channel.getEnabled() ? Color.RED : Color.GREEN );
|
||||
mEnableButton.setBackground( channel.getEnabled() ? Color.GREEN : getBackground() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -126,6 +128,7 @@ public class ChannelEditor extends JPanel
|
||||
{
|
||||
setLayout( new MigLayout( "fill,wrap 2", "[right,grow][grow]", "[][][][][grow][]" ) );
|
||||
|
||||
mEnableButton.addActionListener( this );
|
||||
mEnableButton.setEnabled( false );
|
||||
add( mEnableButton, "growx,push" );
|
||||
add( mChannelName, "growx,push" );
|
||||
@@ -175,15 +178,28 @@ public class ChannelEditor extends JPanel
|
||||
case NOTIFICATION_PROCESSING_START:
|
||||
case NOTIFICATION_PROCESSING_STOP:
|
||||
setChannel( mChannel );
|
||||
mChannelEnableRequested = false;
|
||||
break;
|
||||
case NOTIFICATION_DELETE:
|
||||
mChannel = null;
|
||||
setChannel( mChannel );
|
||||
break;
|
||||
case NOTIFICATION_ENABLE_REJECTED:
|
||||
if( mChannelEnableRequested )
|
||||
{
|
||||
JOptionPane.showMessageDialog( ChannelEditor.this,
|
||||
"Channel could not be enabled. This is likely because "
|
||||
+ "there are no tuner channels available", "Couldn't "
|
||||
+ "enable channel", JOptionPane.INFORMATION_MESSAGE );
|
||||
|
||||
mChannelEnableRequested = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -191,7 +207,22 @@ public class ChannelEditor extends JPanel
|
||||
{
|
||||
String command = e.getActionCommand();
|
||||
|
||||
if( command.contentEquals( "Save" ) )
|
||||
if( command.contentEquals( "Enable" ) )
|
||||
{
|
||||
if( mChannel != null )
|
||||
{
|
||||
mChannelEnableRequested = true;
|
||||
mChannelModel.broadcast( new ChannelEvent( mChannel, Event.REQUEST_ENABLE ) );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Disable" ) )
|
||||
{
|
||||
if( mChannel != null )
|
||||
{
|
||||
mChannelModel.broadcast( new ChannelEvent( mChannel, Event.REQUEST_DISABLE ) );
|
||||
}
|
||||
}
|
||||
else if( command.contentEquals( "Save" ) )
|
||||
{
|
||||
save();
|
||||
}
|
||||
|
||||
@@ -170,6 +170,11 @@ public class ChannelModel implements IChannelEventBroadcaster, TableModel
|
||||
}
|
||||
|
||||
broadcast( new ChannelEvent( channel, Event.NOTIFICATION_ADD ) );
|
||||
|
||||
if( channel.getEnabled() )
|
||||
{
|
||||
broadcast( new ChannelEvent( channel, Event.REQUEST_ENABLE ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -140,6 +140,13 @@ public class ChannelProcessingManager implements ChannelEventListener
|
||||
stopProcessing( channel, true );
|
||||
}
|
||||
break;
|
||||
case NOTIFICATION_CONFIGURATION_CHANGE:
|
||||
if( isProcessing( channel ) )
|
||||
{
|
||||
stopProcessing( channel, false );
|
||||
startProcessing( channel );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* 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
|
||||
@@ -120,7 +120,7 @@ public class SDRTrunk
|
||||
|
||||
ChannelModel channelModel = new ChannelModel();
|
||||
|
||||
PlaylistManager playlistManager = new PlaylistManager( channelModel );
|
||||
PlaylistManager playlistManager = new PlaylistManager( threadPoolManager, channelModel );
|
||||
|
||||
RecorderManager recorderManager = new RecorderManager( threadPoolManager );
|
||||
|
||||
@@ -146,6 +146,9 @@ public class SDRTrunk
|
||||
new ChannelSelectionManager( channelModel );
|
||||
channelModel.addListener( channelSelectionManager );
|
||||
|
||||
//TODO: move this to the end once we add the alias model, otherwise the
|
||||
//configuration tree won't load correctly
|
||||
|
||||
//Initialize the playlist manager to load the saved playlist
|
||||
playlistManager.init();
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ import module.decode.config.DecodeConfiguration;
|
||||
import net.miginfocom.swing.MigLayout;
|
||||
import playlist.PlaylistManager;
|
||||
import source.IControllableFileSource;
|
||||
import controller.ThreadPoolManager;
|
||||
import controller.channel.ChannelModel;
|
||||
|
||||
public class DecoderSelectionFrame extends JInternalFrame
|
||||
@@ -29,7 +30,10 @@ public class DecoderSelectionFrame extends JInternalFrame
|
||||
IControllableFileSource source )
|
||||
{
|
||||
ChannelModel channelModel = new ChannelModel();
|
||||
mPlaylistManager = new PlaylistManager( channelModel );
|
||||
|
||||
ThreadPoolManager tpm = new ThreadPoolManager();
|
||||
|
||||
mPlaylistManager = new PlaylistManager( tpm, channelModel );
|
||||
|
||||
mDesktop = desktop;
|
||||
mSource = source;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*******************************************************************************
|
||||
* SDR Trunk
|
||||
* Copyright (C) 2014 Dennis Sheirer
|
||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
||||
*
|
||||
* 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
|
||||
@@ -25,6 +25,8 @@ import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.xml.bind.JAXBContext;
|
||||
import javax.xml.bind.JAXBException;
|
||||
@@ -39,8 +41,16 @@ import controller.channel.Channel;
|
||||
import controller.channel.ChannelModel;
|
||||
import controller.site.Site;
|
||||
import controller.system.SystemList;
|
||||
import controller.ThreadPoolManager;
|
||||
import controller.channel.Channel;
|
||||
import controller.channel.Channel.ChannelType;
|
||||
import controller.channel.ChannelEvent;
|
||||
import controller.channel.ChannelEventListener;
|
||||
import controller.channel.ChannelModel;
|
||||
import controller.site.Site;
|
||||
import controller.system.SystemList;
|
||||
|
||||
public class PlaylistManager
|
||||
public class PlaylistManager implements ChannelEventListener
|
||||
{
|
||||
private final static Logger mLog =
|
||||
LoggerFactory.getLogger( PlaylistManager.class );
|
||||
@@ -50,8 +60,31 @@ public class PlaylistManager
|
||||
private ChannelModel mChannelModel;
|
||||
|
||||
public PlaylistManager( ChannelModel channelModel )
|
||||
private ThreadPoolManager mThreadPoolManager;
|
||||
private ChannelModel mChannelModel;
|
||||
|
||||
private AtomicBoolean mPlaylistSavePending = new AtomicBoolean();
|
||||
private boolean mPlaylistLoading = false;
|
||||
|
||||
/**
|
||||
* Playlist manager - manages all channel configurationc, channel maps, and
|
||||
* alias lists and handles loading or persisting to a playlist.xml file
|
||||
*
|
||||
* Monitors playlist changes to automatically save configuration changes
|
||||
* after they occur.
|
||||
*
|
||||
* @param threadPoolManager
|
||||
* @param channelModel
|
||||
*/
|
||||
public PlaylistManager( ThreadPoolManager threadPoolManager,
|
||||
ChannelModel channelModel )
|
||||
{
|
||||
mThreadPoolManager = threadPoolManager;
|
||||
mChannelModel = channelModel;
|
||||
|
||||
//Register for channel events so that we can save the playlist when
|
||||
//any channels change
|
||||
mChannelModel.addListener( this );
|
||||
}
|
||||
|
||||
public Playlist getPlayist()
|
||||
@@ -64,8 +97,11 @@ public class PlaylistManager
|
||||
*/
|
||||
private void transferPlaylistToModels()
|
||||
{
|
||||
//Load channels
|
||||
mPlaylistLoading = true;
|
||||
|
||||
mChannelModel.addChannels( mPlaylist.getChannels() );
|
||||
|
||||
mPlaylistLoading = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +124,46 @@ public class PlaylistManager
|
||||
|
||||
transferPlaylistToModels();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Channel event listener method. Monitors channel events for events that
|
||||
* indicate that the playlist has changed and queues automatic playlist
|
||||
* saving.
|
||||
*/
|
||||
@Override
|
||||
public void channelChanged( ChannelEvent event )
|
||||
{
|
||||
//Only save playlist for changes to standard channels (not traffic)
|
||||
if( event.getChannel().getChannelType() == ChannelType.STANDARD )
|
||||
{
|
||||
switch( event.getEvent() )
|
||||
{
|
||||
case NOTIFICATION_ADD:
|
||||
case NOTIFICATION_CONFIGURATION_CHANGE:
|
||||
case NOTIFICATION_DELETE:
|
||||
case NOTIFICATION_PROCESSING_START:
|
||||
case NOTIFICATION_PROCESSING_STOP:
|
||||
schedulePlaylistSave();
|
||||
break;
|
||||
case NOTIFICATION_ENABLE_REJECTED:
|
||||
case NOTIFICATION_SELECTION_CHANGE:
|
||||
case NOTIFICATION_STATE_RESET:
|
||||
case REQUEST_DELETE:
|
||||
case REQUEST_DESELECT:
|
||||
case REQUEST_DISABLE:
|
||||
case REQUEST_ENABLE:
|
||||
case REQUEST_SELECT:
|
||||
//Do nothing for these event types
|
||||
break;
|
||||
default:
|
||||
//When a new event enum entry is added and received, throw an
|
||||
//exception here to ensure developer adds support for the
|
||||
//use case
|
||||
throw new IllegalArgumentException( "Unrecognized Channel "
|
||||
+ "Event [" + event.getEvent().name() + "]" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void save()
|
||||
{
|
||||
@@ -284,12 +359,87 @@ public class PlaylistManager
|
||||
}
|
||||
else
|
||||
{
|
||||
mLog.info( "playlist does not exist [" + playlistPath.toString() + "]" );
|
||||
mLog.info( "PlaylistManager - playlist not found at [" +
|
||||
playlistPath.toString() + "]" );
|
||||
}
|
||||
|
||||
if( mPlaylist == null )
|
||||
{
|
||||
mPlaylist = new Playlist();
|
||||
save();
|
||||
}
|
||||
|
||||
//Check for and convert from legacy play list format
|
||||
if( mPlaylist.hasSystemList() )
|
||||
{
|
||||
convertPlaylistFormat();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts playlist data over to new format
|
||||
*/
|
||||
private void convertPlaylistFormat()
|
||||
{
|
||||
mLog.info( "Legacy playlist format detected - converting ..." );
|
||||
|
||||
createBackupPlaylist();
|
||||
|
||||
//Playlist version 1 to version 2 format conversion. In order to keep
|
||||
//backwards compatibility, transfer all of the System-Site-Channel
|
||||
//objects over to the new channel list format
|
||||
SystemList systemList = mPlaylist.getSystemList();
|
||||
|
||||
for( controller.system.System system: systemList.getSystem() )
|
||||
{
|
||||
for( Site site: system.getSite() )
|
||||
{
|
||||
for( Channel channel: site.getChannel() )
|
||||
{
|
||||
channel.setSystem( system.getName() );
|
||||
channel.setSite( site.getName() );
|
||||
|
||||
mPlaylist.getChannels().add( channel );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mPlaylist.getSystemList().clearSystems();
|
||||
|
||||
mLog.info( "Converted [" + mPlaylist.getChannels().size() +
|
||||
"] channels to new playlist format" );
|
||||
|
||||
save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedules a playlist save task. Subsequent calls to this method will be
|
||||
* ignored until the save event occurs, thus limiting repetitive playlist
|
||||
* saving to a minimum.
|
||||
*/
|
||||
private void schedulePlaylistSave()
|
||||
{
|
||||
if( !mPlaylistLoading )
|
||||
{
|
||||
if( mPlaylistSavePending.compareAndSet( false, true ) )
|
||||
{
|
||||
mThreadPoolManager.scheduleOnce( new PlaylistSaveTask(),
|
||||
2, TimeUnit.SECONDS );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the playlist and resets the playlist save pending flag to false
|
||||
*/
|
||||
public class PlaylistSaveTask implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
save();
|
||||
|
||||
mPlaylistSavePending.set( false );
|
||||
}
|
||||
|
||||
//Check for and convert from legacy play list format
|
||||
|
||||
Reference in New Issue
Block a user