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.wpilibj.smartdashboard; 006 007import edu.wpi.first.networktables.NetworkTable; 008import java.util.HashMap; 009import java.util.Map; 010 011/** 012 * Common base class for all Mechanism2d node types. 013 * 014 * <p>To append another node, call {@link #append(MechanismObject2d)}. Objects that aren't appended 015 * to a published {@link Mechanism2d} container are nonfunctional. 016 * 017 * @see Mechanism2d 018 */ 019public abstract class MechanismObject2d implements AutoCloseable { 020 /** Relative to parent. */ 021 private final String m_name; 022 023 private NetworkTable m_table; 024 private final Map<String, MechanismObject2d> m_objects = new HashMap<>(1); 025 026 /** 027 * Create a new Mechanism node object. 028 * 029 * @param name the node's name, must be unique. 030 */ 031 protected MechanismObject2d(String name) { 032 m_name = name; 033 } 034 035 @Override 036 public void close() { 037 for (MechanismObject2d obj : m_objects.values()) { 038 obj.close(); 039 } 040 } 041 042 /** 043 * Append a Mechanism object that is based on this one. 044 * 045 * @param <T> The object type. 046 * @param object the object to add. 047 * @return the object given as a parameter, useful for variable assignments and call chaining. 048 * @throws UnsupportedOperationException if the object's name is already used - object names must 049 * be unique. 050 */ 051 public final synchronized <T extends MechanismObject2d> T append(T object) { 052 if (m_objects.containsKey(object.getName())) { 053 throw new UnsupportedOperationException("Mechanism object names must be unique!"); 054 } 055 m_objects.put(object.getName(), object); 056 if (m_table != null) { 057 object.update(m_table.getSubTable(object.getName())); 058 } 059 return object; 060 } 061 062 final synchronized void update(NetworkTable table) { 063 m_table = table; 064 updateEntries(m_table); 065 for (MechanismObject2d obj : m_objects.values()) { 066 obj.update(m_table.getSubTable(obj.m_name)); 067 } 068 } 069 070 /** 071 * Update this object's entries with new ones from a new table. 072 * 073 * @param table the new table. 074 */ 075 protected abstract void updateEntries(NetworkTable table); 076 077 /** 078 * Retrieve the object's name. 079 * 080 * @return the object's name relative to its parent. 081 */ 082 public final String getName() { 083 return m_name; 084 } 085}