PDA

View Full Version : Delaying instantiation manually


antun
08-08-2003, 02:08 PM
If you have a large and complex app that takes a long time to start up, typically one of the first things you'll do to try and speed it up is to delay the instantiation of parts of that app that aren't needed immediately. If you want precise control over when specific parts instantiate, you wnat to use the initstage="defer" attribute of <view>:


<canvas>

<button>Complete the instantiation on deferred
<method event="onclick">
deferred.completeInstantiation();
</method>
</button>

<view y="35" name="early">
<view name="bluebox" bgcolor="blue" width="250" height="50" />
</view>

<view y="100" name="deferred" initstage="defer" width="250" height="50"
bgcolor="yellow">
<view name="bluebox" bgcolor="blue" align="center" valign="middle"
width="${parent.width-4}"
height="${parent.height-4}" />
</view>

</canvas>


This prevents the children of the deferred view from instantiating until completeInstantiation() is called on that view. Note that the affected view itself does instantiate at the normal time.

Enjoy!

nmudd
01-11-2006, 01:24 PM
Hi Antun, I was wondering if there is any way to catch when instantiation has completed? Here is my problem, I need to call a dataset to retrieve data after instantiation has occurred. If I try doing it before, the dataset is returned from the server to quickly and things seem to always get messed up. Let me know your thoughts on this. I may have missied a post about this already so my apologies if someone has already answered this question.

Thanks.

antun
01-11-2006, 01:33 PM
Hi nmudd

I believe that the view that is deferred will send the oninit event when instantiation has completed.

Failing that, remember that you can also defer instantiation using states (in fact it is a slightly cleaner approach):


<view name="myparentview">
<state name="laters">
<attribute name="foo" />
<view name="mychildview">
...
</view>
</state>
</view>


This means that the onfoo event will get sent by myparentview. States also send the onapply event (although I'm not sure if it is sent after views within the state have finished initializing or before - you'd have to test).

-Antun

nmudd
01-12-2006, 08:20 AM
Thanks Antun. oninit actully solved my problems. I wasn't aware of using states anywhere. Now that my team has looked through it, it seems it would have been better (or at least cleaner) to use states. I think at the time no one had considered using them. So for now we are sticking with our instantiation implementation. I do however have another question that follows along similar lines...

We have a "Loading..." page we show whenever we switch views or load a view that is being instantiated. I have a view right now that is pretty resource intensive and we defer its instantiation. As a sidenote, which I shall refer to below, this view has a resetMyView() method which I call to reset all of the data etc in the view before a new dataset is retrieved. In forcing the loading animation to show up before the view is loaded, I would think I could call:

startLoadingDialog(); //which is in a separate view loaded on startup
myResourceIntensiveView.completeInstantiation(); //complete the instantiation process
.
.
.
<view name="myResourceIntensiveView" initstage="defer"...>
<method event="oninit">
stopLoadingDialog();
</method>
<method name="resetMyView">
...
</method>
.
.
.

The problem here is the Loading dialog stalls out and never really starts up until after the myResourceIntensiveView shows up. It shows for what seems like a millisecond and then the myResourceIntensiveView is shown.

Instead, to get around this (a really wierd hack), I call the reset method on myResourceIntensiveView() to force instantiation of the view after I start the loading dialog. This seems to fix the problem but it is a hack and I don't know why this is happening this way. Thus to get things to work I have

startLoadingDialog(); //which is in a separate view loaded on startup
myResourceIntensiveView.resetMyView(); //complete the instantiation process
.
.
.
<view name="myResourceIntensiveView" initstage="defer"...>
<method event="oninit">
stopLoadingDialog();
</method>
<method name="resetMyView">
...
</method>
.
.
.

Thank you.

jackeryf
02-20-2006, 07:55 AM
nmudd,
I have had the same problem you are describing.
I'm playing around with the idea of floating a
div over the laszlo app with the loading
animation in it. But this would only work if
you run your app in a browser.

It appears to me that the Flash plugin only has
one process thread available to it. Because it
has trouble running more than one process at a
time, includeing external animated swf files
that are brought in as a resource.

But that can not be true because the
completeInstantiation() call does not pause the
execution of the method that called it. It appears
to continue on but is crippled somehow.

I am trying to do testing to learn more about
how the processes are handled and control.
I would rather read about it but have not found
much in the docs yet.

I would really like to see a way to pause
execution without trying to setup some kind of
call back method.

nmudd
02-20-2006, 08:07 AM
Hi Jack. I still found more problems with this approach, just as you described. My solution was a total hack, but it works, although there appears to be a little studdering with the loading animation at first. I had this huge view I wanted to load, so what I did was added a timer after it so that essentially told the flash player to sit idle for a moment. Then the only thing it is told to do is load the animation. Once the animation is going, I instantiate my view, and then when data hits it (use any event you find appropriate--I used ondata for my needs), set the animation invisible and show your huge view. Here is some sample code. I hope this helps! :

this.myDel = new LzDelegate ( this, 'MyHugeViewIWantToLoad');
LzTimer.addTimer ( this.myDel, 2000 ); //Set a timer
LoadingView.notReady(); //starts my 'Not Ready' animation

...
...
...

<view "MyHugeViewIWantToLoad">
<method event="ondata">
stopMyAnimation();
showThisView();
</method>
</view>

jackeryf
02-20-2006, 09:06 AM
nmudd,
It's funny I did something similar.
But I set almost all of my views to initstage=defer
and then made a loading loop that goes through an
array and loads each view and uses a timer to wait
a few seconds between each call to laod the next.

The reason for this is cause there are still some
things going on after the oninit is called.
I have found that if the user is using a music
player or they are using an older computer that
they get the hung messsage. Using the timer between
calls to completeinstan helps stop this.

To make this more dynamic I made a small hardware
test function where I rate the CPU availability and
from that I set the pause time between each
completeinstan call.