GMLC-TDC / HELICS

@@ -23,7 +23,7 @@
Loading
23 23
                                    void* userdata,
24 24
                                    helics_error* err)
25 25
{
26 -
    auto brk = getBroker(broker, err);
26 +
    auto* brk = getBroker(broker, err);
27 27
    if (brk == nullptr) {
28 28
        return;
29 29
    }
@@ -46,7 +46,7 @@
Loading
46 46
                                  void* userdata,
47 47
                                  helics_error* err)
48 48
{
49 -
    auto cr = getCore(core, err);
49 +
    auto* cr = getCore(core, err);
50 50
    if (cr == nullptr) {
51 51
        return;
52 52
    }
@@ -70,7 +70,7 @@
Loading
70 70
                                      void* userdata,
71 71
                                      helics_error* err)
72 72
{
73 -
    auto fedptr = getFed(fed, err);
73 +
    auto* fedptr = getFed(fed, err);
74 74
    if (fedptr == nullptr) {
75 75
        return;
76 76
    }
@@ -88,3 +88,56 @@
Loading
88 88
        helicsErrorHandler(err);  // LCOV_EXCL_LINE
89 89
    }
90 90
}
91 +
92 +
void helicsFederateSetQueryCallback(helics_federate fed,
93 +
                                    void (*queryAnswer)(const char* query, int querySize, helics_query_buffer buffer, void* userdata),
94 +
                                    void* userdata,
95 +
                                    helics_error* err)
96 +
{
97 +
    auto* fedptr = getFed(fed, err);
98 +
    if (fedptr == nullptr) {
99 +
        return;
100 +
    }
101 +
102 +
    try {
103 +
        if (queryAnswer == nullptr) {
104 +
            fedptr->setQueryCallback({});
105 +
        } else {
106 +
            fedptr->setQueryCallback([queryAnswer, userdata](const std::string& query) {
107 +
                std::string buffer(1, '>');
108 +
                queryAnswer(query.c_str(), static_cast<int>(query.size()), &buffer, userdata);
109 +
                buffer.pop_back();
110 +
                return buffer;
111 +
            });
112 +
        }
113 +
    }
114 +
    catch (...) {  // LCOV_EXCL_LINE
115 +
        helicsErrorHandler(err);  // LCOV_EXCL_LINE
116 +
    }
117 +
}
118 +
119 +
void helicsQueryBufferFill(helics_query_buffer buffer, const char* string, int stringSize, helics_error* err)
120 +
{
121 +
    static const char* invalidBuffer = "The given buffer is not valid";
122 +
123 +
    if (((err) != nullptr) && ((err)->error_code != 0)) {
124 +
        return;
125 +
    }
126 +
    if (buffer == nullptr) {
127 +
        assignError(err, helics_error_invalid_object, invalidBuffer);
128 +
        return;
129 +
    }
130 +
131 +
    auto* bufferStr = reinterpret_cast<std::string*>(buffer);
132 +
    if (bufferStr->empty() || bufferStr->back() != '>') {
133 +
        assignError(err, helics_error_invalid_object, invalidBuffer);
134 +
        return;
135 +
    }
136 +
    if (stringSize <= 0 || string == nullptr) {
137 +
        bufferStr->clear();
138 +
        bufferStr->push_back('>');
139 +
    }
140 +
    bufferStr->reserve(stringSize + 1);
141 +
    bufferStr->assign(string, string + stringSize);
142 +
    bufferStr->push_back('>');
143 +
}

@@ -219,7 +219,7 @@
Loading
219 219
    Time requestTime(Time nextInternalTimeStep);
220 220
221 221
    /** request a time advancement to the next allowed time
222 -
  @return the granted time step*/
222 +
    @return the granted time step*/
223 223
    Time requestNextStep() { return requestTime(timeZero); }
224 224
225 225
    /** request a time advancement by a certain amount
@@ -349,12 +349,12 @@
Loading
349 349
350 350
    /** get the results of an async query
351 351
    @details the call will block until the results are returned inquiry of queryCompleted() to check
352 -
   if the results have been returned or not yet
352 +
    if the results have been returned or not yet
353 353
354 354
    @param queryIndex the int value returned from the queryAsync call
355 -
   @return a string with the value requested.  the format of the string will be either a single
356 -
   string a string vector like "[string1; string2]" or JSON The string "#invalid" is returned if the
357 -
   query was not valid
355 +
    @return a string with the value requested.  the format of the string will be either a single
356 +
    string a string vector like "[string1; string2]" or JSON The string "#invalid" is returned if
357 +
    the query was not valid
358 358
    */
359 359
    std::string queryComplete(query_id_t queryIndex);
360 360
@@ -363,6 +363,16 @@
Loading
363 363
    */
