Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
languagecpp
themeDJango
linenumberstrue
collapsetrue
void calibrateSync() {
  // do calibration...
}

void ExampleImpl::calibrate() {
    new std::thread(calibrateSync); //Thread resources are never de-allocated for simplicity
}

...

Code Block
languagecpp
themeDJango
linenumberstruecollapsetrue
void calibrateSync() {
    // do calibration...
}

//Function running on some other thread...
void run() {
    if (queue.size() > 0) {
        if (queue.pop() == CALIBRATE_ACTION) {
            calibrateSync();
        } else {
            //Some error
        }
    }
}

void ExampleImpl::calibrate() {
    queue.push(CALIBRATE_ACTION);
}

...

Code Block
languagecpp
themeDJango
linenumberstrue
collapsetrue
interface Example: ... {
    ...
    oneway void calibrate();
    ...
}

...

Code Block
languagecpp
themeDJango
linenumberstrue
collapsetrue
void ExampleImpl::calibrate() {
    // do calibration...
}

...

Code Block
collapse
languagecpp
themeDJango
linenumberstruetrue
interface OffShoot {};

This is by design, allowing anyone to extend such interface as they prefer. For instance:

Code Block
languagecpp
themeDJango
linenumberstruecollapsetrue
module Definitions {
    interface SimpleCallback : ACS::OffShoot {
        oneway void report(in boolean error);
    };
};

...

Code Block
collapse
languagecpp
themeDJango
linenumberstruetrue
interface Example: ... {
    ...
    oneway void calibrate(in Definitions::SimpleCallback cBcb);
    ...
}

Which would lead to an implementation (Assuming the oneway case) as follows:

Code Block
collapse
languagecpp
themeDJango
linenumberstruetrue
void ExampleImpl::calibrate(SimpleCallback* cb) {
    // do calibration...
    cb->report(status);
}

...

Callbacks are in fact a specialization of the Offshoot and were designed to be used mainly by BACI (Monitoring, Actions, etc.). These are based on the basic ACS types (void, float, double, long, boolean, string, etc.).

They can be used manually, but they're discouraged, because they depend on CBDescIn and CBDescOut structures. These are used to define the expected timeout and to hold back the Tag ID of the execution, but they don't have any use on a custom implementation, so it's better to use an extension to the Offshoot if you're making your own implementation for reporting back to the caller.

An example of callback is the CBvoid interface:

Code Block
languagecpp
themeDJango
linenumberstrue
interface Callback : OffShoot {
    boolean negotiate (in TimeInterval time_to_transmit, in CBDescOut desc);
};

interface CBvoid : Callback {
    oneway void working (in ACSErr::Completion c, in CBDescOut desc);
    oneway void done (in ACSErr::Completion c, in CBDescOut desc);
};

BACI Actions

BACI Actions make use of these Callback definitions to leverage the execution of asynchronous actions. The same example as before could go something like this:

Code Block
languagecpp
themeDJango
linenumberstrue
interface Example: ... {
    ...
    oneway void calibrate(in ACS::CBvoid cb, in ACS::CBDescIn desc);
    ...
}

The implementation needs to have the calibrateAction returning one of the four alternatives:

  • reqNone: Do nothing; the request will remain in the queue
  • reqInvokeWorking: Notify a working update; the request will remain in the queue
  • reqInvokeDone: Notify that the request has finished; the request is removed from the queue
  • reqDestroy: Remove the request from the queue without notifying (When it should have already been destroyed or if you want to ignore the request completely)

Also it needs to modify the invokeAction method, to ensure that the correct action is called:

Code Block
languagecpp
themeDJango
linenumberstrue
ActionRequest ExampleImpl::calibrateAction (BACIComponent *cob_p, const int &callbackID, const CBDescIn &descIn, BACIValue *value_p, Completion &completion, CBDescOut &descOut) {
    completion = ACSErrTypeOK::ACSErrOKCompletion();
    // do calibration...
    completion = //Actual status of calibration process
    return reqInvokeDone;
}


ActionRequest ExampleImpl::invokeAction (int function, BACIComponent *cob_p, const int &callbackID, const CBDescIn &descIn, BACIValue *value_p, Completion &completion, CBDescOut &descOut) {
    switch (function) {
        case CALIBRATE_ACTION: {
            return calibrateAction(cob_p, callbackID, descIn, value_p, completion, descOut);
        }
        default: {
            return reqDestroy;
        }
    }
}


void ExampleImpl::calibrate(ACS::CBvoid_ptr cb, const ACS::CBDescIn& desc) {
    getComponent()->registerAction(BACIValue::type_null, cb, desc, this, CALIBRATE_ACTION);
}

More information can be found in BACI Device Server Programming Tutorial.