Refactor command system - remove BaseCommand class implementation in favour of std::function

This commit is contained in:
Lorow
2025-04-09 21:43:49 +02:00
parent 8a2695977c
commit eaa60cb877
17 changed files with 268 additions and 271 deletions

View File

@@ -8,37 +8,39 @@ std::unordered_map<std::string, CommandType> commandTypeMap = {
{"save_config", CommandType::SAVE_CONFIG},
};
std::unique_ptr<Command> CommandManager::createCommand(CommandType type)
std::function<CommandResult()> CommandManager::createCommand(CommandType type, std::string_view json)
{
typedef std::function<CommandResult()> CommandFunction;
switch (type)
{
case CommandType::PING:
return std::make_unique<PingCommand>();
return CommandFunction(PingCommand);
case CommandType::SET_WIFI:
return std::make_unique<setWiFiCommand>(projectConfig);
return CommandFunction(std::bind(setWiFiCommand, this->registry, json));
case CommandType::UPDATE_WIFI:
return std::make_unique<updateWifiCommand>(projectConfig);
return CommandFunction(std::bind(updateWiFiCommand, this->registry, json));
case CommandType::UPDATE_AP_WIFI:
return std::make_unique<updateAPWiFiCommand>(projectConfig);
return CommandFunction(std::bind(updateAPWiFiCommand, this->registry, json));
case CommandType::DELETE_NETWORK:
return std::make_unique<deleteWifiCommand>(projectConfig);
return CommandFunction(std::bind(deleteWiFiCommand, this->registry, json));
case CommandType::SET_MDNS:
return std::make_unique<setMDNSCommand>(projectConfig);
return CommandFunction(std::bind(setMDNSCommand, this->registry, json));
// updating the mnds name is essentially the same operation
case CommandType::UPDATE_MDNS:
return std::make_unique<setMDNSCommand>(projectConfig);
return CommandFunction(std::bind(setMDNSCommand, this->registry, json));
case CommandType::UPDATE_CAMERA:
return std::make_unique<updateCameraCommand>(projectConfig);
return CommandFunction(std::bind(updateCameraCommand, this->registry, json));
case CommandType::RESTART_CAMERA:
return std::make_unique<restartCameraCommand>(cameraManager);
return CommandFunction(std::bind(restartCameraCommand, this->registry, json));
case CommandType::GET_CONFIG:
return std::make_unique<getConfigCommand>(projectConfig);
return CommandFunction(std::bind(getConfigCommand, this->registry));
case CommandType::SAVE_CONFIG:
return std::make_unique<saveConfigCommand>(projectConfig);
return CommandFunction(std::bind(saveConfigCommand, this->registry));
case CommandType::RESET_CONFIG:
return std::make_unique<resetConfigCommand>(projectConfig);
return CommandFunction(std::bind(resetConfigCommand, this->registry, json));
case CommandType::RESTART_DEVICE:
return std::make_unique<restartDeviceCommand>();
return CommandFunction(restartDeviceCommand);
default:
return nullptr;
}
@@ -56,9 +58,10 @@ CommandResult CommandManager::executeFromJson(std::string_view json)
{
const cJSON *commandTypeString = cJSON_GetObjectItem(commandData, "command");
const cJSON *commandPayload = cJSON_GetObjectItem(commandData, "data");
auto commandType = commandTypeMap.at(std::string(commandTypeString->valuestring));
auto command = createCommand(commandType);
std::string commandPayloadString = std::string(cJSON_Print(commandPayload));
auto command = createCommand(commandType, commandPayloadString);
if (command == nullptr)
{
@@ -66,9 +69,8 @@ CommandResult CommandManager::executeFromJson(std::string_view json)
return CommandResult::getErrorResult("Unknown command");
}
std::string commandPayloadString = std::string(cJSON_Print(commandPayload));
cJSON_Delete(parsedJson);
return command->execute(commandPayloadString);
return command();
}
cJSON_Delete(parsedJson);
@@ -77,12 +79,12 @@ CommandResult CommandManager::executeFromJson(std::string_view json)
CommandResult CommandManager::executeFromType(CommandType type, std::string_view json)
{
auto command = createCommand(type);
auto command = createCommand(type, json);
if (command == nullptr)
{
return CommandResult::getErrorResult("Unknown command");
}
return command->execute(json);
return command();
}

View File

@@ -7,9 +7,10 @@
#include <string>
#include <optional>
#include <unordered_map>
#include <functional>
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
#include "commands/BaseCommand.hpp"
#include "DependencyRegistry.hpp"
#include "commands/simple_commands.hpp"
#include "commands/camera_commands.hpp"
#include "commands/config_commands.hpp"
@@ -18,9 +19,6 @@
#include "commands/device_commands.hpp"
#include <cJSON.h>
// mostlikely missing commands
// reset config
// restart device
enum CommandType
{
None,
@@ -43,12 +41,11 @@ enum CommandType
class CommandManager
{
private:
std::shared_ptr<ProjectConfig> projectConfig;
std::shared_ptr<CameraManager> cameraManager;
std::shared_ptr<DependencyRegistry> registry;
public:
CommandManager(std::shared_ptr<ProjectConfig> projectConfig, std::shared_ptr<CameraManager> cameraManager) : projectConfig(projectConfig), cameraManager(cameraManager) {};
std::unique_ptr<Command> createCommand(CommandType type);
CommandManager(std::shared_ptr<DependencyRegistry> DependencyRegistry) : registry(DependencyRegistry) {};
std::function<CommandResult()> createCommand(CommandType type, std::string_view json);
CommandResult executeFromJson(std::string_view json);
CommandResult executeFromType(CommandType type, std::string_view json);

View File

@@ -0,0 +1,37 @@
#ifndef _DEPENDENCY_REGISTRY_HPP_
#define _DEPENDENCY_REGISTRY_HPP_
#include <memory>
#include <unordered_map>
enum DependencyType
{
project_config,
camera_manager
};
class DependencyRegistry
{
std::unordered_map<DependencyType, std::shared_ptr<void>> services;
public:
template <typename ServiceType>
void registerService(DependencyType dependencyType, std::shared_ptr<ServiceType> service)
{
this->services[dependencyType] = std::static_pointer_cast<void>(service);
}
template <typename ServiceType>
std::shared_ptr<ServiceType> resolve(DependencyType dependencyType)
{
auto serviceIT = this->services.find(dependencyType);
if (serviceIT != this->services.end())
{
return std::static_pointer_cast<ServiceType>(serviceIT->second);
}
return nullptr;
}
};
#endif

View File

@@ -1,20 +0,0 @@
#ifndef COMMAND_HPP
#define COMMAND_HPP
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
#include <optional>
#include <cJSON.h>
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
class Command
{
public:
Command() = default;
virtual ~Command() = default;
virtual CommandResult execute(std::string_view jsonPayload) = 0;
};
#endif

View File

@@ -1,6 +1,6 @@
#include "camera_commands.hpp"
std::optional<UpdateCameraConfigPayload> updateCameraCommand::parsePayload(std::string_view jsonPayload)
std::optional<UpdateCameraConfigPayload> parseUpdateCameraPayload(std::string_view jsonPayload)
{
UpdateCameraConfigPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -29,27 +29,7 @@ std::optional<UpdateCameraConfigPayload> updateCameraCommand::parsePayload(std::
return payload;
}
CommandResult updateCameraCommand::execute(std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
auto updatedConfig = payload.value();
auto oldConfig = projectConfig->getCameraConfig();
this->projectConfig->setCameraConfig(
updatedConfig.vflip.has_value() ? updatedConfig.vflip.value() : oldConfig.vflip,
updatedConfig.framesize.has_value() ? updatedConfig.framesize.value() : oldConfig.framesize,
updatedConfig.href.has_value() ? updatedConfig.href.value() : oldConfig.href,
updatedConfig.quality.has_value() ? updatedConfig.quality.value() : oldConfig.quality,
updatedConfig.brightness.has_value() ? updatedConfig.brightness.value() : oldConfig.brightness);
return CommandResult::getSuccessResult("Config updated");
}
std::optional<RestartCameraPayload> restartCameraCommand::parsePayload(std::string_view jsonPayload)
std::optional<RestartCameraPayload> parseRestartCameraPayload(std::string_view jsonPayload)
{
RestartCameraPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -71,14 +51,36 @@ std::optional<RestartCameraPayload> restartCameraCommand::parsePayload(std::stri
return payload;
}
CommandResult restartCameraCommand::execute(std::string_view jsonPayload)
CommandResult updateCameraCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
auto payload = parseUpdateCameraPayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
auto updatedConfig = payload.value();
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
auto oldConfig = projectConfig->getCameraConfig();
projectConfig->setCameraConfig(
updatedConfig.vflip.has_value() ? updatedConfig.vflip.value() : oldConfig.vflip,
updatedConfig.framesize.has_value() ? updatedConfig.framesize.value() : oldConfig.framesize,
updatedConfig.href.has_value() ? updatedConfig.href.value() : oldConfig.href,
updatedConfig.quality.has_value() ? updatedConfig.quality.value() : oldConfig.quality,
updatedConfig.brightness.has_value() ? updatedConfig.brightness.value() : oldConfig.brightness);
return CommandResult::getSuccessResult("Config updated");
}
CommandResult restartCameraCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parseRestartCameraPayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
this->cameraManager->resetCamera(payload.value().mode);
std::shared_ptr<CameraManager> cameraManager = registry->resolve<CameraManager>(DependencyType::camera_manager);
cameraManager->resetCamera(payload.value().mode);
return CommandResult::getSuccessResult("Camera restarted");
}

View File

@@ -1,27 +1,20 @@
#ifndef CAMERA_COMMANDS_HPP
#define CAMERA_COMMANDS_HPP
#include "BaseCommand.hpp"
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
#include <optional>
#include <cJSON.h>
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
#include "DependencyRegistry.hpp"
#include <CameraManager.hpp>
class updateCameraCommand : public Command
{
std::shared_ptr<ProjectConfig> projectConfig;
public:
updateCameraCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<UpdateCameraConfigPayload> parsePayload(std::string_view jsonPayload);
};
class restartCameraCommand : public Command
{
std::shared_ptr<CameraManager> cameraManager;
public:
restartCameraCommand(std::shared_ptr<CameraManager> cameraManager) : cameraManager(cameraManager) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<RestartCameraPayload> parsePayload(std::string_view jsonPayload);
};
std::optional<UpdateCameraConfigPayload> parseUpdateCameraPayload(std::string_view jsonPayload);
CommandResult updateCameraCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
std::optional<RestartCameraPayload> parseRestartCameraPayload(std::string_view jsonPayload);
CommandResult restartCameraCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
#endif
// add cropping command

View File

@@ -1,18 +1,6 @@
#include "config_commands.hpp"
CommandResult saveConfigCommand::execute(std::string_view jsonPayload)
{
projectConfig->save();
return CommandResult::getSuccessResult("Config saved");
}
CommandResult getConfigCommand::execute(std::string_view jsonPayload)
{
auto configRepresentation = projectConfig->getTrackerConfig().toRepresentation();
return CommandResult::getSuccessResult(configRepresentation);
}
std::optional<ResetConfigPayload> resetConfigCommand::parsePayload(std::string_view jsonPayload)
std::optional<ResetConfigPayload> parseResetConfigCommandPayload(std::string_view jsonPayload)
{
ResetConfigPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -34,9 +22,28 @@ std::optional<ResetConfigPayload> resetConfigCommand::parsePayload(std::string_v
return payload;
}
CommandResult resetConfigCommand::execute(std::string_view jsonPayload)
CommandResult saveConfigCommand(std::shared_ptr<DependencyRegistry> registry)
{
auto payload = parsePayload(jsonPayload);
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->save();
return CommandResult::getSuccessResult("Config saved");
}
CommandResult getConfigCommand(std::shared_ptr<DependencyRegistry> registry)
{
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
auto configRepresentation = projectConfig->getTrackerConfig().toRepresentation();
return CommandResult::getSuccessResult(configRepresentation);
}
CommandResult resetConfigCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
std::array<std::string, 4> supported_sections = {
"all",
};
auto payload = parseResetConfigCommandPayload(jsonPayload);
if (!payload.has_value())
{
@@ -45,7 +52,7 @@ CommandResult resetConfigCommand::execute(std::string_view jsonPayload)
auto sectionPayload = payload.value();
if (std::find(this->supported_sections.begin(), this->supported_sections.end(), sectionPayload.section) == this->supported_sections.end())
if (std::find(supported_sections.begin(), supported_sections.end(), sectionPayload.section) == supported_sections.end())
{
return CommandResult::getErrorResult("Selected section is unsupported");
}
@@ -53,7 +60,10 @@ CommandResult resetConfigCommand::execute(std::string_view jsonPayload)
// we cannot match on string, and making a map would be overkill right now, sooo
// todo, add more granual control for other sections, like only reset camera, or only reset wifi
if (sectionPayload.section == "all")
this->projectConfig->reset();
{
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->reset();
}
return CommandResult::getSuccessResult("Config reset");
}

View File

@@ -1,30 +1,14 @@
#include "BaseCommand.hpp"
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
#include <optional>
#include <cJSON.h>
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
#include "DependencyRegistry.hpp"
class saveConfigCommand : public Command
{
public:
std::shared_ptr<ProjectConfig> projectConfig;
saveConfigCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
};
CommandResult saveConfigCommand(std::shared_ptr<DependencyRegistry> registry);
CommandResult getConfigCommand(std::shared_ptr<DependencyRegistry> registry);
class getConfigCommand : public Command
{
public:
std::shared_ptr<ProjectConfig> projectConfig;
getConfigCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
};
class resetConfigCommand : public Command
{
std::array<std::string, 4> supported_sections = {
"all",
};
public:
std::shared_ptr<ProjectConfig> projectConfig;
resetConfigCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<ResetConfigPayload> parsePayload(std::string_view jsonPayload);
};
std::optional<ResetConfigPayload> parseresetConfigCommandPayload(std::string_view jsonPayload);
CommandResult resetConfigCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);

View File

@@ -1,6 +1,6 @@
#include "device_commands.hpp"
CommandResult restartDeviceCommand::execute(std::string_view jsonPayload)
CommandResult restartDeviceCommand()
{
// todo implement this: https://github.com/EyeTrackVR/OpenIris/blob/master/ESP/lib/src/tasks/tasks.cpp
// OpenIrisTasks::ScheduleRestart(2000);

View File

@@ -1,6 +1,3 @@
#include "BaseCommand.hpp"
#include "CommandResult.hpp"
class restartDeviceCommand : public Command
{
CommandResult execute(std::string_view jsonPayload) override;
};
CommandResult restartDeviceCommand();

View File

@@ -1,6 +1,6 @@
#include "mdns_commands.hpp"
std::optional<MDNSPayload> setMDNSCommand::parsePayload(std::string_view jsonPayload)
std::optional<MDNSPayload> parseMDNSCommandPayload(std::string_view jsonPayload)
{
MDNSPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -20,12 +20,13 @@ std::optional<MDNSPayload> setMDNSCommand::parsePayload(std::string_view jsonPay
return payload;
}
CommandResult setMDNSCommand::execute(std::string_view jsonPayload)
CommandResult setMDNSCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
auto payload = parseMDNSCommandPayload(jsonPayload);
if (!payload.has_value())
return CommandResult::getErrorResult("Invalid payload");
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->setMDNSConfig(payload.value().hostname);
return CommandResult::getSuccessResult("Config updated");

View File

@@ -1,11 +1,11 @@
#include "BaseCommand.hpp"
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
#include <optional>
#include <cJSON.h>
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
#include "DependencyRegistry.hpp"
class setMDNSCommand : public Command
{
std::shared_ptr<ProjectConfig> projectConfig;
public:
setMDNSCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<MDNSPayload> parsePayload(std::string_view jsonPayload);
};
std::optional<MDNSPayload> parseMDNSCommandPayload(std::string_view jsonPayload);
CommandResult setMDNSCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);

View File

@@ -1,6 +1,6 @@
#include "simple_commands.hpp"
CommandResult PingCommand::execute(std::string_view jsonPayload)
CommandResult PingCommand()
{
return CommandResult::getSuccessResult("pong");
}
};

View File

@@ -1,8 +1,9 @@
#include "BaseCommand.hpp"
#ifndef SIMPLE_COMMANDS
#define SIMPLE_COMMANDS
class PingCommand : public Command
{
public:
PingCommand() = default;
CommandResult execute(std::string_view jsonPayload) override;
};
#include <string>
#include "CommandResult.hpp"
CommandResult PingCommand();
#endif

View File

@@ -1,6 +1,6 @@
#include "wifi_commands.hpp"
std::optional<WifiPayload> setWiFiCommand::parsePayload(std::string_view jsonPayload)
std::optional<WifiPayload> parseSetWiFiCommandPayload(std::string_view jsonPayload)
{
WifiPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -47,25 +47,7 @@ std::optional<WifiPayload> setWiFiCommand::parsePayload(std::string_view jsonPay
return payload;
}
CommandResult setWiFiCommand::execute(std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
auto wifiConfig = payload.value();
projectConfig->setWifiConfig(
wifiConfig.networkName,
wifiConfig.ssid,
wifiConfig.password,
wifiConfig.channel,
wifiConfig.power);
return CommandResult::getSuccessResult("Config updated");
}
std::optional<deleteNetworkPayload> deleteWifiCommand::parsePayload(std::string_view jsonPayload)
std::optional<deleteNetworkPayload> parseDeleteWifiCommandPayload(std::string_view jsonPayload)
{
deleteNetworkPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -86,17 +68,7 @@ std::optional<deleteNetworkPayload> deleteWifiCommand::parsePayload(std::string_
return payload;
}
CommandResult deleteWifiCommand::execute(std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
if (!payload.has_value())
return CommandResult::getErrorResult("Invalid payload");
projectConfig->deleteWifiConfig(payload.value().networkName);
return CommandResult::getSuccessResult("Config updated");
}
std::optional<UpdateWifiPayload> updateWifiCommand::parsePayload(std::string_view jsonPayload)
std::optional<UpdateWifiPayload> parseUpdateWifiCommandPayload(std::string_view jsonPayload)
{
UpdateWifiPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -141,37 +113,7 @@ std::optional<UpdateWifiPayload> updateWifiCommand::parsePayload(std::string_vie
return payload;
}
CommandResult updateWifiCommand::execute(std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
auto updatedConfig = payload.value();
auto storedNetworks = projectConfig->getWifiConfigs();
if (auto networkToUpdate = std::find_if(
storedNetworks.begin(),
storedNetworks.end(),
[&](auto &network)
{ return network.name == updatedConfig.networkName; });
networkToUpdate != storedNetworks.end())
{
projectConfig->setWifiConfig(
updatedConfig.networkName,
updatedConfig.ssid.has_value() ? updatedConfig.ssid.value() : networkToUpdate->ssid,
updatedConfig.password.has_value() ? updatedConfig.password.value() : networkToUpdate->password,
updatedConfig.channel.has_value() ? updatedConfig.channel.value() : networkToUpdate->channel,
updatedConfig.power.has_value() ? updatedConfig.power.value() : networkToUpdate->power);
return CommandResult::getSuccessResult("Config updated");
}
else
return CommandResult::getErrorResult("Requested network does not exist");
}
std::optional<UpdateAPWiFiPayload> updateAPWiFiCommand::parsePayload(std::string_view jsonPayload)
std::optional<UpdateAPWiFiPayload> parseUpdateAPWiFiCommandPayload(std::string_view jsonPayload)
{
UpdateAPWiFiPayload payload;
cJSON *parsedJson = cJSON_Parse(jsonPayload.data());
@@ -198,14 +140,81 @@ std::optional<UpdateAPWiFiPayload> updateAPWiFiCommand::parsePayload(std::string
return payload;
}
CommandResult updateAPWiFiCommand::execute(std::string_view jsonPayload)
CommandResult setWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parsePayload(jsonPayload);
auto payload = parseSetWiFiCommandPayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
auto wifiConfig = payload.value();
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->setWifiConfig(
wifiConfig.networkName,
wifiConfig.ssid,
wifiConfig.password,
wifiConfig.channel,
wifiConfig.power);
return CommandResult::getSuccessResult("Config updated");
}
CommandResult deleteWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parseDeleteWifiCommandPayload(jsonPayload);
if (!payload.has_value())
return CommandResult::getErrorResult("Invalid payload");
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
projectConfig->deleteWifiConfig(payload.value().networkName);
return CommandResult::getSuccessResult("Config updated");
}
CommandResult updateWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parseUpdateWifiCommandPayload(jsonPayload);
if (!payload.has_value())
{
return CommandResult::getErrorResult("Invalid payload");
}
auto updatedConfig = payload.value();
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
auto storedNetworks = projectConfig->getWifiConfigs();
if (auto networkToUpdate = std::find_if(
storedNetworks.begin(),
storedNetworks.end(),
[&](auto &network)
{ return network.name == updatedConfig.networkName; });
networkToUpdate != storedNetworks.end())
{
projectConfig->setWifiConfig(
updatedConfig.networkName,
updatedConfig.ssid.has_value() ? updatedConfig.ssid.value() : networkToUpdate->ssid,
updatedConfig.password.has_value() ? updatedConfig.password.value() : networkToUpdate->password,
updatedConfig.channel.has_value() ? updatedConfig.channel.value() : networkToUpdate->channel,
updatedConfig.power.has_value() ? updatedConfig.power.value() : networkToUpdate->power);
return CommandResult::getSuccessResult("Config updated");
}
else
return CommandResult::getErrorResult("Requested network does not exist");
}
CommandResult updateAPWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload)
{
auto payload = parseUpdateAPWiFiCommandPayload(jsonPayload);
if (!payload.has_value())
return CommandResult::getErrorResult("Invalid payload");
auto updatedConfig = payload.value();
std::shared_ptr<ProjectConfig> projectConfig = registry->resolve<ProjectConfig>(DependencyType::project_config);
auto previousAPConfig = projectConfig->getAPWifiConfig();
projectConfig->setAPWifiConfig(

View File

@@ -1,41 +1,20 @@
#include "BaseCommand.hpp"
#include <ProjectConfig.hpp>
#include <memory>
#include <string>
#include <optional>
#include <cJSON.h>
#include "CommandResult.hpp"
#include "CommandSchema.hpp"
#include "DependencyRegistry.hpp"
class setWiFiCommand : public Command
{
std::shared_ptr<ProjectConfig> projectConfig;
std::optional<WifiPayload> parseSetWiFiCommandPayload(std::string_view jsonPayload);
CommandResult setWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
public:
setWiFiCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<WifiPayload> parsePayload(std::string_view jsonPayload);
};
std::optional<deleteNetworkPayload> parseDeleteWifiCommandPayload(std::string_view jsonPayload);
CommandResult deleteWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
class deleteWifiCommand : public Command
{
std::shared_ptr<ProjectConfig> projectConfig;
std::optional<UpdateWifiPayload> parseUpdateWifiCommandPayload(std::string_view jsonPayload);
CommandResult updateWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);
public:
deleteWifiCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<deleteNetworkPayload> parsePayload(std::string_view jsonPayload);
};
class updateWifiCommand : public Command
{
std::shared_ptr<ProjectConfig> projectConfig;
public:
updateWifiCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<UpdateWifiPayload> parsePayload(std::string_view jsonPayload);
};
class updateAPWiFiCommand : public Command
{
std::shared_ptr<ProjectConfig> projectConfig;
public:
updateAPWiFiCommand(std::shared_ptr<ProjectConfig> projectConfig) : projectConfig(projectConfig) {};
CommandResult execute(std::string_view jsonPayload) override;
std::optional<UpdateAPWiFiPayload> parsePayload(std::string_view jsonPayload);
};
std::optional<UpdateAPWiFiPayload> parseUpdateAPWiFiCommandPayload(std::string_view jsonPayload);
CommandResult updateAPWiFiCommand(std::shared_ptr<DependencyRegistry> registry, std::string_view jsonPayload);

View File

@@ -30,16 +30,19 @@
static const char *TAG = "[MAIN]";
std::shared_ptr<DependencyRegistry> dependencyRegistry = std::make_unique<DependencyRegistry>();
std::shared_ptr<CommandManager> commandManager = std::make_shared<CommandManager>(dependencyRegistry);
WebSocketLogger webSocketLogger;
Preferences preferences;
auto deviceConfig = std::make_shared<ProjectConfig>(&preferences);
std::shared_ptr<ProjectConfig> deviceConfig = std::make_shared<ProjectConfig>(&preferences);
WiFiManager wifiManager(deviceConfig);
MDNSManager mdnsManager(deviceConfig);
std::shared_ptr<CameraManager> cameraHandler = std::make_shared<CameraManager>(deviceConfig);
StreamServer streamServer(80);
auto commandManager = std::make_shared<CommandManager>(deviceConfig, cameraHandler);
RestAPI restAPI("http://0.0.0.0:81", commandManager);
#ifdef CONFIG_WIRED_MODE
@@ -71,8 +74,10 @@ int test_log(const char *format, va_list args)
extern "C" void app_main(void)
{
// uvc plan
dependencyRegistry->registerService<ProjectConfig>(DependencyType::project_config, deviceConfig);
dependencyRegistry->registerService<CameraManager>(DependencyType::camera_manager, cameraHandler);
// uvc plan
// cleanup the logs - done
// prepare the camera to be initialized with UVC - done?
// debug uvc performance - done
@@ -90,7 +95,7 @@ extern "C" void app_main(void)
// then add ADHOC and support for more networks in wifi manager - done
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// simplify commands - a simple dependency injection + std::function should do it
// simplify commands - a simple dependency injection + std::function should do it - DONE
// something like
// template<typename T>
// void registerService(std::shared_pointer<T> service)