When I add actionscript to a Flash movie, it runs every time the movie enters a new loop. How do I make it run only once, when the movie has finished loading?
Just set a flag telling you if the script has already executed. Like this;
var done:Boolean;
if (!done) {
// any code here will run only once.
done=true;
}
Related
I’m trying to get a callback at a given point in an AKPlayer’s file playback (currently, just before the end). I see the Apple docs on addBoundaryTimeObserver(), which would work, but it doesn’t seem to be accessible from AKPlayer (I guess an AVAudioPlayerNode vs AVPlayer thing). Any suggestions? I see a few callbacks in AVAudioPlayerNode… maybe I could determine the buffer based on the desired time and use dataConsumed?
The goal is to trigger another event just before the file finishes playing (there is a callback on completion, but obviously that's too late).
If anybody has done something similar, or knows of something similar (a gist, etc), that would be great.
There's an AudioKit playground called AKPlaygroundLoop that shows you how to call an arbitrary handler periodically, based on CADisplayLink. In your handler you could check the AKPlayer's currentTime and if it's close to the end (say 1 second before) you could trigger whatever event you want.
This is a rough outline:
var player: AKPlayer!
var loop: AKPlaygroundLoop!
func play() {
// ...
playgroundLoop = AKPlaygroundLoop(frequency: 10.0, handler: myHandler)
}
func myHandler() {
if player.currentTime >= player.duration - 1.0 {
// trigger some event
}
}
See also this answer for advice on how to synchronize events with AudioKit.
I’m manually writing a video recorder. Unfortunately it’s necessary if you want to record video and use ARKit at the same time. I’ve got most of it figured out, but now I need to optimize it a bit because my phone gets pretty hot running ARKit, Vision and this recorder all at once.
To make the recorder, you need to use an AVAssetWriter with an AVAssetWriterInput (and AVAssetWriterInputPixelBufferAdaptor). The input has a isReadyForMoreMediaData property you need to check before you can write another frame. I’m recording in real-time (or as close to as possible).
Right now, when ARKit.ARSession gives me a new session I immediately pass it to the AVAssetWriterInput. What I want to do is add it to a queue, and have loop check to see if there’s samples available to write. For the life of me I can’t figure out how to do that efficiently.
I want to just run a while loop like this, but it seems like it would be a bad idea:
func startSession() {
// …
while isRunning {
guard !pixelBuffers.isEmpty && writerInput.isReadyForMoreMediaData else {
continue
}
// process sample
}
}
Can I run this a separate thread from the ARSession.delegateQueue? I don't want to run into issues with CVPixelBuffers from the camera being retained for too long.
I have a little card playing app. When the computer is playing, some functions are being fired after some time to mimic a real player, like so:
self.operation.addOperation {
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now()+2) {
self.passTurn()
}
}
Everything works fine, but when I want to cancel the game and start a new one, the app crashes if I do it within two seconds before the self.passTurn() function fires.
Ideally I would like to have some sort of pause between the different operations. The above mentioned operation gets released from the queue immediately after it fires the delayed function, so cancelling or suspends the operation does not work.
Is it possible to somehow retain the operation in the queue for two seconds and release it afterwards when the actual function is done?
Thanks!
I am using webview load to detect when a page is loaded but i need it to only fire once but it fires many times i have come up with a solution below to get it fire once, but this will only happen once and once only i need it to fire every time a page is loaded but only once example.
webviewload = true;
webview.addEventListener('load', function() {
if(webviewload){
//run code to add stuff to webview this will run once
webview.remove(oldsidebar);
webview.add(newsidebar);
webviewload = false;
}
});
the above works fine for one webview load but if you run again it is obviously set to false so i can only run this code once.
I found a hack that kind off works for me but i am looking for a better solution i understand its firing because it fires on every element load ads etc on webview.
webviewload = true;
webview.addEventListener('load', function() {
if(webviewload){
//run code to add stuff to webview this will run once
webview.remove(oldsidebar);
webview.add(newsidebar);
webviewload = false;
}
setTimeout(function(){
webviewload = true;
},5000)
});
ok above works but isn't ideal if the page take longer than 5 seconds to load etc i am getting problems.
Can anyone give me a suggestion on how to fire webview load once then reset so i can run a block of code correctly.
Hope this makes sense thanks
Yea, this is due to the fact that the page you are loading, like almost any portal homepage, is comprised almost fully of ajax calls to other pages and scripts, etc. This is going to cause your load event to fire, and fire, and fire again until everything is loaded.
I suppose one way around this would be listen for the load event and set some interval that if passed would kill the listener and carry on.
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.