AVURLAsset loadValuesAsynchronouslyForKeys, synchronous version? - asynchronous

is there a way to load an AVURLAsset in a synchronous manner?
My scenario is one which I need to load the assets in the background while showing a different view and change to the view showing the AVPlayer when the assets are ready to play. Not before.
I've tried loading async and calling a delegate method to tell "the assets are ready, you can show the next view", but if I get a mem warning before that, the views containing the assets in the background get released before they finish loading...so i never get the delegate call. That's why I rather do it synchronously.
Any ideas?

I'm not 100% sure I understand what you're getting at, but I believe you should be able to just use [AVURLAsset commonMetadata] or [AVURLAsset metadataForFormat:[[AVURLAsset availableMetadataFormats] lastObject]] and then show your view once this information has been loaded. Theses methods return an array of AVMetadataItems, which you should rather easily be able to traverse with a for loop. Sorry if this wasn't what you were looking for.

Related

How to initialise controllers using provider state in flutter

I recently refactored half my app to use the provider pattern and i now have a problem. The main issue is that i need to initialise controllers in the init (e.g. a text controller to have an initial value or the list size of a tab controller)
How am i meant to init Controllers if the data i need has to come from the state in the build method.
For example.
// This must go in the build as it requires state
myTabsController = TabController(length: myState.list.length, vsync: this);
I'm initialisng the controller every time it builds now... How am i meant to put this in the init but still access the state variables (as there is no context).
I've tried using the afterFirstLayout() callback from the AfterLayoutMixin library but that just causes more problems. Currently with the tab bar it flashes error as no tab initialised for the first frame and then displays properly when the afterFirstLayout is called and initialises the tab. This seems like a hacky fix
I would like to learn more about how to use this pattern properly and what would be the best solution to this problem.
Feel free to ask me to clarify more.
Thanks for your help.

Avoid deletion of an object (using IObjectWillBeRemovedEvent) and do a redirect to a custom view/template?

I would like to abort the deletion of an object (A custom Content-Type), and redirect to a page (a view) that sets the workflow to a custom state named Unavailable, shows a message to the user "You succesfully deleted the object!". The object will still be on ZODB, but for some groups it'll simply not be seen, as if it was really deleted.
I can do a raise in a subscriber using IObjectWillBeRemovedEvent, but trying to use raise zExceptions.Redirect("url") doesn't work. The raise call avoids the deletion, but a message "The object could not be deleted" is shown instead of the redirection.
Anyone has a solution to this scenario?
As you can see Plone / Zope 2 object management is messy (yes, I am willing to burn karma just to say this). You need to override delete action in the user interface level, not on the object level.
Try to figure out how to customize delete actions in Plone user interface.
Make sure the default Delete actions is no longer visible and available (e.g. set higher needed permission for it e.g. cmf.ManagePortal)
Create another Delete action which goes according to your specialized workflow
I believe Delete can be configured from portal_actions, but there might be separate cases for deleting one object (Actions menu) and deleting multiple objects (folder_contents).
You need REQUEST.response.redirect("url"). I'm pretty sure that zExceptions.Redirect is the way that Zope internally handles response.redirect() calls. Be sure you still raise another exception after calling redirect() so that the transaction is aborte.
That said, this sure seems like the wrong way to accomplish this. For one thing, you'll do at least double indexing, which is done before the transaction aborts. Catalog indexing is the most expensive part of processing a request that modifies content so this creates wasteful load on your server.
Events are for doing additional stuff which is only tangentially related to the event. What you want is to fundamentally change what happens when someone deletes. Maybe you should patch/override the underlying deletion method on the container objects (folders?) to do your worklfow transition.
You could raise a OFS.ObjectManager.BeforeDeleteException in the event handler to stop the deletion. If you raise a LinkIntegrityNotificationException you get redirected to Plones nice Link intergrity page.
from OFS.interfaces import IObjectWillBeRemovedEvent
from plone.app.linkintegrity.exceptions import LinkIntegrityNotificationException
import grok
#grok.subscribe(ICSRDocument, IObjectWillBeRemovedEvent)
def document_willbemoved(doc, event):
raise LinkIntegrityNotificationException(doc)

MVVM Light Messenger executing multiple times

