001// Copyright (c) FIRST and other WPILib contributors.
002// Open Source Software; you can modify and/or share it under the terms of
003// the WPILib BSD license file in the root directory of this project.
004
005package edu.wpi.first.networktables;
006
007/** NetworkTables Topic. */
008public class Topic {
009  /**
010   * Constructor; use NetworkTableInstance.getTopic() instead.
011   *
012   * @param inst Instance
013   * @param handle Native handle
014   */
015  Topic(NetworkTableInstance inst, int handle) {
016    m_inst = inst;
017    m_handle = handle;
018  }
019
020  /**
021   * Determines if the native handle is valid.
022   *
023   * @return True if the native handle is valid, false otherwise.
024   */
025  public boolean isValid() {
026    return m_handle != 0;
027  }
028
029  /**
030   * Gets the native handle for the topic.
031   *
032   * @return Native handle
033   */
034  public int getHandle() {
035    return m_handle;
036  }
037
038  /**
039   * Gets the instance for the topic.
040   *
041   * @return Instance
042   */
043  public NetworkTableInstance getInstance() {
044    return m_inst;
045  }
046
047  /**
048   * Gets the name of the topic.
049   *
050   * @return the topic's name
051   */
052  public String getName() {
053    return NetworkTablesJNI.getTopicName(m_handle);
054  }
055
056  /**
057   * Gets the type of the topic.
058   *
059   * @return the topic's type
060   */
061  public NetworkTableType getType() {
062    return NetworkTableType.getFromInt(NetworkTablesJNI.getType(m_handle));
063  }
064
065  /**
066   * Gets the type string of the topic. This may have more information than the numeric type
067   * (especially for raw values).
068   *
069   * @return the topic's type
070   */
071  public String getTypeString() {
072    return NetworkTablesJNI.getTopicTypeString(m_handle);
073  }
074
075  /**
076   * Gets combined information about the topic.
077   *
078   * @return Topic information
079   */
080  public TopicInfo getInfo() {
081    return NetworkTablesJNI.getTopicInfo(m_inst, m_handle);
082  }
083
084  /**
085   * Make value persistent through server restarts.
086   *
087   * @param persistent True for persistent, false for not persistent.
088   */
089  public void setPersistent(boolean persistent) {
090    NetworkTablesJNI.setTopicPersistent(m_handle, persistent);
091  }
092
093  /**
094   * Returns whether the value is persistent through server restarts.
095   *
096   * @return True if the value is persistent.
097   */
098  public boolean isPersistent() {
099    return NetworkTablesJNI.getTopicPersistent(m_handle);
100  }
101
102  /**
103   * Make the server retain the topic even when there are no publishers.
104   *
105   * @param retained True for retained, false for not retained.
106   */
107  public void setRetained(boolean retained) {
108    NetworkTablesJNI.setTopicRetained(m_handle, retained);
109  }
110
111  /**
112   * Returns whether the topic is retained by server when there are no publishers.
113   *
114   * @return True if the topic is retained.
115   */
116  public boolean isRetained() {
117    return NetworkTablesJNI.getTopicRetained(m_handle);
118  }
119
120  /**
121   * Determines if the topic is currently being published.
122   *
123   * @return True if the topic exists, false otherwise.
124   */
125  public boolean exists() {
126    return NetworkTablesJNI.getTopicExists(m_handle);
127  }
128
129  /**
130   * Gets the current value of a property (as a JSON string).
131   *
132   * @param name property name
133   * @return JSON string; "null" if the property does not exist.
134   */
135  public String getProperty(String name) {
136    return NetworkTablesJNI.getTopicProperty(m_handle, name);
137  }
138
139  /**
140   * Sets a property value.
141   *
142   * @param name property name
143   * @param value property value (JSON string)
144   * @throws IllegalArgumentException if properties is not parseable as JSON
145   */
146  public void setProperty(String name, String value) {
147    NetworkTablesJNI.setTopicProperty(m_handle, name, value);
148  }
149
150  /**
151   * Deletes a property. Has no effect if the property does not exist.
152   *
153   * @param name property name
154   */
155  public void deleteProperty(String name) {
156    NetworkTablesJNI.deleteTopicProperty(m_handle, name);
157  }
158
159  /**
160   * Gets all topic properties as a JSON object string. Each key in the object is the property name,
161   * and the corresponding value is the property value.
162   *
163   * @return JSON string
164   */
165  public String getProperties() {
166    return NetworkTablesJNI.getTopicProperties(m_handle);
167  }
168
169  /**
170   * Updates multiple topic properties. Each key in the passed-in object is the name of the property
171   * to add/update, and the corresponding value is the property value to set for that property. Null
172   * values result in deletion of the corresponding property.
173   *
174   * @param properties JSON object string with keys to add/update/delete
175   * @throws IllegalArgumentException if properties is not a JSON object
176   */
177  public void setProperties(String properties) {
178    NetworkTablesJNI.setTopicProperties(m_handle, properties);
179  }
180
181  /**
182   * Create a new subscriber to the topic.
183   *
184   * <p>The subscriber is only active as long as the returned object is not closed.
185   *
186   * @param options subscribe options
187   * @return subscriber
188   */
189  public GenericSubscriber genericSubscribe(PubSubOption... options) {
190    return genericSubscribe("", options);
191  }
192
193  /**
194   * Create a new subscriber to the topic.
195   *
196   * <p>The subscriber is only active as long as the returned object is not closed.
197   *
198   * <p>Subscribers that do not match the published data type do not return any values. To determine
199   * if the data type matches, use the appropriate Topic functions.
200   *
201   * @param typeString type string
202   * @param options subscribe options
203   * @return subscriber
204   */
205  public GenericSubscriber genericSubscribe(String typeString, PubSubOption... options) {
206    return new GenericEntryImpl(
207        this,
208        NetworkTablesJNI.subscribe(
209            m_handle, NetworkTableType.getFromString(typeString).getValue(), typeString, options));
210  }
211
212  /**
213   * Create a new publisher to the topic.
214   *
215   * <p>The publisher is only active as long as the returned object is not closed.
216   *
217   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
218   * publishers are typically resolved by the server on a first-come, first-served basis. Any
219   * published values that do not match the topic's data type are dropped (ignored). To determine if
220   * the data type matches, use the appropriate Topic functions.
221   *
222   * @param typeString type string
223   * @param options publish options
224   * @return publisher
225   */
226  public GenericPublisher genericPublish(String typeString, PubSubOption... options) {
227    return new GenericEntryImpl(
228        this,
229        NetworkTablesJNI.publish(
230            m_handle, NetworkTableType.getFromString(typeString).getValue(), typeString, options));
231  }
232
233  /**
234   * Create a new publisher to the topic, with type string and initial properties.
235   *
236   * <p>The publisher is only active as long as the returned object is not closed.
237   *
238   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
239   * publishers are typically resolved by the server on a first-come, first-served basis. Any
240   * published values that do not match the topic's data type are dropped (ignored). To determine if
241   * the data type matches, use the appropriate Topic functions.
242   *
243   * @param typeString type string
244   * @param properties JSON properties
245   * @param options publish options
246   * @return publisher
247   * @throws IllegalArgumentException if properties is not a JSON object
248   */
249  public GenericPublisher genericPublishEx(
250      String typeString, String properties, PubSubOption... options) {
251    return new GenericEntryImpl(
252        this,
253        NetworkTablesJNI.publishEx(
254            m_handle,
255            NetworkTableType.getFromString(typeString).getValue(),
256            typeString,
257            properties,
258            options));
259  }
260
261  /**
262   * Create a new generic entry for the topic.
263   *
264   * <p>Entries act as a combination of a subscriber and a weak publisher. The subscriber is active
265   * as long as the entry is not closed. The publisher is created when the entry is first written
266   * to, and remains active until either unpublish() is called or the entry is closed.
267   *
268   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
269   * publishers are typically resolved by the server on a first-come, first-served basis. Any
270   * published values that do not match the topic's data type are dropped (ignored). To determine if
271   * the data type matches, use the appropriate Topic functions.
272   *
273   * @param options publish and/or subscribe options
274   * @return entry
275   */
276  public GenericEntry getGenericEntry(PubSubOption... options) {
277    return getGenericEntry("", options);
278  }
279
280  /**
281   * Create a new generic entry for the topic.
282   *
283   * <p>Entries act as a combination of a subscriber and a weak publisher. The subscriber is active
284   * as long as the entry is not closed. The publisher is created when the entry is first written
285   * to, and remains active until either unpublish() is called or the entry is closed.
286   *
287   * <p>It is not possible to publish two different data types to the same topic. Conflicts between
288   * publishers are typically resolved by the server on a first-come, first-served basis. Any
289   * published values that do not match the topic's data type are dropped (ignored). To determine if
290   * the data type matches, use the appropriate Topic functions.
291   *
292   * @param typeString type string
293   * @param options publish and/or subscribe options
294   * @return entry
295   */
296  public GenericEntry getGenericEntry(String typeString, PubSubOption... options) {
297    return new GenericEntryImpl(
298        this,
299        NetworkTablesJNI.getEntry(
300            m_handle, NetworkTableType.getFromString(typeString).getValue(), typeString, options));
301  }
302
303  @Override
304  public boolean equals(Object other) {
305    if (other == this) {
306      return true;
307    }
308    if (!(other instanceof Topic)) {
309      return false;
310    }
311
312    return m_handle == ((Topic) other).m_handle;
313  }
314
315  @Override
316  public int hashCode() {
317    return m_handle;
318  }
319
320  protected NetworkTableInstance m_inst;
321  protected int m_handle;
322}