364 364
    bool isQueryCompleted(query_id_t queryIndex) const;
365 365
366 +
    /** supply a query callback function
367 +
    @details the intention of the query callback is to allow federates to answer particular requests
368 +
    through the query interface this allows other federates to make requests or queries of other
369 +
    federates in an asynchronous fashion.
370 +
    @param queryFunction  a function object that returns a string as a result of a query in the form
371 +
    of const string ref. This callback will be called when a federate received a query that cannot
372 +
    be answered internally that is directed at that particular federate
373 +
    */
374 +
    void setQueryCallback(const std::function<std::string(const std::string&)>& queryFunction);
375 +
366 376
    /** set a federation global value
367 377
    @details this overwrites any previous value for this name
368 378
    @param valueName the name of the global to set

@@ -1152,6 +1152,16 @@
Loading
1152 1152
    return {"#invalid"};
1153 1153
}
1154 1154
1155 +
void Federate::setQueryCallback(const std::function<std::string(const std::string&)>& queryFunction)
1156 +
{
1157 +
    if (coreObject) {
1158 +
        coreObject->setQueryCallback(fedID, queryFunction);
1159 +
    } else {
1160 +
        throw(InvalidFunctionCall(
1161 +
            " setQueryCallback cannot be called on uninitialized federate or after finalize call"));
1162 +
    }
1163 +
}
1164 +
1155 1165
bool Federate::isQueryCompleted(query_id_t queryIndex) const  // NOLINT
1156 1166
{
1157 1167
    auto asyncInfo = asyncCallInfo->lock();

@@ -2064,8 +2064,7 @@
Loading
2064 2064
        return filteredEndpointQuery(fed);
2065 2065
    }
2066 2066
    if ((queryStr == "queries") || (queryStr == "available_queries")) {
2067 -
        return std::string(
2068 -
                   "[exists;isinit;state;global_state;version;queries;filtered_endpoints;current_time;") +
2067 +
        return std::string("[exists;isinit;state;version;queries;filtered_endpoints;") +
2069 2068
            fed->processQuery(queryStr) + "]";
2070 2069
    }
2071 2070
    return fed->processQuery(queryStr);

@@ -2716,6 +2716,7 @@
Loading
2716 2716
    gidString.push_back(']');
2717 2717
    return gidString;
2718 2718
}
2719 +
2719 2720
void CoreBroker::initializeMapBuilder(const std::string& request, std::uint16_t index, bool reset)
2720 2721
{
2721 2722
    if (!isValidIndex(index, mapBuilders)) {

@@ -10,6 +10,7 @@
Loading
10 10
11 11
#include "../shared_api_library/MessageFilters.h"
12 12
#include "../shared_api_library/helics.h"
13 +
#include "../shared_api_library/helicsCallbacks.h"
13 14
#include "Filter.hpp"
14 15
#include "config.hpp"
15 16
#include "helicsExceptions.hpp"
@@ -18,6 +19,11 @@
Loading
18 19
#include <string>
19 20
#include <vector>
20 21
22 +
#if defined(HELICS_HAS_FUNCTIONAL) && HELICS_HAS_FUNCTIONAL != 0
23 +
#    include <functional>
24 +
#    include <utility>
25 +
#endif
26 +
21 27
namespace helicscpp {
22 28
/** hold federate information in the C++98 API*/
23 29
class FederateInfo {
@@ -153,6 +159,22 @@
Loading
153 159
    helics_federate_info fi;  //!< handle for the underlying federate_info object
154 160
};
155 161
162 +
#if defined(HELICS_HAS_FUNCTIONAL) && HELICS_HAS_FUNCTIONAL != 0
163 +
namespace details {
164 +
    /** helper function for the callback executor for queries*/
165 +
    inline void helicCppQueryCallbackExecutor(const char* query,
166 +
                                              int stringSize,
167 +
                                              helics_query_buffer buffer,
168 +
                                              void* userData)
169 +
    {
170 +
        auto cback = reinterpret_cast<std::function<std::string(const std::string&)>*>(userData);
171 +
        std::string val(query, stringSize);
172 +
        std::string result = (*cback)(val);
173 +
        helicsQueryBufferFill(buffer, result.c_str(), static_cast<int>(result.size()), nullptr);
174 +
    }
175 +
}  // namespace details
176 +
#endif
177 +
156 178
/** an iteration time structure */
157 179
typedef struct {
158 180
  public:
@@ -199,6 +221,13 @@
Loading
199 221
        if (fed != HELICS_NULL_POINTER) {
200 222
            helicsFederateFree(fed);
201 223
        }
224 +
#if defined(HELICS_HAS_FUNCTIONAL) && HELICS_HAS_FUNCTIONAL != 0
225 +
        if (callbackBuffer != nullptr) {
226 +
            auto cback =
227 +
                reinterpret_cast<std::function<std::string(const std::string&)>*>(callbackBuffer);
228 +
            delete cback;
229 +
        }
230 +
#endif
202 231
    }