I am using MVVM Light and am using Messages to communicate between ViewModels to let a ViewModel know when it is ok to execute something. My problem is that I register for a message and then it receives it multiple times. so to keep from my program executing something more than once I have to create boolean flags to see if it has already been recieved. Any idea why it does this and how I can stop it?
Make sure you unregister your message handlers once you do not need them anymore. The Messenger keeps a reference to the registered methods and this prevents them from being garbage collected.
Therefore, for ViewModels: make sure that you call Cleanup once you done (or implement IDisposable and call Cleanup from there).
For Views (Controls, Windows, or similar) call Messenger.Unregister in an event that occurs on the teardown of the view, e.g. the Unloaded event.
This is a known behaviour of the MVVM and has been discussed in several places.
Very old question but I solved the problem by doing this:
static bool isRegistered = false;
and then, in the constructor:
if( !isRegistered )
{
Messenger.Default.Register<MyMessage>(this, OnMessageReceived);
isRegisterd = true;
}
I have seen this issue before. It had to do with the Messenger.Default.Register being called more than once. The MVVMLight Messenger class will register the same item 'x' number of times. This is why when you call the Send you get it many times.
Anyone know how to prevent MVVMLight from registering multiple times?
really old but thought I would answer just in case somebody needs it. I was fairly new to silverlight at the time and the issue ended up being a memory leak as the viewModel, which had multiple instances, was still in memory.
As other contributors mentioned, the same message is being registered multiple times. I have noticed this behavior taking place while navigating to View X then navigating back to View Z where the message is registered in the constructor of the Z ViewModel. One solution is to set the NavigationCacheMode property to Required
<Page
........
........
NavigationCacheMode="Required">

Forcing Flex to update the screen?

This may be a bit of a beginners question, but I can't for the life of me figure it out.
I'm using flex to develop a GUI for a large project, specifically a status bar along the bottom. Within my StatusBar class is a ProgressBar, which other classes doing work can tell to update(change bar completion and label) as they progress. The problem I'm encountering is that flex won't update whats shown on the screen until it's too late, for example
ProgressBar initialized, 0% done
some class sets the ProgressBar to be 12% done
some class does some work
some class sets the ProgressBar to be 56% done
Whats happening is the 12% done is never displaying, it just hangs at 0% during the work, then skips right to 56% done. I've tried to understand the lifecycle of a flex component (invalidation and validation), and I think I understand it and am applying it correctly, but it's not working at all. I need to tell flex to redraw my StatusBar (or at least the ProgressBar within) after some class sets it to be 12% done, but before some class starts doing its work. How do I do this?
As mentioned in other answers, the flash player is single threaded, if you don't break up your work into discrete chunks that can be executed in separate "frames", you're going to see jumps and stutters in the ui, which is effectively what you're seeing.
If you really must see that 12% message, then it's not enough to invalidate the display list, as the display list isn't getting a chance to update until after the 56% work has completed, you must explicitly interrupt the natural event cycle with a call to validateNow() after your message has been set.
This however is not the best way to do things if performance is of concern. You might get by with judicial usage of callLater() to schedule each chunk of work in turn, as this will allow the player to potentially complete a frame cycle (and update the display list) before attempting the next step in your process.
Glenn,
That is not at all how the threading in Flex works whatsoever. Like many UIs it has a message pump on the main UI thread (they do it in frames). When you call callLater() it places the passed in function pointer at the end of the message pump queue (on the next frame) and returns immediately. The function then gets called when the message pump has finished processing all of the messages prior (like mouse clicks).
The issue is that as the property change causes UI events to be triggered, they then place their own messages on the pump which now comes after your method call that you placed there from callLater().
Flex does have multiple threads but they are there for Adobe's own reasons and therefore are not user accessible. I don't know if there is a way to guarantee that a UI update will occur at a specific point, but an option is to call callLater a number of times until the operation occurs. Start off with a small number and increase until the number of iterations produces the result you want. Example:
// Change this to a number that works... it will probably be over 1, depending on what you're doing.
private const TOTAL_CALL_COUNT:int = 5;
private var _timesCalled:int = 0;
//----------------------------------------------------------------
private function set Progress( progress:int ):void
{
progressBar.value = progress;
DoNextFunction();
}
//----------------------------------------------------------------
private function DoNextFunction():void
{
if( _timesCalled >= TOTAL_CALL_COUNT )
{
_timesCalled = 0;
Function();
}
else
{
_timesCalled++;
callLater( DoNextFunction );
}
}
Try calling invalidateDisplayList() after each changes to your progress bar. Something like :
Class StatusBar
{
public function set progress(value:uint):void
{
progressBar.value = value;
progressBar.invalidateDisplayList();
}
}
Flex has an invalidation cycle that avoid screen redrawing everytime a property changes. As an example, if a property's value changes 3 times in a single frame, it will render only with the last value set. You can force a component to be redrawn by calling invidateDisplayList() which means updateDisplayList will be immediatly executed instead of waiting the next frame.
Actionscript in Flash player, like Javascript in the browser, is pseudo-multithreaded. That is, they're single threaded, but they have multiple execution stacks. This means you can't "sleep" in a particular thread, but you can spawn a new execution stack that gets deferred until a later time. The flex way of doing this is the "callLater" function. You can also use the setTimeout/setInterval functions. Or you can use a timer object built into the flash player. Or even "ENTER_FRAME" event listener. All of these will essentially allow you to do what you need, if I'm correct about the cause of your problems.
It sounds like you have one "thread" doing most of your work, never stopping to allow other execution stacks (threads*) to run.
The problem could be what PeZ is saying, but if that doesn't help, you might want to try some deferred calls for worker classes. So your process might look like this now:
Progress initialized.
Do some work.
Update progress bar to 12. (invalidate display list)
setTimeout(doMoreWork, 100);
Update progress bar to 52.
(if your worker is a UIcomponent, you can use uicomp.callLater(...), otherwise, you need to use setTimeout/timers/enter_frame for pure AS3 classes).
Sometimes its necessary set to zero before assign another value.
progressBar.setProgress(0, progressBar.maximum);
progressBar.setProgress(newValue, progressBar.maximum);
I'm using Flash Builder 4.6 and I also have a problem for the display of my progress bar. I open a new window where I start a new multiloader class (39 Mo of content). The new window is opened in background and the main window display a progress bar until the multiloader class has finished his work. However the opening window is blocking the animation of my main window. I know it's not the multiloader class cause I saw it running correctly.
But I will try to find some new ways of doing it.
The main purpose of my post is the complexity adobe has build around flash.
When you seek ressources for your own application or answers for your questions, it's a real pain to find the good ressource. There is a total mix up (at adobe side and at user side) between AS3, Flex, Flash CS, Flash Builder, AiR, ... If you try to develop in AS3, you will find that some examples won't work for you because it is not implemented in your SDK. You have more and more forums giving you the "best practice" or ironic answers based on experiences on different developping platform.
By example, just here above, I see progressBar.value = value; With my experience, I can say that in Flash Builder 4.6, this property is read-only. But It might be a custom class made by the user but who can tell.

