001package jmri.jmrit.withrottle; 002 003import java.util.ArrayList; 004import java.util.List; 005 006/** 007 * Abstract for controllers that want to receive or send communications to a 008 * connected wi-fi device. 009 * 010 * 011 * @author Brett Hoffman Copyright (C) 2010 012 */ 013abstract public class AbstractController { 014 015 ArrayList<ControllerInterface> listeners = null; 016 List<String> sysNameList = null; 017 018 boolean isValid = false; 019 boolean canBuildList = true; 020 021 /** 022 * isValid is used to indicate if the Controller is created. If false, we 023 * can null the controller and reduce overhead. 024 * 025 * @return isValid 026 */ 027 abstract boolean verifyCreation(); 028 029 /** 030 * Break down a message and use it. 031 * @param message message for controller to parse and take action 032 * @param deviceServer DeviceServer that sent this message, used to send response messages to proper client 033 * 034 */ 035 abstract void handleMessage(String message, DeviceServer deviceServer); 036 037 /** 038 * Register as listener of NamedBeans to be updated of changes. 039 */ 040 abstract void register(); 041 042 /** 043 * Deregister as listener of NamedBeans 044 */ 045 abstract void deregister(); 046 047 /** 048 * Build list only if there are no controller listeners. This way the list 049 * is not changed while in use. This should only be called by a subclass of 050 * jmri.Manager *Manager can implement specifics in register(). 051 * @param manager which manager to get system names for. 052 * 053 */ 054 public void buildList(jmri.Manager<?> manager) { 055 if (sysNameList == null) { 056 sysNameList = new ArrayList<>(manager.getNamedBeanSet().size()); 057 manager.getNamedBeanSet().forEach(bean -> { 058 sysNameList.add(bean.getSystemName()); 059 }); 060 filterList(); // To remove unwanted objects 061 register(); 062 canBuildList = false; 063 } 064 065 } 066 067 public void filterList() { 068 // Override to filter by wifiControlled field of turnout or route object. 069 } 070 071 /** 072 * If no listeners, clear sysNameList pointer and allow list to be re-built 073 *Manager can implement specifics in deregister(). 074 */ 075 public void checkCanBuildList() { 076 if (listeners.isEmpty()) { 077 if (sysNameList != null) { 078 deregister(); 079 sysNameList = null; 080 } 081 canBuildList = true; 082 } 083 } 084 085 /** 086 * Add a listener to handle: listener.sendPacketToDevice(message); 087 * @param listener listener to add to listeners list 088 */ 089 public void addControllerListener(ControllerInterface listener) { 090 if (listeners == null) { 091 listeners = new ArrayList<>(1); 092 } 093 if (!listeners.contains(listener)) { 094 listeners.add(listener); 095 } 096 } 097 098 public void removeControllerListener(ControllerInterface listener) { 099 if (listeners == null) { 100 return; 101 } 102 if (listeners.contains(listener)) { 103 listeners.remove(listener); 104 } 105 checkCanBuildList(); 106 } 107 108}