1 /*
2  * Copyright (c) 2017 Helmut Neemann
3  * Use of this source code is governed by the GPL v3 license
4  * that can be found in the LICENSE file.
5  */
6 package de.neemann.digital.core.switching;
7 
8 import de.neemann.digital.core.*;
9 import de.neemann.digital.core.element.Element;
10 import de.neemann.digital.core.element.ElementAttributes;
11 import de.neemann.digital.core.element.ElementTypeDescription;
12 import de.neemann.digital.core.element.Keys;
13 import de.neemann.digital.core.stats.Countable;
14 
15 import static de.neemann.digital.core.element.PinInfo.input;
16 
17 /**
18  * A simple relay.
19  */
20 public class Relay extends Node implements Element, Countable {
21 
22     /**
23      * The relays description
24      */
25     public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Relay.class, input("in1"), input("in2"))
26             .addAttribute(Keys.ROTATE)
27             .addAttribute(Keys.MIRROR)
28             .addAttribute(Keys.BITS)
29             .addAttribute(Keys.LABEL)
30             .addAttribute(Keys.POLES)
31             .addAttribute(Keys.RELAY_NORMALLY_CLOSED);
32 
33     private final boolean invers;
34     private ObservableValue input1;
35     private ObservableValue input2;
36     private final Switch s;
37 
38     /**
39      * Create a new instance
40      *
41      * @param attr the attributes
42      */
Relay(ElementAttributes attr)43     public Relay(ElementAttributes attr) {
44         super(false);
45         invers = attr.get(Keys.RELAY_NORMALLY_CLOSED);
46         s = new Switch(attr, invers);
47     }
48 
49     @Override
setInputs(ObservableValues inputs)50     public void setInputs(ObservableValues inputs) throws NodeException {
51         input1 = inputs.get(0).checkBits(1, this).addObserverToValue(this);
52         input2 = inputs.get(1).checkBits(1, this).addObserverToValue(this);
53         s.setInputs(new ObservableValues(inputs, 2, inputs.size()));
54     }
55 
56     @Override
readInputs()57     public void readInputs() {
58         if (input1.isHighZ() || input2.isHighZ())
59             s.setClosed(invers);
60         else
61             s.setClosed((input1.getBool() ^ input2.getBool()) ^ invers);
62     }
63 
64     @Override
writeOutputs()65     public void writeOutputs() throws NodeException {
66     }
67 
68     @Override
getOutputs()69     public ObservableValues getOutputs() {
70         return s.getOutputs();
71     }
72 
73     @Override
init(Model model)74     public void init(Model model) {
75         s.init(model);
76     }
77 
78     /**
79      * @return the state of the relay
80      */
isClosed()81     public boolean isClosed() {
82         return s.isClosed();
83     }
84 
85     @Override
getDataBits()86     public int getDataBits() {
87         return s.getDataBits();
88     }
89 
90     @Override
getInputsCount()91     public int getInputsCount() {
92         return s.getInputsCount();
93     }
94 }
95