How could i make this function sleep for a certain amount of time? - actionscript

So here's my problem. I have code set up that calls a function whenever my player is over its last destination in the a* pathfinding array...
public function rakeSoil(e:Event):void {
var:Cell = Grid.getCellAt(player.x/50, player.y/50);
if (cell.isWalkable == false) {
return;
else {
//here is where i want to do the sleep code so this doesnt happen straight away? If possible.
target.sprites = [grass];
}
}
thanks guys :)

Generally, the "right" way to delay execution of something is to use a Timer.
Hacking up some kind of a sleep function could cause problems, since Flash runs in a single thread, so you won't be able to do anything else while your function is running, including refreshing the screen (making your game appear as if it crashed, or at least started lagging).
If you're absolutely, positively sure you want to do this, you could call the getTimer() function in a loop to see if a certain amount of miliseconds has passed.

Related

MQL Program unexpectedly terminated

I'm new to MQL language, so please correct me if I described something wrong.
I made an script by the script editor to place orders automatically. The program should be never stopped unless by manually termination. My code looks like that:
void onStart()
{
While(true)
{
Sleep(10000);
MakeOrder(....);//of course actual code is much more complicated
}
}
The only preset functions I use are trade functions, math functions and time functions.
The code works well for most of the times that can continue running at least for 48 hours, but sometimes it might unexpectedly stopped reporting deinit reason 4(which is the same exit code if I click stop button when debugging) within one hour after starting. It looks that MQL doesn't have try...catch module, and getting error in some coding lines won't stop it. I wonder what might have happened behind the termination? Or how can I ignore it, so at least the program can automatically restart?
You should check the OnTimer and OnTick functions.
And recommended to use IsStopped() in the While loop.
void onStart()
{
while(!IsStopped())
{
Sleep(10000);
MakeOrder(....);//of course actual code is much more complicated
}
}
Uninitialization Reason 4 is : chart has been closed. In MT4, you always need to run a script on a chart (window), so of course if this chart is close for any reason, your script will terminate. There is nothing you can do to prevent that.
As suggested, adding IsStopped() will terminate your loop (and script), so what you can do is to add some code after your loop to notify you the script is being terminated.
For example :
void OnStart()
{
//---
while(!IsStopped())
{
Sleep(10000);
//MakeOrder(....);//of course actual code is much more complicated
}
//---
if(UninitializeReason()==REASON_CHARTCLOSE)
{
string msg="Chart is closed and the script is terminated.";
Alert(msg);
SendNotification(msg);
}
}

What is the best practice to show a progress in angulardart?

