Package com.cburch.logisim.std.wiring

Source Code of com.cburch.logisim.std.wiring.Constant$ConstantExpression

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.std.wiring;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import com.cburch.logisim.analyze.model.Expression;
import com.cburch.logisim.analyze.model.Expressions;
import com.cburch.logisim.circuit.ExpressionComputer;
import com.cburch.logisim.data.AbstractAttributeSet;
import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.AttributeSet;
import com.cburch.logisim.data.Attributes;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.data.Direction;
import com.cburch.logisim.data.Location;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.instance.Instance;
import com.cburch.logisim.instance.InstanceFactory;
import com.cburch.logisim.instance.InstancePainter;
import com.cburch.logisim.instance.InstanceState;
import com.cburch.logisim.instance.Port;
import com.cburch.logisim.instance.StdAttr;
import com.cburch.logisim.tools.key.BitWidthConfigurator;
import com.cburch.logisim.tools.key.JoinedConfigurator;
import com.cburch.logisim.util.GraphicsUtil;

public class Constant extends InstanceFactory {
  public static final Attribute<Integer> ATTR_VALUE
    = Attributes.forHexInteger("value", Strings.getter("constantValueAttr"));

  public static InstanceFactory FACTORY = new Constant();

  private static final Color BACKGROUND_COLOR = new Color(230, 230, 230);
 
  private static final List<Attribute<?>> ATTRIBUTES
    = Arrays.asList(new Attribute<?>[] {
        StdAttr.FACING, StdAttr.WIDTH, ATTR_VALUE
    });
 
  private static class ConstantAttributes extends AbstractAttributeSet {
    private Direction facing = Direction.EAST;;
    private BitWidth width = BitWidth.ONE;
    private Value value = Value.TRUE;

    @Override
    protected void copyInto(AbstractAttributeSet destObj) {
      ConstantAttributes dest = (ConstantAttributes) destObj;
      dest.facing = this.facing;
      dest.width = this.width;
      dest.value = this.value;
    }

    @Override
    public List<Attribute<?>> getAttributes() {
      return ATTRIBUTES;
    }

    @Override
    @SuppressWarnings("unchecked")
    public <V> V getValue(Attribute<V> attr) {
      if (attr == StdAttr.FACING) return (V) facing;
      if (attr == StdAttr.WIDTH) return (V) width;
      if (attr == ATTR_VALUE) return (V) Integer.valueOf(value.toIntValue());
      return null;
    }

    @Override
    public <V> void setValue(Attribute<V> attr, V value) {
      if (attr == StdAttr.FACING) {
        facing = (Direction) value;
      } else if (attr == StdAttr.WIDTH) {
        width = (BitWidth) value;
        this.value = this.value.extendWidth(width.getWidth(),
            this.value.get(this.value.getWidth() - 1));
      } else if (attr == ATTR_VALUE) {
        int val = ((Integer) value).intValue();
        this.value = Value.createKnown(width, val);
      } else {
        throw new IllegalArgumentException("unknown attribute " + attr);
      }
      fireAttributeValueChanged(attr, value);
    }      
  }
 
  private static class ConstantExpression implements ExpressionComputer {
    private Instance instance;
   
    public ConstantExpression(Instance instance) {
      this.instance = instance;
    }
   
    public void computeExpression(Map<Location,Expression> expressionMap) {
      AttributeSet attrs = instance.getAttributeSet();
      int intValue = attrs.getValue(ATTR_VALUE).intValue();

      expressionMap.put(instance.getLocation(),
          Expressions.constant(intValue));
    }
  }
 
  public Constant() {
    super("Constant", Strings.getter("constantComponent"));
    setFacingAttribute(StdAttr.FACING);
    setKeyConfigurator(JoinedConfigurator.create(
        new ConstantConfigurator(),
        new BitWidthConfigurator(StdAttr.WIDTH)));
  }

  @Override
  public AttributeSet createAttributeSet() {
    return new ConstantAttributes();
  }

  @Override
  protected void configureNewInstance(Instance instance) {
    instance.addAttributeListener();
    updatePorts(instance);
  }
 
  private void updatePorts(Instance instance) {
    Port[] ps = { new Port(0, 0, Port.OUTPUT, StdAttr.WIDTH) };
    instance.setPorts(ps);
  }

  @Override
  protected void instanceAttributeChanged(Instance instance, Attribute<?> attr) {
    if (attr == StdAttr.WIDTH) {
      instance.recomputeBounds();
      updatePorts(instance);
    } else if (attr == StdAttr.FACING) {
      instance.recomputeBounds();
    } else if (attr == ATTR_VALUE) {
      instance.fireInvalidated();
    }
  }
 
  @Override
  protected Object getInstanceFeature(Instance instance, Object key) {
    if (key == ExpressionComputer.class) return new ConstantExpression(instance);
    return super.getInstanceFeature(instance, key);
  }

  @Override
  public void propagate(InstanceState state) {
    BitWidth width = state.getAttributeValue(StdAttr.WIDTH);
    int value = state.getAttributeValue(ATTR_VALUE).intValue();
    state.setPort(0, Value.createKnown(width, value), 1);
  }

