package com.lushprojects.circuitjs1.client;
import com.google.gwt.user.client.ui.Button;
public class CustomLogicElm extends ChipElm {
String modelName;
int postCount;
int inputCount, outputCount;
CustomLogicModel model;
boolean lastValues[];
boolean patternValues[];
static String lastModelName = "default";
public CustomLogicElm(int xx, int yy) {
super(xx, yy);
modelName = lastModelName;
setupPins();
}
public CustomLogicElm(int xa, int ya, int xb, int yb, int f,
StringTokenizer st) {
super(xa, ya, xb, yb, f, st);
modelName = st.nextToken();
updateModels();
int i;
for (i = 0; i != getPostCount(); i++) {
if (pins[i].output) {
volts[i] = new Double(st.nextToken()).doubleValue();
pins[i].value = volts[i] > 2.5;
}
}
}
String dump() {
String s = super.dump();
s += " " + modelName;
// the code to do this in ChipElm doesn't work here because we don't know
// how many pins to read until we read the model name! So we have to
// duplicate it here.
int i;
for (i = 0; i != getPostCount(); i++) {
if (pins[i].output)
s += " " + volts[i];
}
return s;
}
String dumpModel() {
if (model.dumped)
return "";
return model.dump();
}
public void updateModels() {
model = CustomLogicModel.getModelWithNameOrCopy(modelName, model);
setupPins();
allocNodes();
setPoints();
}
@Override
void setupPins() {
if (modelName == null) {
postCount = bits;
allocNodes();
return;
}
model = CustomLogicModel.getModelWithName(modelName);
inputCount = model.inputs.length;
outputCount = model.outputs.length;
sizeY = inputCount > outputCount ? inputCount : outputCount;
if (sizeY == 0)
sizeY = 1;
sizeX = 2;
postCount = inputCount+outputCount;
pins = new Pin[postCount];
int i;
for (i = 0; i != inputCount; i++) {
pins[i] = new Pin(i, SIDE_W, model.inputs[i]);
fixPinName(pins[i]);
}
for (i = 0; i != outputCount; i++) {
pins[i+inputCount] = new Pin(i, SIDE_E, model.outputs[i]);
pins[i+inputCount].output = true;
fixPinName(pins[i+inputCount]);
}
lastValues = new boolean[postCount];
patternValues = new boolean[26];
}
void fixPinName(Pin p) {
if (p.text.startsWith("/")) {
p.text = p.text.substring(1);
p.lineOver = true;
}
if (p.text.compareToIgnoreCase("clk") == 0) {
p.text = "";
p.clock = true;
}
}
int getPostCount() { return postCount; }
@Override
int getVoltageSourceCount() {
return outputCount;
}
void execute() {
int i;
for (i = 0; i != model.rulesLeft.size(); i++) {
// check for a match
String rl = model.rulesLeft.get(i);
int j;
for (j = 0; j != rl.length(); j++) {
char x = rl.charAt(j);
if (x == '0' || x == '1') {
if (pins[j].value == (x == '1'))
continue;
break;
}
// don't care
if (x == '?')
continue;
// up transition
if (x == '+') {
if (pins[j].value && !lastValues[j])
continue;
break;
}
// down transition
if (x == '-') {
if (!pins[j].value && lastValues[j])
continue;
break;
}
// save pattern values
if (x >= 'a' && x <= 'z') {
patternValues[x-'a'] = pins[j].value;
continue;
}
// compare pattern values
if (x >= 'A' && x <= 'z') {
if (patternValues[x-'A'] != pins[j].value)
break;
continue;
}
}
if (j != rl.length())
continue;
// success
String rr = model.rulesRight.get(i);
for (j = 0; j != rr.length(); j++) {
char x = rr.charAt(j);
if (x >= 'a' && x <= 'z')
pins[j+inputCount].value = patternValues[x-'a'];
else
pins[j+inputCount].value = (x == '1');
}
// save values for transition checking
for (j = 0; j != postCount; j++)
lastValues[j] = pins[j].value;
break;
}
}
public EditInfo getEditInfo(int n) {
if (n == 2) {
EditInfo ei = new EditInfo("Model Name", 0, -1, -1);
ei.text = modelName;
return ei;
}
if (n == 3) {
EditInfo ei = new EditInfo("", 0, -1, -1);
ei.button = new Button("Edit Model");
return ei;
}
return super.getEditInfo(n);
}
public void setEditValue(int n, EditInfo ei) {
if (n == 2) {
modelName = lastModelName = ei.textf.getText();
model = CustomLogicModel.getModelWithNameOrCopy(modelName, model);
setupPins();
allocNodes();
setPoints();
return;
}
if (n == 3)
{
EditDialog editDialog = new EditDialog(model, sim);
CirSim.customLogicEditDialog = editDialog;
editDialog.show();
return;
}
super.setEditValue(n, ei);
}
int getDumpType() { return 208; }
void getInfo(String arr[]) {
super.getInfo(arr);
arr[0] = model.infoText;
}
}