<template name="file-header">
    /*
        Generated by sbus code generator

        Copyright (C) 2017 Red Hat

        This program is free software; you can redistribute it and/or modify
        it under the terms of the GNU General Public License as published by
        the Free Software Foundation; either version 3 of the License, or
        (at your option) any later version.

        This program is distributed in the hope that it will be useful,
        but WITHOUT ANY WARRANTY; without even the implied warranty of
        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        GNU General Public License for more details.

        You should have received a copy of the GNU General Public License
        along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */

    #ifndef ${file-guard}
    #define ${file-guard}

    #include "${sbus-path}/sbus_interface_declarations.h"
    #include "${header:invokers}"
    #include "${header:symbols}"
    #include "${header:keygens}"

</template>

<template name="interface">
    /* Interface: ${name} */
    #define SBUS_IFACE_${token}(methods, signals, properties) ({ \
        sbus_interface("${name}", <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
            (methods), (signals), (properties)); \
    })

</template>

<template name="method">
    /* Method: ${interface}.${name} */
    #define SBUS_METHOD_SYNC_${token}(handler, data) ({ \
        SBUS_CHECK_SYNC((handler), (data)<loop name="in">, ${type}</loop><loop name="in-raw">, ${type}</loop><loop name="out">, ${type}</loop><loop name="out-raw">, ${type}</loop>); \
        sbus_method_sync("${name}", \
            &_sbus_args_${token}, \
            <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
            _sbus_invoke_in_${input-signature}_out_${output-signature}_send, \
            <toggle line name="keygen">_sbus_key_${key-signature}<loop name="key-argument">_${key-index}</loop><or>NULL</toggle>, \
            (handler), (data)); \
    })

    #define SBUS_METHOD_ASYNC_${token}(handler_send, handler_recv, data) ({ \
        SBUS_CHECK_SEND((handler_send), (data)<loop name="in">, ${type}</loop><loop name="in-raw">, ${type}</loop><loop name="out-raw">, ${type}</loop>); \
        SBUS_CHECK_RECV((handler_recv)<loop name="out">, ${type}</loop>); \
        sbus_method_async("${name}", \
            &_sbus_args_${token}, \
            <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
            _sbus_invoke_in_${input-signature}_out_${output-signature}_send, \
            <toggle line name="keygen">_sbus_key_${key-signature}<loop name="key-argument">_${key-index}</loop><or>NULL</toggle>, \
            (handler_send), (handler_recv), (data)); \
    })

</template>

<template name="signal">
    /* Signal: ${interface}.${name} */
    #define SBUS_SIGNAL_EMITS_${token}() ({ \
        sbus_signal("${name}", \
            _sbus_args_${token}, \
            <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>); \
    })

    #define SBUS_SIGNAL_SYNC_${token}(path, handler, data) ({ \
        SBUS_CHECK_SYNC((handler), (data)<loop name="in">, ${type}</loop><loop name="in-raw">, ${type}</loop>); \
        sbus_listener_sync("${interface}", "${name}", (path), \
            _sbus_invoke_in_${input-signature}_out_${output-signature}_send, \
            <toggle line name="keygen">_sbus_key_${key-signature}<loop name="key-argument">_${key-index}</loop><or>NULL</toggle>, \
            (handler), (data)); \
    })

    #define SBUS_SIGNAL_ASYNC_${token}(path, handler_send, handler_recv, data) ({ \
        SBUS_CHECK_SEND((handler_send), (data)<loop name="in">, ${type}</loop><loop name="in-raw">, ${type}</loop>); \
        SBUS_CHECK_RECV((handler_recv)); \
        sbus_listener_async("${interface}", "${name}", (path), \
            _sbus_invoke_in_${input-signature}_out_${output-signature}_send, \
            <toggle line name="keygen">_sbus_key_${key-signature}<loop name="key-argument">_${key-index}</loop><or>NULL</toggle>, \
            (handler_send), (handler_recv), (data)); \
    })

</template>

<template name="property">
    /* Property: ${interface}.${name} */
    #define SBUS_GETTER_SYNC_${token}(handler, data) ({ \
        SBUS_CHECK_SYNC((handler), (data)<loop name="out">, ${type}</loop><loop name="out-raw">, ${type}</loop>); \
        sbus_property_sync("${name}", "${type}", SBUS_PROPERTY_READABLE, \
           <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
           _sbus_invoke_in__out_${output-signature}_send, \
           (handler), (data)); \
    })

    #define SBUS_GETTER_ASYNC_${token}(handler_send, handler_recv, data) ({ \
        SBUS_CHECK_SEND((handler_send), (data)<loop name="out-raw">, ${type}</loop>); \
        SBUS_CHECK_RECV((handler_recv)<loop name="out">, ${type}</loop>); \
        sbus_property_async("${name}", "${type}", SBUS_PROPERTY_READABLE, \
           <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
           _sbus_invoke_in__out_${output-signature}_send, \
           (handler_send), (handler_recv), (data)); \
    })

    #define SBUS_SETTER_SYNC_${token}(handler, data) ({\
        SBUS_CHECK_SYNC((handler), (data)<loop name="in">, ${type}</loop><loop name="in-raw">, ${type}</loop>); \
        sbus_property_sync("${name}", "${type}", SBUS_PROPERTY_WRITABLE, \
           <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
           _sbus_invoke_in_${input-signature}_out__send, \
           (handler), (data)); \
    })

    #define SBUS_SETTER_ASYNC_${token}(handler_send, handler_recv, data) ({ \
        SBUS_CHECK_SEND((handler_send), (data)<loop name="in">, ${type}</loop><loop name="in-raw">, ${type}</loop>); \
        SBUS_CHECK_RECV((handler_recv)); \
        sbus_property_async("${name}", "${type}", SBUS_PROPERTY_WRITABLE, \
           <toggle line name="annotations">_sbus_annotations_${token}<or>NULL</toggle>, \
           _sbus_invoke_in_${input-signature}_out__send, \
           (handler_send), (handler_recv), (data)); \
    })

</template>

<template name="file-footer">
    #endif /* ${file-guard} */
</template>