I tried to show a progress in angulardart, and thought that a Future would be good for this. But then i realized that a Future must be recursive to show a progress, since the Future returns immediately and the lengthy operation is executed afterwards.
If i create a Future that calls itself until the end condition is met it works with the progressbar. But i think this could not be a very good practice sind these calls will raise the memory on the stack with every recursion. Just consider a loop going through 1 billion datasets that could run a few hours and every loop calls a new Future within the current Future.
Is there a better way to create a loop that needs a certain amount of time to do work on every element (including calling a website that must be done asynchronous and evaluating the return value)? During the loop the user should see a progress that shows him "x/1000000 done".
I think it must be done with a Future since the UI needs to reload after initiating the loop, but a recursive Future seems like a bad idea to me.
You need the future to return back to you right away on the web because it is a single threaded platform. If an async action didn't return until it was complete then you would hang the browser and it wouldn't be a great experience to the user.
Instead you have a couple of options:
Dart has the ability to make the future look like it is synchronous with the await keyword. So you can do something like:
void performAction() async {
showProgress = true;
await expensiveRpc();
showProgress = false;
}
This would require the progress to be intermediate, as you aren't actually updating the progress bar as it goes along. That said if you don't really get progress events from your RPC this is probably the better solution.
Now if your RPC or action gives you some kind of feedback as it goes you can do something a bit nicer with a stream.
void performAction() {
showProgress = true;
expensiveRpc().listen((progress) {
if (progress.done) {
showProgress = false;
} else {
percentComplete = progress.value;
});
}
Really it depends more on the RPC or service you are interacting with on how you can update the progress nicely more than the progress itself.
Meanwhile i recognized that a Future-method returns immediately without executing anything in the method-body. So the solution is pretty easy:
Just declare the rpc with a Future, do whatever you need to do in the method and when calling it, use then(...) to do what you need to do after collecting the data.
int progress = 0;
int progressMax = 100;
bool progressCanceled = false;
Future rpc(var data)
async{
for(progress=0; progress<progressMax, progress++)
{
// do whatever you need to do with data
if(progressCanceled)
return;
}
}
rpc(data).then(
{
if(progressCanceled)
return;
// do whatever is needed after having received that data
});
rpc is executed and the calling process can continue while rpc does what rpc has to do. The main program can handle button clicks to set progressCanceled to true and the rpc-method will ask for the state and stop processing if it is set.

Flood main thread with consuming tasks

I would like to flood the main thread with random tasks for a certain amount of time in order to figure out how another part of my application would in this circumstances. How can I achieve this?
You could just create an while-loop that never ends. Something like:
BOOL contunue = YES;
while (contunue) {
// Code
}
That would run until you stop the program yourself.
Edit:
To add a timer to the above code, you could use NSTimer to change the value of continue to NO after a determined amount of time

actionscript 2 go to another screen after variable = 10

I'm making a game where i have a character moving through a maze collecting coins. Once I have collected 10 coins i want my game to automatically go to the end keyframe. The variable Coincounter keeps a record of the number of coins the user has collected so far. So far i have this code to make my game do that....
if (_root.Coincounter == 10) {
trace("got to ten" +_root.Coincounter);
gotoAndStop(4) ;
}
The code is inside an onClipEvent - either keyDown or enterFrame, i can put it in either of them. The trace works fine so it's my gotoAndStop code that doesn't work - i'm not sure why. Thanks for the help.

Is it possible to check that main thread is idle / to drain a main run loop?

I've just read the following post and have tried to implement the approach described there:
Writing iOS acceptance tests using Kiwi - Being Agile
All the stuff described there does work perfectly. But! there is one thing that breaks determinism when I am running my acceptance tests.
Here is the repo on Github where author of the post pushed his experiments (it can be found on the bottom of the page in the comments): https://github.com/moredip/2012-Olympics-iOS--iPad-and-iPhone--source-code/tree/kiwi-acceptance-mk1
Consider this code he uses for tapping a view:
- (void) tapViewViaSelector:(NSString *)viewSelector{
[UIAutomationBridge tapView:[self viewViaSelector:viewSelector]];
sleepFor(0.1); //ugh
}
...where sleepFor has the following definition behind itself:
#define sleepFor(interval) (CFRunLoopRunInMode(kCFRunLoopDefaultMode, interval, false))
It is a naive attempt ('naive' is not about the author, but about the fact that it is the first thing that comes into a head) to wait for a tiny period of time until all the animations are processed and soak all the possible events that were(or could be) scheduled to a main run loop (see also this comment).
The problem is that this naive code does not work in a deterministic way. There are a bunches of UI interactions which cause fx next button tap to be pressed before the current edited textfield's keyboard is disappeared and so on...
If I just increase the time from 0.1 to fx 1 all the problems disappear, but this leads to that every single interaction like "fill in textfield with a text..." or "tap button with title..." become to cost One second!
So I don't mean just increasing a wait time here, but rather a way to make such artificial waits guarantee that I do can proceed my test case with a next step.
I hope that it should be a more reliable way to wait enough until all the stuff caused by current action (all the transitions/animations or whatever main run loop stuff) are done.
To summarize it all to be a question:
Is there a way to exhaust/drain/soak all the stuff scheduled to a main thread and its run loop to be sure that main thread is idle and its run loop is "empty"?
This was my initial solution:
// DON'T like it
static inline void runLoopIfNeeded() {
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFRunLoopRef/Reference/reference.html
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource);
// DON'T like it
if (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource) runLoopIfNeeded();
}
you can try this
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) == kCFRunLoopRunHandledSource);
this will run until no more things in the run loop. you can try to change the time interval to 0.1 if 0 is not working.
To check on the status of a run loop associated with a thread and register callbacks for separate phases, you may use a CFRunLoopObserverRef. This allows for extremely fine grained control over when the callbacks are invoked. Also, you don't have to depend on hacky timeouts and such.
One can be added like so (notice I am adding one to the main run loop)
CFRunLoopObserverRef obs = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopAllActivities, true, 0 /* order */, handler);
CFRunLoopAddObserver([NSRunLoop mainRunLoop].getCFRunLoop, obs, kCFRunLoopCommonModes);
CFRelease(obs);
Depending on the activities you register for, your handler will get invoked appropriately. In the sample above, the observer listens for all activities. You probably only need kCFRunLoopBeforeWaiting
You handler could look like this
id handler = ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) {
switch (activity) {
case kCFRunLoopEntry:
// About to enter the processing loop. Happens
// once per `CFRunLoopRun` or `CFRunLoopRunInMode` call
break;
case kCFRunLoopBeforeTimers:
case kCFRunLoopBeforeSources:
// Happens before timers or sources are about to be handled
break;
case kCFRunLoopBeforeWaiting:
// All timers and sources are handled and loop is about to go
// to sleep. This is most likely what you are looking for :)
break;
case kCFRunLoopAfterWaiting:
// About to process a timer or source
break;
case kCFRunLoopExit:
// The `CFRunLoopRun` or `CFRunLoopRunInMode` call is about to
// return
break;
}
};
Here is my current solution, I will add some comments and explanations to the code a bit later, if nobody tell me I am wrong or suggests a better answer first:
// It is much better, than it was, but still unsure
static inline void runLoopIfNeeded() {
// https://developer.apple.com/library/mac/#documentation/CoreFOundation/Reference/CFRunLoopRef/Reference/reference.html
__block BOOL flag = NO;
// http://stackoverflow.com/questions/7356820/specify-to-call-someting-when-main-thread-is-idle
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
flag = YES;
});
});
while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.1, YES) == kCFRunLoopRunHandledSource);
if (flag == NO) runLoopIfNeeded();
}
Right now I don't have any ideas how this could be made more effective.

Resources