The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

311 lines
12KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2016 - ROLI Ltd.
  5. Permission is granted to use this software under the terms of the ISC license
  6. http://www.isc.org/downloads/software-support-policy/isc-license/
  7. Permission to use, copy, modify, and/or distribute this software for any
  8. purpose with or without fee is hereby granted, provided that the above
  9. copyright notice and this permission notice appear in all copies.
  10. THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
  11. TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  12. FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
  13. OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
  14. USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  16. OF THIS SOFTWARE.
  17. -----------------------------------------------------------------------------
  18. To release a closed-source product which uses other parts of JUCE not
  19. licensed under the ISC terms, commercial licenses are available: visit
  20. www.juce.com for more information.
  21. ==============================================================================
  22. */
  23. /**
  24. Represents an individual BLOCKS device.
  25. */
  26. class Block : public juce::ReferenceCountedObject
  27. {
  28. public:
  29. //==============================================================================
  30. /** Destructor. */
  31. virtual ~Block();
  32. /** The different block types.
  33. @see Block::getType()
  34. */
  35. enum Type
  36. {
  37. unknown = 0,
  38. lightPadBlock,
  39. liveBlock,
  40. loopBlock,
  41. developerControlBlock,
  42. seaboardBlock // on-screen seaboard view
  43. };
  44. /** The Block class is reference-counted, so always use a Block::Ptr when
  45. you are keeping references to them.
  46. */
  47. using Ptr = juce::ReferenceCountedObjectPtr<Block>;
  48. /** The Block class is reference-counted, so Block::Array is useful when
  49. you are storing lists of them.
  50. */
  51. using Array = juce::ReferenceCountedArray<Block>;
  52. /** The Block's serial number. */
  53. const juce::String serialNumber;
  54. using UID = uint64;
  55. /** This Block's UID.
  56. This will be globally unique, and remains constant for a particular device.
  57. */
  58. const UID uid;
  59. //==============================================================================
  60. /** Returns the type of this device.
  61. @see Block::Type
  62. */
  63. virtual Type getType() const = 0;
  64. /** Returns a human-readable description of this device type. */
  65. virtual juce::String getDeviceDescription() const = 0;
  66. /** Returns the battery level in the range 0.0 to 1.0. */
  67. virtual float getBatteryLevel() const = 0;
  68. /** Returns true if the battery is charging. */
  69. virtual bool isBatteryCharging() const = 0;
  70. //==============================================================================
  71. /** Returns true if this block is connected and active. */
  72. virtual bool isConnected() const = 0;
  73. /** Returns true if this block is directly connected to the application,
  74. as opposed to only being connected to a different block via a connection port.
  75. @see ConnectionPort
  76. */
  77. virtual bool isMasterBlock() const = 0;
  78. //==============================================================================
  79. /** Returns the width of the device in logical device units. */
  80. virtual int getWidth() const = 0;
  81. /** Returns the height of the device in logical device units. */
  82. virtual int getHeight() const = 0;
  83. /** Returns true if the device is a physical hardware block (i.e. not a virtual block). */
  84. virtual bool isHardwareBlock() const = 0;
  85. /** Returns the length of one logical device unit as physical millimeters. */
  86. virtual float getMillimetersPerUnit() const = 0;
  87. //==============================================================================
  88. /** If this block has a grid of LEDs, this will return an object to control it.
  89. Note that the pointer that is returned belongs to this object, and the caller must
  90. neither delete it or use it after the lifetime of this Block object has finished.
  91. If there are no LEDs, then this method will return nullptr.
  92. */
  93. virtual LEDGrid* getLEDGrid() const = 0;
  94. /** If this block has a row of LEDs, this will return an object to control it.
  95. Note that the pointer that is returned belongs to this object, and the caller must
  96. neither delete it or use it after the lifetime of this Block object has finished.
  97. If there are no LEDs, then this method will return nullptr.
  98. */
  99. virtual LEDRow* getLEDRow() const = 0;
  100. /** If this block has any status LEDs, this will return an array of objects to control them.
  101. Note that the objects in the array belong to this Block object, and the caller must
  102. neither delete them or use them after the lifetime of this Block object has finished.
  103. */
  104. virtual juce::Array<StatusLight*> getStatusLights() const = 0;
  105. /** If this block has a pressure-sensitive surface, this will return an object to
  106. access its data.
  107. Note that the pointer returned does is owned by this object, and the caller must
  108. neither delete it or use it after the lifetime of this Block object has finished.
  109. If the device is not touch-sensitive, then this method will return nullptr.
  110. */
  111. virtual TouchSurface* getTouchSurface() const = 0;
  112. /** If this block has any control buttons, this will return an array of objects to control them.
  113. Note that the objects in the array belong to this Block object, and the caller must
  114. neither delete them or use them after the lifetime of this Block object has finished.
  115. */
  116. virtual juce::Array<ControlButton*> getButtons() const = 0;
  117. //==============================================================================
  118. /** This returns true if the block supports generating graphics by drawing into a JUCE
  119. Graphics context. This should only be true for virtual on-screen blocks; hardware
  120. blocks will instead use the LED Grid for visuals.
  121. */
  122. virtual bool supportsGraphics() const = 0;
  123. //==============================================================================
  124. /** These are the edge-connectors that a device may have. */
  125. struct ConnectionPort
  126. {
  127. enum class DeviceEdge
  128. {
  129. north,
  130. south,
  131. east,
  132. west
  133. };
  134. /** The side of the device on which this port is located. */
  135. DeviceEdge edge;
  136. /** The index of this port along the device edge.
  137. For north and south edges, index 0 is the left-most port.
  138. For east and west edges, index 0 is the top-most port.
  139. */
  140. int index;
  141. bool operator== (const ConnectionPort&) const noexcept;
  142. bool operator!= (const ConnectionPort&) const noexcept;
  143. };
  144. /** Returns a list of the connectors that this device has. */
  145. virtual juce::Array<ConnectionPort> getPorts() const = 0;
  146. //==============================================================================
  147. /** A program that can be loaded onto a block. */
  148. struct Program
  149. {
  150. /** Creates a Program for the corresponding LEDGrid. */
  151. Program (Block&);
  152. /** Destructor. */
  153. virtual ~Program();
  154. /** Returns the LittleFoot program to execute on the BLOCKS device. */
  155. virtual juce::String getLittleFootProgram() = 0;
  156. Block& block;
  157. };
  158. /** Sets the Program to run on this block.
  159. The supplied Program's lifetime will be managed by this class, so do not
  160. use the Program in other places in your code.
  161. */
  162. virtual juce::Result setProgram (Program*) = 0;
  163. /** Returns a pointer to the currently loaded program. */
  164. virtual Program* getProgram() const = 0;
  165. //==============================================================================
  166. /** A message that can be sent to the currently loaded program. */
  167. struct ProgramEventMessage
  168. {
  169. int32 values[3];
  170. };
  171. /** Sends a message to the currently loaded program.
  172. To receive the message the program must provide a littlefoot function called
  173. handleMessage with the following form:
  174. @code
  175. void handleMessage (int param1, int param2, int param3)
  176. {
  177. // Do something with the two integer parameters that the app has sent...
  178. }
  179. @endcode
  180. */
  181. virtual void sendProgramEvent (const ProgramEventMessage&) = 0;
  182. /** Interface for objects listening to custom program events. */
  183. struct ProgramEventListener
  184. {
  185. virtual ~ProgramEventListener() {}
  186. /** Called whenever a message from a block is received. */
  187. virtual void handleProgramEvent (Block& source, const ProgramEventMessage&) = 0;
  188. };
  189. /** Adds a new listener for custom program events from the block. */
  190. virtual void addProgramEventListener (ProgramEventListener*);
  191. /** Removes a listener for custom program events from the block. */
  192. virtual void removeProgramEventListener (ProgramEventListener*);
  193. //==============================================================================
  194. /** Returns the size of the data block that setDataByte and other functions can write to. */
  195. virtual uint32 getMemorySize() = 0;
  196. /** Sets a single byte on the littlefoot heap. */
  197. virtual void setDataByte (size_t offset, uint8 value) = 0;
  198. /** Sets multiple bytes on the littlefoot heap. */
  199. virtual void setDataBytes (size_t offset, const void* data, size_t num) = 0;
  200. /** Sets multiple bits on the littlefoot heap. */
  201. virtual void setDataBits (uint32 startBit, uint32 numBits, uint32 value) = 0;
  202. /** Gets a byte from the littlefoot heap. */
  203. virtual uint8 getDataByte (size_t offset) = 0;
  204. /** Sets the current program as the block's default state. */
  205. virtual void saveProgramAsDefault() = 0;
  206. //==============================================================================
  207. /** Allows the user to provide a function that will receive log messages from the block. */
  208. virtual void setLogger (std::function<void(const String&)> loggingCallback) = 0;
  209. /** Sends a firmware update packet to a block, and waits for a reply. Returns an error code. */
  210. virtual bool sendFirmwareUpdatePacket (const uint8* data, uint8 size,
  211. std::function<void (uint8)> packetAckCallback) = 0;
  212. //==============================================================================
  213. /** Interface for objects listening to input data port. */
  214. struct DataInputPortListener
  215. {
  216. virtual ~DataInputPortListener() {}
  217. /** Called whenever a message from a block is received. */
  218. virtual void handleIncomingDataPortMessage (Block& source, const void* messageData, size_t messageSize) = 0;
  219. };
  220. /** Adds a new listener for the data input port. */
  221. virtual void addDataInputPortListener (DataInputPortListener*);
  222. /** Removes a listener for the data input port. */
  223. virtual void removeDataInputPortListener (DataInputPortListener*);
  224. /** Sends a message to the block. */
  225. virtual void sendMessage (const void* messageData, size_t messageSize) = 0;
  226. //==============================================================================
  227. /** This type is used for timestamping events. It represents a number of milliseconds since the block
  228. device was booted.
  229. */
  230. using Timestamp = uint32;
  231. protected:
  232. //==============================================================================
  233. Block (const juce::String& serialNumberToUse);
  234. juce::ListenerList<DataInputPortListener> dataInputPortListeners;
  235. juce::ListenerList<ProgramEventListener> programEventListeners;
  236. private:
  237. //==============================================================================
  238. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Block)
  239. };