It's a pleasure to share some information with you.
Excuse me, does anybody know how to have two FORMS running at the same time?
I mean, I execute a FOR clicking one BUTTON on FORM1 and set FOR's values to a LABEL on FORM2.
Here some codes in FORM1:
void __fastcall Form1::Button1Click(TObject *Sender){
int i = 0;
for (i=0;i<=10000;i++){
Form1->Label1->Caption = i;
Form2->Label1->Caption = i;
}
}
I just want to see this:
if.... Form1->Label1->Caption = 1, Form2->Label1->Caption has to be 1 too and so on.
FORM2 shows me just the last result, which is 10,000.
I appreciate any help.
Thank you !
Just call Update(): (*)
void __fastcall Form1::Button1Click(TObject *Sender)
{
for(int i = 0; i <= 10000; ++i)
{
Form1->Label1->Caption = i;
Form2->Label1->Caption = i;
Form1->Label1->Update();
Form2->Label1->Update();
}
}
Update():
Processes any pending paint messages immediately.
Call Update to force the control to be repainted before any more, possibly time-consuming,
processing takes place. Use Update to provide immediate feedback to the user that cannot wait
for the Windows paint message to arrive.
Update does not invalidate the control, but simply forces a repaint of any regions that have
already been invalidated.
Application->ProcessMessages() will also work, but it's not the right choice: it interrupts the execution of an application so that it can process the message queue. ProcessMessages can be way slower.
(*) Changed since Remy's hint was absolutely better than the original answer (Update vs ProcessMessages)
Related
I want to make a program in which there are two dots blinking (with a break of 10ms) simultaneously, but one with delay 200ms and other with delay of 300ms. How can I play these two dots simultaneously from beginning? Is there a better way to that from following:
for(int i=1;i<100;i++)
{
if (i%2==0)
circle(10,10,2);
if (i%3==0)
circle(20,10,2);
delay(10);
cleardevice();
delay(100);
}
I would do something like this instead:
int t0=0,t1=0,t=0,s0=0,s1=0,render=1;
for (;;)
{
if (some stop condition like keyboard hit ...) break;
// update time, state
if (t>=t0) { render=1; s0=!s0; if (s0) t0+=10; else t0+=200; }
if (t>=t1) { render=1; s1=!s1; if (s1) t1+=10; else t1+=300; }
// render
if (render)
{
render=0;
cleardevice();
if (s0) circle(10,10,2);
if (s1) circle(20,10,2);
}
// update main time
delay(10); // Sleep(10) would be better but I am not sure it is present in TC++
t+=10;
if (t>10000) // make sure overflow is not an issue
{
t -=10000;
t0-=10000;
t1-=10000;
}
}
Beware the code is untested as I wrote it directly in here (so there might be syntax errors or typos).
The basic idea is having one global time t with small enough granularity (10ms). And for each object have time of event (t0,t1) state of object (s0,s1) and periods (10/200 , 10/300).
If main time reach the event time swap the state on/off and update event time to next state swap time.
This way you can have any number of objects just make sure your main time step is small enough.
The render flag just ensures that the scene is rendered on change only.
To improve timing you can use RDTSC instead of t+=10 and actually measure how much time has passed with CPU frequency accuracy.
To display the two circles simultaneously in the first round, you have to satisfy both conditions i%2==0 and i%3==0 at once. You can achieve it by simply changing
for(int i=1;i<100;i++)
to
for(int i=0;i<100;i++)
// ↑ zero here
I have a text file full of information on where to place tiles in a game i'm making, the fastest way to access this information is with a for loop. But whenever i use the for loop to get through all the information it freezes the program for about 12 seconds, in those 12 i cant move the window, nothing on the renderer updates/is drawn, and then when i click on the window it breaks and says "window name (Not Responding)". I tried using a while loop but it still does the same thing.
How can i loop through bigger numbers (there are about 4,000 tiles in the level) without the program freezing/hanging on me? I'm just using SDL 2, no OpenGL involved.
int tiles = 4000;
int x[4000];
int y[4000];
tile obj[4000];
for(int i = 0; i < tiles; i++)
{
x[i] = txt.x;
y[i] = txt.y;
obj[i].Load(x[i], y[i]);
obj[i].Add();
SDL_RenderClear(ren);
LoadScreen();
SDL_RenderPresent(ren);
}
Thanks.
You need to create another thread.
It's good idea to wait for all data to load before starting game, so during load, you don't need to render anything. Even with this approach, it is better to use another thread and don't keep "UI Thread" busy. During load time your UI would be mostly disabled except a cancel button that will stop loading thread.
#include <process.h>
bool bReady;
void LoadTiles(void* pArg)
{
// Load Data here
*((int*)pArg) = 0;
///////////////////
bReady = true;
}
void main()
{
btnStart.SetEnabled(false);
bReady = false;
int iTarget;
uintptr_t hLoadingThread = _beginthread(LoadTiles, 0, &iTarget);
while (true) // usually you pick a message here
{
if (bReady)
btnStart.SetEnabled(true);
}
}
This is just a very simple example, multi-threading needs a lot of work and study!
The QtConcurrent namespace is really great for simplifying the management of multi-threaded calculations. Overall this works great and I have been able to use QtConcurrent run(), map(), and other variants in the way they are described in the API.
Overall Goal:
I would like to query, cancel(), or pause() a numerically intensive calculation from QML. So far this is working the way I would like, except that I cannot access the sequence numbers in the calculation. Here is a link that describes a similar QML setup.
Below is an image from small test app that I created to encapsulate what I am trying to do:
In the example above the calculation has nearly completed and all the cores have been enqueued with work properly, as can be seen from a system query:
But what I really would like to do is use the sequence numbers from a given list of the items IN THE multi-threaded calculation itself. E.g., one approach might be to simply setup the sequence numbers directly in a QList or QVector (other C++ STL containers can work as well), like this:
void TaskDialog::mapTask()
{
// Number of times the map function will be called:
int N = 5;
// Prepare the vector that we operate on with mapFunction:
QList<int> vectorOfInts;
for (int i = 0; i < N; i++) {
vectorOfInts << i;
}
// Start the calc:
QFuture<void> future = QtConcurrent::map(vectorOfInts, mapFunction);
_futureWatcher.setFuture(future);
//_futureWatcher.waitForFinished();
}
The calculation is non-blocking with the line: _futureWatcher.waitForFinished(); commented out, as shown in the code above. Note that when setup as a non-blocking calculation, the GUI thread is responsive, and the progress bar updates as desired.
But when the values in the QList container are queried during the calculation, what appears seem to be the uninitialized garbage values that one would expect when the array is not properly initialized.
Below is the example function I am calling:
void mapFunction(int& n)
{
// Check the n values:
qDebug() << "n = " << n;
/* Below is an arbitrary task but note that we left out n,
* although normally we would want to use it): */
const long work = 10000 * 10000 * 10;
long s = 0;
for (long j = 0; j < work; j++)
s++;
}
And the output of qDebug() is:
n = 30458288
n = 204778
n = 270195923
n = 0
n = 270385260
The n-values are useless but the sum values, s, are correct (although not shown) when the calculation is mapped in this fashion (non-blocking).
Now, if I uncomment the _futureWatcher.waitForFinished(); line then I get the expected values (the order is irrelevant):
n = 0
n = 2
n = 4
n = 3
n = 1
But in this case, with _futureWatcher.waitForFinished(); enabled, my GUI thread is blocked and the progress bar does not update.
What then would be the advantage of using QtConcurrent::map() with blocking enabled, if the goal to not block the main GUI thread?
Secondly, how can get the correct values of n in the non-blocking case, allowing the GUI to remain responsive and have the progress bar keep updating?
My only option may be to use QThread directly but I wanted to take advantage of all the nice tools setup for us in QtConcurrent.
Thoughts? Suggestions? Other options? Thanks.
EDIT: Thanks to user2025983 for the insight which helped me to solve this. The bottom line is that I first needed to dynamically allocate the QList:
QList<int>* vectorOfInts = new QList<int>;
for (int i = 0; i < N; i++)
vectorOfInts->push_back(i);
Next, the vectorOfInts is passed by reference to the map function by de-referencing the pointer, like this:
QFuture<void> future = QtConcurrent::map(*vectorOfInts, mapFunction);
Note also that the prototype of the mapFunction remains the same:
void mapFunction(int& n)
And then it all works properly: the GUI remained responsive, progress bar updated, the values of n are all correct, etc., WITHOUT the need to add blocking through the function:
_futureWatcher.waitForFinished();
Hope these extra details can help someone else.
The problem here is that your QList goes out of the scope when mapTask() finishes.
Since the mapFunction(int &n) takes the parameter by reference, it gets references to integer values which are now part of an array which is out of scope! So then the computer is free to do whatever it likes with that memory, which is why you see garbage values. If you are just using integer parameters, I would recommend passing the parameters by value and then everything should work.
Alternatively, if you must pass by reference you can have the futureWatcher delete the array when its finished.
QList<int>* vectorOfInts = new QList<int>;
// push back into structure
connect(_futureWatcher, SIGNAL(finished()), vectorOfInts, SLOT(deleteLater()));
// launch stuff
QtConcurrent::map...
// profit
I have read the question that was posted earlier that seemed to be having the same error that I am getting when using wait for multiple objects but I believe that mine is different. I am using several threads to compute different parts of a mandelbrot set. The program compiles and produces the correct result about 3 out of 5 times but sometimes I get an error that says "Access violation when writing to ... (some memory location that is different every time)". Like I said, sometimes it works, sometimes it doesn't. I put break points before and after the waitformultipleobjects and have concluded that that must be the culprit. I just dont know why. Here is the code...
int max = size();
if (max == 0) //Return false if there are no threads
return false;
for(int i=0;i<max;++i) //Resume all threads
ResumeThread(threads[i]);
HANDLE *first = &threads[0]; //Create a pointer to the first thread
WaitForMultipleObjects(max,first,TRUE,INFINITE);//Wait for all threads to finish
Update: I tried using a for loop and WaitForSingleObject and the problem still persisted.
Update 2: Here is the thread function. It looks kind of ugly with all of the pointers.
unsigned MandelbrotSet::tfcn(void* obj)
{
funcArg *args = (funcArg*) obj;
int count = 0;
vector<int> dummy;
while(args->set->counts.size() <= args->row)
{
args->set->counts.push_back(dummy);
}
for(int y = 0; y < args->set->nx; ++y)
{
complex<double> c(args->set->zCorner.real() + (y * args->set->dx), args->set->zCorner.imag() + (args->row * args->set->dy));
count = args->set->iterate(c);
args->set->counts[args->row].push_back(count);
}
return 0;
}
Resolved: Alright everyone, I found the issue. You were right. It was in the thread itself. The problem was that all of the threads were trying to add rows to my 2D vector of counts (counts.push_back(dummy)). I guess the race condition was taking effect and each thread assumed it should add more rows even when it wasn't necessary. Thanks for the help.
I solved the problem. I edited the question and stated what was wrong but I will do it again here. I was encountering the race condition when I tried to push a vector of complex numbers to the 2D vector in my thread function. This is controlled by the while loop and when each thread is executed, each thread believes that it needs to push more vector to the 2D vector called counts. I moved this loop to the constructor and simply push all of the necessary vectors onto counts upon creation. Thanks for helping me look in a different direction!
i want to fill database table in wxListCtrl, i can do this , i m using wxThread for this. my problem is - my concept is working for small amount of data, when i increase the size, it shows a error like-
showingdatainwxlistctrl: ../../src/XlibInt.c:595: _XPrivSyncFunction: Assertion `dpy->synchandler == _XPrivSyncFunction' failed.
my code is given below:-
void *MyThread :: Entry()
{
int i=1,j,k=0 ;
while(i!=400)
{
long index=this->temp->data_list_control->InsertItem(i,wxT("amit"));
for(j=1;j<3;j++)
{
this->temp->data_list_control->SetItem(index,j,wxT("pathak"));
}
k++;
if(k==30)
{
this->Sleep(1000);
k=0;
}
i++;
}
}
if i used i =4, 10 100, it is working but i crossed the limit( i dont know at which point) it start showing error
if you have any suggestion then pls help me...
Instead of direct SetItem call from the worker thread, you need to post event to the main thread and add item in the event handler. Data for list control event should be placed to custom event class. See details in wxPostEvent function and here: http://wiki.wxwidgets.org/Custom_Events
You're accessing a non-threadsafe wxListCtrl from another thread, this will simply not work.
A better solution may be to skip the thread, use a wxTimer, then fill 400 more entries every time OnTimer is called.