In my application ( QML, QtQuck 1.1, C++ ) I want to reuse some items in my screen.
Generally there are two options ( please let me know if there are more)
1.Use a separate .qml file and put the basic block inside and import in new screen
2.Create a component and use loader to load it.
But I cannot understand which option to use.
Whats the difference between these two options.
Or
which will consume less CPU load?
Thanks!!
Use the first approach unless:
You need to conditionally load QML based on some runtime condition. Note that file selectors are more efficient than Loaders for this purpose, but it might not be possible to use them, depending on your requirements.
You want to avoid loading expensive QML until absolutely necessary (lazy loading).
You should especially be wary of using Loader to load components that are created in large numbers (such as those used as delegates in views), as it doesn't come for free.
To clarify on a part of the answer provided by Mitch:
You should especially be wary of using Loader to load components that
are created in large numbers (such as those used as delegates in
views), as it doesn't come for free.
Using a Loaderas a delegate just to create some other object doesn't make sense except for a very narrow case. You can directly and most definitely should use YourItem {} as a delegate instead. Delaying instantiation in a view delegate in particular is not a very good idea, since that will mess up the view layout, absent the actual item's dimensions which can't be determined without loading it. Even in the case where the Loader is not the top element but nested, it won't be problematic, as QML views only instantiate delegate objects for objects that are in view, if your model has 10k objects it is not like you will have 10k loaders unless they are all in view, which ... won't me much of a view.
Also, if you really need dynamic instantiation, then you will need at least an Item to use as a parent anyway, so the overhead of the Loader becomes negligible and a very good trade-off for the extra flexibility and functionality such as use bindings for the item or to set a dynamic source component. You could do that with an Item but you will have to implement it yourself, and in the end it will end up with larger overhead than Loader.
The CPU time for either of the approaches will not make a difference. Now if you are dynamically creating lots of objects manually, you definitely neither need nor should be using loaders. And not because of the CPU time, but because of memory usage - QML objects are memory hogs, a few thousand objects of medium complexity will likely run you into serious trouble on a 32bit build, especially on a mobile device. Even an empty, non visible QtObject is like 160 bytes. On top of that JS garbage collection is pretty much a joke when it comes to releasing resources, it will do fine on reusing. If you for example create 1 GB of visual items, then delete them and force garbage collection, you will only get a tiny fraction of that memory back, but if you create the objects again, memory usage will be pretty much the same +/- a few megabytes.
In short, in separate .qml file put global component wich you will include and use in different files.
Create component in same file if you will use it only in one file.
Also it depends on the size and complexity of the component. Big and complex component preferably place to separate file.
Compiling faster when all code in one file, but development faster when everything in their place.
Related
i wan't to use Native OpenGL in the paint function of my widgets(QPainter), to improve performance.
i saw that there is function QPainter::begin/endNativePainting(), that can help me.
but i can't find examples for that...
i wanted to know if those functions are low cost, or evry use of them reduce performance?
2.can i define beginNativePainting() and endNativePainting(), in general for all the widgets i use, instead of using that in every paint function i have.
tnx for any help....
There is some basic example code right in the documentation: http://doc.qt.io/qt-4.8/qpainter.html#beginNativePainting
The functions themselves should be fairly low-cost, but calling them might still cause a noticeably overhead, because Qt has to flush its internal painting queue on the beginNativePainting() call and probably has to assume that everything is changed as soon as endNativePainting() is called.
For the second part I am not sure if I understand what you are aiming at. Basically if you have a QPainter object, you can call beginNativePainting() once. But you have to match it with an endNativePainting() call. So the usual place would be the paint() method.
Qt is using a range of OpenGL functionalities to implement its 2D painting, including custom shaders and various frame buffers. It puts OpenGL into a pretty messy state.
beginNativePainting / endNativePainting are there to allow Qt's drawing engine to save this context and retrieve it once the user is done drawing.
It would have been nice to have the xxxNativePainting methods do the contrary (i.e. automatically save and restore user configuration of OpenGL), but since Qt allows to call OpenGL primitives directly, saving the global state is nigh impossible without tons of code and potential serious performance hit.
Instead, these methods simply save Qt's internal OpenGL state and, rather than having user code start in a configuration that would be meaningless anyway (and likely to change with each new Qt release), reset OpenGL to a "neutral" state.
It means that, inside a begin/end section, you will start with a clean slate: no shader linked, no vertex array, most of global parameters reset, etc.
Contrary to a simple QGLWidget / PaintGL scenario where you can afford to setup the global OpenGL state once and for all and simply call the rendering primitives each frame, you will have to restore pretty much everything just after the call to beginNativePainting (link/bind your shaders, set global parameters, select and enable various buffers, etc).
It also means that you should use native painting sparringly. Having each single widget do custom painting might soon bring your rendering to its knees.
I'm just starting my first fairly large Qt project which will be mostly a bunch of screens with buttons, tab widgets, and Qwt Plots. The panel stack pattern described in Qt Quarterly 27 seems pretty nice for my application. Each of my screens is a QWidget encapsulated in a Panel which is shown/hidden by a QStackedWidget. However it uses a singleton pattern for each Panel so that they aren't all created immediately as the app starts and so that more than one of each screen isn't ever created.
So I started coding. Got the panel stack working. Added some code so that dynamically updating widgets aren't dynamically updating all the time. Got my history stack/back button working for the panels. Everything seems just fine, but I've got one nagging worry:
My code smells.
I am in no place to argue with any of the hate posted here and on blogs about the singleton pattern. I think I get it and the code I've written does make me feel a bit dirty with all the boilerplate lines and global objects. But I do like not having to worry about whether or not I already instantiated a screen before switching to it and adding it to my history stack. I just say switch to that screen, it's added to my history stack, and the magic works.
From what I've read there are also some cases where singletons can be worthwhile. Is this one of those special cases? The magic screen switching / history stack makes me think 'yes' but the sheer number of different singleton classes I'm going to have to create makes me think 'NO no NO NO NO'.
I want to just man up and figure out how to get the singleton pattern out of my code now so that I don't have to do it later. But I don't want to get rid of all my singleton classes just to get rid of my singleton classes because they're EVIL [citation needed].
Any input is much appreciated!
I don't really hate singletons, but this sounds like a case with no use for them. I don't understand why there are so many singletons in that article.
First, the PanelStack is a singleton by itself. Why? If that's your main widget, then just create it on the stack in the main(), which is both cleaner and faster. If it is a part of a more complicated UI, then put it there as a member of that UI. A regular class is just fine here, making it singleton only limits its possible uses.
Then, each panel is also a singleton? At this point even singleton lovers should begin to feel that there are too many of them already. Which is probably why you are asking this question in the first place. Let's see what real advantages singletons give here. Well, about the only advantage I can figure out from that article is the ability of lazily creating panels on the fly as they are needed. This is actually a good thing, but in fact, lazy creation and singletons are different patterns, although one often uses the other.
Why not just put all those panels in some common container instead? In this case, the PanelStack looks like a perfect candidate for it. It is the very place where panels are stored after all. Instead of a bunch of singletons, let's create a bunch of methods in the PanelStack:
class PanelStack : public QWidget
{
Q_OBJECT
public:
int addPanel(AbstractPanel *);
void showPanel(int);
RecordingsPanel *getRecordingsPanel();
ReecrdingDetailsPanel *getRecordingDetailsPanel();
private:
...
};
And so on. These get*Panel() methods can still create panels lazily as needed. Now, it's essentially the same thing as having a bunch of singletons, with some advantages added:
If we make panels children of the stack, they are automatically deleted when the stack is deleted. No need to worry about memory management which is always a pain with singletons.
You could even implement some sort of "garbage collector" in the PanelStack that deletes panels that haven't been used for some time. Or when some sort of "max active panels" limit is reached.
Now, the only disadvantage I can think of is that we have a dependency between the stack and the panels now. But what's worse, to store instances in one class, introducing a dependency, or to store them globally? If you think that the stack should be independent from panels, which does sound reasonable, then we probably just need another class to put all those things in. It could be a subclass of QApplication, or just some random "UI manager" class, but it is still better to store everything in one place than to store everything globally.
Using singletons here only breaks encapsulation and limits the possible uses of the whole UI. What if we want to have two windows with those panels? Or multiple tabs (think web browser)? Singletons will bite hard. And they are only really useful when the instance is accessed widely across many unrelated classes (think DB connections, loggers, pools and other typical singleton uses). They are mostly useless in an UI because with UI it is almost always obvious that "this thing belongs there, and probably nowhere else".
What are the main key-points a Flex developer should remember in order to improve performance of Flex applications?
The ones which come to my mind are:
extending ItemRenderers from more lightweight base classes: i.e. UIComponent
using suspendBackgroundProcessing set to true for animations
using ArrayLists instead of ArrayCollections where appropriate.
useVirtualLayout in Spark DataGroups (unfortunately this step requires Scrollers to make this advice effective)
SQLight performance optimizations for AIR apps (transactions etc)
Probably splitting long data processing into different frames? (Never done this though, so I might be mistaken)
What are the key guidelines you try to follow while developing your Flex3/Flex4/AIR applications in order to increase their performance?
It seems to me a lot of people have performance issues w/ itemRenderers. So, my one contribution here to never use binding an itemRenderer. I fix a lot of customer "memory leak" bugs just by rewriting their itemRenderers to use the dataChange event instead of binding.
Beyond that, I second #Wade Mueller's comment about avoiding nested containers as much as possible.
Although this is less important with the lighter weight Spark Groups, I always try to keep the number of nested containers to a minimum and set explicit positions/sizes when possible. Complicated UIs with dynamically sized containers nested within one another cause a ton of (usually unnecessary) measuring to have to occur. This often results in huge lags when switching between views.
My list:
use local vars instead of global as much as possible
ActionScript instead of MXML as much as possible
[Bindable] generates tons of code, try to avoid it
P.S. Автор, а ты русский язык знаешь? :)
The main things I consider, in order of importance:
Binding
Creates a lot of extra code, and can cause a serious degradation in performance when bindings are not removed. For example, if you reuse components in an applications, listening functions are active throughout the entire flow of your application, consuming unnecessary memory and CPU cycles. For larger applications consider the BindingUtils class.
Note that you cannot unbind properties bound with curly braces {myVariable}
Validate (invalidate) calls are some of the most expensive calls in Flex. Be careful when using them.
validateNow();
Understand the Flex component lifecycle. Overriding these methods can streamline the instantiation process.
Use Vector objects. More information.
Ints > Numbers. Excellent SO answer.
Some more basic tips:
Do not use expensive operations in loops.
for(var i:int = 0; i < massiveArray.length; i++)
In the case of massiveArray, a very large array, length() might be an expensive operation. Assign var massiveArrayLength:int = massiveArray.length; to improve performance.
http://jacksondunstan.com/ has a wealth of articles on optimizing your code. The man is a genius.
Avoid creating unnecessary variables, as instantiation is expensive. Always reuse variables if possible.
function getComplexValue():int {
var i:int = complexCalculation(); // returns int after calculating
return i;
}
Instead, just return immediately.
function getComplexValue():int {
return complexCalculation();
}
If you have access to it, the Flash Profile perspective is your friend. It's a powerful profiler that can reduce the time involved in optimizing a codebase.
I'm currently working on a very large Flash platformer game (hundreds of classes) and dealing with an issue where the game slowly grinds to a halt if you leave it on for long enough. I didn't write the game and so I'm only vaguely familiar with its internals. Some of the mysterious symptoms include,
The game will run fine for a determinate amount of time (on a given level) when all of a sudden it will exponentially start leaking memory.
The time it takes for the game to hit the point where it leaks exponentially is shorter when there's more sprites on the screen.
Even when nothing is being visibly rendered to the screen, the game slows down.
The game slows down faster with more frequent sprite collisions.
Completely disabling the collision code does slow down the degradation but doesn't prevent the game from eventually dropping frames.
Looking at the source and using Flex profiler, my prime suspects are,
There are many loitering objects, especially WeakMethodClosure, taking up large amounts of memory.
The program makes extremely extensive use of weak event listeners (dozens dispatched per frame).
BitmapData is being copied every time a new sprite is created. These are 50x50 pixel sprites that spawn at about 8 sprites per second.
I know it's next to impossible to tell me the problem without seeing the source, so I'm just looking for tidbits that might help me narrow this down. Has anybody experienced this evasive performance degradation in their own projects? What was the cause in your case?
I recently completed a optimization of an large project.
And I can give you some architectural advices:
Main principle – try do as little as possible function / events calls
Get rid off all but one
onEnterFrame / onInterval / onTimer cycles. Do everything you
need in one general event call.
You probably will need a lot of static arrays for storing processed object
references.
Do your graphics / render stuff also in one main loop
Try use big (probably prerendered) canvases instead of small sprites / bitmaps.
Usually it usable for backgrounds. But also working good for a smaller objects
(like trees, platforms, etc)
Rid off small bitmap resources, assemble it to one tile-sheet and draw your stuff
directly from it, through source–rect property
I hope its helps you!
Memory leaks – such headash.
P.S. Test your game in different browsers, IE – most leaking of all, sometimes it don`t clear memory every after refresh.
Avoid anonymous methods - change them into class level methods.
Use weak reference in addEventListener and/or make sure you remove all the listeners of an object before removing it with removeChild
Make sure you removeChild all the sprites instead of just letting them fly off the screen. Also, if possible, reuse the sprites instead of creating new ones.
You should consider object pooling if you have a lot of creation/destruction going on, especially with heavy objects like bitmapdata.
see Object Pool class
Sounds like you need to profile your application to see what is happening.
This thread had a couple of suggestions, but, ultimately, you will need to just put in code to help determine what is going on.
Profiling ActionScript-3 Code
You may want to see if you can just run some smaller parts over a period of time and see if you see a slowdown.
You may want to unit test your application, so you can run various parts rapidly, looking for memory leaks.
One framework is: http://asunit.org/, and another is: http://opensource.adobe.com/wiki/display/flexunit/
Unit testing is something I use a great deal for profiling, so you can test at the top level of your game, run it thousands of times, looking for problems, then run each part and see which has problems, and just work your way down. This is a manual process, but if the two ideas in the SO thread listed in the beginning don't help, this may be your best approach.
Are you using too much memory? Or is your cpu usage too high?
First determine if its a memory or processor limit you are hitting. It sounds like the later, seems like there are many objects doing stuff around ... likely those extra sprites aren't being freed well. Look for dependencies among objects / variables / anything in those events, make sure the sprites are removed, pay attention to any handlers of EnterFrame or recurring events.
It sounds far more likely that you are capping out on processor speed than memory. You have to try extra hard to memory cap a Flash application.
Fortunately there are a lot of easy things you can do to keep CPU down...
1) Stringently manage event listeners for everything, especially mouse listeners. Do you have $texas event listeners on all your sprite objects? That could be a problem.
2) Access arrays using int or uint instead of Number. This is huge, and this is one of those backwater Adobe tricks. Accessing array object with int and uint is way faster than Number and if you do a lot of iteration (and it sounds like you do) this could shave precious milliseconds off your frame execution.
3) In the same vein as #2, monitor your math operations and what types you are using for certain operations. The slowest thing you can do in math operations for AS3 is repetitive casting (feeding ints to a function that returns a Number), or performing basic operations like add and subtract on Number instead of int.
The great thing about having a wtfhuge program like this in Flash is that even a minor optimization change could have a major impact on performance. I once toyed with a raytrace engine in AS3 where I declared one extra variable and it killed my FPS from 30 to 23.
Flash has a rather infamous issue (many consider it a bug) that causes event listeners for timers and the ENTER_FRAME event to not get garbage collected, even if they were weakly referenced. So, even though it's good practice to use weakly referenced events, you should still remove all your event listeners when they are no longer needed.
I have a large codebase that targetted Flash 7, with a lot of AS2 classes. I'm hoping that I'll be able to use Flex for any new projects, but a lot of new stuff in our roadmap is additions to the old code.
The syntax for AS2 and AS3 is generally the same, so I'm starting to wonder how hard it would be to port the current codebase to Flex/AS3. I know all the UI-related stuff would be iffy (currently the UI is generated at runtime with a lot of createEmptyMovieClip() and attachMovie() stuff), but the UI and controller/model stuff is mostly separated.
Has anyone tried porting a large codebase of AS2 code to AS3? How difficult is it? What kinds of pitfalls did you run into? Any recommendations for approaches to doing this kind of project?
Some notable problems I saw when attempting to convert a large number of AS2 classes to AS3:
Package naming
class your.package.YourClass
{
}
becomes
package your.package
{
class YourClass
{
}
}
Imports are required
You must explicitly import any outside classes used -- referring to them by their fully qualified name is no longer enough.
Interface methods can't be labelled 'public'
This makes total sense, but AS2 will let you do it so if you have any they'll need to be removed.
Explicit 'override' keyword
Any functions that override a parent class function must be declared with the override keyword, much like C#. Along the same lines, if you have interfaces that extend other interfaces and redeclare functions, those overrides must be removed (again, as with public, this notation didn't make sense anyway but AS2 let you do it).
All the Flash builtin stuff changed
You alluded to this above, but it's now flash.display.MovieClip instead of just MovieClip, for example. There are a lot of specifics in this category, and I didn't get far enough to find them all, but there's going to be a lot of annoyance here.
Conclusion
I didn't get to work on this conversion to the point of success, but I was able in a matter of hours to write a quick C# tool that handled every aspect of this except the override keyword. Automating the imports can be tricky -- in my case the packages we use all start with a few root-level packages so they're easy to detect.
First off, I hope you're not using eval() in your projects, since there is no equivalent in AS3.
One of the things I would do is go through Adobe's migration guide (which is basically just an itemized list of what has changed) item by item and try to figure out if each item can be changed via a simple search and replace operation (possibly using a regex) or whether it's easier to just manually edit the occurrences to correspond to AS3. Probably in a lot of cases (especially if, as you said, the amount of code to be migrated is quite high) you'll be best off scripting the changes (i.e. using regex search & replace) and manually fixing any border cases where the automated changes have failed.
Be prepared to set some time aside for a bit of debugging and running through some test cases as well.
Also, as others have already mentioned, trying to combine AS2 SWFs with AS3 SWFs is not a good idea and doesn't really even work, so you'll definitely have to migrate all of the code in one project at once.
Here are some additional references for moving from AS2 to AS3:
Grant Skinners Introductory AS3 Workshop slidedeck
http://gskinner.com/talks/as3workshop/
Lee Brimelow : 6 Reasons to learn ActionScript 3
http://www.adobe.com/devnet/actionscript/articles/six_reasons_as3.html
Colin Moock : Essential ActionScript 3 (considered the "bible" for ActionScript developers):
http://www.amazon.com/Essential-ActionScript-3-0/dp/0596526946
mike chambers
mesh#adobe.com
My experience has been that the best way to migrate to AS3 is in two phases - first structurally, and second syntactically.
First, do rounds of refactoring where you stay in AS2, but get as close to AS3 architecture as you can. Naturally this includes moving all your frame scripts and #include scripts into packages and classes, but you can do more subtle things like changing all your event listeners and dispatchers to follow the AS3 flow (using static class properties for event types, and registering by method rather than by object). You'll also want to get rid of all your "built-in" events (such as onEnterFrame), and you'll want to take a close look at nontrivial mouse interaction (such as dragging) and keyboard interaction (such as detecting whether a key is pressed). This phase can be done incrementally.
The second phase is to convert from AS2 to AS3 - changing "_x" to "x", and all the APIs, and so on. This can't be done incrementally, you have to just do as much as you can in one fell swoop and then start fixing all the compile errors. For this reason, the more you can do in the first phase, the more pain you avoid in the second phase.
This process has worked for me on a reasonably large project, but I should note that the first phase requires a solid understanding of how AS3 is structured. If you're new to AS3, then you'll probably need to try building some of the functionality you'll need to be porting. For example, if your legacy code uses dragging and drop targets, you'll want to try implementing that in AS3 to understand how your code will have to change structurally. If you then refactor your AS2 with that in mind, the final syntax changes should go smoothly.
The biggest pitfalls for me were the parts that involved a lot of attaching, duplicating and moving MovieClips, changing their depths, and so on. All that stuff can't really be rearchitected to look like AS3; you have to just mash it all into the newer way of thinking and then start fixing the bugs.
One final note - I really wouldn't worry about stuff like import and override statements, at least not to the point of automating it. If you miss any, it will be caught by the compiler. But if you miss structural problems, you'll have a lot more pain.
Migrating a bigger project like this from as2 will be more than a simple search and replace. The new syntax is fairly similar and simple to adapt (as lilserf mentioned) but if nothing else the fact that as3 is more strict and the new event model will mostly likely cause a lot of problems. You'll probably be better off by more or less rewriting almost everything from scratch, possibly using the old code as a guide.
Migrating from as2 -> as3 in terms of knowledge is fairly simple though. If you know object oriented as2, moving on to as3 won't be a problem at all.
You still don't have to use mxml for your UI unless you specifically want to. Mxml just provides a quick way to build the UI (etc) but if you want to do it yourself with actionscript there's nothing stopping you (this would also probably be easier if you already have that UI in as2 code). Flex (Builder) is just a quick way to do stuff you may not want to do yourself, such as building the UI and binding data but essentially it's just creating a part of the .swf for you -- there's no magic to it ;)