203 232
    /** cast operator to get the underlying helics_federate object*/
204 233
    operator helics_federate() const { return fed; }
@@ -469,6 +498,26 @@
Loading
469 498
        return result;
470 499
    }
471 500
501 +
    void setQueryCallback(
502 +
        void (*queryAnswer)(const char* query, int querySize, helics_query_buffer, void* userdata),
503 +
        void* userdata)
504 +
505 +
    {
506 +
        helicsFederateSetQueryCallback(fed, queryAnswer, userdata, hThrowOnError());
507 +
    }
508 +
509 +
#if defined(HELICS_HAS_FUNCTIONAL) && HELICS_HAS_FUNCTIONAL != 0
510 +
    void setQueryCallback(std::function<std::string(const std::string&)> callback)
511 +
512 +
    {
513 +
        callbackBuffer = new std::function<std::string(const std::string&)>(std::move(callback));
514 +
        helicsFederateSetQueryCallback(fed,
515 +
                                       details::helicCppQueryCallbackExecutor,
516 +
                                       callbackBuffer,
517 +
                                       hThrowOnError());
518 +
    }
519 +
520 +
#endif
472 521
    /** define a filter interface
473 522
    @details a filter will modify messages coming from or going to target endpoints
474 523
    @param type the type of the filter to register
@@ -599,7 +648,12 @@
Loading
599 648
  protected:
600 649
    helics_federate fed;  //!< underlying helics_federate object
601 650
    bool exec_async_iterate;  //!< indicator that the federate is in an async operation
651 +
#if defined(HELICS_HAS_FUNCTIONAL) && HELICS_HAS_FUNCTIONAL != 0
652 +
  private:
653 +
    void* callbackBuffer{nullptr};  //!< buffer to contain pointer to a callback
654 +
#endif
602 655
};
603 656
604 657
}  // namespace helicscpp
658 +
605 659
#endif

@@ -722,6 +722,7 @@
Loading
722 722
    return until the query is answered so use with caution
723 723
    */
724 724
    virtual std::string query(const std::string& target, const std::string& queryStr) = 0;
725 +
725 726
    /** supply a query callback function
726 727
    @details the intention of the query callback is to allow federates to answer particular requests
727 728
    through the query interface this allows other federates to make requests or queries of other
@@ -733,14 +734,16 @@
Loading
733 734
    */
734 735
    virtual void setQueryCallback(local_federate_id federateID,
735 736
                                  std::function<std::string(const std::string&)> queryFunction) = 0;
737 +
736 738
    /**
737 739
     * setter for the interface information
738 740
     * @param handle the identifiers for the interface to set the info data on
739 741
     * @param info a string containing the info data
740 742
     */
741 743
    virtual void setInterfaceInfo(interface_handle handle, std::string info) = 0;
744 +
742 745
    /**
743 -
     * gett for the interface information
746 +
     * getter for the interface information
744 747
     * @param handle the identifiers for the interface to query
745 748
     * @return a string containing the Info data stored in an interface
746 749
     */
Files Coverage
src/helics 76.98%
Project Totals (210 files) 76.98%
12921.9
TRAVIS_OS_NAME=linux
12919.9
TRAVIS_OS_NAME=linux
12922.9
TRAVIS_OS_NAME=linux
1
codecov:
2
  notify:
3
    require_ci_to_pass: no
4
  branch: develop
5

6
coverage:
7
  precision: 2
8
  round: down
9
  range: '50...95'
10
  status:
11
    project: yes
12
    patch: yes
13
    changes: no
14

15
parsers:
16
  gcov:
17
    branch_detection:
18
      conditional: yes
19
      loop: yes
20
      method: no
21
      macro: no
22

23
comment:
24
  layout: 'header, diff'
25
  behavior: default
26
  require_changes: no
27

28
ignore:
29
  - 'ThirdParty'
30
  - 'examples'
31
  - 'tests'
32
  - 'interfaces'
33
  - 'src/helics/core/mpi'
34
  - '**/logger.*'
35
  - '**/loggerCore.*'
36
  - '**/zmqHelper.*'
37
  - 'src/helics/shared_api_library/internal/api_objects.h'
Sunburst
The inner-most circle is the entire project, moving away from the center are folders then, finally, a single file. The size and color of each slice is representing the number of statements and the coverage, respectively.
Icicle
The top section represents the entire project. Proceeding with folders and finally individual files. The size and color of each slice is representing the number of statements and the coverage, respectively.
Grid
Each block represents a single file in the project. The size and color of each block is represented by the number of statements and the coverage, respectively.
Loading