diff --git a/CMakeLists.txt b/CMakeLists.txt index 572e4e0ac..32a983442 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -242,8 +242,10 @@ function(csp_autogen MODULE_NAME DEST_FILENAME HEADER_NAME_OUTVAR SOURCE_NAME_OU cmake_path(SET CSP_AUTOGEN_MODULE_PATH NORMALIZE "${CMAKE_SOURCE_DIR}/csp/build/csp_autogen.py") cmake_path(SET CSP_AUTOGEN_DESTINATION_FOLDER NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen") - cmake_path(SET CSP_AUTOTGEN_CPP_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.cpp") - cmake_path(SET CSP_AUTOTGEN_H_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.h") + cmake_path(SET CSP_AUTOGEN_CPP_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.cpp") + cmake_path(SET CSP_AUTOGEN_CPP_MAYBE_EXISTING NORMALIZE "${CMAKE_CURRENT_SOURCE_DIR}/csp_autogen/${DEST_FILENAME}.cpp") + cmake_path(SET CSP_AUTOGEN_H_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.h") + cmake_path(SET CSP_AUTOGEN_H_MAYBE_EXISTING NORMALIZE "${CMAKE_CURRENT_SOURCE_DIR}/csp_autogen/${DEST_FILENAME}.h") if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(CSP_AUTOGEN_PYTHONPATH ${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE};${CMAKE_SOURCE_DIR};%PYTHONPATH% ) @@ -251,17 +253,23 @@ function(csp_autogen MODULE_NAME DEST_FILENAME HEADER_NAME_OUTVAR SOURCE_NAME_OU set(CSP_AUTOGEN_PYTHONPATH ${PROJECT_BINARY_DIR}/lib:${CMAKE_SOURCE_DIR}:$$PYTHONPATH ) endif() - add_custom_command(OUTPUT "${CSP_AUTOTGEN_CPP_OUT}" "${CSP_AUTOTGEN_H_OUT}" - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CSP_AUTOGEN_PYTHONPATH}" ${Python_EXECUTABLE} ${CSP_AUTOGEN_MODULE_PATH} -m ${MODULE_NAME} -d ${CSP_AUTOGEN_DESTINATION_FOLDER} -o ${DEST_FILENAME} ${CSP_AUTOGEN_EXTRA_ARGS} - COMMENT "generating csp c++ types from module ${MODULE_NAME}" - DEPENDS mkdir_autogen_${MODULE_NAME} - ${CMAKE_SOURCE_DIR}/csp/build/csp_autogen.py - ${CMAKE_SOURCE_DIR}/${MODULE_FILENAME} - csptypesimpl - ) - - set(${SOURCE_NAME_OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.cpp" PARENT_SCOPE ) - set(${HEADER_NAME_OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.h" PARENT_SCOPE ) + if (EXISTS "${CSP_AUTOGEN_CPP_MAYBE_EXISTING}" AND EXISTS "${CSP_AUTOGEN_H_MAYBE_EXISTING}") + # Files exist in-source + set(${SOURCE_NAME_OUTVAR} "${CSP_AUTOGEN_CPP_MAYBE_EXISTING}" PARENT_SCOPE ) + set(${HEADER_NAME_OUTVAR} "${CSP_AUTOGEN_H_MAYBE_EXISTING}" PARENT_SCOPE ) + else() + add_custom_command(OUTPUT "${CSP_AUTOGEN_CPP_OUT}" "${CSP_AUTOGEN_H_OUT}" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CSP_AUTOGEN_PYTHONPATH}" ${Python_EXECUTABLE} ${CSP_AUTOGEN_MODULE_PATH} -m ${MODULE_NAME} -d ${CSP_AUTOGEN_DESTINATION_FOLDER} -o ${DEST_FILENAME} ${CSP_AUTOGEN_EXTRA_ARGS} + COMMENT "generating csp c++ types from module ${MODULE_NAME}" + DEPENDS mkdir_autogen_${MODULE_NAME} + ${CMAKE_SOURCE_DIR}/csp/build/csp_autogen.py + ${CMAKE_SOURCE_DIR}/${MODULE_FILENAME} + csptypesimpl + ) + + set(${SOURCE_NAME_OUTVAR} "${CSP_AUTOGEN_CPP_OUT}" PARENT_SCOPE ) + set(${HEADER_NAME_OUTVAR} "${CSP_AUTOGEN_H_OUT}" PARENT_SCOPE ) + endif() endfunction() diff --git a/cpp/cmake/modules/Findcsp_autogen.cmake b/cpp/cmake/modules/Findcsp_autogen.cmake index 1c28a99f6..4e7588308 100644 --- a/cpp/cmake/modules/Findcsp_autogen.cmake +++ b/cpp/cmake/modules/Findcsp_autogen.cmake @@ -15,8 +15,10 @@ function(csp_autogen MODULE_NAME DEST_FILENAME HEADER_NAME_OUTVAR SOURCE_NAME_OU cmake_path(SET CSP_AUTOGEN_MODULE_PATH NORMALIZE "${CMAKE_SOURCE_DIR}/csp/build/csp_autogen.py") cmake_path(SET CSP_AUTOGEN_DESTINATION_FOLDER NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen") - cmake_path(SET CSP_AUTOTGEN_CPP_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.cpp") - cmake_path(SET CSP_AUTOTGEN_H_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.h") + cmake_path(SET CSP_AUTOGEN_CPP_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.cpp") + cmake_path(SET CSP_AUTOGEN_CPP_MAYBE_EXISTING NORMALIZE "${CMAKE_CURRENT_SOURCE_DIR}/csp_autogen/${DEST_FILENAME}.cpp") + cmake_path(SET CSP_AUTOGEN_H_OUT NORMALIZE "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.h") + cmake_path(SET CSP_AUTOGEN_H_MAYBE_EXISTING NORMALIZE "${CMAKE_CURRENT_SOURCE_DIR}/csp_autogen/${DEST_FILENAME}.h") if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") set(CSP_AUTOGEN_PYTHONPATH ${PROJECT_BINARY_DIR}/lib/${CMAKE_BUILD_TYPE};${CMAKE_SOURCE_DIR};%PYTHONPATH% ) @@ -24,15 +26,21 @@ function(csp_autogen MODULE_NAME DEST_FILENAME HEADER_NAME_OUTVAR SOURCE_NAME_OU set(CSP_AUTOGEN_PYTHONPATH ${PROJECT_BINARY_DIR}/lib:${CMAKE_SOURCE_DIR}:$$PYTHONPATH ) endif() - add_custom_command(OUTPUT "${CSP_AUTOTGEN_CPP_OUT}" "${CSP_AUTOTGEN_H_OUT}" - COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CSP_AUTOGEN_PYTHONPATH}" ${Python_EXECUTABLE} ${CSP_AUTOGEN_MODULE_PATH} -m ${MODULE_NAME} -d ${CSP_AUTOGEN_DESTINATION_FOLDER} -o ${DEST_FILENAME} ${CSP_AUTOGEN_EXTRA_ARGS} - COMMENT "generating csp c++ types from module ${MODULE_NAME}" - DEPENDS mkdir_autogen_${MODULE_NAME} - ${CMAKE_SOURCE_DIR}/csp/build/csp_autogen.py - ${CMAKE_SOURCE_DIR}/${MODULE_FILENAME} - csptypesimpl - ) + if (EXISTS "${CSP_AUTOGEN_CPP_MAYBE_EXISTING}" AND EXISTS "${CSP_AUTOGEN_H_MAYBE_EXISTING}") + # Files exist in-source + set(${SOURCE_NAME_OUTVAR} "${CSP_AUTOGEN_CPP_MAYBE_EXISTING}" PARENT_SCOPE ) + set(${HEADER_NAME_OUTVAR} "${CSP_AUTOGEN_H_MAYBE_EXISTING}" PARENT_SCOPE ) + else() + add_custom_command(OUTPUT "${CSP_AUTOGEN_CPP_OUT}" "${CSP_AUTOGEN_H_OUT}" + COMMAND ${CMAKE_COMMAND} -E env "PYTHONPATH=${CSP_AUTOGEN_PYTHONPATH}" ${Python_EXECUTABLE} ${CSP_AUTOGEN_MODULE_PATH} -m ${MODULE_NAME} -d ${CSP_AUTOGEN_DESTINATION_FOLDER} -o ${DEST_FILENAME} ${CSP_AUTOGEN_EXTRA_ARGS} + COMMENT "generating csp c++ types from module ${MODULE_NAME}" + DEPENDS mkdir_autogen_${MODULE_NAME} + ${CMAKE_SOURCE_DIR}/csp/build/csp_autogen.py + ${CMAKE_SOURCE_DIR}/${MODULE_FILENAME} + csptypesimpl + ) - set(${SOURCE_NAME_OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.cpp" PARENT_SCOPE ) - set(${HEADER_NAME_OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/csp_autogen/${DEST_FILENAME}.h" PARENT_SCOPE ) + set(${SOURCE_NAME_OUTVAR} "${CSP_AUTOGEN_CPP_OUT}" PARENT_SCOPE ) + set(${HEADER_NAME_OUTVAR} "${CSP_AUTOGEN_H_OUT}" PARENT_SCOPE ) + endif() endfunction() \ No newline at end of file diff --git a/cpp/csp/adapters/websocket/csp_autogen/websocket_types.cpp b/cpp/csp/adapters/websocket/csp_autogen/websocket_types.cpp new file mode 100644 index 000000000..370f84943 --- /dev/null +++ b/cpp/csp/adapters/websocket/csp_autogen/websocket_types.cpp @@ -0,0 +1,87 @@ + +// AUTOGENERATED BY CSP_AUTOGEN +// DO NOT MODIFY DIRECTLY +// command: python csp/build/csp_autogen.py -m csp.adapters.websocket_types -d cpp/csp/adapters/websocket/csp_autogen/ -o websocket_types + +#include "websocket_types.h" +#include +#include +#include +#include +#include +#include + +namespace csp::autogen +{ + +#define _offsetof( C, M ) ( ( char * ) &( ( C * ) nullptr ) -> M - ( char * ) 0 ) + +static void assert_or_die( bool assertion, const char * error ) +{ + if( !assertion ) + { + std::cerr << "Fatal error on import of " << __FILE__ << ": " << error << std::endl; + if( PyErr_Occurred() ) + PyErr_Print(); + abort(); + } +} + + +bool WebsocketStatus::static_init() +{ + if( Py_IsInitialized() ) + { + csp::python::AcquireGIL gil; + + // initialize EnumMeta from python type if we're in python + PyObject * pymodule = PyImport_ImportModule( "csp.adapters.websocket_types" ); + assert_or_die( pymodule != nullptr, "failed to import struct module csp.adapters.websocket_types" ); + + PyObject * enumType = PyObject_GetAttrString(pymodule, "WebsocketStatus" ); + assert_or_die( enumType != nullptr, "failed to find num type WebsocketStatus in module csp.adapters.websocket_types" ); + + // should add some assertion here.. + csp::python::PyCspEnumMeta * pymeta = ( csp::python::PyCspEnumMeta * ) enumType; + s_meta = pymeta -> enumMeta; + } + + return true; +} + +bool static_init_WebsocketStatus = WebsocketStatus::static_init(); +std::shared_ptr WebsocketStatus::s_meta; +WebsocketStatus WebsocketStatus::ACTIVE = WebsocketStatus::create("ACTIVE"); +WebsocketStatus WebsocketStatus::GENERIC_ERROR = WebsocketStatus::create("GENERIC_ERROR"); +WebsocketStatus WebsocketStatus::CONNECTION_FAILED = WebsocketStatus::create("CONNECTION_FAILED"); +WebsocketStatus WebsocketStatus::CLOSED = WebsocketStatus::create("CLOSED"); +WebsocketStatus WebsocketStatus::MESSAGE_SEND_FAIL = WebsocketStatus::create("MESSAGE_SEND_FAIL"); + + +bool WebsocketHeaderUpdate::static_init() +{ + + if( Py_IsInitialized() ) + { + //Note that windows requires we grab the GIL since the windows DLL loading code releases GIL + csp::python::AcquireGIL gil; + + // initialize StructMeta from python type if we're in python + PyObject * pymodule = PyImport_ImportModule( "csp.adapters.websocket_types" ); + assert_or_die( pymodule != nullptr, "failed to import struct module csp.adapters.websocket_types" ); + + PyObject * structType = PyObject_GetAttrString(pymodule, "WebsocketHeaderUpdate" ); + assert_or_die( structType != nullptr, "failed to find struct type WebsocketHeaderUpdate in module csp.adapters.websocket_types" ); + + // should add some assertion here.. + csp::python::PyStructMeta * pymeta = ( csp::python::PyStructMeta * ) structType; + s_meta = pymeta -> structMeta; + } + + return true; +} + +bool static_init_WebsocketHeaderUpdate = WebsocketHeaderUpdate::static_init(); +csp::StructMetaPtr WebsocketHeaderUpdate::s_meta; + +} diff --git a/cpp/csp/adapters/websocket/csp_autogen/websocket_types.h b/cpp/csp/adapters/websocket/csp_autogen/websocket_types.h new file mode 100644 index 000000000..4811dd543 --- /dev/null +++ b/cpp/csp/adapters/websocket/csp_autogen/websocket_types.h @@ -0,0 +1,224 @@ + +// AUTOGENERATED BY CSP_AUTOGEN +// DO NOT MODIFY DIRECTLY +// command: python csp/build/csp_autogen.py -m csp.adapters.websocket_types -d cpp/csp/adapters/websocket/csp_autogen/ -o websocket_types + +#ifndef _IN_CSP_AUTOGEN_CSP_ADAPTERS_WEBSOCKET_TYPES +#define _IN_CSP_AUTOGEN_CSP_ADAPTERS_WEBSOCKET_TYPES + +#include +#include +#include + +namespace csp::autogen +{ + +class WebsocketStatus : public csp::CspEnum +{ +public: + // Raw value quick access + enum class enum_ + { + ACTIVE = 0, + GENERIC_ERROR = 1, + CONNECTION_FAILED = 2, + CLOSED = 3, + MESSAGE_SEND_FAIL = 4 + }; + + // CspEnum types + static WebsocketStatus ACTIVE; + static WebsocketStatus GENERIC_ERROR; + static WebsocketStatus CONNECTION_FAILED; + static WebsocketStatus CLOSED; + static WebsocketStatus MESSAGE_SEND_FAIL; + + const char * asCString() const { return name().c_str(); } + const std::string & asString() const { return name(); } + + static WebsocketStatus create( enum_ v ) { return s_meta -> create( ( int64_t ) v ); } + static WebsocketStatus create( const char * name) { return s_meta -> fromString( name ); } + static WebsocketStatus create( const std::string & s ) { return create( s.c_str() ); } + + enum_ enum_value() const { return ( enum_ ) value(); } + + static constexpr uint32_t num_types() { return 5; } + + static bool static_init(); + + WebsocketStatus( const csp::CspEnum & v ) : csp::CspEnum( v ) { CSP_TRUE_OR_THROW( v.meta() == s_meta.get(), AssertionError, "Mismatched enum meta" ); } + +private: + + static std::shared_ptr s_meta; +}; + +class WebsocketHeaderUpdate : public csp::Struct +{ +public: + + using Ptr = csp::TypedStructPtr; + + WebsocketHeaderUpdate() = delete; + ~WebsocketHeaderUpdate() = delete; + WebsocketHeaderUpdate( const WebsocketHeaderUpdate & ) = delete; + WebsocketHeaderUpdate( WebsocketHeaderUpdate && ) = delete; + + Ptr copy() const { return csp::structptr_cast( Struct::copy() ); } + + static WebsocketHeaderUpdate::Ptr create() + { + return Ptr( static_cast( s_meta -> createRaw() ) ); + } + + static const csp::StructMetaPtr & meta() { return s_meta; } + + + const std::string & key() const + { + static_assert( offsetof( WebsocketHeaderUpdate,m_key ) == 0 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + if( !key_isSet() ) + CSP_THROW( csp::ValueError, "field key on struct WebsocketHeaderUpdate is not set" ); + + return m_key; + } + + void set_key( const std::string & value ) + { + + static_assert( offsetof( WebsocketHeaderUpdate,m_key ) == 0 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + m_WebsocketHeaderUpdate_mask[0] |= 1; + + + //TODO employ move semantics where it makes sense + m_key = value; + } + + + void set_key( const char * value ) + { + + static_assert( offsetof( WebsocketHeaderUpdate,m_key ) == 0 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + m_WebsocketHeaderUpdate_mask[0] |= 1; + + m_key = value; + } + + void set_key( std::string_view value ) + { + + static_assert( offsetof( WebsocketHeaderUpdate,m_key ) == 0 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + m_WebsocketHeaderUpdate_mask[0] |= 1; + + m_key = value; + } + + + bool key_isSet() const + { + static_assert(( offsetof( WebsocketHeaderUpdate,m_WebsocketHeaderUpdate_mask) + 0 ) == 48 ); + return m_WebsocketHeaderUpdate_mask[0] & 1; + } + + void clear_key() + { + static_assert(( offsetof( WebsocketHeaderUpdate,m_WebsocketHeaderUpdate_mask) + 0 ) == 48 ); + m_WebsocketHeaderUpdate_mask[0] &= ~1; + } + + const std::string & value() const + { + static_assert( offsetof( WebsocketHeaderUpdate,m_value ) == 24 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + if( !value_isSet() ) + CSP_THROW( csp::ValueError, "field value on struct WebsocketHeaderUpdate is not set" ); + + return m_value; + } + + void set_value( const std::string & value ) + { + + static_assert( offsetof( WebsocketHeaderUpdate,m_value ) == 24 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + m_WebsocketHeaderUpdate_mask[0] |= 2; + + + //TODO employ move semantics where it makes sense + m_value = value; + } + + + void set_value( const char * value ) + { + + static_assert( offsetof( WebsocketHeaderUpdate,m_value ) == 24 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + m_WebsocketHeaderUpdate_mask[0] |= 2; + + m_value = value; + } + + void set_value( std::string_view value ) + { + + static_assert( offsetof( WebsocketHeaderUpdate,m_value ) == 24 ); + static_assert( alignof( std::string ) == 8 ); + static_assert( sizeof( std::string ) == 24 ); + + m_WebsocketHeaderUpdate_mask[0] |= 2; + + m_value = value; + } + + + bool value_isSet() const + { + static_assert(( offsetof( WebsocketHeaderUpdate,m_WebsocketHeaderUpdate_mask) + 0 ) == 48 ); + return m_WebsocketHeaderUpdate_mask[0] & 2; + } + + void clear_value() + { + static_assert(( offsetof( WebsocketHeaderUpdate,m_WebsocketHeaderUpdate_mask) + 0 ) == 48 ); + m_WebsocketHeaderUpdate_mask[0] &= ~2; + } + + + static bool static_init(); + +private: + + std::string m_key; + std::string m_value; + char m_WebsocketHeaderUpdate_mask[1]; + + + static csp::StructMetaPtr s_meta; + + static void assert_mask() + { + static_assert( offsetof( WebsocketHeaderUpdate, m_WebsocketHeaderUpdate_mask ) == 48 ); + } +}; + +} +#endif \ No newline at end of file diff --git a/cpp/csp/engine/csp_autogen/autogen_types.cpp b/cpp/csp/engine/csp_autogen/autogen_types.cpp new file mode 100644 index 000000000..ed2a1ff33 --- /dev/null +++ b/cpp/csp/engine/csp_autogen/autogen_types.cpp @@ -0,0 +1,112 @@ + +// AUTOGENERATED BY CSP_AUTOGEN +// DO NOT MODIFY DIRECTLY +// command: python csp/build/csp_autogen.py -m csp.impl.types.autogen_types -d cpp/csp/engine/csp_autogen -o autogen_types + +#include "autogen_types.h" +#include +#include +#include +#include +#include +#include + +namespace csp::autogen +{ + +#define _offsetof( C, M ) ( ( char * ) &( ( C * ) nullptr ) -> M - ( char * ) 0 ) + +static void assert_or_die( bool assertion, const char * error ) +{ + if( !assertion ) + { + std::cerr << "Fatal error on import of " << __FILE__ << ": " << error << std::endl; + if( PyErr_Occurred() ) + PyErr_Print(); + abort(); + } +} + + +bool TimeIndexPolicy::static_init() +{ + if( Py_IsInitialized() ) + { + csp::python::AcquireGIL gil; + + // initialize EnumMeta from python type if we're in python + PyObject * pymodule = PyImport_ImportModule( "csp.impl.types.autogen_types" ); + assert_or_die( pymodule != nullptr, "failed to import struct module csp.impl.types.autogen_types" ); + + PyObject * enumType = PyObject_GetAttrString(pymodule, "TimeIndexPolicy" ); + assert_or_die( enumType != nullptr, "failed to find num type TimeIndexPolicy in module csp.impl.types.autogen_types" ); + + // should add some assertion here.. + csp::python::PyCspEnumMeta * pymeta = ( csp::python::PyCspEnumMeta * ) enumType; + s_meta = pymeta -> enumMeta; + } + + return true; +} + +bool static_init_TimeIndexPolicy = TimeIndexPolicy::static_init(); +std::shared_ptr TimeIndexPolicy::s_meta; +TimeIndexPolicy TimeIndexPolicy::INCLUSIVE = TimeIndexPolicy::create("INCLUSIVE"); +TimeIndexPolicy TimeIndexPolicy::EXCLUSIVE = TimeIndexPolicy::create("EXCLUSIVE"); +TimeIndexPolicy TimeIndexPolicy::EXTRAPOLATE = TimeIndexPolicy::create("EXTRAPOLATE"); + + +bool DynamicBasketEvent::static_init() +{ + + if( Py_IsInitialized() ) + { + //Note that windows requires we grab the GIL since the windows DLL loading code releases GIL + csp::python::AcquireGIL gil; + + // initialize StructMeta from python type if we're in python + PyObject * pymodule = PyImport_ImportModule( "csp.impl.types.autogen_types" ); + assert_or_die( pymodule != nullptr, "failed to import struct module csp.impl.types.autogen_types" ); + + PyObject * structType = PyObject_GetAttrString(pymodule, "DynamicBasketEvent" ); + assert_or_die( structType != nullptr, "failed to find struct type DynamicBasketEvent in module csp.impl.types.autogen_types" ); + + // should add some assertion here.. + csp::python::PyStructMeta * pymeta = ( csp::python::PyStructMeta * ) structType; + s_meta = pymeta -> structMeta; + } + + return true; +} + +bool static_init_DynamicBasketEvent = DynamicBasketEvent::static_init(); +csp::StructMetaPtr DynamicBasketEvent::s_meta; + + +bool DynamicBasketEvents::static_init() +{ + + if( Py_IsInitialized() ) + { + //Note that windows requires we grab the GIL since the windows DLL loading code releases GIL + csp::python::AcquireGIL gil; + + // initialize StructMeta from python type if we're in python + PyObject * pymodule = PyImport_ImportModule( "csp.impl.types.autogen_types" ); + assert_or_die( pymodule != nullptr, "failed to import struct module csp.impl.types.autogen_types" ); + + PyObject * structType = PyObject_GetAttrString(pymodule, "DynamicBasketEvents" ); + assert_or_die( structType != nullptr, "failed to find struct type DynamicBasketEvents in module csp.impl.types.autogen_types" ); + + // should add some assertion here.. + csp::python::PyStructMeta * pymeta = ( csp::python::PyStructMeta * ) structType; + s_meta = pymeta -> structMeta; + } + + return true; +} + +bool static_init_DynamicBasketEvents = DynamicBasketEvents::static_init(); +csp::StructMetaPtr DynamicBasketEvents::s_meta; + +} diff --git a/cpp/csp/engine/csp_autogen/autogen_types.h b/cpp/csp/engine/csp_autogen/autogen_types.h new file mode 100644 index 000000000..81d5cda6a --- /dev/null +++ b/cpp/csp/engine/csp_autogen/autogen_types.h @@ -0,0 +1,250 @@ + +// AUTOGENERATED BY CSP_AUTOGEN +// DO NOT MODIFY DIRECTLY +// command: python csp/build/csp_autogen.py -m csp.impl.types.autogen_types -d cpp/csp/engine/csp_autogen -o autogen_types + +#ifndef _IN_CSP_AUTOGEN_CSP_IMPL_TYPES_AUTOGEN_TYPES +#define _IN_CSP_AUTOGEN_CSP_IMPL_TYPES_AUTOGEN_TYPES + +#include +#include +#include + +namespace csp::autogen +{ + +class TimeIndexPolicy : public csp::CspEnum +{ +public: + // Raw value quick access + enum class enum_ + { + INCLUSIVE = 1, + EXCLUSIVE = 2, + EXTRAPOLATE = 3 + }; + + // CspEnum types + static TimeIndexPolicy INCLUSIVE; + static TimeIndexPolicy EXCLUSIVE; + static TimeIndexPolicy EXTRAPOLATE; + + const char * asCString() const { return name().c_str(); } + const std::string & asString() const { return name(); } + + static TimeIndexPolicy create( enum_ v ) { return s_meta -> create( ( int64_t ) v ); } + static TimeIndexPolicy create( const char * name) { return s_meta -> fromString( name ); } + static TimeIndexPolicy create( const std::string & s ) { return create( s.c_str() ); } + + enum_ enum_value() const { return ( enum_ ) value(); } + + static constexpr uint32_t num_types() { return 3; } + + static bool static_init(); + + TimeIndexPolicy( const csp::CspEnum & v ) : csp::CspEnum( v ) { CSP_TRUE_OR_THROW( v.meta() == s_meta.get(), AssertionError, "Mismatched enum meta" ); } + +private: + + static std::shared_ptr s_meta; +}; + +class DynamicBasketEvent : public csp::Struct +{ +public: + + using Ptr = csp::TypedStructPtr; + + DynamicBasketEvent() = delete; + ~DynamicBasketEvent() = delete; + DynamicBasketEvent( const DynamicBasketEvent & ) = delete; + DynamicBasketEvent( DynamicBasketEvent && ) = delete; + + Ptr copy() const { return csp::structptr_cast( Struct::copy() ); } + + static DynamicBasketEvent::Ptr create() + { + return Ptr( static_cast( s_meta -> createRaw() ) ); + } + + static const csp::StructMetaPtr & meta() { return s_meta; } + + + const csp::DialectGenericType & key() const + { + static_assert( offsetof( DynamicBasketEvent,m_key ) == 0 ); + static_assert( alignof( csp::DialectGenericType ) == 8 ); + static_assert( sizeof( csp::DialectGenericType ) == 8 ); + + if( !key_isSet() ) + CSP_THROW( csp::ValueError, "field key on struct DynamicBasketEvent is not set" ); + + return m_key; + } + + void set_key( const csp::DialectGenericType & value ) + { + + static_assert( offsetof( DynamicBasketEvent,m_key ) == 0 ); + static_assert( alignof( csp::DialectGenericType ) == 8 ); + static_assert( sizeof( csp::DialectGenericType ) == 8 ); + + m_DynamicBasketEvent_mask[0] |= 1; + + + //TODO employ move semantics where it makes sense + m_key = value; + } + + + + bool key_isSet() const + { + static_assert(( offsetof( DynamicBasketEvent,m_DynamicBasketEvent_mask) + 0 ) == 9 ); + return m_DynamicBasketEvent_mask[0] & 1; + } + + void clear_key() + { + static_assert(( offsetof( DynamicBasketEvent,m_DynamicBasketEvent_mask) + 0 ) == 9 ); + m_DynamicBasketEvent_mask[0] &= ~1; + } + + const bool & added() const + { + static_assert( offsetof( DynamicBasketEvent,m_added ) == 8 ); + static_assert( alignof( bool ) == 1 ); + static_assert( sizeof( bool ) == 1 ); + + if( !added_isSet() ) + CSP_THROW( csp::ValueError, "field added on struct DynamicBasketEvent is not set" ); + + return m_added; + } + + void set_added( const bool & value ) + { + + static_assert( offsetof( DynamicBasketEvent,m_added ) == 8 ); + static_assert( alignof( bool ) == 1 ); + static_assert( sizeof( bool ) == 1 ); + + m_DynamicBasketEvent_mask[0] |= 2; + + + //TODO employ move semantics where it makes sense + m_added = value; + } + + + + bool added_isSet() const + { + static_assert(( offsetof( DynamicBasketEvent,m_DynamicBasketEvent_mask) + 0 ) == 9 ); + return m_DynamicBasketEvent_mask[0] & 2; + } + + void clear_added() + { + static_assert(( offsetof( DynamicBasketEvent,m_DynamicBasketEvent_mask) + 0 ) == 9 ); + m_DynamicBasketEvent_mask[0] &= ~2; + } + + + static bool static_init(); + +private: + + csp::DialectGenericType m_key; + bool m_added; + char m_DynamicBasketEvent_mask[1]; + + + static csp::StructMetaPtr s_meta; + + static void assert_mask() + { + static_assert( offsetof( DynamicBasketEvent, m_DynamicBasketEvent_mask ) == 9 ); + } +}; + +class DynamicBasketEvents : public csp::Struct +{ +public: + + using Ptr = csp::TypedStructPtr; + + DynamicBasketEvents() = delete; + ~DynamicBasketEvents() = delete; + DynamicBasketEvents( const DynamicBasketEvents & ) = delete; + DynamicBasketEvents( DynamicBasketEvents && ) = delete; + + Ptr copy() const { return csp::structptr_cast( Struct::copy() ); } + + static DynamicBasketEvents::Ptr create() + { + return Ptr( static_cast( s_meta -> createRaw() ) ); + } + + static const csp::StructMetaPtr & meta() { return s_meta; } + + + const std::vector & events() const + { + static_assert( offsetof( DynamicBasketEvents,m_events ) == 0 ); + static_assert( alignof( std::vector ) == 8 ); + static_assert( sizeof( std::vector ) == 24 ); + + if( !events_isSet() ) + CSP_THROW( csp::ValueError, "field events on struct DynamicBasketEvents is not set" ); + + return m_events; + } + + void set_events( const std::vector & value ) + { + + static_assert( offsetof( DynamicBasketEvents,m_events ) == 0 ); + static_assert( alignof( std::vector ) == 8 ); + static_assert( sizeof( std::vector ) == 24 ); + + m_DynamicBasketEvents_mask[0] |= 1; + + + //TODO employ move semantics where it makes sense + m_events = value; + } + + + + bool events_isSet() const + { + static_assert(( offsetof( DynamicBasketEvents,m_DynamicBasketEvents_mask) + 0 ) == 24 ); + return m_DynamicBasketEvents_mask[0] & 1; + } + + void clear_events() + { + static_assert(( offsetof( DynamicBasketEvents,m_DynamicBasketEvents_mask) + 0 ) == 24 ); + m_DynamicBasketEvents_mask[0] &= ~1; + } + + + static bool static_init(); + +private: + + std::vector m_events; + char m_DynamicBasketEvents_mask[1]; + + + static csp::StructMetaPtr s_meta; + + static void assert_mask() + { + static_assert( offsetof( DynamicBasketEvents, m_DynamicBasketEvents_mask ) == 24 ); + } +}; + +} +#endif \ No newline at end of file diff --git a/csp/build/csp_autogen.py b/csp/build/csp_autogen.py index 4e121da5b..b014c7f39 100644 --- a/csp/build/csp_autogen.py +++ b/csp/build/csp_autogen.py @@ -2,6 +2,7 @@ import importlib import importlib.util import importlib.machinery +import logging import os.path import sys import types @@ -14,8 +15,11 @@ csp_mod = importlib.util.module_from_spec(spec) sys.modules["csp"] = csp_mod -from csp.impl.struct import Struct # noqa: E402 -from csp.impl.enum import Enum # noqa: E402 + +_GEN_COMMAND = f"""// AUTOGENERATED BY CSP_AUTOGEN +// DO NOT MODIFY DIRECTLY +// command: python {" ".join(sys.argv)} +""" def struct_type(type_info): @@ -80,6 +84,9 @@ def __init__(self, module_name: str, output_filename: str, namespace: str, gener self._external_types[v] = importlib.import_module(v.__module__) continue + from csp.impl.struct import Struct + from csp.impl.enum import Enum + if issubclass(v, Struct) and v is not Struct: self._struct_types.append(v) elif issubclass(v, Enum) and v is not Enum: @@ -87,6 +94,8 @@ def __init__(self, module_name: str, output_filename: str, namespace: str, gener def _get_dependent_headers(self): """see if there are any dependent headers we need to include""" + from csp.impl.struct import Struct + headers = set() for struct_type in self._struct_types: metainfo = struct_type._metadata_info() @@ -118,6 +127,7 @@ def cpp_filename(self): def generate_header_code(self): include_guard = "_IN_CSP_AUTOGEN_" + self._module_name.replace(".", "_").upper() out = f""" +{_GEN_COMMAND} #ifndef {include_guard} #define {include_guard} @@ -188,6 +198,8 @@ class {enum_name} : public csp::CspEnum return out def _generate_struct_class(self, struct_type): + from csp.impl.struct import Struct + struct_name = struct_type.__name__ metainfo = struct_type._metadata_info() @@ -354,6 +366,8 @@ class {struct_name} : public {base_class} return out def generate_cpp_code(self): + from csp.impl.struct import Struct + struct_inits = [] for struct_type in self._struct_types: struct_name = struct_type.__name__ @@ -453,6 +467,7 @@ def generate_cpp_code(self): enum_inits = "\n".join(enum_inits) out = f""" +{_GEN_COMMAND} #include "{self._header_filename}" #include #include @@ -485,17 +500,17 @@ def generate_cpp_code(self): return out -class Test(Struct): - bl: bool - a: int - b: float - s: str - # o: object +# class Test(Struct): +# bl: bool +# a: int +# b: float +# s: str +# # o: object -class Derived(Test): - string: str - flt: float +# class Derived(Test): +# string: str +# flt: float # Test2 = csp.impl.struct.define_struct( 'Test2', { 'A' + str(i) : bool for i in range(25 )}) @@ -528,22 +543,25 @@ class Derived(Test): args = parser.parse_args() - struct_gen = CodeGenerator(args.module_name, args.outname, args.namespace, bool(args.generate_imports)) + try: + struct_gen = CodeGenerator(args.module_name, args.outname, args.namespace, bool(args.generate_imports)) - header_file = os.path.join(args.output_directory, struct_gen.header_filename()) - cpp_file = os.path.join(args.output_directory, struct_gen.cpp_filename()) + header_file = os.path.join(args.output_directory, struct_gen.header_filename()) + cpp_file = os.path.join(args.output_directory, struct_gen.cpp_filename()) - header_code = struct_gen.generate_header_code() - cpp_code = struct_gen.generate_cpp_code() + header_code = struct_gen.generate_header_code() + cpp_code = struct_gen.generate_cpp_code() - if args.dry_run: - print(header_file, ":") - print(header_code) - print(cpp_file) - print(cpp_code) - else: - with open(header_file, "w") as f: - f.write(header_code) + if args.dry_run: + print(header_file, ":") + print(header_code) + print(cpp_file) + print(cpp_code) + else: + with open(header_file, "w") as f: + f.write(header_code) - with open(cpp_file, "w") as f: - f.write(cpp_code) + with open(cpp_file, "w") as f: + f.write(cpp_code) + except Exception: + logging.exception("Error running `csp_autogen`. Your build may fail!")