📄 mechsummarycache.java
字号:
/* * MegaMek - Copyright (C) 2000,2001,2002,2003,2004 Ben Mazur (bmazur@sev.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 of the License, 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. */package megamek.common;import java.io.BufferedReader;import java.io.File;import java.io.FileReader;import java.io.FileWriter;import java.util.ArrayList;import java.util.Enumeration;import java.util.Hashtable;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set;import java.util.Vector;import java.util.zip.ZipEntry;import java.util.zip.ZipFile;import megamek.common.loaders.EntityLoadingException;import megamek.common.preference.PreferenceManager;import megamek.common.verifier.EntityVerifier;import megamek.common.verifier.TestEntity;import megamek.common.verifier.TestMech;import megamek.common.verifier.TestTank;/** * Cache of the Mech summary information. * Implemented as Singleton so a client and server running in the same * process can share it */public class MechSummaryCache { public static interface Listener { void doneLoading(); } private static MechSummaryCache m_instance; private boolean initialized = false; private boolean initializing = false; private ArrayList listeners = new ArrayList(); private StringBuffer loadReport = new StringBuffer(); private final static String CONFIG_FILENAME = "data/mechfiles/UnitVerifierOptions.xml"; //should be a client option? private EntityVerifier entityVerifier = null; private Thread loader; public static synchronized MechSummaryCache getInstance() { if(m_instance == null) m_instance = new MechSummaryCache(); if (!m_instance.initialized && !m_instance.initializing) { m_instance.initializing = true; m_instance.loader = new Thread(new Runnable() { public void run() { m_instance.loadMechData(); } }, "Mech Cache Loader"); m_instance.loader.setPriority(Thread.NORM_PRIORITY - 1); m_instance.loader.start(); } return m_instance; } public static void dispose() { if(m_instance != null) { synchronized(m_instance) { m_instance.loader.interrupt(); m_instance = null; } } } public boolean isInitialized() { return initialized; } public void addListener(Listener listener) { synchronized (listeners) { listeners.add(listener); } } public void removeListener(Listener listener) { synchronized (listeners) { listeners.remove(listener); } } private MechSummary[] m_data; private Map m_nameMap; private Hashtable hFailedFiles; private int cacheCount; private int fileCount; private int zipCount; private static final char SEPARATOR = '|'; private static final File ROOT = new File(PreferenceManager.getClientPreferences().getMechDirectory()); private static final File CACHE = new File(ROOT, "units.cache"); private MechSummaryCache() { m_nameMap = new HashMap(); } public MechSummary[] getAllMechs() { block(); return m_data; } private void block() { if (!initialized) { synchronized (m_instance) { try { m_instance.wait(); } catch (Exception e) { } } } } public MechSummary getMech(String sRef) { block(); return (MechSummary) m_nameMap.get(sRef); } public Hashtable getFailedFiles() { block(); return hFailedFiles; } private void loadMechData() { Vector vMechs = new Vector(); Set sKnownFiles = new HashSet(); long lLastCheck = 0; entityVerifier = new EntityVerifier(new File(CONFIG_FILENAME)); hFailedFiles = new Hashtable(); EquipmentType.initializeTypes(); // load master equipment lists loadReport.append("\n"); loadReport.append("Reading unit files:\n"); // check the cache try { if (CACHE.exists() && CACHE.lastModified() >= megamek.MegaMek.TIMESTAMP) { loadReport.append(" Reading from unit cache file...\n"); lLastCheck = CACHE.lastModified(); BufferedReader br = new BufferedReader(new FileReader(CACHE)); String s; while ((s = br.readLine()) != null) { if(Thread.interrupted()) { done(); return; } MechSummary ms = new MechSummary(); // manually do a string tokenizer. Much faster int nIndex1 = s.indexOf(SEPARATOR); ms.setName(s.substring(0, nIndex1)); int nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setChassis(s.substring(nIndex1 + 1, nIndex2)); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setModel(s.substring(nIndex1 + 1, nIndex2)); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setUnitType(s.substring(nIndex1 + 1, nIndex2)); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setSourceFile(new File(s.substring(nIndex1 + 1, nIndex2))); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setEntryName(s.substring(nIndex1 + 1, nIndex2)); // have to translate "null" to null if (ms.getEntryName().equals("null")) { ms.setEntryName(null); } nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setYear(Integer.parseInt(s.substring(nIndex1 + 1, nIndex2))); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setType(Integer.parseInt(s.substring(nIndex1 + 1, nIndex2))); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setTons(Integer.parseInt(s.substring(nIndex1 + 1, nIndex2))); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 + 1); ms.setBV(Integer.parseInt(s.substring(nIndex1 + 1, nIndex2))); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 +1); ms.setLevel(s.substring(nIndex1 + 1, nIndex2)); nIndex1 = nIndex2; nIndex2 = s.indexOf(SEPARATOR, nIndex1 +1); ms.setCost(Integer.parseInt(s.substring(nIndex1 + 1,nIndex2))); ms.setCanon(s.substring(nIndex2+1).equals("T")? true : false); // Verify that this file still exists and is older than // the cache. File fSource = ms.getSourceFile(); if (fSource.exists() && fSource.lastModified() < lLastCheck) { vMechs.addElement(ms); sKnownFiles.add(ms.getSourceFile().toString()); cacheCount++; } } } } catch (Exception e) { loadReport.append(" Unable to load unit cache: ") .append(e.getMessage()).append("\n"); } // load any changes since the last check time boolean bNeedsUpdate = loadMechsFromDirectory(vMechs, sKnownFiles, lLastCheck, ROOT); // convert to array m_data = new MechSummary[vMechs.size()]; vMechs.copyInto(m_data); // store map references for (int x = 0; x < m_data.length; x++) { m_nameMap.put(m_data[x].getName(), m_data[x]); } // save updated cache back to disk if (bNeedsUpdate) { try { saveCache(); } catch (Exception e) { loadReport.append(" Unable to save mech cache\n"); } } loadReport.append(m_data.length).append(" units loaded.\n"); if (hFailedFiles.size() > 0) { loadReport.append(" ").append(hFailedFiles.size()) .append(" units failed to load...\n"); } /* Enumeration failedUnits = hFailedFiles.keys(); Enumeration failedUnitsDesc = hFailedFiles.elements(); while (failedUnits.hasMoreElements()) { loadReport.append(" ").append(failedUnits.nextElement()) .append("\n"); loadReport.append(" --") .append(failedUnitsDesc.nextElement()).append("\n"); } */ System.out.print(loadReport.toString());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -