CDT  v4.2.0
инструменты разработчика
dispatcher.hpp
См. документацию.
1#pragma once
2#include "action.hpp"
3
4#include <bluegrass/meta/preprocessor.hpp>
5#include <tuple>
6
7namespace eosio {
8
17
18 template<typename Contract, typename FirstAction>
19 bool dispatch( uint64_t code, uint64_t act ) {
20 if( code == FirstAction::get_account() && FirstAction::get_name() == act ) {
21 Contract().on( unpack_action_data<FirstAction>() );
22 return true;
23 }
24 return false;
25 }
26
28
41 template<typename Contract, typename FirstAction, typename SecondAction, typename... Actions>
43 if( code == FirstAction::get_account() && FirstAction::get_name() == act ) {
44 Contract().on( unpack_action_data<FirstAction>() );
45 return true;
46 }
47 return eosio::dispatch<Contract,SecondAction,Actions...>( code, act );
48 }
49
50
51
52
64 template<typename T, typename... Args>
65 bool execute_action( name self, name code, void (T::*func)(Args...) ) {
66 size_t size = action_data_size();
67
68 //using malloc/free here potentially is not exception-safe, although WASM doesn't support exceptions
69 constexpr size_t max_stack_buffer_size = 512;
70 void* buffer = nullptr;
71 if( size > 0 ) {
72 buffer = max_stack_buffer_size < size ? malloc(size) : alloca(size);
73 read_action_data( buffer, size );
74 }
75
76 std::tuple<std::decay_t<Args>...> args;
77 datastream<const char*> ds((char*)buffer, size);
78 ds >> args;
79
80 T inst(self, code, ds);
81
82 auto f2 = [&]( auto... a ){
83 ((&inst)->*func)( a... );
84 };
85
86 std::apply( f2, args );
87 if ( max_stack_buffer_size < size ) {
88 free(buffer);
89 }
90 return true;
91 }
92
94
95 // Helper macro for EOSIO_DISPATCH_INTERNAL
96 #define EOSIO_DISPATCH_INTERNAL( OP, elem ) \
97 case eosio::name( BLUEGRASS_META_STRINGIZE(elem) ).value: \
98 eosio::execute_action( eosio::name(receiver), eosio::name(code), &OP::elem ); \
99 break;
100
101 // Helper macro for EOSIO_DISPATCH
102 #define EOSIO_DISPATCH_HELPER( TYPE, MEMBERS ) \
103 BLUEGRASS_META_FOREACH_SEQ( EOSIO_DISPATCH_INTERNAL, TYPE, MEMBERS )
104
106
120#define EOSIO_DISPATCH( TYPE, MEMBERS ) \
121extern "C" { \
122 [[eosio::wasm_entry]] \
123 void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
124 if( code == receiver ) { \
125 switch( action ) { \
126 EOSIO_DISPATCH_HELPER( TYPE, MEMBERS ) \
127 } \
128 /* does not allow destructor of thiscontract to run: eosio_exit(0); */ \
129 } \
130 } \
131} \
132
133}