Run away variable - game-maker

i have a small function in a collision event in Game Maker, for some reason once triggered, the variable is supposed to increment, by another variable, it just runs off and keeps increment to max. here is the code.
if(global.rep <= 5000){
global.rep += rep_gain;
global.poop_time = poop_time - 5;
}
if this is in a collision event it should only fire once, the variable rep_gain is an irandom(5,10), but it will just keep running to 5000 which is max.

In game maker, the collision event is constantly called until the collision is addressed by making the 2 objects no longer collide. if you don't do this, then the variable will increment until max.

Related

Qt measuring rendering time during which application is frozen

I have a Qt application, where, among other things, there is a function render which goes through a list of objects and creates for each an according (subclassed) QGraphicsPathItem which it then puts as a child in a (subclassed) QGraphicsScene. (It is done in the code below through a visitor GGObjConstructor which gets initialized with the variable scene which is the scene where the items are to be added to).
XTimer timer;
timer.start();
gobjlist gobjlis = ogc._gobjectlis;
GGObjConstructor ggoc(scene, z_value, bkground_color);
for(auto obj: gobjlis) {
obj->exec( &ggoc );
}
timer.stop();
My class XTimer is used in an obvious way to measure the time for this proceeding.
Now the problem is: Only the time spent in the loop where all the items are prepared and inserted into the scene is measured by timer. For a typical example with ~165000 items this gives about 7.5 sec as timer-value at reaching timer.stop(). But the application is after these 7.5 sec still frozen, with the screen-window where the scene is to by displayed yet invisible and only after about 25 sec (hand-stopped) suddenly the display window appears with all the items to be displayed.
Now of course I would like to measure these "freeze time" (or time till the application becomes responsive again, or maybe time till display window appears). But I found no way to do this although I looked some time through stackoverflow or the net in general. The best hint I found was
stackoverflow question
The answer there seemed to imply, that it would be not really simple to achieve (overriding paintEvent method and such things).
Question: Is this true? Or is there a simple way to measure the time till the application becomes responsive again/the image is really displayed?
I had a similar problem with an application once, where I wanted to measure the time the app freezes to figure out with logging what was causing these freezes. What I came up was to measure how long the Eventloop of the mainthread was not responding, because this directly corresponds to a frozen app.
The basic idea is to not run a QApplication but inherit from QApplication and override the notify() function. Some apps do this anyway to catch exceptions which would otherwise break the eventloop. Here is some pseudo-code which should bring the idea across:
bool MyApplication::notify( QObject * receiver, QEvent * event )
{
// something like storing current time like:
// auto start = std::chrono::system_clock::now();
// auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(start - end );
// if( elapsed.count() > 1000 ){
// log something like: Mainthread responds again after <elapsed> seconds
// }
// Note that end must be a member variable
// end = start;
return QApplication::notify(receiver, event);
}
Note 1: If your app does not continuesly run through notify() you can for testing purposes introduce a dummy QTimer which triggers faster than the logging time threshold.
Note 2: if you use multiple threads, esp. QThreads it could be necessary to filter the receiver object and perform that code only if the reciever is in the mainthread.
With this code you can log every freeze of the main-thread (frozen GUI) and determine the length of the freeze. With proper logging you can figure out whats causing the freezes.
Keep in mind that this will only log after the freeze has resolved!
Addition:
It is more complicated and slow, but for debugging/investigation purposes you can store the last event and Object-Tree of the reciever and log that as well. Than you even know which was the last event which triggered the freeze and the recieving Object.

An empty window pops up and steals focus each time an int is assigned using qrand() in Qt

I'm having a strange problem in a game I'm building in Qt where each time I generate I call qrand() (or rand(), I tried both), a separate tiny window pops up and steals focus from my game. I want to 'roll' a pair of dice every 2 seconds so I'm generating a number between 1 and 12. I'm using a QTimer object in a GameBoard custom widget constructor to call the public slot updateDice() that resets a private variable to a random number.
void GameBord::updateDice(){
dice_int = qrand()%12 +1;
repaint();
QCoreApplication::processEvents();
return;
}
and in my repaint()
...
dice_roll->clear();
dice_roll->setText(QString::number(dice_int));
...
where dice_roll is the label that displays what number the roll was for the player.
With the debugger I found that every time dice_int is assigned the window pops up. The weirdest part to me is that I have other random numbers generated and they don't cause this problem.
I know you can setAttribute so that the window comes up without activating, but I don't know where the window is coming from.
And if there is no solution to this problem, is there a way to set Focus on a widget so that it never changes? I tried Qt::StrongFocus but that doesn't help.
I'd be happy to post more code if you want it, and thanks in advance.

Adobe AIR issue

