.. _program_listing_file_src_tap_control_concurrent_command.hpp: Program Listing for File concurrent_command.hpp =============================================== |exhale_lsh| :ref:`Return to documentation for file ` (``src/tap/control/concurrent_command.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp /* * Copyright (c) 2024-2025 Advanced Robotics at the University of Washington * * This file is part of Taproot. * * Taproot is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Taproot is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Taproot. If not, see . */ #ifndef TAPROOT_CONCURRENT_COMMAND_HPP_ #define TAPROOT_CONCURRENT_COMMAND_HPP_ #include #include "modm/architecture/interface/assert.hpp" #include "command.hpp" #include "command_scheduler_types.hpp" namespace tap { namespace control { template class ConcurrentTemplateCommand : public Command { public: ConcurrentTemplateCommand(std::array commands, const char* name) : Command(), commands(commands), name(name), finishedCommands(0), allCommands(0) { for (Command* command : commands) { modm_assert( command != nullptr, "ConcurrentCommand::ConcurrentCommand", "Null pointer command passed into concurrent command."); auto requirements = command->getRequirementsBitwise(); modm_assert( (this->commandRequirementsBitwise & requirements) == 0, "ConcurrentCommand::ConcurrentCommand", "Multiple commands to concurrent command have overlapping requirements."); this->commandRequirementsBitwise |= requirements; this->allCommands |= (1ull << command->getGlobalIdentifier()); } } const char* getName() const override { return this->name; } bool isReady() override { for (Command* command : commands) { if (!command->isReady()) { return false; } } return true; } void initialize() override { for (Command* command : commands) { command->initialize(); } } void execute() override { for (Command* command : commands) { if (!(this->finishedCommands & (1ull << command->getGlobalIdentifier()))) { command->execute(); if (command->isFinished()) { command->end(false); this->finishedCommands |= 1ull << command->getGlobalIdentifier(); } } } } void end(bool interrupted) override { for (Command* command : commands) { if (!(this->finishedCommands & (1ull << command->getGlobalIdentifier()))) { if (RACE) { command->end(true); } else { command->end(interrupted); } } } } bool isFinished() const override { if (RACE) { return this->finishedCommands != 0; } return this->finishedCommands == this->allCommands; } private: std::array commands; const char* name; command_scheduler_bitmap_t finishedCommands; command_scheduler_bitmap_t allCommands; }; // class ConcurrentTemplateCommand template using ConcurrentCommand = ConcurrentTemplateCommand; template using ConcurrentRaceCommand = ConcurrentTemplateCommand; } // namespace control } // namespace tap #endif // TAPROOT_CONCURRENT_COMMAND_HPP_