Add support for multiple evaluators per operation type
This commit adds the ability to register multiple evaluator types for a given operation type. This will be used to allow plug-ins to define their own evaluators for various operation types (most notably, custom operations) so that they may be used to carry app-specific data which can be parsed by a plug-in.
This commit is contained in:
parent
4d836dacb9
commit
ab113b2fc4
2 changed files with 30 additions and 3 deletions
|
|
@ -344,11 +344,27 @@ namespace graphene { namespace chain {
|
|||
void initialize_indexes();
|
||||
void init_genesis(const genesis_state_type& genesis_state = genesis_state_type());
|
||||
|
||||
/**
|
||||
* @brief Register a new evaluator to the evaluator chain for its operation type
|
||||
* @tparam EvaluatorType An evaluator type which will be used to evaluate its declared operation type
|
||||
*
|
||||
* This method registers a new evaluator type with tthe database. The evaluator specifies an operation type
|
||||
* which it should be used to evaluate. The evaluator will be instantiated each time an operaton of the
|
||||
* appropriate type is processed and used to evaluate the operation.
|
||||
*
|
||||
* This method may be called more than once with multiple evaluator types for a given operation type. When
|
||||
* multiple evaluator types are registered for a given operation type, they will all execute in the order of
|
||||
* registration; however, only the return value of the first registered evaluator will be returned; return
|
||||
* values of subsequently registered evaluators will be silently dropped.
|
||||
*/
|
||||
template<typename EvaluatorType>
|
||||
void register_evaluator()
|
||||
{
|
||||
_operation_evaluators[
|
||||
operation::tag<typename EvaluatorType::operation_type>::value].reset( new op_evaluator_impl<EvaluatorType>() );
|
||||
auto& eval_ptr = _operation_evaluators[operation::tag<typename EvaluatorType::operation_type>::value];
|
||||
if (eval_ptr == nullptr)
|
||||
eval_ptr = std::make_unique<op_evaluator_impl<EvaluatorType>>();
|
||||
else
|
||||
eval_ptr->append_evaluator(std::make_unique<op_evaluator_impl<EvaluatorType>>());
|
||||
}
|
||||
|
||||
//////////////////// db_balance.cpp ////////////////////
|
||||
|
|
|
|||
|
|
@ -124,17 +124,28 @@ namespace graphene { namespace chain {
|
|||
{
|
||||
public:
|
||||
virtual ~op_evaluator(){}
|
||||
virtual void append_evaluator(unique_ptr<op_evaluator> next_evaluator) = 0;
|
||||
virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply) = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class op_evaluator_impl : public op_evaluator
|
||||
{
|
||||
unique_ptr<op_evaluator> next_evaluator;
|
||||
public:
|
||||
virtual void append_evaluator(unique_ptr<op_evaluator> next_evaluator) override {
|
||||
if (this->next_evaluator == nullptr)
|
||||
this->next_evaluator = std::move(next_evaluator);
|
||||
else
|
||||
this->next_evaluator->append_evaluator(std::move(next_evaluator));
|
||||
}
|
||||
virtual operation_result evaluate(transaction_evaluation_state& eval_state, const operation& op, bool apply = true) override
|
||||
{
|
||||
T eval;
|
||||
return eval.start_evaluate(eval_state, op, apply);
|
||||
auto result = eval.start_evaluate(eval_state, op, apply);
|
||||
if (next_evaluator != nullptr)
|
||||
next_evaluator->evaluate(eval_state, op, apply);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue