#pragma once #include "ConfigureHardwareWindow.hpp" #include "DataMaskRenderAreaComponent.hpp" #include "LoggerComponent.hpp" #include "SoftKeyMaskComponent.hpp" #include "SoftKeyMaskRenderAreaComponent.hpp" #include "WorkingSetSelectorComponent.hpp" #include "isobus/isobus/isobus_virtual_terminal_server.hpp" #include class ServerMainComponent : public juce::Component , public juce::KeyListener , public isobus::VirtualTerminalServer , public Timer , public ApplicationCommandTarget , public MenuBarModel { public: ServerMainComponent(std::shared_ptr serverControlFunction, std::vector> &canDrivers); ~ServerMainComponent() override; bool get_is_enough_memory(std::uint32_t requestedMemory) const override; VTVersion get_version() const override; std::uint8_t get_number_of_navigation_soft_keys() const override; std::uint8_t get_soft_key_descriptor_x_pixel_width() const override; std::uint8_t get_soft_key_descriptor_y_pixel_height() const override; std::uint8_t get_number_of_possible_virtual_soft_keys_in_soft_key_mask() const override; std::uint8_t get_number_of_physical_soft_keys() const override; std::uint8_t get_physical_soft_key_rows() const; std::uint8_t get_physical_soft_key_columns() const; std::uint16_t get_data_mask_area_size_x_pixels() const override; std::uint16_t get_data_mask_area_size_y_pixels() const override; void suspend_working_set(std::shared_ptr workingSetWithError) override; SupportedWideCharsErrorCode get_supported_wide_chars(std::uint8_t codePlane, std::uint16_t firstWideCharInInquiryRange, std::uint16_t lastWideCharInInquiryRange, std::uint8_t &numberOfRanges, std::vector &wideCharRangeArray) override; bool keyPressed(const juce::KeyPress &key, juce::Component *originatingComponent) override; bool keyStateChanged(bool isKeyDown, juce::Component *originatingComponent) override; std::vector> get_versions(isobus::NAME clientNAME) override; std::vector get_supported_objects() const override; /// @brief This function is called when the client wants the server to load a previously stored object pool. /// If there exists in the VT's non-volatile memory an object pool matching the provided version label, /// return it. If one does not exist, return an empty vector. /// @param[in] versionLabel The object pool version to load for the given client NAME /// @param[in] clientNAME The client requesting the object pool /// @returns The requested object pool associated with the version label. std::vector load_version(const std::vector &versionLabel, isobus::NAME clientNAME) override; /// @brief This function is called when the client wants the server to save an object pool /// to the VT's non-volatile memory. /// If the object pool is saved successfully, return true, otherwise return false. /// @note This may be called multiple times with the same version, but different data. When this /// happens, the expectation is that you will append each objectPool together into one large file. /// @param[in] objectPool The object pool data to save /// @param[in] versionLabel The object pool version to save for the given client NAME /// @param[in] clientNAME The client requesting the object pool /// @returns The requested object pool associated with the version label. bool save_version(const std::vector &objectPool, const std::vector &versionLabel, isobus::NAME clientNAME) override; /// @brief This function is called when the client wants the server to delete a stored object pool. /// All object pool files matching the specified version label should then be deleted from the VT's /// non-volatile storage. /// @param[in] versionLabel The version label for the object pool(s) to delete /// @param[in] clientNAME The NAME of the client that is requesting deletion /// @returns True if the version was deleted from VT non-volatile storage, otherwise false. bool delete_version(const std::vector &versionLabel, isobus::NAME clientNAME) override; /// @brief This function is called when the client wants the server to delete ALL stored object pools associated to it's NAME. /// All object pool files matching the specified client NAME should then be deleted from the VT's /// non-volatile storage. /// @param[in] clientNAME The NAME of the client that is requesting deletion /// @returns True if all relevant object pools were deleted from VT non-volatile storage, otherwise false. bool delete_all_versions(isobus::NAME clientNAME) override; /// @brief This function is called when the client wants the server to deactivate its object pool. /// You should treat this as a disconnection by the client, as it may be moving to another VT. /// @attention This does not mean to delete the pool from non-volatile memory!!! This only deactivates the active pool. /// @details This command is used to delete the entire object pool of this Working Set from volatile storage. /// This command can be used by an implement when it wants to move its object pool to another VT, /// or when it is shutting down or during the development of object pools. /// @param[in] clientNAME The NAME of the client that is requesting deletion /// @returns True if the client's active object pool was deactivated and removed from volatile storage, otherwise false. bool delete_object_pool(isobus::NAME clientNAME) override; void timerCallback() override; void paint(juce::Graphics &g) override; void resized() override; ApplicationCommandTarget *getNextCommandTarget() override; void getAllCommands(juce::Array &allCommands) override; void getCommandInfo(juce::CommandID commandID, ApplicationCommandInfo &result) override; bool perform(const InvocationInfo &info) override; StringArray getMenuBarNames() override; PopupMenu getMenuForIndex(int, const juce::String &) override; void menuItemSelected(int, int) override; std::shared_ptr get_client_control_function_for_working_set(std::shared_ptr workingSet) const; void change_selected_working_set(std::uint8_t index); void set_button_held(std::shared_ptr workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey); void set_button_released(std::shared_ptr workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey); void repaint_on_next_update(); void save_settings(); private: enum class CommandIDs : int { NoCommand = 0, /// 0 Is an invalid command ID About, ConfigureLanguageCommand, ConfigureReportedVersion, ConfigureReportedHardware, ConfigureLogging, ConfigureShortcuts, GenerateLogPackage, ClearISOData, ConfigureCANHardware, StartStop, AutoStart }; SoftKeyMaskDimensions softKeyMaskDimensions; class LanguageCommandConfigClosed { public: void operator()(int result) const noexcept; ServerMainComponent &mParent; private: }; friend class LanguageCommandConfigClosed; struct HeldButtonData { HeldButtonData(std::shared_ptr workingSet, std::uint16_t objectID, std::uint16_t maskObjectID, std::uint8_t keyCode, bool isSoftKey); bool operator==(const HeldButtonData &other); std::shared_ptr associatedWorkingSet; std::uint32_t timestamp_ms; std::uint16_t buttonObjectID; std::uint16_t activeMaskObjectID; std::uint8_t buttonKeyCode; bool isSoftKey; }; static VTVersion get_version_from_setting(std::uint8_t aVersion); std::size_t number_of_iop_files_in_directory(std::filesystem::path path); void on_change_active_mask_callback(std::shared_ptr affectedWorkingSet, std::uint16_t workingSet, std::uint16_t newMask); void repaint_data_and_soft_key_mask(); void check_load_settings(); void remove_working_set(std::shared_ptr workingSetToRemove); void clear_iso_data(); const std::string ISO_DATA_PATH = "iso_data"; juce::ApplicationCommandManager mCommandManager; WorkingSetSelectorComponent workingSetSelector; DataMaskRenderAreaComponent dataMaskRenderer; SoftKeyMaskRenderAreaComponent softKeyMaskRenderer; MenuBarComponent menuBar; LoggerComponent logger; Viewport loggerViewport; SoundPlayer mSoundPlayer; AudioDeviceManager mAudioDeviceManager; std::unique_ptr popupMenu; std::unique_ptr configureHardwareWindow; std::shared_ptr alarmAckKeyWs; std::vector> &parentCANDrivers; std::vector heldButtons; std::uint32_t alarmAckKeyMaskId = isobus::NULL_OBJECT_ID; int alarmAckKeyCode = juce::KeyPress::escapeKey; std::uint8_t numberOfPoolsToRender = 0; VTVersion versionToReport = VTVersion::Version5; bool needToRepaint = false; bool autostart = false; bool hasStartBeenCalled = false; bool alarmAckKeyPressed = false; JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ServerMainComponent) };