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.simulation; 006 007/** Manages simulation callbacks; each object is associated with a callback. */ 008public class CallbackStore implements AutoCloseable { 009 /** <b>Note: This interface is for simulation classes only. It should not be used by teams!</b> */ 010 interface CancelCallbackFunc { 011 void cancel(int index, int uid); 012 } 013 014 /** <b>Note: This interface is for simulation classes only. It should not be used by teams!</b> */ 015 interface CancelCallbackChannelFunc { 016 void cancel(int index, int channel, int uid); 017 } 018 019 /** <b>Note: This interface is for simulation classes only. It should not be used by teams!</b> */ 020 interface CancelCallbackNoIndexFunc { 021 void cancel(int uid); 022 } 023 024 /** 025 * Constructs an empty CallbackStore. This constructor is to allow 3rd party sim providers (eg 026 * vendors) to subclass this class (without needing provide dummy constructing parameters) so that 027 * the register methods of their sim classes can return CallbackStores like the builtin sims. 028 * <b>Note: It should not be called by teams that are just using sims!</b> 029 */ 030 protected CallbackStore() { 031 this.m_cancelType = -1; 032 this.m_index = -1; 033 this.m_uid = -1; 034 this.m_cancelCallback = null; 035 this.m_cancelCallbackChannel = null; 036 } 037 038 /** 039 * <b>Note: This constructor is for simulation classes only. It should not be called by teams!</b> 040 * 041 * @param index TODO 042 * @param uid TODO 043 * @param ccf TODO 044 */ 045 public CallbackStore(int index, int uid, CancelCallbackFunc ccf) { 046 this.m_cancelType = kNormalCancel; 047 this.m_index = index; 048 this.m_uid = uid; 049 this.m_cancelCallback = ccf; 050 } 051 052 /** 053 * <b>Note: This constructor is for simulation classes only. It should not be called by teams!</b> 054 * 055 * @param index TODO 056 * @param channel TODO 057 * @param uid TODO 058 * @param ccf TODO 059 */ 060 public CallbackStore(int index, int channel, int uid, CancelCallbackChannelFunc ccf) { 061 this.m_cancelType = kChannelCancel; 062 this.m_index = index; 063 this.m_uid = uid; 064 this.m_channel = channel; 065 this.m_cancelCallbackChannel = ccf; 066 } 067 068 /** 069 * <b>Note: This constructor is for simulation classes only. It should not be called by teams!</b> 070 * 071 * @param uid TODO 072 * @param ccf TODO 073 */ 074 public CallbackStore(int uid, CancelCallbackNoIndexFunc ccf) { 075 this.m_cancelType = kNoIndexCancel; 076 this.m_uid = uid; 077 this.m_cancelCallbackNoIndex = ccf; 078 } 079 080 private int m_index; 081 private int m_channel; 082 private final int m_uid; 083 private CancelCallbackFunc m_cancelCallback; 084 private CancelCallbackChannelFunc m_cancelCallbackChannel; 085 private CancelCallbackNoIndexFunc m_cancelCallbackNoIndex; 086 private static final int kAlreadyCancelled = -1; 087 private static final int kNormalCancel = 0; 088 private static final int kChannelCancel = 1; 089 private static final int kNoIndexCancel = 2; 090 private int m_cancelType; 091 092 /** Cancel the callback associated with this object. */ 093 @Override 094 public void close() { 095 switch (m_cancelType) { 096 case kAlreadyCancelled -> { 097 // Already cancelled so do nothing so that close() is idempotent. 098 return; 099 } 100 case kNormalCancel -> m_cancelCallback.cancel(m_index, m_uid); 101 case kChannelCancel -> m_cancelCallbackChannel.cancel(m_index, m_channel, m_uid); 102 case kNoIndexCancel -> m_cancelCallbackNoIndex.cancel(m_uid); 103 default -> { 104 assert false; 105 } 106 } 107 m_cancelType = kAlreadyCancelled; 108 } 109}