1 /*******************************************************************************
2 * jArduino: Arduino C++ Code Generation From Java
3 * Copyright 2020 Tony Washer
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 ******************************************************************************/
17 package net.sourceforge.jarduino.message;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22 /**
23 * Message selection.
24 */
25 public class ArduinoMsgFilter {
26 /**
27 * Parse message indication.
28 */
29 private static final Integer ZERO = 0;
30
31 /**
32 * Parse message indication.
33 */
34 public static final int PARSEMSG = 1;
35
36 /**
37 * Build message indication.
38 */
39 public static final int BUILDMSG = 2;
40
41 /**
42 * The map of messageId to output selection.
43 */
44 private final Map<String, Integer> theSelection;
45
46 /**
47 * The public fields indication.
48 */
49 private boolean pubFields;
50
51 /**
52 * Constructor.
53 */
54 public ArduinoMsgFilter() {
55 theSelection = new HashMap<>();
56 }
57
58 /**
59 * Obtain the number of messages.
60 * @return the number of messages
61 */
62 public int size() {
63 return theSelection.size();
64 }
65
66 /**
67 * Is the selection empty?
68 * @return true/false
69 */
70 public boolean isEmpty() {
71 return theSelection.isEmpty();
72 }
73
74 /**
75 * Are fields public?
76 * @return true/false
77 */
78 public boolean publicFields() {
79 return pubFields;
80 }
81
82 /**
83 * toggle public fields.
84 */
85 public void togglePublicFields() {
86 pubFields = !pubFields;
87 }
88
89 /**
90 * Does the map have any selected entries.
91 * @return true/false
92 */
93 public boolean hasSelected() {
94 /* Loop through the map */
95 for (Integer myValue : theSelection.values()) {
96 if (!ZERO.equals(myValue)) {
97 return true;
98 }
99 }
100
101 /* No selected entries */
102 return false;
103 }
104
105 /**
106 * Is the message selected?
107 * @param pId the messageId
108 * @return true/false
109 */
110 public boolean isSelected(final String pId) {
111 final Integer myState = theSelection.get(pId);
112 return myState != null && !ZERO.equals(myState);
113 }
114
115 /**
116 * Is the message selected for parse?
117 * @param pId the messageId
118 * @return true/false
119 */
120 public boolean isParsed(final String pId) {
121 final Integer myState = theSelection.get(pId);
122 return myState != null && !ZERO.equals(myState & PARSEMSG);
123 }
124
125 /**
126 * Is the message selected for build?
127 * @param pId the messageId
128 * @return true/false
129 */
130 public boolean isBuilt(final String pId) {
131 final Integer myState = theSelection.get(pId);
132 return myState != null && !ZERO.equals(myState & BUILDMSG);
133 }
134
135 /**
136 * Toggle the flag for the message.
137 * @param pId the messageId
138 * @param pFlag the flag
139 */
140 public void toggleFlag(final String pId,
141 final int pFlag) {
142 /* Calculate the new state */
143 Integer myState = theSelection.computeIfAbsent(pId, i -> ZERO);
144 myState ^= pFlag;
145
146 /* Remove or update the state */
147 if (ZERO.equals(myState)) {
148 removeMessage(pId);
149 } else {
150 theSelection.put(pId, myState);
151 }
152 }
153
154 /**
155 * Select message.
156 * @param pId the messageId
157 */
158 public void selectMessage(final String pId) {
159 theSelection.put(pId, PARSEMSG | BUILDMSG);
160 }
161
162 /**
163 * Remove message.
164 * @param pId the messageId
165 */
166 public void removeMessage(final String pId) {
167 theSelection.remove(pId);
168 }
169
170 /**
171 * Reset the selection for a new object.
172 * @param pObject the object
173 */
174 public void resetSelection(final ArduinoNamedObject pObject) {
175 if (pObject instanceof ArduinoSystem) {
176 resetSelection((ArduinoSystem) pObject);
177 }
178 if (pObject instanceof ArduinoNode) {
179 resetSelection((ArduinoNode) pObject);
180 }
181 }
182
183 /**
184 * Reset the selection for a new system.
185 * @param pSystem the system
186 */
187 public void resetSelection(final ArduinoSystem pSystem) {
188 /* Remove the existing selection */
189 theSelection.clear();
190
191 /* Loop through the messages */
192 for (ArduinoMessage myMessage : pSystem.getMessages()) {
193 /* Add all messages by default */
194 theSelection.put(myMessage.getId(), PARSEMSG | BUILDMSG);
195 }
196 }
197
198 /**
199 * Match the selection to a node.
200 * @param pNode the node
201 */
202 public void resetSelection(final ArduinoNode pNode) {
203 /* Remove the existing selection */
204 theSelection.clear();
205
206 /* Loop through the messages */
207 for (ArduinoMessage myMessage : pNode.getOwner().getMessages()) {
208 /* Determine if we send the message */
209 int myValue = pNode.getMessages().contains(myMessage) ? BUILDMSG : ZERO;
210
211 /* Determine if we receive the message */
212 if (pNode.receivesMessage(myMessage)) {
213 myValue |= PARSEMSG;
214 }
215
216 /* If we should handle the message */
217 if (!ZERO.equals(myValue)) {
218 /* Add to the selection */
219 theSelection.put(myMessage.getId(), myValue);
220 }
221 }
222 }
223 }