/***************************
@Author: Chunel
@Contact: chunel@foxmail.com
@File: PyCGraph.cpp
@Time: 2025/1/30 21:43
@Desc:
***************************/
#include
#include
#include
#include "CGraph.h"
#include "wrapper/PyWrapperInclude.h"
using namespace CGraph;
namespace py = pybind11;
PYBIND11_MODULE(pycgraph, cg) {
cg.doc() = "CGraph with python api, github: https://github.com/ChunelFeng/CGraph";
py::class_(cg, "UThreadPoolConfig")
.def(py::init())
.def_readwrite("default_thread_size", &UThreadPoolConfig::default_thread_size_)
.def_readwrite("secondary_thread_size", &UThreadPoolConfig::secondary_thread_size_)
.def_readwrite("max_thread_size", &UThreadPoolConfig::max_thread_size_)
.def_readwrite("max_task_steal_range", &UThreadPoolConfig::max_task_steal_range_)
.def_readwrite("max_local_batch_size", &UThreadPoolConfig::max_local_batch_size_)
.def_readwrite("max_pool_batch_size", &UThreadPoolConfig::max_pool_batch_size_)
.def_readwrite("max_steal_batch_size", &UThreadPoolConfig::max_steal_batch_size_)
.def_readwrite("pipeline_wait_busy_epoch", &UThreadPoolConfig::pipeline_wait_busy_epoch_)
.def_readwrite("primary_thread_busy_epoch", &UThreadPoolConfig::primary_thread_busy_epoch_)
.def_readwrite("primary_thread_empty_interval", &UThreadPoolConfig::primary_thread_empty_interval_)
.def_readwrite("secondary_thread_ttl", &UThreadPoolConfig::secondary_thread_ttl_)
.def_readwrite("monitor_span", &UThreadPoolConfig::monitor_span_)
.def_readwrite("queue_empty_interval", &UThreadPoolConfig::queue_emtpy_interval_)
.def_readwrite("primary_thread_policy", &UThreadPoolConfig::primary_thread_policy_)
.def_readwrite("secondary_thread_policy", &UThreadPoolConfig::secondary_thread_policy_)
.def_readwrite("primary_thread_priority", &UThreadPoolConfig::primary_thread_priority_)
.def_readwrite("secondary_thread_priority", &UThreadPoolConfig::secondary_thread_priority_)
.def_readwrite("bind_cpu_enable", &UThreadPoolConfig::bind_cpu_enable_)
.def_readwrite("batch_task_enable", &UThreadPoolConfig::batch_task_enable_)
.def_readwrite("monitor_enable", &UThreadPoolConfig::monitor_enable_)
.def_readwrite("deliver_running_primary_thread_enable", &UThreadPoolConfig::deliver_running_primary_thread_enable_);
py::class_(cg, "GElementRelation")
.def(py::init())
.def_readonly("predecessors", &GElementRelation::predecessors_)
.def_readonly("successors", &GElementRelation::successors_)
.def_readonly("children", &GElementRelation::children_)
.def_readonly("belong", &GElementRelation::belong_);
py::class_(cg, "UThreadPool")
.def(py::init(),
py::arg("autoInit") = true,
py::arg("config") = UThreadPoolConfig{})
.def("setConfig", &UThreadPool::setConfig,
py::arg("config"),
py::keep_alive())
.def("getConfig", &UThreadPool::getConfig)
.def("init", &UThreadPool::init)
.def("destroy", &UThreadPool::destroy)
.def("isInit", &UThreadPool::isInit);
py::register_exception(cg, "CException");
py::enum_(cg, "GEngineType")
.value("DYNAMIC", GEngineType::DYNAMIC)
.value("TOPO", GEngineType::TOPO)
.value("STATIC", GEngineType::STATIC)
.export_values();
py::enum_(cg, "GElementTimeoutStrategy")
.value("AS_ERROR", GElementTimeoutStrategy::AS_ERROR)
.value("HOLD_BY_PIPELINE", GElementTimeoutStrategy::HOLD_BY_PIPELINE)
.value("NO_HOLD", GElementTimeoutStrategy::NO_HOLD)
.export_values();
py::enum_(cg, "GMultiConditionType")
.value("SERIAL", GMultiConditionType::SERIAL)
.value("PARALLEL", GMultiConditionType::PARALLEL)
.export_values();
py::enum_(cg, "GEventType")
.value("SYNC", GEventType::SYNC)
.value("ASYNC", GEventType::ASYNC)
.export_values();
py::enum_(cg, "GEventAsyncStrategy")
.value("PIPELINE_RUN_FINISH", GEventAsyncStrategy::PIPELINE_RUN_FINISH)
.value("PIPELINE_DESTROY", GEventAsyncStrategy::PIPELINE_DESTROY)
.value("NO_WAIT", GEventAsyncStrategy::NO_WAIT)
.export_values();
py::enum_(cg, "CFunctionType")
.value("INIT", CFunctionType::INIT)
.value("RUN", CFunctionType::RUN)
.value("DESTROY", CFunctionType::DESTROY)
.export_values();
py::enum_(cg, "GElementState")
.value("NORMAL", GElementState::NORMAL)
.value("CANCEL", GElementState::CANCEL)
.value("SUSPEND", GElementState::SUSPEND)
.value("TIMEOUT", GElementState::TIMEOUT)
.export_values();
cg.attr("GPipelineState") = cg.attr("GElementState");
py::enum_(cg, "StdLaunchPolicy")
.value("ASYNC", std::launch::async)
.value("DEFERRED", std::launch::deferred)
.export_values();
py::class_(cg, "StdSharedFutureVoid")
.def("wait", [] (std::shared_future& fut) {
fut.wait();
}, py::call_guard());
py::class_(cg, "StdFutureCStatus")
.def("get", [] (std::future& fut) {
return fut.get();
}, py::call_guard())
.def("wait", [] (std::future& fut) {
fut.wait();
}, py::call_guard());
py::class_(cg, "CStatus")
.def(py::init())
.def(py::init(),
py::arg("errorCode"),
py::arg("errorInfo"))
.def("__iadd__", &CStatus::operator+=,
py::return_value_policy::reference)
.def("__bool__", &CStatus::operator bool)
.def("getCode", &CStatus::getCode)
.def("getInfo", &CStatus::getInfo)
.def("reset", &CStatus::reset)
.def("isOK", &CStatus::isOK)
.def("isErr", &CStatus::isErr)
.def("isCrash", &CStatus::isCrash);
py::class_(cg, "GAspect")
.def(py::init())
.def("getName", &GAspect::__getName_4py)
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GAspect)
.PYCGRAPH_DEF_GEVENT_PYBIND11_FUNCTIONS(GAspect);
py::class_(cg, "GDaemon")
.def(py::init())
.def("getInterval", &GDaemon::__getInterval_4py)
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GDaemon)
.PYCGRAPH_DEF_GEVENT_PYBIND11_FUNCTIONS(GDaemon);
py::class_(cg, "GEvent")
.def(py::init())
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GEvent);
py::class_(cg, "GStage")
.def(py::init())
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GStage);
py::class_(cg, "GParam")
.def(py::init())
.def("lock", &GParam::lock,
py::call_guard())
.def("unlock", &GParam::unlock,
py::call_guard())
.def("tryLock", &GParam::tryLock,
py::call_guard())
.def("addTrace", &GParam::addTrace,
py::arg("trace"),
py::arg("repeatable") = true,
py::call_guard())
.def("removeTrace", &GParam::removeTrace,
py::arg("trace"),
py::call_guard())
.def("clearTrace", &GParam::clearTrace,
py::call_guard())
.def("getTraces", &GParam::getTraces,
py::call_guard())
.def("__enter__", [](GParam& self) -> GParam& {
self.lock();
return self;
}, py::call_guard(), py::return_value_policy::reference_internal)
.def("__exit__", [](GParam& self, py::object, py::object, py::object) {
self.unlock();
return false;
}, py::call_guard());
py::class_(cg, "GPassedParam")
.def(py::init());
cg.attr("GElementParam") = cg.attr("GPassedParam");
cg.attr("GDaemonParam") = cg.attr("GPassedParam");
cg.attr("GStageParam") = cg.attr("GPassedParam");
cg.attr("GEventParam") = cg.attr("GPassedParam");
py::class_(cg, "GPipeline")
.def(py::init([]() { return GPipelineFactory::create(); }))
.def("init", &GPipeline::init)
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GPipeline)
.def("setUniqueThreadPoolConfig", &GPipeline::setUniqueThreadPoolConfig,
py::arg("config"))
.def("setSharedThreadPool", &GPipeline::setSharedThreadPool,
py::arg("ptr"),
py::call_guard(),
py::keep_alive())
.def("setGEngineType", &GPipeline::setGEngineType,
py::arg("type"))
.def("run", &GPipeline::run,
py::call_guard())
.def("process", &GPipeline::process,
py::arg("runTimes") = 1,
py::call_guard())
.def("destroy", &GPipeline::destroy)
.def("addGEvent", &GPipeline::__addGEvent_4py,
py::arg("event"),
py::arg("key"),
py::keep_alive())
.def("addGDaemon", &GPipeline::__addGDaemon_4py,
py::arg("daemon"),
py::arg("ms"),
py::keep_alive())
.def("addGStage", &GPipeline::__addGStage_4py,
py::arg("stage"),
py::arg("key"),
py::arg("threshold"),
py::keep_alive())
.def("asyncRun", &GPipeline::asyncRun,
py::arg("policy") = std::launch::async,
py::call_guard())
.def("asyncProcess", &GPipeline::asyncProcess,
py::arg("runTimes") = CGRAPH_DEFAULT_LOOP_TIMES,
py::arg("policy") = std::launch::async,
py::call_guard())
.def("cancel", &GPipeline::cancel,
py::call_guard())
.def("suspend", &GPipeline::suspend,
py::call_guard())
.def("resume", &GPipeline::resume,
py::call_guard())
.def("perf", &GPipeline::__perf_4py,
py::call_guard())
.def("dump", &GPipeline::__dump_4py)
.def("trim", &GPipeline::trim)
.def("makeSerial", &GPipeline::makeSerial)
.def("getMaxPara", &GPipeline::getMaxPara)
.def("getCurState", &GPipeline::getCurState)
.def("checkSeparate", &GPipeline::checkSeparate,
py::arg("fst"),
py::arg("snd"))
.def("registerGElement", &GPipeline::__registerGElement_4py,
py::arg("element"),
py::arg("depends") = GElementPtrSet{},
py::arg("name") = CGRAPH_EMPTY,
py::arg("loop") = CGRAPH_DEFAULT_LOOP_TIMES,
py::keep_alive());
py::class_(cg, "GPipelineManager")
.def(py::init())
.def("init", &GPipelineManager::init)
.def("run", &GPipelineManager::run,
py::call_guard())
.def("destroy", &GPipelineManager::destroy)
.def("add", &GPipelineManager::add,
py::arg("ptr"),
py::keep_alive())
.def("clear", &GPipelineManager::clear)
.def("find", &GPipelineManager::find,
py::arg("ptr"))
.def("remove", &GPipelineManager::remove,
py::arg("ptr"))
.def("getSize", &GPipelineManager::getSize)
.def("fetch", &GPipelineManager::fetch,
py::call_guard())
.def("release", &GPipelineManager::release,
py::arg("ptr"),
py::call_guard());
py::class_(cg, "GElement")
.def(py::init())
.def("__str__", &GElement::__str_4py)
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GElement)
.PYCGRAPH_DEF_GEVENT_PYBIND11_FUNCTIONS(GElement)
.def("enterStage", &GElement::__enterStage_4py,
py::arg("key"),
py::call_guard())
.def("getName", &GElement::getName)
.def("getSession", &GElement::getSession)
.def("getRelation", &GElement::getRelation)
.def("getLoop", &GElement::getLoop)
.def("getCurState", &GElement::getCurState)
.def("setLoop", &GElement::setLoop,
py::arg("loop"))
.def("setName", &GElement::setName,
py::arg("name"))
.def("setLevel", &GElement::setLevel,
py::arg("level"))
.def("setVisible", &GElement::setVisible,
py::arg("visible"))
.def("setMacro", &GElement::setMacro,
py::arg("macro"))
.def("setTimeout", &GElement::setTimeout,
py::arg("timeout"),
py::arg("strategy") = GElementTimeoutStrategy::AS_ERROR)
.def("isTimeout", &GElement::__isTimeout_4py)
.def("isGGroup", &GElement::isGGroup)
.def("isGAdaptor", &GElement::isGAdaptor)
.def("isGNode", &GElement::isGNode)
.def("addGAspect", &GElement::__addGAspect_4py,
py::arg("aspect"),
py::keep_alive())
.def("addDependGElements", &GElement::addDependGElements,
py::arg("elements"))
.def("removeDepend", &GElement::removeDepend,
py::arg("element"));
py::class_(cg, "GNode")
.def(py::init(),
py::arg("name"),
py::arg("loop") = CGRAPH_DEFAULT_LOOP_TIMES)
.def(py::init(),
py::arg("depends") = GElementPtrSet{},
py::arg("name") = CGRAPH_EMPTY,
py::arg("loop") = CGRAPH_DEFAULT_LOOP_TIMES);
py::class_(cg, "GFence")
.def(py::init())
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GFence)
.def("waitGElement", &GFence::waitGElement,
py::arg("element"))
.def("waitGElements", &GFence::waitGElements,
py::arg("elements"))
.def("clear", &GFence::clear);
py::class_(cg, "GFunction")
.def(py::init())
.PYCGRAPH_DEF_GPARAM_PYBIND11_FUNCTIONS(GFunction)
.PYCGRAPH_DEF_GEVENT_PYBIND11_FUNCTIONS(GFunction)
.def("setFunction", &GFunction::setFunction,
py::arg("type"),
py::arg("func"));
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GCluster);
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GRegion);
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GCondition);
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GSerialMultiCondition);
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GParallelMultiCondition);
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GSome);
PYCGRAPH_DECLARE_GGROUP_PYBIND11_FUNCTIONS(GMutable);
}