[Mod]new pybind11 wrap
This commit is contained in:
parent
8a2489ebf9
commit
416f2a1e17
@ -7,19 +7,34 @@ if typing.TYPE_CHECKING:
|
||||
from .vnxtp import *
|
||||
|
||||
|
||||
def set_async_callback_exception_handler(handler: Callable[[AsyncDispatchException], None]):
|
||||
"""
|
||||
set a customize exception handler for async callback in this module(pyd)
|
||||
\a handler should return True if it handles that exception,
|
||||
If the return value of \a handler is not True, exception will be re-thrown.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class AsyncDispatchException:
|
||||
what: str
|
||||
instance: object
|
||||
function_name: str
|
||||
|
||||
|
||||
from . import vnxtp_XTP as XTP
|
||||
class XTPRspInfoStruct():
|
||||
|
||||
|
||||
error_id: int
|
||||
error_msg: Sequence[int]
|
||||
error_msg: str
|
||||
|
||||
|
||||
class XTPSpecificTickerStruct():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
|
||||
|
||||
class XTPMarketDataStockExData():
|
||||
@ -71,7 +86,7 @@ class XTPMarketDataStruct():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
last_price: float
|
||||
pre_close_price: float
|
||||
open_price: float
|
||||
@ -95,7 +110,7 @@ class XTPMarketDataStruct():
|
||||
bid_qty: Sequence[int]
|
||||
ask_qty: Sequence[int]
|
||||
trades_count: int
|
||||
ticker_status: Sequence[int]
|
||||
ticker_status: str
|
||||
stk: XTPMarketDataStockExData
|
||||
opt: XTPMarketDataOptionExData
|
||||
data_type: XTP_MARKETDATA_TYPE
|
||||
@ -106,8 +121,8 @@ class XTPQuoteStaticInfo():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker_name: Sequence[int]
|
||||
ticker: str
|
||||
ticker_name: str
|
||||
ticker_type: XTP_TICKER_TYPE
|
||||
pre_close_price: float
|
||||
upper_limit_price: float
|
||||
@ -121,7 +136,7 @@ class OrderBookStruct():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
last_price: float
|
||||
qty: int
|
||||
turnover: float
|
||||
@ -161,7 +176,7 @@ class XTPTickByTickStruct():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
seq: int
|
||||
data_time: int
|
||||
type: XTP_TBT_TYPE
|
||||
@ -173,7 +188,7 @@ class XTPTickerPriceInfo():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
last_price: float
|
||||
|
||||
|
||||
@ -182,7 +197,7 @@ class XTPOrderInsertInfo():
|
||||
|
||||
order_xtp_id: int
|
||||
order_client_id: int
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
market: XTP_MARKET_TYPE
|
||||
price: float
|
||||
stop_price: float
|
||||
@ -210,7 +225,7 @@ class XTPOrderInfo():
|
||||
order_client_id: int
|
||||
order_cancel_client_id: int
|
||||
order_cancel_xtp_id: int
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
market: XTP_MARKET_TYPE
|
||||
price: float
|
||||
quantity: int
|
||||
@ -227,7 +242,7 @@ class XTPOrderInfo():
|
||||
update_time: int
|
||||
cancel_time: int
|
||||
trade_amount: float
|
||||
order_local_id: Sequence[int]
|
||||
order_local_id: str
|
||||
order_status: XTP_ORDER_STATUS_TYPE
|
||||
order_submit_status: XTP_ORDER_SUBMIT_STATUS_TYPE
|
||||
order_type: int
|
||||
@ -238,16 +253,16 @@ class XTPTradeReport():
|
||||
|
||||
order_xtp_id: int
|
||||
order_client_id: int
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
market: XTP_MARKET_TYPE
|
||||
local_order_id: int
|
||||
exec_id: Sequence[int]
|
||||
exec_id: str
|
||||
price: float
|
||||
quantity: int
|
||||
trade_time: int
|
||||
trade_amount: float
|
||||
report_index: int
|
||||
order_exch_id: Sequence[int]
|
||||
order_exch_id: str
|
||||
trade_type: int
|
||||
u32: int
|
||||
side: int
|
||||
@ -255,13 +270,13 @@ class XTPTradeReport():
|
||||
reserved1: int
|
||||
reserved2: int
|
||||
business_type: XTP_BUSINESS_TYPE
|
||||
branch_pbu: Sequence[int]
|
||||
branch_pbu: str
|
||||
|
||||
|
||||
class XTPQueryOrderReq():
|
||||
|
||||
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
begin_time: int
|
||||
end_time: int
|
||||
|
||||
@ -270,13 +285,13 @@ class XTPQueryReportByExecIdReq():
|
||||
|
||||
|
||||
order_xtp_id: int
|
||||
exec_id: Sequence[int]
|
||||
exec_id: str
|
||||
|
||||
|
||||
class XTPQueryTraderReq():
|
||||
|
||||
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
begin_time: int
|
||||
end_time: int
|
||||
|
||||
@ -311,8 +326,8 @@ class XTPQueryAssetRsp():
|
||||
class XTPQueryStkPositionRsp():
|
||||
|
||||
|
||||
ticker: Sequence[int]
|
||||
ticker_name: Sequence[int]
|
||||
ticker: str
|
||||
ticker_name: str
|
||||
market: XTP_MARKET_TYPE
|
||||
total_qty: int
|
||||
sellable_qty: int
|
||||
@ -350,17 +365,17 @@ class XTPQueryStructuredFundInfoReq():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
sf_ticker: Sequence[int]
|
||||
sf_ticker: str
|
||||
|
||||
|
||||
class XTPStructuredFundInfo():
|
||||
|
||||
|
||||
exchange_id: XTP_EXCHANGE_TYPE
|
||||
sf_ticker: Sequence[int]
|
||||
sf_ticker_name: Sequence[int]
|
||||
ticker: Sequence[int]
|
||||
ticker_name: Sequence[int]
|
||||
sf_ticker: str
|
||||
sf_ticker_name: str
|
||||
ticker: str
|
||||
ticker_name: str
|
||||
split_merge_status: XTP_SPLIT_MERGE_STATUS
|
||||
ratio: int
|
||||
min_split_qty: int
|
||||
@ -372,15 +387,15 @@ class XTPQueryETFBaseReq():
|
||||
|
||||
|
||||
market: XTP_MARKET_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
|
||||
|
||||
class XTPQueryETFBaseRsp():
|
||||
|
||||
|
||||
market: XTP_MARKET_TYPE
|
||||
etf: Sequence[int]
|
||||
subscribe_redemption_ticker: Sequence[int]
|
||||
etf: str
|
||||
subscribe_redemption_ticker: str
|
||||
unit: int
|
||||
subscribe_status: int
|
||||
redemption_status: int
|
||||
@ -395,16 +410,16 @@ class XTPQueryETFComponentReq():
|
||||
|
||||
|
||||
market: XTP_MARKET_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
|
||||
|
||||
class XTPQueryETFComponentRsp():
|
||||
|
||||
|
||||
market: XTP_MARKET_TYPE
|
||||
ticker: Sequence[int]
|
||||
component_ticker: Sequence[int]
|
||||
component_name: Sequence[int]
|
||||
ticker: str
|
||||
component_ticker: str
|
||||
component_name: str
|
||||
quantity: int
|
||||
component_market: XTP_MARKET_TYPE
|
||||
replace_type: ETF_REPLACE_TYPE
|
||||
@ -416,8 +431,8 @@ class XTPQueryIPOTickerRsp():
|
||||
|
||||
|
||||
market: XTP_MARKET_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker_name: Sequence[int]
|
||||
ticker: str
|
||||
ticker_name: str
|
||||
price: float
|
||||
unit: int
|
||||
qty_upper_limit: int
|
||||
@ -434,17 +449,17 @@ class XTPQueryOptionAuctionInfoReq():
|
||||
|
||||
|
||||
market: XTP_MARKET_TYPE
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
|
||||
|
||||
class XTPQueryOptionAuctionInfoRsp():
|
||||
|
||||
|
||||
ticker: Sequence[int]
|
||||
ticker: str
|
||||
security_id_source: XTP_MARKET_TYPE
|
||||
symbol: Sequence[int]
|
||||
contract_id: Sequence[int]
|
||||
underlying_security_id: Sequence[int]
|
||||
symbol: str
|
||||
contract_id: str
|
||||
underlying_security_id: str
|
||||
underlying_security_id_source: XTP_MARKET_TYPE
|
||||
list_date: int
|
||||
last_trade_date: int
|
||||
@ -483,8 +498,8 @@ class XTPFundTransferReq():
|
||||
|
||||
|
||||
serial_id: int
|
||||
fund_account: Sequence[int]
|
||||
password: Sequence[int]
|
||||
fund_account: str
|
||||
password: str
|
||||
amount: float
|
||||
transfer_type: XTP_FUND_TRANSFER_TYPE
|
||||
|
||||
@ -610,7 +625,7 @@ class XTP_POSITION_DIRECTION_TYPE(Enum):
|
||||
class XTP_MARKETDATA_TYPE(Enum):
|
||||
XTP_MARKETDATA_ACTUAL: XTP_MARKETDATA_TYPE
|
||||
XTP_MARKETDATA_OPTION: XTP_MARKETDATA_TYPE
|
||||
XTPVersionType = Sequence[int]
|
||||
XTPVersionType = str
|
||||
XTP_LOG_LEVEL = XTP_LOG_LEVEL
|
||||
XTP_PROTOCOL_TYPE = XTP_PROTOCOL_TYPE
|
||||
XTP_EXCHANGE_TYPE = XTP_EXCHANGE_TYPE
|
||||
|
@ -277,9 +277,14 @@ void generate_class_XTP_API_QuoteApi(pybind11::object & parent)
|
||||
PyQuoteApi
|
||||
> c(parent, "QuoteApi");
|
||||
c.def_static("CreateQuoteApi",
|
||||
autocxxpy::apply_function_transform<
|
||||
autocxxpy::function_constant<
|
||||
&XTP::API::QuoteApi::CreateQuoteApi
|
||||
//,
|
||||
//pybind11::call_guard<pybind11::gil_scoped_release>()
|
||||
>,
|
||||
brigand::list<
|
||||
>
|
||||
>::value,
|
||||
pybind11::call_guard<pybind11::gil_scoped_release>()
|
||||
);
|
||||
c.def("Release",
|
||||
autocxxpy::apply_function_transform<
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/functional.h>
|
||||
#include <autocxxpy/autocxxpy.hpp>
|
||||
|
||||
#include "module.hpp"
|
||||
@ -20,6 +21,12 @@ void additional_init(pybind11::module &m)
|
||||
|
||||
void init_dispatcher(pybind11::module &m)
|
||||
{
|
||||
m.def("set_async_callback_exception_handler", &autocxxpy::async_callback_exception_handler::set_handler);
|
||||
pybind11::class_<autocxxpy::async_dispatch_exception> c(m, "AsyncDispatchException");
|
||||
c.def_property("what", &autocxxpy::async_dispatch_exception::what, nullptr);
|
||||
c.def_readonly("instance", &autocxxpy::async_dispatch_exception::instance);
|
||||
c.def_readonly("function_name", &autocxxpy::async_dispatch_exception::function_name);
|
||||
|
||||
autocxxpy::dispatcher::instance().start();
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <optional>
|
||||
|
||||
#include "brigand.hpp"
|
||||
|
||||
@ -66,7 +67,7 @@ namespace autocxxpy
|
||||
template <auto method>
|
||||
constexpr callback_type callback_type_of_v = callback_type_of<method>::value;
|
||||
|
||||
#ifdef PYBIND11_OVERLOAD_NAME
|
||||
#ifdef AUTOCXXPY_INCLUDED_PYBIND11
|
||||
template <class ret_type>
|
||||
struct pybind11_static_caster {
|
||||
static pybind11::detail::overload_caster_t<ret_type> caster;
|
||||
@ -75,18 +76,59 @@ namespace autocxxpy
|
||||
template <class ret_type>
|
||||
AUTOCXXPY_SELECT_ANY pybind11::detail::overload_caster_t<ret_type> pybind11_static_caster<ret_type>::caster;
|
||||
|
||||
struct async_dispatch_exception : public std::exception
|
||||
{
|
||||
async_dispatch_exception(const char *what, const pybind11::object &instance, std::string function_name)
|
||||
: std::exception(what), instance(instance), function_name(function_name)
|
||||
{}
|
||||
pybind11::object instance;
|
||||
std::string function_name;
|
||||
inline const char* what() noexcept
|
||||
{
|
||||
return std::exception::what();
|
||||
}
|
||||
};
|
||||
|
||||
struct async_callback_exception_handler
|
||||
{
|
||||
using handler_type = std::function<void(const async_dispatch_exception&)>;
|
||||
static handler_type custom_handler;
|
||||
|
||||
inline static void handle_excepiton(const async_dispatch_exception&e)
|
||||
{
|
||||
if (custom_handler)
|
||||
{
|
||||
custom_handler(e);
|
||||
}
|
||||
}
|
||||
|
||||
inline static void set_handler(const handler_type& handler)
|
||||
{
|
||||
custom_handler = handler;
|
||||
}
|
||||
};
|
||||
|
||||
AUTOCXXPY_SELECT_ANY async_callback_exception_handler::handler_type async_callback_exception_handler::custom_handler;
|
||||
#endif
|
||||
|
||||
namespace arg_helper
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// stores
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// # todo: char8, char16, char32, wchar_t, etc...
|
||||
// # todo: shall i copy only const type, treating non-const type as output pointer?
|
||||
inline auto save(const char *val)
|
||||
inline std::optional<std::string> save(const char* val)
|
||||
{ // match const char *
|
||||
if (nullptr == val) AUTOCXXPY_UNLIKELY
|
||||
return std::nullopt; // maybe empty string is also a choice?
|
||||
return std::string(val);
|
||||
}
|
||||
inline auto save(char *val)
|
||||
inline std::optional<std::string> save(char* val)
|
||||
{ // match char *
|
||||
if (nullptr == val) AUTOCXXPY_UNLIKELY
|
||||
return std::nullopt; // maybe empty string is also a choice?
|
||||
return std::string(val);
|
||||
}
|
||||
template<size_t size>
|
||||
@ -101,29 +143,41 @@ namespace autocxxpy
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T &save(T *val)
|
||||
inline std::optional<T> save(T * val)
|
||||
{ // match pointer
|
||||
if (nullptr == val) AUTOCXXPY_UNLIKELY
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return *val;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T &save(const T *val)
|
||||
inline std::optional<T>& save(const T * val)
|
||||
{ // match const pointer
|
||||
if (nullptr == val) AUTOCXXPY_UNLIKELY
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
return const_cast<T&>(*val);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline T &save(const T &val)
|
||||
inline T& save(const T & val)
|
||||
{ // match everything else : just use original type
|
||||
return const_cast<T&>(val);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// loads
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
template <class to_type>
|
||||
struct loader
|
||||
{ // match default(everyting besides pointer)
|
||||
template <class src_type>
|
||||
inline to_type operator ()(src_type &val)
|
||||
inline to_type operator ()(src_type& val)
|
||||
{
|
||||
return val;
|
||||
}
|
||||
@ -132,57 +186,57 @@ namespace autocxxpy
|
||||
template <size_t size>
|
||||
struct loader<const string_array<size>>
|
||||
{ // match const char []
|
||||
using to_type = const char *;
|
||||
inline to_type operator ()(const std::string &val)
|
||||
using to_type = const char*;
|
||||
inline to_type operator ()(const std::string& val)
|
||||
{
|
||||
return const_cast<char *>(val.data());
|
||||
return const_cast<char*>(val.data());
|
||||
}
|
||||
};
|
||||
|
||||
template <size_t size>
|
||||
struct loader<string_array<size>>
|
||||
{ // match char []
|
||||
using to_type = char *;
|
||||
inline to_type operator ()(const std::string &val)
|
||||
using to_type = char*;
|
||||
inline to_type operator ()(const std::string& val)
|
||||
{
|
||||
return const_cast<char *>(val.data());
|
||||
return const_cast<char*>(val.data());
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct loader<const char *>
|
||||
struct loader<const char*>
|
||||
{ // match const char *
|
||||
using to_type = const char *;
|
||||
inline to_type operator ()(const std::string &val)
|
||||
using to_type = const char*;
|
||||
inline to_type operator ()(const std::optional<std::string>& val)
|
||||
{
|
||||
return const_cast<char *>(val.data());
|
||||
if (val) AUTOCXXPY_LIKELY
|
||||
return const_cast<char*>(val->data());
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct loader<char *>
|
||||
struct loader<char*>
|
||||
{ // match char *
|
||||
using to_type = char *;
|
||||
inline to_type operator ()(const std::string &val)
|
||||
using to_type = char*;
|
||||
inline to_type operator ()(const std::optional<std::string>& val)
|
||||
{
|
||||
return const_cast<char *>(val.data());
|
||||
if (val) AUTOCXXPY_LIKELY
|
||||
return const_cast<char*>(val->data());
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
template <class to_type>
|
||||
struct loader<to_type *>
|
||||
struct loader<to_type*>
|
||||
{ // match pointer
|
||||
template <class src_type>
|
||||
inline to_type *operator ()(src_type &val)
|
||||
inline to_type* operator ()(const std::optional<src_type>& val)
|
||||
{ // val to poiner
|
||||
return const_cast<to_type *>(&val);
|
||||
if (val) AUTOCXXPY_LIKELY
|
||||
return const_cast<to_type*>(&(*val));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//template <class src_type>
|
||||
//inline to_type *operator ()(src_type *val)
|
||||
//{ // pointer to pointer
|
||||
// return val;
|
||||
//}
|
||||
};
|
||||
|
||||
};
|
||||
@ -195,7 +249,7 @@ namespace autocxxpy
|
||||
using class_type = class_of_member_method_t<method>;
|
||||
public:
|
||||
template <class ... arg_types>
|
||||
inline static ret_type call(class_type *instance, const char *py_func_name, arg_types ... args)
|
||||
inline static ret_type call(class_type* instance, const char* py_func_name, arg_types ... args)
|
||||
{
|
||||
if constexpr (callback_type_of_v<method> == callback_type::Direct)
|
||||
{
|
||||
@ -211,47 +265,70 @@ namespace autocxxpy
|
||||
}
|
||||
|
||||
template <class ... arg_types>
|
||||
inline static void async(class_type *instance, const char *py_func_name, arg_types ... args)
|
||||
inline static void async(class_type* instance, const char* py_func_name, arg_types ... args)
|
||||
{
|
||||
return async_impl(instance, py_func_name, std::index_sequence_for<arg_types ...>{}, args ...);
|
||||
}
|
||||
|
||||
template <class ... arg_types>
|
||||
inline static ret_type sync(class_type *instance, const char * py_func_name, arg_types ... args)
|
||||
inline static ret_type sync(class_type * instance, const char* py_func_name, arg_types ... args)
|
||||
{
|
||||
// if this code is under test environment, we don't need pybind11
|
||||
// since header of pybind11 use #pragma once, no macros is defined, we use a public macro to check if pybind11 is included or not
|
||||
#ifdef PYBIND11_OVERLOAD_NAME
|
||||
pybind11::gil_scoped_acquire gil;
|
||||
pybind11::function overload = pybind11::get_overload(static_cast<const class_type *>(instance), py_func_name);
|
||||
if (overload) {
|
||||
auto o = overload(args ...);
|
||||
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) {
|
||||
auto & caster = pybind11_static_caster<ret_type>::caster;
|
||||
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster);
|
||||
pybind11::function overload = pybind11::get_overload(static_cast<const class_type*>(instance), py_func_name);
|
||||
if (overload) AUTOCXXPY_LIKELY{
|
||||
try
|
||||
{
|
||||
auto result = overload(args ...);
|
||||
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value)
|
||||
{
|
||||
auto& caster = pybind11_static_caster<ret_type>::caster;
|
||||
return pybind11::detail::cast_ref<ret_type>(std::move(result), caster);
|
||||
}
|
||||
else
|
||||
{
|
||||
return pybind11::detail::cast_safe<ret_type>(std::move(result));
|
||||
}
|
||||
}
|
||||
catch (const pybind11::error_already_set & e)
|
||||
{
|
||||
// todo: option to not to throw when sync is called directly
|
||||
throw async_dispatch_exception(e.what(), pybind11::cast(instance), py_func_name);
|
||||
}
|
||||
else return pybind11::detail::cast_safe<ret_type>(std::move(o));
|
||||
}
|
||||
#endif
|
||||
return (instance->*method)(args ...);
|
||||
}
|
||||
private:
|
||||
template <class ... arg_types, size_t ... idx>
|
||||
inline static void async_impl(class_type *instance, const char *py_func_name, std::index_sequence<idx ...>, arg_types ... args)
|
||||
inline static void async_impl(class_type * instance, const char* py_func_name, std::index_sequence<idx ...>, arg_types ... args)
|
||||
{
|
||||
// wrap for ctp like function calls:
|
||||
// all the pointer might be unavailable after this call, so copy its value into a tuple
|
||||
auto arg_tuple = std::make_tuple(arg_helper::save(args) ...);
|
||||
auto task = [instance, py_func_name, arg_tuple = std::move(arg_tuple)]()
|
||||
{
|
||||
// resolve all value:
|
||||
// if it was originally a pointer, then use pointer type.
|
||||
// if it was originally a value, just keep a reference to that value.
|
||||
sync<arg_types ...>(
|
||||
instance, py_func_name,
|
||||
arg_helper::loader<brigand::at<brigand::list<arg_types ...>, brigand::integral_constant<int, idx> > >{}
|
||||
(std::get<idx>(arg_tuple)) ...
|
||||
);
|
||||
#ifdef AUTOCXXPY_INCLUDED_PYBIND11
|
||||
try
|
||||
{
|
||||
#endif
|
||||
// resolve all value:
|
||||
// if it was originally a pointer, then use pointer type.
|
||||
// if it was originally a value, just keep a reference to that value.
|
||||
sync<arg_types ...>(
|
||||
instance, py_func_name,
|
||||
arg_helper::loader<brigand::at<brigand::list<arg_types ...>, brigand::integral_constant<int, idx> > >{}
|
||||
(std::get<idx>(arg_tuple)) ...
|
||||
);
|
||||
#ifdef AUTOCXXPY_INCLUDED_PYBIND11
|
||||
}
|
||||
catch (const async_dispatch_exception &e)
|
||||
{
|
||||
async_callback_exception_handler::handle_excepiton(e);
|
||||
}
|
||||
#endif
|
||||
};
|
||||
dispatcher::instance().add(std::move(task));
|
||||
}
|
||||
|
@ -8,12 +8,30 @@
|
||||
|
||||
|
||||
#ifndef AUTOCXXPY_UNUSED
|
||||
#define AUTOCXXPY_UNUSED(x) (void)(x)
|
||||
# define AUTOCXXPY_UNUSED(x) (void)(x)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define AUTOCXXPY_SELECT_ANY __declspec(selectany)
|
||||
# define AUTOCXXPY_SELECT_ANY __declspec(selectany)
|
||||
|
||||
#else
|
||||
#define AUTOCXXPY_SELECT_ANY __attribute__ ((selectany))
|
||||
#endif
|
||||
# define AUTOCXXPY_SELECT_ANY __attribute__ ((selectany))
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __has_cpp_attribute
|
||||
# if __has_cpp_attribute(likely)
|
||||
# define AUTOCXXPY_LIKELY [[likely]]
|
||||
# endif
|
||||
# if __has_cpp_attribute(unlikely)
|
||||
# define AUTOCXXPY_UNLIKELY [[unlikely]]
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef AUTOCXXPY_LIKELY
|
||||
#define AUTOCXXPY_LIKELY
|
||||
#endif
|
||||
|
||||
#ifndef AUTOCXXPY_UNLIKELY
|
||||
#define AUTOCXXPY_UNLIKELY
|
||||
#endif
|
||||
|
@ -119,6 +119,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -138,6 +139,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -160,6 +162,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@ -184,6 +187,7 @@
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
<DisableSpecificWarnings>4819</DisableSpecificWarnings>
|
||||
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
@ -7,5 +7,20 @@ if typing.TYPE_CHECKING:
|
||||
from .vnxtp import *
|
||||
|
||||
|
||||
def set_async_callback_exception_handler(handler: Callable[[Exception, object, str], bool]):
|
||||
"""
|
||||
set a customize exception handler for async callback in this module(pyd)
|
||||
\a handler should return True if it handles that exception,
|
||||
If the return value of \a handler is not True, exception will be re-thrown.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class AsyncDispatchException:
|
||||
what: str
|
||||
instance: object
|
||||
function_name: str
|
||||
|
||||
|
||||
from . import vnxtp_XTP_API as API
|
||||
|
||||
|
@ -7,6 +7,21 @@ if typing.TYPE_CHECKING:
|
||||
from .vnxtp import *
|
||||
|
||||
|
||||
def set_async_callback_exception_handler(handler: Callable[[Exception, object, str], bool]):
|
||||
"""
|
||||
set a customize exception handler for async callback in this module(pyd)
|
||||
\a handler should return True if it handles that exception,
|
||||
If the return value of \a handler is not True, exception will be re-thrown.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class AsyncDispatchException:
|
||||
what: str
|
||||
instance: object
|
||||
function_name: str
|
||||
|
||||
|
||||
class TraderSpi():
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user