/******************************************************************************* * This file is part of logisim-evolution. * * logisim-evolution 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 3 of the License, or * (at your option) any later version. * * logisim-evolution 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. * * You should have received a copy of the GNU General Public License * along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>. * * Original code by Carl Burch (http://www.cburch.com), 2011. * Subsequent modifications by : * + Haute École Spécialisée Bernoise * http://www.bfh.ch * + Haute École du paysage, d'ingénierie et d'architecture de Genève * http://hepia.hesge.ch/ * + Haute École d'Ingénierie et de Gestion du Canton de Vaud * http://www.heig-vd.ch/ * The project is currently maintained by : * + REDS Institute - HEIG-VD * Yverdon-les-Bains, Switzerland * http://reds.heig-vd.ch *******************************************************************************/ package com.cburch.logisim.proj; import com.cburch.logisim.circuit.Circuit; import com.cburch.logisim.circuit.CircuitEvent; import com.cburch.logisim.circuit.CircuitListener; import com.cburch.logisim.circuit.SubcircuitFactory; import com.cburch.logisim.comp.Component; import com.cburch.logisim.comp.ComponentFactory; import com.cburch.logisim.file.LibraryEvent; import com.cburch.logisim.file.LibraryListener; import com.cburch.logisim.file.LogisimFile; import com.cburch.logisim.tools.AddTool; import com.cburch.logisim.util.Dag; public class Dependencies { private class MyListener implements LibraryListener, CircuitListener { public void circuitChanged(CircuitEvent e) { Component comp; switch (e.getAction()) { case CircuitEvent.ACTION_ADD: comp = (Component) e.getData(); if (comp.getFactory() instanceof SubcircuitFactory) { SubcircuitFactory factory = (SubcircuitFactory) comp .getFactory(); depends.addEdge(e.getCircuit(), factory.getSubcircuit()); } break; case CircuitEvent.ACTION_REMOVE: comp = (Component) e.getData(); if (comp.getFactory() instanceof SubcircuitFactory) { SubcircuitFactory factory = (SubcircuitFactory) comp .getFactory(); boolean found = false; for (Component o : e.getCircuit().getNonWires()) { if (o.getFactory() == factory) { found = true; break; } } if (!found) depends.removeEdge(e.getCircuit(), factory.getSubcircuit()); } break; case CircuitEvent.ACTION_CLEAR: depends.removeNode(e.getCircuit()); break; } } public void libraryChanged(LibraryEvent e) { switch (e.getAction()) { case LibraryEvent.ADD_TOOL: if (e.getData() instanceof AddTool) { ComponentFactory factory = ((AddTool) e.getData()) .getFactory(); if (factory instanceof SubcircuitFactory) { SubcircuitFactory circFact = (SubcircuitFactory) factory; processCircuit(circFact.getSubcircuit()); } } break; case LibraryEvent.REMOVE_TOOL: if (e.getData() instanceof AddTool) { ComponentFactory factory = ((AddTool) e.getData()) .getFactory(); if (factory instanceof SubcircuitFactory) { SubcircuitFactory circFact = (SubcircuitFactory) factory; Circuit circ = circFact.getSubcircuit(); depends.removeNode(circ); circ.removeCircuitListener(this); } } break; } } } private MyListener myListener = new MyListener(); private Dag depends = new Dag(); Dependencies(LogisimFile file) { addDependencies(file); } private void addDependencies(LogisimFile file) { file.addLibraryListener(myListener); for (Circuit circuit : file.getCircuits()) { processCircuit(circuit); } } public boolean canAdd(Circuit circ, Circuit sub) { return depends.canFollow(sub, circ); } public boolean canRemove(Circuit circ) { return !depends.hasPredecessors(circ); } private void processCircuit(Circuit circ) { circ.addCircuitListener(myListener); for (Component comp : circ.getNonWires()) { if (comp.getFactory() instanceof SubcircuitFactory) { SubcircuitFactory factory = (SubcircuitFactory) comp .getFactory(); depends.addEdge(circ, factory.getSubcircuit()); } } } }