Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,12 @@ private:

interface(ctx, parent, interface, export_list) ::= <<

$if(interface.withOutputParameters)$
namespace detail {

$interface.operations : { op | $if(op.outputparam)$$operation_out_struct_fwd_decl(interface, op)$$endif$}$
}
} // namespace detail
$endif$

/*!
* @brief This class represents the interface $interface.name$ defined by the user in the IDL file.
Expand All @@ -207,10 +209,12 @@ public:
$export_list$
};

$if(interface.withOutputParameters)$
namespace detail {

$interface.operations : { op | $if(op.outputparam)$$operation_out_struct(interface, op)$$"\n"$$endif$}$
}
} // namespace detail
$endif$
>>

operation(ctx, parent, operation, param_list, operation_type) ::= <<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,20 @@
group TypesSwigInterface;

import "com/eprosima/fastdds/idl/templates/eprosima.stg"
import "FastCdrCommon.stg"

main(ctx, definitions) ::= <<
$fileHeader(ctx=ctx, file=[ctx.filename, ".i"], description=["This header file contains the SWIG interface of the described types in the IDL file."])$

%module(moduleimport="if __import__('os').name == 'nt': import win32api; win32api.LoadLibrary('$ctx.filename$.dll')\nif __package__ or '.' in __name__:\n from . import _$ctx.filename$Wrapper\nelse:\n import _$ctx.filename$Wrapper") $ctx.filename$
%module($if(ctx.thereIsInterface)$threads="1",directors="1",$endif$moduleimport="if __import__('os').name == 'nt': import win32api; win32api.LoadLibrary('$ctx.filename$.dll')\nif __package__ or '.' in __name__:\n from . import _$ctx.filename$Wrapper\nelse:\n import _$ctx.filename$Wrapper") $ctx.filename$

$if(ctx.thereIsInterface)$
// We have enabled threads because the RPC server directors will call the target language environment
// from the C++ server threads, but we don't want the calls from the target language to release their
// locks (e.g. Python GIL) when calling the C++ methods.
// See a very nice explanation at https://github.com/swig/swig/issues/927#issuecomment-289279243
%feature("nothreadallow");
Comment thread
Mario-DL marked this conversation as resolved.
$endif$

// If using windows in debug, it would try to use python_d, which would not be found.
%begin %{
Expand All @@ -30,9 +39,16 @@ $fileHeader(ctx=ctx, file=[ctx.filename, ".i"], description=["This header file c
%}

// SWIG helper modules
$if(ctx.thereIsInterface)$
%include "exception.i"
$endif$
%include "stdint.i"
%include "std_array.i"
%include "std_map.i"
$if(ctx.thereIsInterface)$
%include "std_pair.i"
%include "std_shared_ptr.i"
$endif$
%include "std_string.i"
%include "std_vector.i"
%include "typemaps.i"
Expand All @@ -47,6 +63,11 @@ $ctx.directIncludeDependencies : {include | %include "$include$.i"}; separator="

%{
#include "$ctx.filename$.hpp"
$if(ctx.thereIsInterface)$
#include "$ctx.filename$Client.hpp"
#include "$ctx.filename$Server.hpp"
#include "$ctx.filename$ServerImpl.hpp"
$endif$

#include <fastdds/dds/core/LoanableSequence.hpp>
%}
Expand All @@ -62,6 +83,118 @@ $endif$
%import(module="fastdds") "fastdds/dds/core/LoanableTypedCollection.hpp"
%import(module="fastdds") "fastdds/dds/core/LoanableSequence.hpp"

$if(ctx.thereIsInterface)$
%import(module="fastdds") "fastdds/dds/rpc/exceptions/RpcException.hpp"
%import(module="fastdds") "fastdds/dds/rpc/exceptions/RpcOperationError.hpp"

%exception {
try
{
\$action
}
catch (const eprosima::fastdds::dds::rpc::RpcException& ex)
{
SWIG_exception(SWIG_RuntimeError, ex.what());
}
catch (const std::exception& ex)
{
SWIG_exception(SWIG_RuntimeError, ex.what());
}
catch (...)
{
SWIG_exception(SWIG_RuntimeError,"Unknown exception");
}
}

$if(ctx.thereIsOutputFeed)$
%import(module="fastdds") "fastdds/dds/rpc/interfaces/RpcServerWriter.hpp"
%ignore eprosima::fastdds::dds::rpc::RpcClientReader::read(T&);
%ignore eprosima::fastdds::dds::rpc::RpcClientReader::read(T&,eprosima::fastdds::dds::Duration_t&);
%import(module="fastdds") "fastdds/dds/rpc/interfaces/RpcClientReader.hpp"
%extend eprosima::fastdds::dds::rpc::RpcClientReader {
std::pair<bool, T> read(
const eprosima::fastdds::dds::Duration_t& timeout = eprosima::fastdds::dds::c_TimeInfinite)
{
std::pair<bool, T> ret_val{};
if (eprosima::fastdds::dds::c_TimeInfinite == timeout)
{
ret_val.first = self->read(ret_val.second);
}
else
{
ret_val.first = self->read(ret_val.second, timeout);
}
return ret_val;
}
}

$ctx.outputFeedTypes : {feed_type | $output_feed(feed_type)$}; separator="\n\n"$
$endif$

$if(ctx.thereIsNonFeedOperation)$
// Code for std::future taken from https://github.com/swig/swig/issues/1828#issuecomment-648449092
namespace eprosima::fastdds::dds::rpc
{
template <class R>
class RpcFuture {
Comment thread
Mario-DL marked this conversation as resolved.
public:
RpcFuture() noexcept;
RpcFuture(RpcFuture &&) noexcept;
RpcFuture(const RpcFuture& rhs) = delete;
~RpcFuture();
RpcFuture& operator=(const RpcFuture& rhs) = delete;
RpcFuture& operator=(RpcFuture&&) noexcept;

// retrieving the value
R get();

// functions to check state
bool valid() const noexcept;
void wait() const;

/*
template <class Rep, class Period>
future_status wait_for(const chrono::duration<Rep, Period>& rel_time) const;
template <class Clock, class Duration>
future_status wait_until(const chrono::time_point<Clock, Duration>& abs_time) const;
*/
};

}

