I have my game setup so that it starts and goes back to a loading screen room for 45 steps after which the next room is randomized. So at alarm[0] the following code activates:
randomize();
chosenRoom = choose(rm_roomOne, rm_roomTwo, rm_roomThree, rm_roomFour);
room_goto(chosenRoom);
The code here works fine the first time, but when it goes back from the randomly chosen room to the loading screen room it stays there and doesn't execute the code again.
Any help would be very much appreciated.
This may sound stupid but did you remember to set the alarm again after it's gone off? I know I've done this several times without thinking. Without seeing your code, I assume that after the alarm goes off it's not being set again, so it won't go off again.
I'm guessing the control object is "persistant", thus the Control Object only exists once and will remain forever (also after swithcing rooms) - thus thie create event only gets fired once - thus the alarm only gets set once.
Try to move your code to the event "Room Start" in your controller and it will work.
you can use event_perform(ev_alarm,0);.
The code here performs alarm[0] after 45 steps. after 45 steps again it triggers alarm[0]. Note that you have to put it in step event. And you have to initialize wait variable and times to zero in create event.
times is the repeat and wait is distance between events.
if(wait == 45 && times !=2){
event_perform(ev_alarm,0);
times++;
wait = 0;
}
else{
wait++;
}
Related
I'd like to preface this by saying that I really tried looking here and anywhere else for an answer but without a succes.
Here is the problem:
I'm trying to automate a test for a web application that is loading a bigger amount of data and therefore has to be loading for a while. I have to wait for the page to load to do the next step and I'm trying to figure how to wait for the loading gif to be complete so that my tests can continue. The gif is a basic spinning thingy.
I would like to avoid using implicit wait time (cy.wait()) that is really only the last resort if noone is able to solve this.
What I found o far are these two functions:
cy.waitFor - this seems to be used mostly in situations, where you are waiting for an element to apper - I've tried this in different scenarios and works perfcetly but I havent been able to apply it here.
cy.waitUntil - this seems to be the thing I'm looking for but there is one huge problem. This function seems to have a timeout and I haven't been able to change it any other way than by changing timeouts globally for all the functions. If I set the global timeout to some longer period (minute +), then it works exactly how I would want it to work but obviously I dont really want to have such a long timeout for everything.
The way I see it, there are two possible solutions to this problem>
to change/turn off the timeout for the waitUntil function.
2)Or to somehow make it work with waitFor, because there seems to be no implicit timeout there and it just kind of waits forever for something to happen.
here is the code snippet of the situation:
cy.get('#load-data-button').click() // this clicks the button that stars the loading proces
cy.waitUntil(() => cy.get('body > div > my-app > billing > div > div > div.text-center > img').should('not.be.visible',) ) // this is the function that waits until the loading gif is invisible
I would be eternaly grateful for a solution, because unfortunatelly no one at my company is really a Cypress expert so they are not able to help.
Could you try something like:
cy.get([loading-spinner-identifier]).should("not.be.visible", { timeout: 60000 });
cy.get([an element that should now be visible]).should("be.visible");
It's a bit rough and ready, but I've used it when waiting for spinners to finish up. This waits a minute to see the spinner isn't there and then checks to see that something I'm expecting is there. I'd had varying success with this, but it has helped in some situations.
You can indeed use cy.waitUntil(). As you can see in the documentation of that package (https://www.npmjs.com/package/cypress-wait-until#arguments), the timeout that the function has is just the default (5000 ms) of an argument you can change it. You can even change how often cypress checks the condition you want, so if you do something like:
cy.waitUntil(() => cy.get('body > div > my-app > billing > div > div > div.text-center > img').should('not.be.visible'), {
errorMsg: 'The loading time was too long even for this crazy thing!',
timeout: 300000,
interval: 5000
});
...it will try for 300 seconds (5 minutes) each 5 seconds (just an example with very long timeout).
Also, maybe you can consider to wait until some element is visible after that loading spinner, instead of checking if it dissapeared. If you want to specifically test it, is fine, but if some element appears or becomes interactable after the loading, it could happen that is still not in the state you want, for a fraction of a second, after the spinner is not visible. If that is the case, I would avoid the checking of the spinner dissapearing in first place, unless it adds value to your test, and I would just wait for that element to be in the state you want (for example wait until some input is not disabled, element is visible, text appeared somewhere...).
Add positive and negative assertion to make sure loading spinner is visible.
Default Time is 4s for assert statement.
You can increase defaultTime to wait for assertion to validate by adding configuration in cypress.json
{
...
"defaultCommandTimeout": 4000,
...
}
const waitForSpinner = () => {
// First, make sure the loading indicator shows up (positive assertion)
cy.get('[data-qa="qa-waiting-spinner"]').should('be.visible')
// Then Assert it goes away (negative assertion)
cy.get('[data-qa="qa-waiting-spinner"]').should('not.be.visible')
}
I've found a possible answer to this question in a Google Group but I'll like to know if it's correct and add a follow-up question if it is correct.
The answer there is
Every time the global update function in your app runs for any reason,
the global subscriptions object is reevaluated as well, and effect
managers receive the new list of current subscriptions
If any time the model is changed subscriptions get called what is the effect on subscriptions such as Time.every second taken from Time Effect Elm Guide - is that means the timer get reset when the model changes? What if that was Time.every minute - if the model changes 20 seconds after it starts will it fire in 60 - 20 = 40 seconds or will it fire in 1 minute?
You can check when update and subscriptions are called by adding a Debug.log statement to each. The subscriptions function is called first at the start (since the messages which will be sent to update may depend on it) and also after each call to update.
The timer interval seems to be unaffected by subsequent calls to subscriptions. For example, if you use the elm clock example, change the subscription to
Time.every (10*Time.second) Tick
and add a button to the view which resets the model value to 0, you will see that the tick still takes place at regular 10s intervals, no matter when you click the button.
TLDR; It will fire in 1 minute, unless you turn your subscription
off and on during the first minute
Every time your update runs, the subscriptions function will run too.
The subscriptions function essentially is a list of things you want your app to subscribe to.
In the example you have a subscription that generates a Tick message every 60 seconds.
The behavior you may expect is:
T= 0s: The first time subscriptions runs, you start your subscription to "receive Tick message every 60 seconds".
T= between 0 AND 60s: As long as that particular subscription remains ON, it doesn't matter how often your update function runs. subscriptions will be run, but as long as your particular subscription to the Tick remains ON, things are fine.
T= 60s: You receive a Tick message from your subscription, which in turn will fire update to be called.
T= 60s: subscriptions will run again (because of previous call to update)
What could be interesting is what happens if the subscription to Tick is canceled along the way and then reinstated:
T= 0: subscription to Tick
T= 20s: suppose something changes in the model, causing subscription to Tick to be canceled
T= 40s: some other change in model, causing subscription to Tick to be turned on again
T= 100s: Tick message is fired, and passed to update function
T= 100s: subscriptions will run again
In normal applescript, the script is executed down the page, and so any code in loops for every 5 seconds will only run while the loop is running - there is no way to have a single function run every few second regardless of what the script is currently doing or where it is in the script (that I know of). In cocoa-applescript, however, is there a way to run a handler every 5 seconds, at all times, no matter what it is currently doing? Here is what it should be doing in my cocoa-applescript app:
on checkInternetStrength()
do shell script "/System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -I | grep 'agrCtlRSSI:'" -- this being the script which returns the line containing the signal strength
set SignalStrength to result
set RSSIcount to (count of characters in SignalStrength)
set SignalStrength to ((characters 18 thru RSSIcount of SignalStrength) as string) as integer -- this to turn SignalStrength into just the number and not the whole output line
set SignalStrength to (100 + SignalStrength) as integer
set SignalBar's setIntValue_(SignalStrength) -- SignalBar being the Level Indicator described below
end checkInternetStrength
Summed up, it runs the airport command to check internet connection, turns this into a number from 1 to 100 and uses this on an NSLevelIndicator (100 maximum) to show current signal strength graphically. Now, there is no point having this run once or when you hit a button - that is an option, but it would be nice if it updated itself every, say, 5 seconds with the realtime value. So is there any way to have a process which runs every 5 seconds to do this, while still enabling full functionality of the rest of the script and interface - i.e. as a background process? Comment if you need more extracts from the script.
Example
In Unity-C# scripting, the 'void Update() {code}' will run the code within it every frame while doing everything else simultaneously, so a cocoa-applescript version of this might be an answer, if anyone knows.
I Dont believe this is possible but what I had a similar problem before, what i do, I have an external applescript applicaion that is hidden the repeats the commands, the only problem is, it wont send it back to the app, you'll have to make the external applescript app do it, like
display notification, etc..., in the applescript apps "Info.plist" you can add this:
<key>LSUIElement</key>
<string>1</string>
To make the app run invisibly, but sorry i dont think you can run a handler in the app its self
I am using server push in Wt and I am trying to push a new chart with the following code:
Wt::WApplication::UpdateLock uiLock(app);
if (uiLock){
chart_ste = new ScatterPlotExample(this,10*asf.get_outputSamplingRate());
app->triggerUpdate();
}
but it waits for the program to end and then it prints it whereas the following code in the same program pushes the word "Demokritus every 0.5 secs as it should do:
for (int i=0; i<10; i++)
{
boost::this_thread::sleep(boost::posix_time::milliseconds(500));
Wt::WApplication::UpdateLock uiLock(app);
if (uiLock) {
showFileName = new WText(this);
showFileName->setText(boost::lexical_cast<std::string>("Demokritus"));
app->triggerUpdate();
}
}
What might be my mistake?
The documentation for triggerUpdate mentions that "The update is not immediate, and thus changes that happen after this call will equally be pushed to the client." If the changes are not immediate, it could be that the first piece of code continuously tries to push updates as fast as your CPU will allow it, so it never gets to the server because a new update overwrites the last and it begins waiting again. Try adding boost::this_thread::sleep(boost::posix_time::milliseconds(500)); to the first piece of code to see if that helps.
I've done a project once where I needed to update a chart every second with new data and had a very similar setup to yours. I put in the sleep from the start because I did not want my boost thread to use too much CPU.
Also, it is unclear if the first piece of code is in a bigger loop, if it is, you probably shouldn't make a new chart every time, but create it before hand and then update it with data. I hope some of this helps.
I modified the OMGStop() method to something more like this:
public void cancelUpdates() {
//TODO potential bug here
if(pi == null)
setPendingIntent();
mgr.cancel(pi);
//Should one of these work?
stopService(new Intent(applicationContext, LocationPoller.class));
stopService(new Intent(applicationContext, LocationPollerService.class));
I'm storing pi (PendingIntent) as a member in my activity class. And this works fine to remove the PendingIntent from the AlarmManager.
However...
I would like to be able to stop the current location poll if there is one going on. Is it possible with your current design? I thought I could just stop the service, but the GPS continues to run.
Basically what i'm trying to do is stop everything when the user (me on my trip) changes a preference (such as the timeout, or USE GPS or update period. And then recreate everything with the new values.
Thanks,
Great code BTW - Exactly what I want for tracking my cross country journey :)
I faced the same issue. - On occasion I let my mousepointer hover over "mgr.setRepeating(..)" and read some of Eclipse's (Indigo) hints:
"If there is already an alarm scheduled for the same IntentSender, it will first be canceled."
But the IntentSender could be gone by then.
This led me to the following "solution" (in original CommonsWare code):
if(pi == null) {
Intent i = new Intent(this, LocationPoller.class);
pi = PendingIntent.getBroadcast(this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + 1000, PERIOD, pi);
}
mgr.cancel();
By adding 1000 msec I tried to make sure the AlarmManager has no chance to start before being hit by a cancel().
HTH, regards.
PS: I'd like to quote mparkes: "Great code"!
Is it possible with your current design?
No, sorry. That's theoretically possible to add, but probably a bit tricky, and definitely not there at the moment.
Basically what i'm trying to do is stop everything when the user (me on my trip) changes a preference (such as the timeout, or USE GPS or update period. And then recreate everything with the new values.
That is a perfectly reasonable concept, just not what LocationPoller supports. LocationPoller was designed more for the "check every hour" sorts of scenarios, where it is statistically unlikely that a check is going on while the user happens to be manipulating your app's UI.