001package jmri.jmrix.can.cbus.node; 002 003import java.util.Arrays; 004import java.util.Objects; 005import jmri.util.StringUtil; 006 007import org.slf4j.Logger; 008import org.slf4j.LoggerFactory; 009 010/** 011 * Class to represent an event stored on a node. 012 * <p> 013 * Custom Equals method 014 * 015 * @author Steve Young Copyright (C) 2019 016 */ 017public class CbusNodeEvent extends CbusBasicNodeEvent implements Comparable<CbusNodeEvent> { 018 019 private int[] _evVarArr; 020 021 /** 022 * Set the value of the event variable array by index 023 * 024 * @param memo CAN System Connection 025 * @param nn Event node Number 026 * @param en Event event or device number 027 * @param thisnode Host node number 028 * @param index number assigned by node, -1 if unknown 029 * @param maxEvVar Maximum event variables for the event 030 */ 031 public CbusNodeEvent( jmri.jmrix.can.CanSystemConnectionMemo memo, int nn, int en, int thisnode, int index, int maxEvVar){ 032 super(memo,nn,en,thisnode,index); 033 _evVarArr = new int[Math.max(maxEvVar, 0)]; 034 java.util.Arrays.fill(_evVarArr,-1); 035 } 036 037 protected CbusNodeEvent( int nn, int en, int thisnode, String eventString ){ 038 super(null,nn,en,thisnode,-1); 039 _evVarArr = StringUtil.intBytesWithTotalFromNonSpacedHexString(eventString,false); 040 setTempFcuNodeName(null); 041 } 042 043 protected CbusNodeEvent( CbusNodeEvent existing ) { 044 super(null,existing.getNn(),existing.getEn(),existing.getParentNn(),existing.getIndex()); 045 setEvArr( Arrays.copyOf( 046 existing.getEvVarArray(), 047 existing.getEvVarArray().length) ); 048 setTempFcuNodeName ( existing.getTempFcuNodeName()); 049 050 } 051 052 /** 053 * Set the value of the event variable array by index 054 * 055 * @param index event variable index, minimum 1 056 * @param value min 0 max 255 057 */ 058 public void setEvVar(int index, int value) { 059 if ( index < 1 ) { 060 log.error("Event Index needs to be more than 0"); 061 return; 062 } 063 if (value > 255 ) { 064 log.error("Event Variable value needs to be less than 255 (oxff)"); 065 return; 066 } 067 _evVarArr[(index-1)]=value; 068 notifyModel(); 069 070 } 071 072 /** 073 * Set the value of the event variable array by existing array 074 * 075 * @param newArray event variable array, 1st value index 0 should be 1st event value, NOT total 076 */ 077 public final void setEvArr( int[] newArray ){ 078 _evVarArr = newArray; 079 notifyModel(); 080 } 081 082 /** 083 * Returns the value of an event variable 084 * 085 * @param index of the variable, no array offset needed, 1 is 1 086 * @return the decimal event indexed variable value 087 */ 088 public int getEvVar(int index) { 089 return _evVarArr[(index-1)]; 090 } 091 092 public int[] getEvVarArray() { 093 return _evVarArr; 094 } 095 096 /** 097 * Returns all event variables as a single string 098 * <p> 099 * eg. /"1, 13, 1, 0, 0/" 100 * 101 * @return the decimal string for of the array, unknown values are blanked 102 */ 103 public String getEvVarString(){ 104 StringBuilder n = new StringBuilder(); 105 // n.append("[ "); 106 for(int i = 0; i< _evVarArr.length; i++){ 107 if ( _evVarArr[i] > -1 ) { 108 n.append( _evVarArr[i] ); 109 } 110 else { 111 n.append( " " ); 112 } 113 if ( i != ( _evVarArr.length-1 ) ) { 114 n.append( ", " ); 115 } 116 } 117 // n.append(" ]"); 118 return n.toString(); 119 } 120 121 /** 122 * Returns all event variables as a single hex string 123 * <p> 124 * eg. returns 0104D6A0 125 * 126 * @return the hex string for of the array 127 */ 128 public String getHexEvVarString() { 129 if (getEvVarArray() != null) { 130 return StringUtil.hexStringFromInts(getEvVarArray()).replaceAll("\\s", ""); 131 } 132 return ""; 133 } 134 135 /** 136 * Returns the number of unknown event variables 137 * 138 * @return the decimal outstanding total 139 */ 140 public int getOutstandingVars() { 141 if ( getEvVarArray() == null ){ 142 return 0; 143 } 144 int count = 0; 145 for (int val : getEvVarArray()){ 146 if (val == -1) { 147 count ++; 148 } 149 } 150 return count; 151 } 152 153 /** 154 * Returns the index of the next unknown event variable 155 * @return the decimal index value else 0 if all known 156 */ 157 public int getNextOutstanding() { 158 for (int i = 0; i < _evVarArr.length; i++) { 159 if ( _evVarArr[i] == -1) { 160 return i+1; 161 } 162 } 163 return 0; 164 } 165 166 /** 167 * Get the number of event variables 168 * by Array Length 169 * 170 * @return number of event variables 171 */ 172 public int getNumEvVars() { 173 return _evVarArr.length; 174 } 175 176 /** 177 * Sets unknown event variables to 0 178 * 179 */ 180 protected void allOutstandingEvVarsNotNeeded(){ 181 for (int i = 0; i < _evVarArr.length; i++) { 182 if ( _evVarArr[i] == -1) { 183 _evVarArr[i] = 0; 184 } 185 } 186 } 187 188 /** 189 * {@inheritDoc} 190 * <p> 191 * Custom method to compare Node Num, Ev Num, Parent Node Num, Event Variables 192 */ 193 @Override 194 public boolean equals(Object o) { 195 if (!(o instanceof CbusNodeEvent)) { 196 return false; 197 } 198 CbusNodeEvent t = (CbusNodeEvent) o; 199 if ( this.getEn()!=t.getEn() || this.getNn()!=t.getNn() ) { 200 return false; 201 } 202 if ( this.getParentNn()!=t.getParentNn() ) { 203 return false; 204 } 205 return this.getHexEvVarString().equals(t.getHexEvVarString()); 206 } 207 208 /** {@inheritDoc} */ 209 @Override 210 public int hashCode() { 211 return Objects.hash(getEn(), getNn(), getParentNn(), getHexEvVarString()); 212 } 213 214 /** 215 * {@inheritDoc} 216 * Compares to the Node / Event numbers of the Event 217 */ 218 @Override 219 public int compareTo(CbusNodeEvent o) { 220 return Integer.compare(this.listOrder(),o.listOrder()); 221 } 222 223 private int listOrder(){ 224 return (getNn()*65535+getEn())+100+(Objects.hash(getHexEvVarString())%100); 225 } 226 227 private static final Logger log = LoggerFactory.getLogger(CbusNodeEvent.class); 228 229}