$ctx.outputNonFeedTypes : {non_feed_type | $output_non_feed(non_feed_type)$}; separator="\n\n"$
$endif$

$if(ctx.thereIsInputFeed)$
%import(module="fastdds") "fastdds/dds/rpc/interfaces/RpcClientWriter.hpp"
%import(module="fastdds") "fastdds/dds/rpc/interfaces/RpcStatusCode.hpp"

%ignore eprosima::fastdds::dds::rpc::RpcServerReader::read(T&);
%ignore eprosima::fastdds::dds::rpc::RpcServerReader::read(T&,eprosima::fastdds::dds::Duration_t&);
%import(module="fastdds") "fastdds/dds/rpc/interfaces/RpcServerReader.hpp"
%extend eprosima::fastdds::dds::rpc::RpcServerReader {
std::pair<bool, T> read(
const eprosima::fastdds::dds::Duration_t& timeout = eprosima::fastdds::dds::c_TimeInfinite)
{
std::pair<bool, T> ret_val{};
if (eprosima::fastdds::dds::c_TimeInfinite == timeout)
{
ret_val.first = self->read(ret_val.second);
}
else
{
ret_val.first = self->read(ret_val.second, timeout);
}
return ret_val;
}
}

$ctx.inputFeedTypes : {feed_type | $input_feed(feed_type)$}; separator="\n\n"$
$endif$

%exception;
$endif$