  @Override
  public Bounds getOffsetBounds(AttributeSet attrs) {
    Direction facing = attrs.getValue(StdAttr.FACING);
    BitWidth width = attrs.getValue(StdAttr.WIDTH);
    int chars = (width.getWidth() + 3) / 4;

    Bounds ret = null;
    if (facing == Direction.EAST) {
      switch (chars) {
      case 1: ret = Bounds.create(-16, -8, 16, 16); break;
      case 2: ret = Bounds.create(-16, -8, 16, 16); break;
      case 3: ret = Bounds.create(-26, -8, 26, 16); break;
      case 4: ret = Bounds.create(-36, -8, 36, 16); break;
      case 5: ret = Bounds.create(-46, -8, 46, 16); break;
      case 6: ret = Bounds.create(-56, -8, 56, 16); break;
      case 7: ret = Bounds.create(-66, -8, 66, 16); break;
      case 8: ret = Bounds.create(-76, -8, 76, 16); break;
      }
    } else if (facing == Direction.WEST) {
      switch (chars) {
      case 1: ret = Bounds.create0, -8, 16, 16); break;
      case 2: ret = Bounds.create0, -8, 16, 16); break;
      case 3: ret = Bounds.create0, -8, 26, 16); break;
      case 4: ret = Bounds.create0, -8, 36, 16); break;
      case 5: ret = Bounds.create0, -8, 46, 16); break;
      case 6: ret = Bounds.create0, -8, 56, 16); break;
      case 7: ret = Bounds.create0, -8, 66, 16); break;
      case 8: ret = Bounds.create0, -8, 76, 16); break;
      }
    } else if (facing == Direction.SOUTH) {
      switch (chars) {
      case 1: ret = Bounds.create(-8, -16, 16, 16); break;
      case 2: ret = Bounds.create(-8, -16, 16, 16); break;
      case 3: ret = Bounds.create(-13, -16, 26, 16); break;
      case 4: ret = Bounds.create(-18, -16, 36, 16); break;
      case 5: ret = Bounds.create(-23, -16, 46, 16); break;
      case 6: ret = Bounds.create(-28, -16, 56, 16); break;
      case 7: ret = Bounds.create(-33, -16, 66, 16); break;
      case 8: ret = Bounds.create(-38, -16, 76, 16); break;
      }
    } else if (facing == Direction.NORTH) {
      switch (chars) {
      case 1: ret = Bounds.create(-8,   0, 16, 16); break;
      case 2: ret = Bounds.create(-8,   0, 16, 16); break;
      case 3: ret = Bounds.create(-13,   0, 26, 16); break;
      case 4: ret = Bounds.create(-18,   0, 36, 16); break;
      case 5: ret = Bounds.create(-23,   0, 46, 16); break;
      case 6: ret = Bounds.create(-28,   0, 56, 16); break;
      case 7: ret = Bounds.create(-33,   0, 66, 16); break;
      case 8: ret = Bounds.create(-38,   0, 76, 16); break;
      }
    }
    if (ret == null) {
      throw new IllegalArgumentException("unrecognized arguments " + facing + " " + width);
    }
    return ret;
  }

  //
  // painting methods
  //
  @Override
  public void paintIcon(InstancePainter painter) {
    int w = painter.getAttributeValue(StdAttr.WIDTH).getWidth();
    int pinx = 16; int piny = 9;
    Direction dir = painter.getAttributeValue(StdAttr.FACING);
    if (dir == Direction.EAST) { } // keep defaults
    else if (dir == Direction.WEST) { pinx = 4; }
    else if (dir == Direction.NORTH) { pinx = 9; piny = 4; }
    else if (dir == Direction.SOUTH) { pinx = 9; piny = 16; }

    Graphics g = painter.getGraphics();
    if (w == 1) {
      int v = painter.getAttributeValue(ATTR_VALUE).intValue();
      Value val = v == 1 ? Value.TRUE : Value.FALSE;
      g.setColor(val.getColor());
      GraphicsUtil.drawCenteredText(g, "" + v, 10, 9);
    } else {
      g.setFont(g.getFont().deriveFont(9.0f));
      GraphicsUtil.drawCenteredText(g, "x" + w, 10, 9);
    }
    g.fillOval(pinx, piny, 3, 3);
  }

  @Override
  public void paintGhost(InstancePainter painter) {
    int v = painter.getAttributeValue(ATTR_VALUE).intValue();
    String vStr = Integer.toHexString(v);
    Bounds bds = getOffsetBounds(painter.getAttributeSet());

    Graphics g = painter.getGraphics();
    GraphicsUtil.switchToWidth(g, 2);
    g.fillOval(-2, -2, 5, 5);
    GraphicsUtil.drawCenteredText(g, vStr, bds.getX() + bds.getWidth() / 2,
        bds.getY() + bds.getHeight() / 2);
  }
 
  @Override
  public void paintInstance(InstancePainter painter) {
    Bounds bds = painter.getOffsetBounds();
    BitWidth width = painter.getAttributeValue(StdAttr.WIDTH);
    int intValue = painter.getAttributeValue(ATTR_VALUE).intValue();
    Value v = Value.createKnown(width, intValue);
    Location loc = painter.getLocation();
    int x = loc.getX();
    int y = loc.getY();

    Graphics g = painter.getGraphics();
    if (painter.shouldDrawColor()) {
      g.setColor(BACKGROUND_COLOR);
      g.fillRect(x + bds.getX(), y + bds.getY(), bds.getWidth(), bds.getHeight());
    }
    if (v.getWidth() == 1) {
      if (painter.shouldDrawColor()) g.setColor(v.getColor());
      GraphicsUtil.drawCenteredText(g, v.toString(),
        x + bds.getX() + bds.getWidth() / 2,
        y + bds.getY() + bds.getHeight() / 2 - 2);
    } else {
      g.setColor(Color.BLACK);
      GraphicsUtil.drawCenteredText(g, v.toHexString(),
        x + bds.getX() + bds.getWidth() / 2,
        y + bds.getY() + bds.getHeight() / 2 - 2);
    }
    painter.drawPorts();
  }

  //TODO: Allow editing of value via text tool/attribute table
}
TOP

Related Classes of com.cburch.logisim.std.wiring.Constant$ConstantExpression

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.