So, I have a huge set of functions to read inputs from some source of the form:
ErrCode_t in_func1(t1_t * const data1);
ErrCode_t in_func2(t2_t * const data2);
...
some trigger functions, telling me if I may call the functions above:
TrCode_t tr_func1();
TrCode_t tr_func2();
...
and corresponding functions to write out the data:
void out_func1(t1_t const * const data1, const uint32_t handled_error);
void out_func2(t2_t const * const data2, const uint32_t handled_error);
...
Also there is a quite complicated algorithm depending on the trigger functions, that decides if I may call the input function, or not. (this is a simplified picture; their more then one trigger function and timers envolved for each I/O).
This algo but basicly says: If the trigger says yes, call the input function with a pointer to a data variable, check the error, do some validation, and then pass the pointer of the updated variable to the output.
void execute_f1(t1_t * const pData1)
{
if(evalTr(tr_func1()))
{
const ErrCode_t myErr = in_func1(pData1);
const uint32_t myOutErr = evalError(myErr);
out_func1(pData1,myOutErr);
}
}
(while evalTr and evalError shall be some evaluation functions that are used correctly)
I would like to encapsulate this algo in a own function,
void execute_io(???)
to be called with some function pointers to perform this. But I can't think of a pattern that would be conform to the standard, without a huge amount of wrapper functions. I wrap the input-functions and output functions to perfom the correct casts, and to adjust the signatures like:
ErrCode_t my_in_func1(void * const pData1)
{
t1_t * const data1 = (t1_t*) pData1;
return in_func1(data1);
}
and output functions alike:
void my out_func2(void const * const data2, const uint32_t handled_error) {...}
so that I have homogeneous signatures, and that way easy function pointers. But I would really prefer not to wrap all those functions. Do anyone know a pattern that would work "inside" execute_io and surrounding code, so I don't have to wrap all that functions?
Update: And here in a combination as requested from barak manos:
system_interface.h
ErrCode_t in_func1(t1_t * const data1);
/* some 500 more of them */
TrCode_t tr_func1();
/* some 500 more of them */
void out_func1(t1_t const * const data1, const uint32_t handled_error);
/* some 500 more of them */
my_code.c
static ErrCode_t my_in_func1(void * const data1)
{
t1_t * const data1 = (t1_t*) pData1;
return in_func1(data1);
}
/* and some 500 more wrappers */
static void my_out_func1(void const * const pData1, const uint32_t handled_error)
{
t1_t const * const data1 = (t1_t) pData1;
out_func1(pData1, handled_error);
return;
}
/* and some 500 more wrappers */
typedef ErrCode_t (*inFuncPtr)(void * const);
typedef void (*outFuncPtr)(void const * const, const uint32_t);
typedef TrCode_t (*trFuncPtr)();
execute_io(inFuncPtr inFunc, outFuncPtr outFunc, trFuncPtr trFunc, void * pData)
{
if(evalTr((*trFunc)()))
{
const ErrCode_t myErr = (*inFunc)(pData);
const uint32_t myOutErr = evalError(myErr);
(*outFunc)(pData,myOutErr);
}
return;
}
void do_all_my_work()
{
{
t1_t data1;
execute_io(&my_in_func1, &my_out_func1, &tr_func1, &data1);
}
{
t2_t data2;
execute_io(&my_in_func2, &my_out_func2, &tr_func2, &data2);
}
/* and some 499 other calls */
}
I want to find another pattern, that does not force me to wrap all that I/O functions. (and no, the above code is surely not an executable example but merely a concept)