Skip to content

Commit

Permalink
New way of generating a LogicSystem from the SchemaModel. Much cleane…
Browse files Browse the repository at this point in the history
…r, I don't hate it. Committing here before I try and plumb it in, which will be messy.
  • Loading branch information
Joe-Jones committed Nov 23, 2014
1 parent b9b67f3 commit 3dc88fb
Show file tree
Hide file tree
Showing 6 changed files with 217 additions and 1 deletion.
120 changes: 120 additions & 0 deletions LogicSystem.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,123 @@ LogicSystem.prototype.addConectionMaker = function(ti, o, f) {
ti["outputs"][o][3].push(f);
};

function copyInto(source, destination) {
var node_map = {};
jsnx.forEach(source.nodes_iter(), function(node) {
var id = _.uniqueId();
var node_attrs = source.node.get(node);
if (node_attrs.type && _.contains(["INPUT", "OUTPUT"], node_attrs.type)) {
node_attrs.from_subcircuit = true;
}
destination.add_node(id, node_attrs);
node_map[node] = id;
});
jsnx.forEach(source.edges_iter(), function(edge) {
destination.add_edge(node_map[edge[0]], node_map[edge[1]], edge[2]);
});
}

function mergeNodes(graph, keep, go_away) {
jsnx.forEach(graph.in_edges(go_away).concat(graph.out_edges(go_away)), function(edge) {
var edge_attrs = graph.get_edge_data(edge[0], edge[1]);
if (edge[0] == go_away) {
graph.add_edge(keep, edge[1], edge_attrs);
} else {
graph.add_edge(edge[0], keep, edge_attrs);
}
});
graph.remove_node(go_away);
}

/*
node is a node in subcircuit. Returns a new graph the same as circuit but with node replaced by subcircuit.
This makes the assumption that subcircuit is the correct circuit to be replacing node. There is no sanity checking,
just pass it the right thing.
*/

function replaceNode(circuit, subcircuit, node_to_replace) {
copyInto(subcircuit, circuit);
jsnx.forEach(circuit.nodes(), function(node) {
if (circuit.has_node(node)) {
var node_attrs = circuit.node.get(node);
if (node_attrs.type && _.contains(["INPUT", "OUTPUT"], node_attrs.type) && node_attrs.from_subcircuit) {
// This is an input/output we need to get rid of.
var marked_connection; // The connection node that is going to go away
var connections; // The one we're keeping is in here
if (node_attrs.type == "INPUT") {
marked_connection = circuit.successors(node)[0];
connections = circuit.in_edges_iter(node_to_replace)
} else {
marked_connection = circuit.predecessors(node)[0];
connections = circuit.out_edges_iter(node_to_replace)
}
var connection; // The one we're going to keep.
jsnx.forEach(connections, function(edge) {
var edge_attrs = circuit.get_edge_data(edge[0], edge[1]);
if (edge_attrs.connect_to == node_attrs.connection_number) {
connection = (node_attrs.type == "INPUT" ? edge[0] : edge[1]);
}
})
if (marked_connection && connection) {
mergeNodes(circuit, connection, marked_connection);
}
circuit.remove_node(node);
}
}
});
circuit.remove_node(node_to_replace);
}

function replaceAllSubCircuits(circuit, project) {
var new_circuit = new jsnx.DiGraph(circuit);
_.each(new_circuit.nodes(), function(node) {
var node_attrs = new_circuit.node.get(node);
if (node_attrs.type == "SUBCIRCIT") {
replaceNode(new_circuit, project.getFlatGraph(node_attrs.schema_id), node);
}
});
return new_circuit;
}

function buildLogicSystem(graph, schema_model) {
var logic_system = new LogicSystem();
var inputs = [];
var outputs = [];
var logic_ids = {};
var connection_nodes = [];
jsnx.forEach(graph.nodes_iter(), function(node) {
var node_attrs = graph.node.get(node);
if (node_attrs.type) {
logic_ids[node] = logic_system.addGate(node_attrs.type);
if (node_attrs.type == "SWITCH") {
inputs.push[node];
} else if (node_attrs.type == "BULB") {
outputs.push[node];
}
} else {
connection_nodes.push(node);
}
});
_.each(connection_nodes, function(connection) {
var from = graph.predecessors(connection)[0];
jsnx.forEach(graph.successors_iter(connection), function(node) {
var edge_attrs = graph.get_edge_data(connection, node);
logic_system.makeConnection(logic_ids[from], logic_ids[node], edge_attrs.connect_to);
});
});
_.each(inputs, function(node) {
var object = schema_model.getObjectByNumber(node);
if (object) {
logic_system.setOutput(logic_ids, object.getState());
}
});
_.each(outputs, function(node) {
var object = schema_model.getObjectByNumber(node);
if (object) {
logic_system.registerCallback(logic_ids[node], function (new_state) {
object.setState(new_state);
});
}
});
}

10 changes: 10 additions & 0 deletions Project.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,14 @@ Project.prototype = {
isComponent: function(schema_id) {
var schema_info = this.getSchemaInfo(schema_id);
return (schema_info.inputs.length > 0 || schema_info.outputs.length > 0);
},

getGraph: function(schema_id) {
return this.schemas[schema_id].asGraph();
},

getFlatGraph: function(schema_id) {
return replaceAllSubCircuits(this.getGraph(schema_id), this);
}

};
Expand Down Expand Up @@ -580,12 +588,14 @@ Action.prototype = {
name: "i_" + model.project.schema_infos[this.schema_id]["input_counter"],
number: object.logic_id})
model.project.schema_infos[this.schema_id]["input_counter"]++;
object.connection_number = model.project.schema_infos[this.schema_id]["inputs"].length - 1;
}
if (this.gate_type == "OUTPUT") {
model.project.schema_infos[this.schema_id]["outputs"].push({
name: "0_" + model.project.schema_infos[this.schema_id]["output_counter"],
number: object.logic_id})
model.project.schema_infos[this.schema_id]["output_counter"]++;
object.connection_number = model.project.schema_infos[this.schema_id]["outputs"].length - 1;
}
model.trigger("gateAdded", object.number);
break;
Expand Down
33 changes: 33 additions & 0 deletions SchemaModel.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,3 +331,36 @@ SchemaModel.prototype.checkAndRebuild = function() {
this.rebuildLogicSystem();
}
};

SchemaModel.prototype.asGraph = function() {
var graph = new jsnx.DiGraph();

_.each(this.objects, function(object) {
// Add object to the graph.
var attrs = { type: object.type };
if (object.type == "SUBCIRCIT") {
attrs.schema_id = object.schema_id;
} else if (_.contains(["INPUT", "OUTPUT"], object.type)) {
attrs.connection_number = object.connection_number;
}
graph.add_node(object.number, attrs);

// Add the connections.
_.each(object.output_connections, function(output) {
var connection_node = _.uniqueId();
_.each(output, function(connection) {
// Gather the information we need to create the connection.
var source_node = object.number;
var source_label = connection.output_num;
var dest_node = connection.input_item.number;
var dest_label = connection.input_num;

// Add the connection.
graph.add_edge(source_node, connection_node, { connect_to: source_label });
graph.add_edge(connection_node, dest_node, { connect_to: dest_label });
}, this);
}, this);
}, this);

return graph;
};
2 changes: 2 additions & 0 deletions logic.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/sylvester/0.1.3/sylvester.js"></script>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="jsnetworkx-drawing.js"></script>
<script src="w2ui.js"></script>
<script src="jake-kit.js"></script>
<script src="database.js"></script>
Expand Down
Loading

0 comments on commit 3dc88fb

Please sign in to comment.