1

The solution may be simple. Then again it may not be possible.

I have the base callback class:

class CFCallback {
    int command_;
    int transfer_rate_;
    public:
    CFCallback(int command, int transfer_rate = 0) {
        command_ = command; transfer_rate_ = transfer_rate; }
    virtual ~CFCallback() {}
    virtual void operator()(void *data) = 0;
    int GetCommand() { return command_; }
    int GetTransferRate() { return transfer_rate_; }
};

And here's one example of deriving from CFCallback:

void CFPacketVersion::InitiateVersion() {
    class InitiateVersionCB : public CFCallback {
        CFPacketVersion *visitor_;
        public:
        InitiateVersionCB(CFPacketVersion *v, int command) :
            CFCallback(command) {
            visitor_ = v;
        }
        void operator()(void *data) {
            Packet *pkt = (Packet *)data;
            unsigned char *pkt_data = pkt->GetData();
            std::string version = "";
            for(unsigned int i = 0; i < pkt->GetDataLength(); i++ )
                version+= pkt_data[i];
            delete []pkt_data;
            boost::regex rex("CFA(.*?):h(.*?),v(.*?)$");
            boost::smatch what;
            if( boost::regex_match(version, what, rex) ) {
                if(visitor_->GetModel()->GetName() != what[1].str() )
                    LCDInfo("Crystalfontz: Model mismatch");
                visitor_->SetHardwareVersion(what[2]);
                visitor_->SetFirmwareVersion(what[3]);
            }
        }
    };
    GetVersion(new InitiateVersionCB(this, 1));
}

GetVersion(CFCallback *) is provided to the script engine.

I want to be able to do the same thing as seen in InitiateVersion, but on the javascript side of things. Is that possible?

I know I need to register meta type info for CFCallback. But I don't know if it's possible to use a pointer to a CFCallback. What I tried initially didn't work.

Also, seeing as CFCallback is a functor, I'm not sure how I translate that over to javascript. I imagine I can make CFCallback a QObject and provide a signal emitted from operator(). If you have any tips, please share.

1 Answer 1

2

I'm afraid it won't work the way you've set it up.

If you want to be able to create the callback in javascript, you need a QObject with an accessible GetVersion(QScriptValue) which the script will the use to pass a script-based implementation of the callback. Note, though, that the callback will not be able to work with untyped (void*) data - you need to pass either a valid QtScript object or QObject with a proper interface (like the Packet one in your example!)

You could then wrap it up like this:

QtScript:

function mycb(packet) {
  var pkt_data = packet.getData(); // pkt_data is probably a String or custom object with proper interface so to simplify things get the version as string
  var version = pkt_data.toString();
  pkt_data.release(); // to simulate delete [] pkt_data; this is part of custom interface
  // proceed further with the regex checks

}

GetVersion(mycb); // implies that you define the GetVersion() as a property of the global object

C++:

QScriptValue getVersion(QScriptContext *ctx, QScriptEngine *engine)
{
 void *data = ...;
 Packet pkt_data = wrapPacketData(data);
 // Packet is interface registered with QtScript or inherits QObject
 // it has methods getData(), toString() and release()
 QScriptValueList args;
 QScriptValue pkt_data_param = engine->newQObject(&pkt_data);
 args << pkt_data_param;
 QScriptValue cb = ctx->argument(0); 
 Q_ASSERT(cb.isFunction()); // we expect a function object!
 cb.call(QScriptValue(), args);
}
QScriptValue getVersionFun = engine->newFunction(getVersion);
engine->globalObject().setProperty(QLatin1String("GetVersion"), getVersionFun);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.