Waiting while SWFLoader loads a swf file

Currently I'm working on an application (Flex) which heavily uses external SWFs.
I'd like to create a static method which takes a filename as an argument and returns SWF wrapped in some other class.
public static function getSWFWrapperFromFile(path:string):SWFWrapper {
var loader:SWFLoader = new SWFLoader();
loader.addListener(Event.COMPLETE, onLoad);
loader.load(path);
// If I create new SWFWrapper object here and try to assign it the loader.content I get null reference
}
However, with this approach I'm not able to encapsulate logic in one function, because of non-blocking load() and the need of onLoad handler. Is there possibility to force a delay after calling load method? Or mayber there is another, better way?
Thank you,
Alonzo
The display list is well-designed for asynchronous loading. You'll notice that Loader is a DisplayObject-derived class and thus can be placed directly in the display list. When its content is loaded it will be a child of the Loader. Thus, if SWFWrapper is DisplayObject-derived, you can simply do the following at the end of your code:
var wrapper:SWFWrapper = new SWFWrapper();
wrapper.addChild(loader);
return wrapper;
You need to wait until your Loader object has completed. Try adding in an event handler. Yes, the whole thing gets murky after a point of time when you have multiple loaders and and have to wait till the last one has completed. But that's the way it is if you are going to use SWFLoader.
In flash you cannot block in a method - you always have to use the onLoad handler for loading data. (The as3 execution model is single threaded, if you block in a method the rest of the program will not get executed)
Like others said, you can't do that. However, take a look at the BulkLoader AS3 library, which takes the burden of managing multiple loaders simultaneously and waiting for their completion, off your shoulder. It is well documented, and requires only a few lines to use.

Resources