From e25799a78ef95ad8b7df50c6d503281f04a81bbd Mon Sep 17 00:00:00 2001 From: Vhati Date: Fri, 22 Nov 2013 00:15:24 -0500 Subject: [PATCH] Refactored modorder as modsTableState --- .../net/vhati/modmanager/ui/ManagerFrame.java | 85 +++++++++++-------- .../modmanager/ui/ManagerInitThread.java | 33 ++++--- .../vhati/modmanager/ui/table/ListState.java | 39 +++++++++ 3 files changed, 110 insertions(+), 47 deletions(-) create mode 100644 src/main/java/net/vhati/modmanager/ui/table/ListState.java diff --git a/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java b/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java index 1e1e8e0..0745f8e 100644 --- a/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java +++ b/src/main/java/net/vhati/modmanager/ui/ManagerFrame.java @@ -79,6 +79,7 @@ import net.vhati.modmanager.ui.SlipstreamConfigDialog; import net.vhati.modmanager.ui.Statusbar; import net.vhati.modmanager.ui.StatusbarMouseListener; import net.vhati.modmanager.ui.table.ChecklistTablePanel; +import net.vhati.modmanager.ui.table.ListState; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -94,7 +95,7 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse private File backupDir = new File( "./backup/" ); private File modsDir = new File( "./mods/" ); - private File modorderFile = new File( modsDir, "modorder.txt" ); + private File modsTableStateFile = new File( modsDir, "modorder.txt" ); private File metadataFile = new File( backupDir, "cached_metadata.json" ); @@ -260,8 +261,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse public void windowClosed( WindowEvent e ) { // dispose() was called. - List sortedMods = modsTablePanel.getAllItems(); - saveModOrder( sortedMods ); + ListState tableState = getCurrentModsTableState(); + saveModsTableState( tableState ); SlipstreamConfig appConfig = ManagerFrame.this.appConfig; @@ -395,7 +396,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse ManagerInitThread initThread = new ManagerInitThread( this, new SlipstreamConfig( appConfig ), - modorderFile, + modsDir, + modsTableStateFile, metadataFile, catalogFile, catalogETagFile, @@ -409,48 +411,60 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse /** - * Returns a mod list with names sorted in a preferred order. - * - * Mods not mentioned in the name list appear at the end, alphabetically. + * Returns a ListState describing content in the mods table. */ - private List reorderMods( List unsortedMods, List preferredOrder ) { - List sortedMods = new ArrayList(); + public ListState getCurrentModsTableState() { + ListState tableState = new ListState(); + + for ( ModFileInfo modFileInfo : modsTablePanel.getAllItems() ) { + tableState.addItem( modFileInfo ); + } + + return tableState; + } + + /** + * Synchronizes a mods table state with a pool of available items. + * + * Items in the table that also are in the pool are unchanged. + * Items in the table that aren't in the pool are pruned. + * Items in the pool that weren't in the table are appended in ascending + * order. + * + * @param tableState an existing state to amend + * @param unsortedMods the pool of currently available local mods + */ + public void amendModsTableState( ListState tableState, List unsortedMods ) { List availableMods = new ArrayList( unsortedMods ); Collections.sort( availableMods ); - if ( preferredOrder != null ) { - for ( String name : preferredOrder ) { - Iterator it = availableMods.iterator(); - while ( it.hasNext() ) { - ModFileInfo modFileInfo = it.next(); - if ( modFileInfo.getName().equals( name ) ) { - it.remove(); - sortedMods.add( modFileInfo ); - break; - } - } + for ( ModFileInfo modFileInfo : availableMods ) { + if ( !tableState.containsItem( modFileInfo ) ) { + tableState.addItem( modFileInfo ); + } + } + for ( ModFileInfo modFileInfo : tableState.getItems() ) { + if ( !availableMods.contains( modFileInfo ) ) { + tableState.removeItem( modFileInfo ); } } - sortedMods.addAll( availableMods ); - - return sortedMods; } - private void saveModOrder( List sortedMods ) { + private void saveModsTableState( ListState tableState ) { BufferedWriter bw = null; try { - FileOutputStream os = new FileOutputStream( modorderFile ); + FileOutputStream os = new FileOutputStream( modsTableStateFile ); bw = new BufferedWriter(new OutputStreamWriter( os, Charset.forName("UTF-8") )); - for ( ModFileInfo modFileInfo : sortedMods ) { + for ( ModFileInfo modFileInfo : tableState.getItems() ) { bw.write( modFileInfo.getName() ); bw.write( "\r\n" ); } bw.flush(); } catch ( IOException e ) { - log.error( String.format( "Error writing \"%s\".", modorderFile.getName() ), e ); + log.error( String.format( "Error writing \"%s\".", modsTableStateFile.getName() ), e ); } finally { try {if (bw != null) bw.close();} @@ -460,9 +474,10 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse /** - * Clears and syncs the mods list with mods/ dir, then starts a new hash thread. + * Clears and syncs the mods list with mods/ dir, then starts a new hash + * thread. */ - public void rescanMods( List preferredOrder ) { + public void rescanMods( ListState tableState ) { managerLock.lock(); try { scanning = true; @@ -484,9 +499,9 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse ModFileInfo modFileInfo = new ModFileInfo( f ); unsortedMods.add( modFileInfo ); } + amendModsTableState( tableState, unsortedMods ); - List sortedMods = reorderMods( unsortedMods, preferredOrder ); - for ( ModFileInfo modFileInfo : sortedMods ) { + for ( ModFileInfo modFileInfo : tableState.getItems() ) { modsTablePanel.getTableModel().addItem( modFileInfo ); } @@ -732,12 +747,8 @@ public class ManagerFrame extends JFrame implements ActionListener, ModsScanObse setStatusText( "" ); if ( rescanMenuItem.isEnabled() == false ) return; - List preferredOrder = new ArrayList(); - - for ( ModFileInfo modFileInfo : modsTablePanel.getAllItems() ) { - preferredOrder.add( modFileInfo.getName() ); - } - rescanMods( preferredOrder ); + ListState tableState = getCurrentModsTableState(); + rescanMods( tableState ); } else if ( source == extractDatsMenuItem ) { setStatusText( "" ); diff --git a/src/main/java/net/vhati/modmanager/ui/ManagerInitThread.java b/src/main/java/net/vhati/modmanager/ui/ManagerInitThread.java index 5974af0..7126b1d 100644 --- a/src/main/java/net/vhati/modmanager/ui/ManagerInitThread.java +++ b/src/main/java/net/vhati/modmanager/ui/ManagerInitThread.java @@ -17,11 +17,13 @@ import javax.swing.SwingUtilities; import net.vhati.modmanager.core.AutoUpdateInfo; import net.vhati.modmanager.core.ModDB; +import net.vhati.modmanager.core.ModFileInfo; import net.vhati.modmanager.core.SlipstreamConfig; import net.vhati.modmanager.json.JacksonAutoUpdateReader; import net.vhati.modmanager.json.JacksonCatalogReader; import net.vhati.modmanager.json.URLFetcher; import net.vhati.modmanager.ui.ManagerFrame; +import net.vhati.modmanager.ui.table.ListState; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -41,7 +43,8 @@ public class ManagerInitThread extends Thread { private final ManagerFrame frame; private final SlipstreamConfig appConfig; - private final File modorderFile; + private final File modsDir; + private final File modsTableStateFile; private final File metadataFile; private final File catalogFile; private final File catalogETagFile; @@ -49,10 +52,11 @@ public class ManagerInitThread extends Thread { private final File appUpdateETagFile; - public ManagerInitThread( ManagerFrame frame, SlipstreamConfig appConfig, File modorderFile, File metadataFile, File catalogFile, File catalogETagFile, File appUpdateFile, File appUpdateETagFile ) { + public ManagerInitThread( ManagerFrame frame, SlipstreamConfig appConfig, File modsDir, File modsTableStateFile, File metadataFile, File catalogFile, File catalogETagFile, File appUpdateFile, File appUpdateETagFile ) { this.frame = frame; this.appConfig = appConfig; - this.modorderFile = modorderFile; + this.modsDir = modsDir; + this.modsTableStateFile = modsTableStateFile; this.metadataFile = metadataFile; this.catalogFile = catalogFile; this.catalogETagFile = catalogETagFile; @@ -79,14 +83,14 @@ public class ManagerInitThread extends Thread { if ( cachedDB != null ) frame.setLocalModDB( cachedDB ); } - final List preferredOrder = loadModOrder(); + final ListState tableState = loadModsTableState(); Lock managerLock = frame.getLock(); managerLock.lock(); try { SwingUtilities.invokeLater(new Runnable() { @Override - public void run() { frame.rescanMods( preferredOrder ); } + public void run() { frame.rescanMods( tableState ); } }); // Wait until notified that "mods/" has been scanned. @@ -167,28 +171,37 @@ public class ManagerInitThread extends Thread { /** * Reads modorder.txt and returns a list of mod names in preferred order. */ - private List loadModOrder() { - List result = new ArrayList(); + private ListState loadModsTableState() { + List fileNames = new ArrayList(); BufferedReader br = null; try { - FileInputStream is = new FileInputStream( modorderFile ); + FileInputStream is = new FileInputStream( modsTableStateFile ); br = new BufferedReader(new InputStreamReader( is, Charset.forName("UTF-8") )); String line; while ( (line = br.readLine()) != null ) { - result.add( line ); + fileNames.add( line ); } } catch ( FileNotFoundException e ) { } catch ( IOException e ) { - log.error( String.format( "Error reading \"%s\".", modorderFile.getName() ), e ); + log.error( String.format( "Error reading \"%s\".", modsTableStateFile.getName() ), e ); + fileNames.clear(); } finally { try {if ( br != null ) br.close();} catch ( Exception e ) {} } + ListState result = new ListState(); + + for ( String fileName : fileNames ) { + File modFile = new File( modsDir, fileName ); + ModFileInfo modFileInfo = new ModFileInfo( modFile ); + result.addItem( modFileInfo ); + } + return result; } diff --git a/src/main/java/net/vhati/modmanager/ui/table/ListState.java b/src/main/java/net/vhati/modmanager/ui/table/ListState.java new file mode 100644 index 0000000..916fd55 --- /dev/null +++ b/src/main/java/net/vhati/modmanager/ui/table/ListState.java @@ -0,0 +1,39 @@ +package net.vhati.modmanager.ui.table; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + + +/** + * An implementation-agnostic model to pass between the GUI thread and the + * (de)serializer. + */ +public class ListState { + + protected List items = new ArrayList(); + + + public ListState() { + } + + + public void addItem( T item ) { + items.add( item ); + } + + /** + * Returns a new list containing items in this state. + */ + public List getItems() { + return new ArrayList( items ); + } + + public void removeItem( T item ) { + items.remove( item ); + } + + public boolean containsItem( T item ) { + return items.contains( item ); + } +}