Skip to content

Commit

Permalink
feat: CustomExecAgent & 子进程 IO 的重构 (#110)
Browse files Browse the repository at this point in the history
  • Loading branch information
MistEO authored Dec 7, 2023
2 parents 5ec31e8 + bca84d8 commit 6a11a8e
Show file tree
Hide file tree
Showing 79 changed files with 1,608 additions and 992 deletions.
2 changes: 2 additions & 0 deletions include/MaaFramework/Utility/MaaBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ extern "C"
int32_t MAA_FRAMEWORK_API MaaGetRectY(MaaRectHandle handle);
int32_t MAA_FRAMEWORK_API MaaGetRectW(MaaRectHandle handle);
int32_t MAA_FRAMEWORK_API MaaGetRectH(MaaRectHandle handle);

MaaBool MAA_FRAMEWORK_API MaaSetRect(MaaRectHandle handle, int32_t x, int32_t y, int32_t w, int32_t h);
MaaBool MAA_FRAMEWORK_API MaaSetRectX(MaaRectHandle handle, int32_t value);
MaaBool MAA_FRAMEWORK_API MaaSetRectY(MaaRectHandle handle, int32_t value);
MaaBool MAA_FRAMEWORK_API MaaSetRectW(MaaRectHandle handle, int32_t value);
Expand Down
24 changes: 24 additions & 0 deletions include/MaaToolKit/ExecAgent/MaaToolKitExecAgent.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "../MaaToolKitDef.h"

#ifdef __cplusplus
extern "C"
{
#endif

MaaBool MAA_TOOLKIT_API MaaToolKitRegisterCustomRecognizerExecutor( //
MaaInstanceHandle handle, MaaStringView recognizer_name, MaaStringView recognizer_exec_path,
MaaStringView recognizer_exec_param_json, MaaToolKitExecAgentArgvTransferMode argv_mode);
MaaBool MAA_TOOLKIT_API MaaToolKitUnregisterCustomRecognizerExecutor( //
MaaInstanceHandle handle, MaaStringView recognizer_name);

MaaBool MAA_TOOLKIT_API MaaToolKitRegisterCustomActionExecutor( //
MaaInstanceHandle handle, MaaStringView action_name, MaaStringView action_exec_path,
MaaStringView action_exec_param_json, MaaToolKitExecAgentArgvTransferMode argv_mode);
MaaBool MAA_TOOLKIT_API MaaToolKitUnregisterCustomActionExecutor( //
MaaInstanceHandle handle, MaaStringView action_name);

#ifdef __cplusplus
}
#endif
1 change: 1 addition & 0 deletions include/MaaToolKit/MaaToolKitAPI.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

#include "Config/MaaToolKitConfig.h"
#include "Device/MaaToolKitDevice.h"
#include "ExecAgent/MaaToolKitExecAgent.h"
#include "Win32/MaaToolKitWin32Window.h"
11 changes: 11 additions & 0 deletions include/MaaToolKit/MaaToolKitDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,14 @@ typedef struct MaaToolKitConfigAPI* MaaToolKitConfigHandle;

struct MaaToolKitTaskAPI;
typedef struct MaaToolKitTaskAPI* MaaToolKitTaskHandle;

typedef int32_t MaaToolKitExecAgentArgvTransferMode;
enum MaaToolKitExecAgentArgvTransferModeEnum
{
MaaToolKitExecAgentArgvTransferMode_Text_StdIO = 1,
// MaaToolKitExecAgentArgvTransferMode_Text_FileIO = 2,
MaaToolKitExecAgentArgvTransferMode_Text_Mask = 0xFF,

MaaToolKitExecAgentArgvTransferMode_Image_FileIO = 1 << 8,
MaaToolKitExecAgentArgvTransferMode_Image_Mask = 0xFF00,
};
7 changes: 2 additions & 5 deletions sample/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,9 @@ MaaBool my_analyze(MaaSyncContextHandle sync_context, const MaaImageBufferHandle

/* Output recognition result */

// Step 1: output out_box
// Step 1: output box
std::array<int, 4> my_box { 0 }; // your result
out_box->x = my_box[0];
out_box->y = my_box[1];
out_box->width = my_box[2];
out_box->height = my_box[3];
MaaSetRect(out_box, my_box[0], my_box[1], my_box[2], my_box[3]);

// Step 2: output anything you want
MaaSetString(out_detail,
Expand Down
8 changes: 0 additions & 8 deletions source/MaaAdbControlUnit/API/AdbControlUnitAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
#include "Input/MinitouchInput.h"
#include "Input/TapInput.h"
#include "Manager/ControlUnitMgr.h"
#include "Platform/PlatformFactory.h"
#include "Screencap/Encode.h"
#include "Screencap/EncodeToFile.h"
#include "Screencap/FastestWay.h"
Expand Down Expand Up @@ -158,13 +157,6 @@ MaaControlUnitHandle MaaAdbControlUnitCreate( //
return nullptr;
}

auto platform_io = PlatformFactory::create();
if (!platform_io) {
LogError << "Create platform io failed";
return nullptr;
}
unit_mgr->set_io(platform_io);

unit_mgr->set_replacement({
{ "{ADB}", adb_path },
{ "{ADB_SERIAL}", adb_serial },
Expand Down
55 changes: 0 additions & 55 deletions source/MaaAdbControlUnit/Base/ArgvWrapper.hpp

This file was deleted.

49 changes: 49 additions & 0 deletions source/MaaAdbControlUnit/Base/ProcessArgvGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include "ProcessArgvGenerator.h"

#include "Utils/IOStream/BoostIO.hpp"
#include "Utils/Logger.h"
#include "Utils/Platform.h"

MAA_CTRL_UNIT_NS_BEGIN

std::optional<ProcessArgvGenerator> ProcessArgvGenerator::create(const json::array& arr)
{
if (!arr.all<std::string>()) {
LogError << "array not all string" << VAR(arr);
return std::nullopt;
}

auto raw = arr.to_vector<std::string>();
if (raw.empty()) {
LogError << "array is empty";
return std::nullopt;
}

return ProcessArgvGenerator(std::move(raw));
}
std::optional<ProcessArgvGenerator::ProcessArgv> ProcessArgvGenerator::gen(const Replacement& replacement) const
{
if (raw_.empty()) {
LogError << "raw is empty";
return std::nullopt;
}

auto res = raw_;
for (auto& s : res) {
string_replace_all_(s, replacement);
}

auto stdpath = MAA_NS::path(res.front());
auto searched_path = boost::process::search_path(stdpath);

if (!std::filesystem::exists(searched_path)) {
LogError << "exec path not exits" << VAR(searched_path);
return std::nullopt;
}

auto args = std::vector(std::make_move_iterator(res.begin() + 1), std::make_move_iterator(res.end()));

return ProcessArgv { .exec = std::move(searched_path), .args = std::move(args) };
}

MAA_CTRL_UNIT_NS_END
36 changes: 36 additions & 0 deletions source/MaaAdbControlUnit/Base/ProcessArgvGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <filesystem>
#include <optional>
#include <unordered_map>

#include <meojson/json.hpp>

#include "Utils/StringMisc.hpp"

MAA_CTRL_UNIT_NS_BEGIN

class ProcessArgvGenerator
{
public:
using Replacement = std::unordered_map<std::string, std::string>;

struct ProcessArgv
{
std::filesystem::path exec;
std::vector<std::string> args;
};

public:
static std::optional<ProcessArgvGenerator> create(const json::array& arr);

ProcessArgvGenerator() = default;
ProcessArgvGenerator(std::vector<std::string> raw) : raw_(std::move(raw)) {}

std::optional<ProcessArgv> gen(const Replacement& replacement) const;

private:
std::vector<std::string> raw_;
};

MAA_CTRL_UNIT_NS_END
49 changes: 17 additions & 32 deletions source/MaaAdbControlUnit/Base/UnitBase.cpp
Original file line number Diff line number Diff line change
@@ -1,26 +1,19 @@
#include "UnitBase.h"

#include "Utils/IOStream/ChildPipeIOStream.h"
#include "Utils/Logger.h"

MAA_CTRL_UNIT_NS_BEGIN

void UnitBase::set_io(std::shared_ptr<PlatformIO> io_ptr)
{
for (auto child : children_) {
child->set_io(io_ptr);
}
io_ptr_ = io_ptr;
}

void UnitBase::set_replacement(Argv::replacement argv_replace)
void UnitBase::set_replacement(Replacement argv_replace)
{
for (auto child : children_) {
child->set_replacement(argv_replace);
}
argv_replace_ = std::move(argv_replace);
}

void UnitBase::merge_replacement(Argv::replacement argv_replace, bool _override)
void UnitBase::merge_replacement(Replacement argv_replace, bool _override)
{
for (auto child : children_) {
child->merge_replacement(argv_replace, _override);
Expand All @@ -35,49 +28,41 @@ void UnitBase::merge_replacement(Argv::replacement argv_replace, bool _override)
}

bool UnitBase::parse_argv(const std::string& key, const json::value& config, const json::array& default_argv,
Argv& argv)
/*out*/ ProcessArgvGenerator& argv)
{
auto jargv = config.get("command", key, default_argv);

if (!argv.parse(jargv)) {
auto opt = ProcessArgvGenerator::create(jargv);
if (!opt) {
LogError << "Parse config failed:" << VAR(key);
return false;
}
argv = std::move(*opt);

return true;
}

std::optional<std::string> UnitBase::command(const Argv::value& cmd, bool recv_by_socket, int64_t timeout)
std::optional<std::string> UnitBase::startup_and_read_pipe(const ProcessArgv& argv, std::chrono::seconds timeout)
{
if (!io_ptr_) {
LogError << "io_ptr is nullptr";
return std::nullopt;
}

auto start_time = std::chrono::steady_clock::now();

std::string pipe_data;
std::string sock_data;
int ret = io_ptr_->call_command(cmd, recv_by_socket, pipe_data, sock_data, timeout);
ChildPipeIOStream ios(argv.exec, argv.args);
std::string output = ios.read(timeout);
bool ret = ios.release();

auto duration = duration_since(start_time);

std::string scmd = json::array(cmd).to_string();
LogDebug << VAR(scmd) << VAR(ret) << VAR(pipe_data.size()) << VAR(sock_data.size()) << VAR(duration);

if (!pipe_data.empty() && pipe_data.size() < 4096) {
LogDebug << MAA_LOG_NS::separator::newline << "stdout output:" << pipe_data;
}
if (recv_by_socket && !sock_data.empty() && sock_data.size() < 4096) {
LogDebug << MAA_LOG_NS::separator::newline << "socket output:" << sock_data;
LogDebug << VAR(output.size()) << VAR(duration);
if (!output.empty() && output.size() < 4096) {
LogDebug << MAA_LOG_NS::separator::newline << "output:" << output;
}

if (ret != 0) {
LogError << "call_command failed" << VAR(cmd) << VAR(ret);
if (!ret) {
LogError << "child return error" << VAR(argv.exec) << VAR(argv.args);
return std::nullopt;
}

return recv_by_socket ? sock_data : pipe_data;
return output;
}

MAA_CTRL_UNIT_NS_END
21 changes: 11 additions & 10 deletions source/MaaAdbControlUnit/Base/UnitBase.h
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
#pragma once

#include <chrono>

#include <meojson/json.hpp>

#include "Base/ArgvWrapper.hpp"
#include "Base/ProcessArgvGenerator.h"
#include "ControlUnit/AdbControlUnitAPI.h"
#include "Platform/PlatformIO.h"
#include "Screencap/ScreencapHelper.h"

MAA_CTRL_UNIT_NS_BEGIN

class UnitBase
{
public:
using Argv = ArgvWrapper<std::vector<std::string>>;
using Replacement = ProcessArgvGenerator::Replacement;
using ProcessArgv = ProcessArgvGenerator::ProcessArgv;

public:
virtual ~UnitBase() = default;

virtual bool parse(const json::value& config) = 0;

virtual void set_io(std::shared_ptr<PlatformIO> io_ptr);
virtual void set_replacement(Argv::replacement argv_replace);
virtual void merge_replacement(Argv::replacement argv_replace, bool _override = true);
virtual void set_replacement(Replacement argv_replace);
virtual void merge_replacement(Replacement argv_replace, bool _override = true);

protected:
static bool parse_argv(const std::string& key, const json::value& config, const json::array& default_argv,
/*out*/ Argv& argv);
/*out*/ ProcessArgvGenerator& argv);

std::optional<std::string> command(const Argv::value& cmd, bool recv_by_socket = false, int64_t timeout = 20000);
std::optional<std::string> startup_and_read_pipe(const ProcessArgv& argv,
std::chrono::seconds timeout = std::chrono::seconds(20));

protected:
std::shared_ptr<PlatformIO> io_ptr_ = nullptr;
std::vector<std::shared_ptr<UnitBase>> children_;
Argv::replacement argv_replace_;
Replacement argv_replace_;
};

class ScreencapBase : public UnitBase
Expand Down
2 changes: 1 addition & 1 deletion source/MaaAdbControlUnit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ add_library(MaaAdbControlUnit SHARED ${maa_adb_control_unit_src} ${maa_adb_contr
target_include_directories(MaaAdbControlUnit PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/../include
${CMAKE_CURRENT_SOURCE_DIR}/../../include)

target_link_libraries(MaaAdbControlUnit MaaUtils HeaderOnlyLibraries ${OpenCV_LIBS} ZLIB::ZLIB Boost::system)
target_link_libraries(MaaAdbControlUnit MaaUtils HeaderOnlyLibraries ${OpenCV_LIBS} ZLIB::ZLIB)
if(WIN32)
target_link_libraries(MaaAdbControlUnit ws2_32)
endif()
Expand Down
Loading

0 comments on commit 6a11a8e

Please sign in to comment.