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 007import edu.wpi.first.util.struct.Struct; 008import edu.wpi.first.util.struct.StructBuffer; 009 010/** 011 * NetworkTables struct-encoded array value topic. 012 * 013 * @param <T> value class 014 */ 015public final class StructArrayTopic<T> extends Topic { 016 private StructArrayTopic(Topic topic, Struct<T> struct) { 017 super(topic.m_inst, topic.m_handle); 018 m_struct = struct; 019 } 020 021 private StructArrayTopic(NetworkTableInstance inst, int handle, Struct<T> struct) { 022 super(inst, handle); 023 m_struct = struct; 024 } 025 026 /** 027 * Create a StructArrayTopic from a generic topic. 028 * 029 * @param <T> value class (inferred from struct) 030 * @param topic generic topic 031 * @param struct struct serialization implementation 032 * @return StructArrayTopic for value class 033 */ 034 public static <T> StructArrayTopic<T> wrap(Topic topic, Struct<T> struct) { 035 return new StructArrayTopic<>(topic, struct); 036 } 037 038 /** 039 * Create a StructArrayTopic from a native handle; generally 040 * NetworkTableInstance.getStructArrayTopic() should be used instead. 041 * 042 * @param <T> value class (inferred from struct) 043 * @param inst Instance 044 * @param handle Native handle 045 * @param struct struct serialization implementation 046 * @return StructArrayTopic for value class 047 */ 048 public static <T> StructArrayTopic<T> wrap( 049 NetworkTableInstance inst, int handle, Struct<T> struct) { 050 return new StructArrayTopic<>(inst, handle, struct); 051 } 052 053 /** 054 * Create a new subscriber to the topic. 055 * 056 * <p>The subscriber is only active as long as the returned object is not closed. 057 * 058 * <p>Subscribers that do not match the published data type do not return any values. To determine 059 * if the data type matches, use the appropriate Topic functions. 060 * 061 * @param defaultValue default value used when a default is not provided to a getter function 062 * @param options subscribe options 063 * @return subscriber 064 */ 065 public StructArraySubscriber<T> subscribe(T[] defaultValue, PubSubOption... options) { 066 return new StructArrayEntryImpl<>( 067 this, 068 StructBuffer.create(m_struct), 069 NetworkTablesJNI.subscribe( 070 m_handle, NetworkTableType.kRaw.getValue(), m_struct.getTypeString() + "[]", options), 071 defaultValue, 072 false); 073 } 074 075 /** 076 * Create a new publisher to the topic. 077 * 078 * <p>The publisher is only active as long as the returned object is not closed. 079 * 080 * <p>It is not possible to publish two different data types to the same topic. Conflicts between 081 * publishers are typically resolved by the server on a first-come, first-served basis. Any 082 * published values that do not match the topic's data type are dropped (ignored). To determine if 083 * the data type matches, use the appropriate Topic functions. 084 * 085 * @param options publish options 086 * @return publisher 087 */ 088 public StructArrayPublisher<T> publish(PubSubOption... options) { 089 m_inst.addSchema(m_struct); 090 return new StructArrayEntryImpl<>( 091 this, 092 StructBuffer.create(m_struct), 093 NetworkTablesJNI.publish( 094 m_handle, NetworkTableType.kRaw.getValue(), m_struct.getTypeString() + "[]", options), 095 null, 096 true); 097 } 098 099 /** 100 * Create a new publisher to the topic, with type string and initial properties. 101 * 102 * <p>The publisher is only active as long as the returned object is not closed. 103 * 104 * <p>It is not possible to publish two different data types to the same topic. Conflicts between 105 * publishers are typically resolved by the server on a first-come, first-served basis. Any 106 * published values that do not match the topic's data type are dropped (ignored). To determine if 107 * the data type matches, use the appropriate Topic functions. 108 * 109 * @param properties JSON properties 110 * @param options publish options 111 * @return publisher 112 * @throws IllegalArgumentException if properties is not a JSON object 113 */ 114 public StructArrayPublisher<T> publishEx(String properties, PubSubOption... options) { 115 m_inst.addSchema(m_struct); 116 return new StructArrayEntryImpl<>( 117 this, 118 StructBuffer.create(m_struct), 119 NetworkTablesJNI.publishEx( 120 m_handle, 121 NetworkTableType.kRaw.getValue(), 122 m_struct.getTypeString() + "[]", 123 properties, 124 options), 125 null, 126 true); 127 } 128 129 /** 130 * Create a new entry for the topic. 131 * 132 * <p>Entries act as a combination of a subscriber and a weak publisher. The subscriber is active 133 * as long as the entry is not closed. The publisher is created when the entry is first written 134 * to, and remains active until either unpublish() is called or the entry is closed. 135 * 136 * <p>It is not possible to use two different data types with the same topic. Conflicts between 137 * publishers are typically resolved by the server on a first-come, first-served basis. Any 138 * published values that do not match the topic's data type are dropped (ignored), and the entry 139 * will show no new values if the data type does not match. To determine if the data type matches, 140 * use the appropriate Topic functions. 141 * 142 * @param defaultValue default value used when a default is not provided to a getter function 143 * @param options publish and/or subscribe options 144 * @return entry 145 */ 146 public StructArrayEntry<T> getEntry(T[] defaultValue, PubSubOption... options) { 147 return new StructArrayEntryImpl<>( 148 this, 149 StructBuffer.create(m_struct), 150 NetworkTablesJNI.getEntry( 151 m_handle, NetworkTableType.kRaw.getValue(), m_struct.getTypeString() + "[]", options), 152 defaultValue, 153 false); 154 } 155 156 /** 157 * Returns the struct. 158 * 159 * @return The struct. 160 */ 161 public Struct<T> getStruct() { 162 return m_struct; 163 } 164 165 @Override 166 public boolean equals(Object other) { 167 if (other == this) { 168 return true; 169 } 170 if (!(other instanceof StructArrayTopic)) { 171 return false; 172 } 173 174 return super.equals(other) && m_struct == ((StructArrayTopic<?>) other).m_struct; 175 } 176 177 @Override 178 public int hashCode() { 179 return super.hashCode() ^ m_struct.hashCode(); 180 } 181 182 private final Struct<T> m_struct; 183}