/*************************** @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<1, 2>()) .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("__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<1, 2>()) .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<1, 2>()) .def("addGDaemon", &GPipeline::__addGDaemon_4py, py::arg("daemon"), py::arg("ms"), py::keep_alive<1, 2>()) .def("addGStage", &GPipeline::__addGStage_4py, py::arg("stage"), py::arg("key"), py::arg("threshold"), py::keep_alive<1, 2>()) .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<1, 2>()); 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<1, 2>()) .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<1, 2>()) .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); }