I have an Adobe AIR application with a chart component displaying some online data.
The chart component has to display a bunch of parameters about 10 of them.
The application has a timer to display current system time.
The chart component is invoked from the timer(using a bindable object) as shown below. A separate bindable object is used to prevent delay in timer.
private function onTimerEvent(event:TimerEvent):void
{
//Update time in screen
oCurrDate = new Date();
curTime = oDateformatter.format(oCurrDate).toString();
oCurrDate = null;
//oUpdate- Bindable object to inform chart about update
//Call chart every 250 ms
oUpdate.bUpdate = !oUpdate.bUpdate;
}
Iam using a calllater function in chart's update event as shown below. updateParameter() will update the dataprovider of each of the parameter and draws it.
public function onUpdateEvent(evt:PropertyChangeEvent):void
{
//aPlotIndex set to 0 for first parameter
aPlotIndex.push(0);
this.callLater(updateParameter, aPlotIndex);
}
The problem is the timer and chart updation stops after running 20 to 21 days. After 20 or 21 days, the update happens only on mouse move. When I moved mouse the time displayed & data in chart are updated.
I profiled the application and found that there is no memory leakage issues. I am logging all the errors but I didn't get any error in the log also. Everything seems weird.
Is it because of using the calllater function.
Is it that the timer is still running but frame update not happening.
I am using Flex SDK3.3 and Flex AIR version 2.0.4.13090.
Please guide me to resolve this issue.
Please read the documentation for Timer.
The total number of times the timer is set to run. If the repeat count is set to 0, the timer continues indefinitely, up to a maximum of 24.86 days, or until the stop() method is invoked or the program stops. If the repeat count is nonzero, the timer runs the specified number of times. If repeatCount is set to a total that is the same or less then currentCount the timer stops and will not fire again.
The maximum is due to the max of an int, which is what the timer uses to store its current count. int has a max value of 2,147,483,647. 2147483647 / 24.86 days / 1440 minutes / 60 seconds /1000 milliseconds is equal to 1 (give or take, differences with the way the docs' number is rounded), which aligns with the fact that the internal clock stores its count per millisecond the Timer has run.
So you cannot set an option to fix this. Instead, you can work around it, assuming nothing actually relies on your timer's value. Each time the timer runs, call
timer.reset();
timer.start();
That will reset the timer to 0 and start it back up again, meaning you will never hit that 24.86 day limit, unless your delay is longer than that (which it cannot possibly be)
Additionally, I'd like to point out that the Flex and AIR versions you are running are severely out of date. Both are nearly 5 years old at this point. AIR may not even run properly on newer versions of Windows and OS X because of it (and won't run on mobile at all). Not a big deal if everything works, but always good to know (many posters on SO do not realize how out of date their Flex and AIR SDKs are)
Timer.repeatCount
int.MAX_VALUE

Flex Mobile validateNow() not working

I have a long and busy for loop which is supposed to addElement on the stage iteratively. Since it takes several seconds to execute the whole loop (i=1:N), i just want to refresh the stage at each loop so that the output is displayed before the loop reaches its final point (N). each iteration should add a displayable element before the next iteration begins.
For this i wrote the following
for(var i:int = 0; i < 280; i++){
addElement(...);
validateNow();
}
but it is not working like i want. anyone having solution please?
You need to divide up this lengthy work so that it can occur over multiple frames. Flash/Flex do not update the screen when your code is executing. Have a look at the elastic race track for Flash to help understand why. The Flex component life cycle adds another layer on top of that as well. By the way, calling validateNow() can be computationally expensive, possibly making your loop take longer :)
There are a number of ways to break up the work in the loop.
Here's a simple example using callLater():
private function startWorking():void
{
// create a queue of work (whatever you are iterating over)
// in your loop you're counting to 280, you could use a
// simple counter variable here instead
var queue:Array = [ a, b, c];
callLater(doWork, [ queue ] );
}
private function doWork(workQueue:Array):void
{
var workItem:Object = workQueue.shift();
// do expensive work to create the element to add to screen
addElement(...);
if (workQueue.length > 0)
callLater(doWork, workQueue);
}
You may want to process more than 1 item at a time. You could also do the same thing using the ENTER_FRAME event instead of callLater() (in essence, this is what callLater() is doing).
References:
validateClient() docs, calling validateNow() results in a call to this expensive method

Actionscript Flex getTimer() maximum

Documentation on the flex getTimer() method states:
int - The number of milliseconds since the runtime was initialized (while processing ActionScript 2.0), or since the virtual machine started (while processing ActionScript 3.0). If the runtime starts playing one SWF file, and another SWF file is loaded later, the return value is relative to when the first SWF file was loaded.
The maximum value for an int is: 2,147,483,647 which is a bit less than 25 days. If someone were to leave the flash application running for an extended period of time, does anyone know what happens when this method reaches the maximum value for int? Does it reset to zero?
When int reaches it maximum value 2147483647 and on adding 1, it should resets to its maximum -ve value -2147483648 and it's iterative in nature, so function should not fails
EDIT Code sample is added
private function intcheck():void
{
var a:int = 2147483647;
var b:int = 1;
var c:int = a+b;
Alert.show(c.toString());
}
Hopes that helps
I don't know the answer for sure, but I would assume the number would roll over. However, if you're concerned about the roll over, you might want to look at the Timer class, or just use a good ol' timestamp with new Date().getTime() and then doing a comparison between the times.

Resources