%define %traits_penumn(Type...)
%fragment(SWIG_Traits_frag(Type),"header",
fragment="StdTraits") {
Expand All @@ -78,6 +211,11 @@ $definitions; separator="\n"$

// Include the class interfaces
%include "$ctx.filename$.hpp"
$if(ctx.thereIsInterface)$
%include "$ctx.filename$Client.hpp"
%include "$ctx.filename$Server.hpp"
%include "$ctx.filename$ServerImpl.hpp"
$endif$

// Include the corresponding TopicDataType
%include "$ctx.filename$PubSubTypes.i"
Expand Down Expand Up @@ -241,3 +379,65 @@ bitset_type(ctx, parent, bitset, extensions) ::= <<
enum_type(ctx, parent, enum) ::= <<
%traits_penumn(enum $enum.cppTypename$);
>>

interface(ctx, parent, interface, export_list) ::= <<

$export_list$

%shared_ptr($interface.scopedname$);
$if(!interface.annotatedAsNested)$
%shared_ptr($interface.scopedname$Server);
%extend $interface.scopedname$Server
{
void run()
{
Py_BEGIN_ALLOW_THREADS
self->run();
Py_END_ALLOW_THREADS
}
}

%shared_ptr($interface.scopedname$Server_IServerImplementation);
%shared_ptr($interface.scopedname$ServerImplementation);
%feature("director") $interface.scopedname$ServerImplementation;
$endif$
>>

output_non_feed(type) ::= <<
%shared_ptr(eprosima::fastdds::dds::rpc::RpcFuture<$type.cppTypename$>);
%template($type.formatedCppTypename$_rpc_future) eprosima::fastdds::dds::rpc::RpcFuture<$type.cppTypename$>;

$!
// Combine the typemap from shared_ptr
// https://github.com/swig/swig/blob/b96b955ca15a01f0425fb26c234528530923202a/Lib/python/boost_shared_ptr.i#L41-L44
// with the use of the 'optimal' attribute to avoid the need for a copy constructor, inspired by
// https://github.com/swig/swig/issues/1828#issuecomment-648449092
!$
%typemap(out, optimal="1") eprosima::fastdds::dds::rpc::RpcFuture<$type.cppTypename$> {
std::shared_ptr<\$1_ltype> *smartresult = new std::shared_ptr<\$1_ltype>(new \$1_ltype(\$1));
\$result = SWIG_NewPointerObj(SWIG_as_voidptr(smartresult), \$descriptor(std::shared_ptr< eprosima::fastdds::dds::rpc::RpcFuture<$type.cppTypename$\>> *), SWIG_POINTER_OWN);
}
>>

output_feed(type) ::= <<
%shared_ptr(eprosima::fastdds::dds::rpc::RpcClientReader<$type.cppTypename$>);
%template($type.formatedCppTypename$_client_reader_result) std::pair<bool, $type.cppTypename$>;
%template($type.formatedCppTypename$_client_reader) eprosima::fastdds::dds::rpc::RpcClientReader<$type.cppTypename$>;

%template($type.formatedCppTypename$_server_writer) eprosima::fastdds::dds::rpc::RpcServerWriter<$type.cppTypename$>;
>>

input_feed(type) ::= <<
%template($type.formatedCppTypename$_server_reader_result) std::pair<bool, $type.cppTypename$>;
%template($type.formatedCppTypename$_server_reader) eprosima::fastdds::dds::rpc::RpcServerReader<$type.cppTypename$>;

%shared_ptr(eprosima::fastdds::dds::rpc::RpcClientWriter<$type.cppTypename$>);
%template($type.formatedCppTypename$_rpc_client_writer) eprosima::fastdds::dds::rpc::RpcClientWriter<$type.cppTypename$>;
%typemap(in,numinputs=0) std::shared_ptr<eprosima::fastdds::dds::rpc::RpcClientWriter<$type.cppTypename$\>>& %{
\$1 = new std::shared_ptr<eprosima::fastdds::dds::rpc::RpcClientWriter<$type.cppTypename$\>>();
%}
%typemap(argout) std::shared_ptr<eprosima::fastdds::dds::rpc::RpcClientWriter<$type.cppTypename$\>>& (PyObject* tmp) %{
tmp = SWIG_NewPointerObj(\$1, \$1_descriptor, SWIG_POINTER_OWN);
\$result = SWIG_Python_AppendOutput(\$result, tmp);
%}
>>
Loading