001package jmri.jmrit.logixng.actions; 002 003import java.util.*; 004 005import jmri.*; 006import jmri.Block; 007import jmri.Sensor; 008import jmri.jmrit.display.layoutEditor.LayoutBlock; 009import jmri.jmrit.display.layoutEditor.LayoutBlockManager; 010import jmri.jmrit.logixng.*; 011import jmri.jmrit.logixng.util.*; 012import jmri.jmrit.logixng.util.parser.*; 013import jmri.util.ThreadingUtil; 014 015/** 016 * This action triggers a block. 017 * 018 * @author Daniel Bergqvist Copyright 2021 019 * @author Dave Sand Copyright 2021 020 */ 021public class ActionBlock extends AbstractDigitalAction { 022 023 private final LogixNG_SelectNamedBean<Block> _selectNamedBean = 024 new LogixNG_SelectNamedBean<>( 025 this, Block.class, InstanceManager.getDefault(BlockManager.class)); 026 027 private final LogixNG_SelectEnum<DirectOperation> _selectEnum = 028 new LogixNG_SelectEnum<>(this, DirectOperation.values(), DirectOperation.SetOccupied); 029 030 private final LogixNG_SelectString _selectBlockValue = 031 new LogixNG_SelectString(this); 032 033 034 public ActionBlock(String sys, String user) 035 throws BadUserNameException, BadSystemNameException { 036 super(sys, user); 037 } 038 039 @Override 040 public Base getDeepCopy(Map<String, String> systemNames, Map<String, String> userNames) throws ParserException { 041 DigitalActionManager manager = InstanceManager.getDefault(DigitalActionManager.class); 042 String sysName = systemNames.get(getSystemName()); 043 String userName = userNames.get(getSystemName()); 044 if (sysName == null) sysName = manager.getAutoSystemName(); 045 ActionBlock copy = new ActionBlock(sysName, userName); 046 copy.setComment(getComment()); 047 _selectNamedBean.copy(copy._selectNamedBean); 048 _selectEnum.copy(copy._selectEnum); 049 _selectBlockValue.copy(copy._selectBlockValue); 050 return manager.registerAction(copy); 051 } 052 053 public LogixNG_SelectNamedBean<Block> getSelectNamedBean() { 054 return _selectNamedBean; 055 } 056 057 public LogixNG_SelectEnum<DirectOperation> getSelectEnum() { 058 return _selectEnum; 059 } 060 061 public LogixNG_SelectString getSelectBlockValue() { 062 return _selectBlockValue; 063 } 064 065 /** {@inheritDoc} */ 066 @Override 067 public LogixNG_Category getCategory() { 068 return LogixNG_Category.ITEM; 069 } 070 071 /** {@inheritDoc} */ 072 @Override 073 public void execute() throws JmriException { 074 ConditionalNG conditionalNG = getConditionalNG(); 075 076 Block block = _selectNamedBean.evaluateNamedBean(conditionalNG); 077 078 if (block == null) { 079 return; 080 } 081 082 DirectOperation oper = _selectEnum.evaluateEnum(getConditionalNG()); 083 084 // Variables used in lambda must be effectively final 085 DirectOperation theOper = oper; 086 087 ThreadingUtil.runOnLayoutWithJmriException(() -> { 088 Sensor sensor; 089 LayoutBlock lblk; 090 091 switch (theOper) { 092 case SetOccupied: 093 sensor = block.getSensor(); 094 if (sensor != null) { 095 try { 096 sensor.setKnownState(Sensor.ACTIVE); 097 } catch (JmriException ex) { 098 log.debug("Exception setting sensor active"); 099 } 100 } else { 101 throw new JmriException(Bundle.getMessage("ActionBlock_ErrorSensor", block.getDisplayName())); 102 } 103 break; 104 case SetNotOccupied: 105 sensor = block.getSensor(); 106 if (sensor != null) { 107 try { 108 sensor.setKnownState(Sensor.INACTIVE); 109 } catch (JmriException ex) { 110 log.debug("Exception setting sensor inactive"); 111 } 112 } else { 113 throw new JmriException(Bundle.getMessage("ActionBlock_ErrorSensor", block.getDisplayName())); 114 } 115 break; 116 case SetAltColorOn: 117 lblk = InstanceManager.getDefault(LayoutBlockManager.class).getLayoutBlock(block); 118 if (lblk != null) { 119 lblk.setUseExtraColor(true); 120 } else { 121 throw new JmriException(Bundle.getMessage("ActionBlock_ErrorLayoutBlock", block.getDisplayName())); 122 } 123 break; 124 case SetAltColorOff: 125 lblk = InstanceManager.getDefault(LayoutBlockManager.class).getLayoutBlock(block); 126 if (lblk != null) { 127 lblk.setUseExtraColor(false); 128 } else { 129 throw new JmriException(Bundle.getMessage("ActionBlock_ErrorLayoutBlock", block.getDisplayName())); 130 } 131 break; 132 case SetNullValue: 133 block.setValue(null); 134 break; 135 case SetValue: 136 block.setValue(_selectBlockValue.evaluateValue(conditionalNG)); 137 break; 138 default: 139 throw new IllegalArgumentException("invalid oper state: " + theOper.name()); 140 } 141 }); 142 } 143 144 @Override 145 public FemaleSocket getChild(int index) throws IllegalArgumentException, UnsupportedOperationException { 146 throw new UnsupportedOperationException("Not supported."); 147 } 148 149 @Override 150 public int getChildCount() { 151 return 0; 152 } 153 154 @Override 155 public String getShortDescription(Locale locale) { 156 return Bundle.getMessage(locale, "ActionBlock_Short"); 157 } 158 159 @Override 160 public String getLongDescription(Locale locale) { 161 String namedBean = _selectNamedBean.getDescription(locale); 162 String state = _selectEnum.getDescription(locale); 163 164 if (_selectEnum.isDirectAddressing()) { 165 if (_selectEnum.getEnum() == DirectOperation.SetValue) { 166 String bundleKey = "ActionBlock_Long_Value"; 167 return Bundle.getMessage(locale, bundleKey, namedBean, _selectBlockValue.getDescription(locale)); 168 } 169 } 170 171 return Bundle.getMessage(locale, "ActionBlock_Long", namedBean, state); 172 } 173 174 /** {@inheritDoc} */ 175 @Override 176 public void setup() { 177 // Do nothing 178 } 179 180 /** {@inheritDoc} */ 181 @Override 182 public void disposeMe() { 183 } 184 185 public enum DirectOperation { 186 SetOccupied(Bundle.getMessage("ActionBlock_SetOccupied")), 187 SetNotOccupied(Bundle.getMessage("ActionBlock_SetNotOccupied")), 188 SetAltColorOn(Bundle.getMessage("ActionBlock_SetAltColorOn")), 189 SetAltColorOff(Bundle.getMessage("ActionBlock_SetAltColorOff")), 190 SetNullValue(Bundle.getMessage("ActionBlock_SetNullValue")), 191 SetValue(Bundle.getMessage("ActionBlock_SetValue")); 192 193 private final String _text; 194 195 private DirectOperation(String text) { 196 this._text = text; 197 } 198 199 @Override 200 public String toString() { 201 return _text; 202 } 203 204 } 205 206 /** {@inheritDoc} */ 207 @Override 208 public void getUsageDetail(int level, NamedBean bean, List<NamedBeanUsageReport> report, NamedBean cdl) { 209 _selectNamedBean.getUsageDetail(level, bean, report, cdl, this, LogixNG_SelectNamedBean.Type.Action); 210 } 211 212 private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(ActionBlock.class); 213 214}