Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [4diac-dev] InterfaceSpecBuilder


I started on improving and adapting the ifSpecBuilder for FORTE core. (Today I figured out unit testing and wrote tests for the storage class.) My idea was to do adaptation in a few phases which would be organized in corresponding commits. Is that even possible to do with Gerrit? Can I contribute multiple commits at once for one issue? If so, are there any special considerations for the commit message? Or should I squash the commits?

On 5/17/22 12:52, Alois Zoitl wrote:

I was never happy with the itnerfaceSpec parsing. It got a bit better with some helper methods we introduced but never really good. I find your approach very
nice and would be happy if you would like to contribute it to 4diac FORTE. 


On Mon, 2022-05-16 at 19:08 +0200, Davor Cihlar wrote:
For iterating access to PostgreSQL result with multiple rows I went with a generic SIFBs (CGenFunctionBlock<CFunctionBlock>). I need some additional events
and outputs and it doesn't make sense to do that through a comm layer.
So I started writing my own GEN_PQ_ITER and everything was fine until I needed to fill out SFBInterfaceSpec. It's a nightmare to set everything up before
filling it, and it's also not flexible at all. Further port changes are the same problems all over again + refactoring of the previous code.
To simplify things I made SFBInterfaceSpec (source code attached). Does it make sense to incorporate it into Forte core? I also think that a parser for
generic SIFBs should be standardized as currently every GEN_* implements its own parser.

An example would look like this:
bool GEN_PQ_ITER::createInterfaceSpec(const char *pa_sConfig, SFBInterfaceSpec &pa_oInterfaceSpec) {
    unsigned long numbers[2];
    if (!parseSpec(pa_sConfig, "PQ_ITER", numbers, 2))
        return false;

    static const std::array staticEINames = { g_nStringIdINIT, g_nStringIdREQ };
    static const std::array staticEONames = { g_nStringIdINITO, g_nStringIdCNF };

    auto ifsb = CIfSpecBuilder();
    bool stat =
        ifsb.m_oEI.setStaticEvents(staticEINames) &&
        ifsb.m_oEO.setStaticEvents(staticEONames) &&
        ifsb.m_oDI.addData("QI", g_nStringIdBYTE) && /* g_nStringIdQI can be used instead of "QI" */
        ifsb.m_oDI.addDataRange("SD_", (int)numbers[0]) &&
        ifsb.m_oDO.addData("QO", g_nStringIdBYTE) &&
        ifsb.m_oDO.addDataRange("RD_", (int)numbers[1]) &&
        ifsb.bind(ifsb.m_oEI["INIT"], {ifsb.m_oDI["QI"], ifsb.m_oDI["ID"]}) &&
        ifsb.bind(ifsb.m_oEI["REQ"], ifsb.m_oDI["QI"]) &&
        ifsb.bind(ifsb.m_oEO["INITO"], ifsb.m_oDO["QO"]);

    stat = stat &&, pa_oInterfaceSpec);
    if (!stat) {
        DEVLOG_ERROR("interface spec builder failed!\n");

    return stat;
As it can be seen, the builder supports both static and dynamic configuration (although not yet for "withs"). And in the end it uses only one member for data
storage (m_oMixedStorage) which automatically cleans up at SIFB's EOL.
I don't expect this method to use more memory than before. It even has potential to use less memory as there is only one memory block used (after setup). The
only disadvantage would be slower initialization which shouldn't matter any way. By using this way of initialization in other GEN_* FBs the code size could
also be reduced a bit.
It would be nice to be able to use constexpr for std::array (so it can be stored in ROM), but something needs to be done first, I need to look into it.
4diac-dev mailing list
To unsubscribe from this list, visit
4diac-dev mailing list
To unsubscribe from this list, visit

Back to the top