I have a connect that works which connects a signal in C++ to a slot in JavaScript:
Object::connect(this, &clsQtPushBtn::clicked
,[pobjScriptEng, strCall, strFile, strScript]() {
QString strScriptWithCall = static_cast<QString>(strStript)
+ static_cast<QString>(strCall) + "();";
pobjScriptEng->evaluate(strScriptWithCall);
});
In the above code:
this is an instance of my PushButton class clsQtPushBtn.
clsQtPushBtn::clicked is the address of the "clicked" signal.
pobjScriptEng is a pointer to an instance of QJSEngine*.
strCall is a JavaScript function "test".
strFile is the name of the JavaScript file "simon2.js".
strScript is the content of the JavaScript file which contains the function test().
The question is how do a make the equivalent disconnect call as I'm having difficulty with it, there are 7 options and just changing connect for disconnect does not work, I get:
no matching member function for call to 'disconnect'
The QObject::connect function returns a QMetaObject::Connection so you can pass it to QObject::disconnect.
Normally, you would just provide the same details as in the connect call (for example, source and target objects, source signal and target slot).
However, that particular connect form you're using returns a QMetaObject::Connection object which you can store for later disconnection:
auto connection = Object::connect(this, &clsQtPushBtn::clicked, blah, blah);
:
QObject::disconnect(connection);
That's most likely a better way, since it can get the information immediately rather than searching for a connection in a possibly large list (though I may be wrong about how that's implemented). It's especially better since I believe it's the only option in this case, seeing that every lambda is unique, so you couldn't use a new one to find the old connection anyway.
In addition, I've used a local variable to store it but you'd probably be better storing it into a member variable of some sort.
Related
I've created a web server using C and C++, which works in the following way:
First, it initialize the socket for the connection.
Then, when the server receives an HTTP request, it calls a function that will retrieve the data form the request, and create an object which will parse the incoming request. (The object contains the request's parameters and headers).
Then, it calls a function named HandleRequest, and gives him the object created. The object's type is Request, which I wrote myself.
The HandleRequest function will analyze the request, generate an HTML document, and returns the whole document as a string.
Finally, The server takes the string returned by the HandleRequest function and send it back to the client.
Now, if I want to create another site, the only code I will have to changed is the HandleRequest function.
My point is I want to pack the server itself in a static library, and then when I want to make a new website, I only have to write the HandleRequest function and link the static library when compiling to make the server.
Of course, when I try to do so, I have the error
undefined reference to 'HandleRequest'
So is it possible to make the library compile, knowing that a function has its code written outside of the library ?
Edit: I tried to compile the .cpp file with without the -c option, so that the library already have the linking done. I am aware that with the -c option, everything works fine.
Also, I tried to put
extern std::string HandleRequest(Request request);
before the function that calls HandleRequest but it didn't worked.
Quick and easy solution
Make HandleRequest a global variable that’s function pointer:
std::string (*HandleRequest)(Request);
You can move the functionality of the old HandleRequest function into something like DefaultHandleRequest, and you can even initialize the function pointer using the DefaultHandleRequest:
std::string DefaultHandleRequest(Request request)
{
// stuff
}
std::string (*HandleRequest)(Request) = DefaultHandleRequest;
If you do this, you won’t have to change any other code, but you’ll be able to update HandleRequest whenever you like.
More thorough solution
We can make this solution much more general, enabling you to have multiple servers running in the same program.
In order to do this, make a Server class, which acts as the server. An instance of this class will act as your server. Have Server store a std::function<std::string(Request)> that handles incoming requests. You can assign or update this at any time, as necessary.
Design Server so that there can be multiple instances at once, each representing a different server/service with it’s own HandleRequest function.
I need to do a callout to webservice from my ApexController class. To do this, I have an asycn method with attribute #future (callout=true). The webservice call needs to refeence an object that gets populated in save call from VF page.
Since, static (future) calls does not all objects to be passed in as method argument, I was planning to add the data in a static Map and access that in my static method to do a webservice call out. However, the static Map object is getting re-initalized and is null in the static method.
I will really appreciate if anyone can give me some pointeres on how to address this issue.
Thanks!
Here is the code snipped:
private static Map<String, WidgetModels.LeadInformation> leadsMap;
....
......
public PageReference save() {
if(leadsMap == null){
leadsMap = new Map<String, WidgetModels.LeadInformation>();
}
leadsMap.put(guid,widgetLead);
}
//make async call to Widegt Webservice
saveWidgetCallInformation(guid)
//async call to widge webserivce
#future (callout=true)
public static void saveWidgetCallInformation(String guid) {
WidgetModels.LeadInformation cachedLeadInfo =
(WidgetModels.LeadInformation)leadsMap.get(guid);
.....
//call websevice
}
#future is totally separate execution context. It won't have access to any history of how it was called (meaning all static variables are reset, you start with fresh governor limits etc. Like a new action initiated by the user).
The only thing it will "know" is the method parameters that were passed to it. And you can't pass whole objects, you need to pass primitives (Integer, String, DateTime etc) or collections of primitives (List, Set, Map).
If you can access all the info you need from the database - just pass a List<Id> for example and query it.
If you can't - you can cheat by serializing your objects and passing them as List<String>. Check the documentation around JSON class or these 2 handy posts:
https://developer.salesforce.com/blogs/developer-relations/2013/06/passing-objects-to-future-annotated-methods.html
https://gist.github.com/kevinohara80/1790817
Side note - can you rethink your flow? If the starting point is Visualforce you can skip the #future step. Do the callout first and then the DML (if needed). That way the usual "you have uncommitted work pending" error won't be triggered. This thing is there not only to annoy developers ;) It's there to make you rethink your design. You're asking the application to have open transaction & lock on the table(s) for up to 2 minutes. And you're giving yourself extra work - will you rollback your changes correctly when the insert went OK but callout failed?
By reversing the order of operations (callout first, then the DML) you're making it simpler - there was no save attempt to DB so there's nothing to roll back if the save fails.
I'm writing a little clojure pub/sub interface. It's very barebones, only two methods that will actually be used: do-pub and sub-listen. sub-listen takes a string (a sub name) and do-pub takes two strings (a sub name and a value).
I'm still fairly new at clojure and am having some trouble coming up with a workable way to do this. My first thought (and indeed my first implementation) uses a single agent which holds a hash:
{ subname (promise1 promise2 etc) }
When a thread wants to sub it conj's a promise object to the list associated with the sub it wants, then immediately tries to de-reference that promise (therefore blocking).
When a pub happens it goes through every item in the list for the sub and delivers the value to that item (the promise). It then dissoc's that subname from the map and returns it to the agent.
In this way I got a simple pub sub implementation working. However, the problem comes when someone subs, doesn't receive a pub for a certain amount of time, then gets killed due to timeout. In this scenario there will be a worthless promise in the agent that doesn't need to be, and moreover this will be a source of a memory leak if that sub never gets pub'd.
Does anyone have any thoughts on how to solve this? Or if there is a better way to do what I'm trying to do overall (I'm trying to avoid using any external pre-cooked pubsub libraries, this is a pet project not a work one)?
You can do something like this:
Create an atom
publish function will update the atom value by the passed in value to the function
Subscribers can use add-watch on the atom to be notified of when the atom value changes i.e due to call to publish function
Use remove-watch to remove the subscription.
This way you will have a very basic pub-sub system.
I have marked Ankur's answer as the solution but I wanted to expand on it a bit. What I ended up doing is having a central atom that all client threads do an add-watch on. When a pub is done the atom's value is changed to a vector containing the name of the sub and the value being pub'd.
The function the clients pass to add-watch is a partial function which looks like
(partial (fn [prom sub key ref _old new] ...) sub prom)
where prom is a promise previously generated. The client then blocks while waiting on that promise. The partial function checks if the sub in new is the same as sub, if so it removes the watch and delivers on the promise with the value from new.
i'm sure this must be really simple or i'm missing the point, but how do you disconnect from Mongo using the C++ driver and DBClientConnection? DBClient has a public member of 'connect' but no disconnect/kill/drop etc that I can find.
There is some talk (in stack overflow and on the web) of using ScopedDBConnection which does seem to be able to allow me to drop my connection - but there are very few examples of how it would be used - or info on when I should use that class over the DBClientConnection class.
Any ideas?
If you're using a DBClientConnection, it has one connection, and you aren't supposed to disconnect/reconnect. I guess it kills the connection when it calls the destructors. You can set it up to automatically reconnect so you can keep using it if it loses its connection.
If you want to have connection pooling and multiple connections, you want to use ScopedDBConnection. You can see some examples here: https://github.com/mongodb/mongo/blob/master/src/mongo/client/model.cpp
Here's the gist:
ScopedDbConnection conn("localhost");
mongo::BSONObjBuilder obj;
obj.append( "name" , "asd" );
conn->insert("test.test", obj);
conn.done();
Basically, you can do anything with conn that you can do with a DBClientConnection, but when you're done you call done().
Hello i am learning qt and trying to upload a file using QFtp i wrote the folowing code
this->connect(this->ftp, SIGNAL(done(bool)), this, SLOT(ftpDone(bool)));
this->connect(this->ftp, SIGNAL(dataTransferProgress(qint64, qint64)), this, SLOT(dataTransferProgress(qint64, qint64)));
this->connect(this->ftp, SIGNAL(stateChanged(int)), this, SLOT(stateChanged(int)));
.....
if(this->file.open(QIODevice::ReadWrite))
{
this->ftp->setTransferMode(QFtp::Active);
this->ftp->connectToHost(this->settings->getHost());
this->ftp->login(this->settings->getUser(), this->settings->getPassword());
this->ftp->cd(remoteFilePath);
this->ftp->get(this->fileName, &this->file);
this->ftp->close();
}
and it kind of stops it reports in dataTransferProgress that it is at 0/XXX but the slot is never invoked again (using the same code but with the get function i can download a file and it works without a problem) also the error that i get after the time out is QFtp::UnknownError.
Assuming all the commands until get are successful, it's likely that you are closing the connection before get finishes. You should save the identifier returned by get and call close when the commandFinished signal is called with that identifier.
Note: Except setTransferMode all of the methods you used are asynchronous. They will be executed in the order that they are called, but since you aren't performing any error checking, it's possible for one to fail and the rest will still be attempted which might result in some confusion.
The proper way of doing this is to connectToHost first, if that's successful (you can track this with the commandFinished signal) call login etc.