It's my first question here, and i'm not an english native speaker, so i apologize in advance, if that makes my explainations difficult to understand.
CONTEXT
I'm in charge of the developpement of a small application which manipulate vocabulary sets.
The application is built on GWT, added by GWT-Bootstrap and some other libraries, that have nothing to do with the ui part of the application.
To expose to the user the terms of this vocabulary, i use a tree stucture, visually speaking.
STORY
The tree has few requirements, it has to allow drag&drop features for his items and show connectors between them.
I started by using the Tree ui class from the native GWT components. It turned out that with a lot of terms loaded in the tree, the performances felt down, even in production mode.
I decided so to try the CellTree implementation, but it didn't fit for me since make disappear the "showmore" button is not an easy task, and styling the tree too.
I finally ends up with my own implementation of a tree, from scratch.
This implementation relies essentially on a simple html list structure (ul-li), and benefits at maximum of css capabilities. Indeed, expanding a tree node is done with css, using a trick known as "checkbox hack".
At this point the custom implementation of the tree is fast (better than tree or celltree), even populated with thousands items, and it met the requirements, but...
THE ISSUE
When an item is being dragged over other items, the style of those items change depending on dropping possibilities.
1st Solution
The first idea was to benefit of the css, and use the :hover selector to change the style of the items, depending on their classes.
But there is a major issue in current browsers (specifically Chrome), which make the css :hover not triggered, if the mouse left button is down, which it's the case when you drag something (chromium issue 122746)
It seems that i have to forgot an exculsive css solution, until the :hover triggering issue will be closed.
2nd solution
The only other solution to which i came by is to change the style of the item programmatically.
Code of the handler
#Override
public void onDragEnter(DragEnterEvent event)
{
if (event.getSource() instanceof Word)
{
event.stopPropagation();
event.preventDefault();
Word word = (Word) event.getSource();
word.addStyleDependentName("over");
}
}
#Override
public void onDragLeave(DragLeaveEvent event)
{
if (event.getSource() instanceof Word)
{
event.stopPropagation();
event.preventDefault();
Word word = (Word) event.getSource();
word.removeStyleDependentName("over");
}
}
It works fine with a few items, but when dealing with thousands it make the application freezing, and the rendering is somehow random.
PRECISIONS
The issue appears when dealing with 5000 items in the tree (the application must handle such dataset).
I'm aware of efficient events handling concerns, as event bubbling, and the handler is unique as it is recommanded when the number of potential handlers, if made specific for each item, is a factor of lack of performance as the number of items increase.
Secondary i've used the speed tracer to analyse the source of the problem, and it turned out something i don't understand:
Events are incredibly slow on top elements of the tree, specifically the paint event which take 1 second to be fired after the style recalculation
Slow events Speed Tracer Screenshot
Events speed is fair enougth on bottom elements of the tree
Fair enougth speed events Speed Tracer Screenshot
QUESTION
I'm stuck with this issue since few days, and i wonder if someone could point out what i am missing.
Perhaps, the behaviour is totally normal, but maybe there is a workaround for a such issue ?
I'll be glad if someone could help me on this point.
Thanks you for any reply !
lilBrain
If you are using GWT-Dnd please have a look at that;
Slow drag performance when there are a lot of draggables on screen
It's mentioned that this performance issue is related to finding x, y coordinates of the widget on a drop event.
com.allen_sauer.gwt.dnd.client.DropControllerCollection.getIntersectDropController(int x, int y)
there is a block of code that loops through the DropController candidates with what appears it's only purpose being for debugging.
for (int i = sortedCandidates.length - 1; i >= 0; i--) {
Candidate candidate = sortedCandidates[i];
if (DOMUtil.DEBUG) {
DOMUtil.debugWidgetWithColor(candidate.getDropTarget(), "blue");
}
}
subsequent to that, the code then loops through and actually tries to
identify if the x and y coordinates are over a DropController.
Hope this will help you.
Related
I have been developing an app using Titanium. I have a scrollview and i am trying to remove childs like below.
First
scrollview.removeAllChildren();
but there is another way to remove the subview by looping the scrollview children like below,
Second
for (var x = 0; x < scrollview.children; x++) {
var child = scrollview.childAt(x);
scrollview.remove(child);
}
My question is which of the above method is good to use when it come to performance wise?
When we deletes child using second method we can visually see the performance. but some suggests second method is the best way.
How much time difference are you observing between the two calls in the worst case scenario (where your scrollview might have hundreds of UI elements). Also you can look into the native implementation in the framework and decide on which is better suited for you. But generally, this first method should be good in most of the cases (also it looks clean)
I have a cocoa application window (NSWindow) which position on the screen should be updated frequently (depending on some calculation). As noticed in the documentation, UI changes should be made on the main thread:
void calculationThread()
{
while(true)
{
calculatePosition();
if(positionChanged)
{
dispatch_async(dispatch_get_main_queue(), ^{ setWindowPos(); });
}
}
}
void setWindowPos()
{
[window setFrame:_newFrame display:YES];
}
Now the problem I have is that the window movement is very slow and delayed. After making some profiling I see that the calculation process takes about 40mSec, meaning that I'm queueing up a backlog of UI updates 25 times a second.
I've read here that this might be faster than they can be processed and timer should be used to fire the changes every tenth of a second or so. But, wouldn't it be too slow for the human eye (I mean, in that case the movement wouldn't be delayed but would be lagged causing pretty much the same affect).
I will appreciate some knowledge sharing on this. Actually my main 2 questions are:
Are 25-30 UI updates per second really to much?
If yes, what is the recommended UI changes frequency?
The frequency at which a window can be moved around onscreen without problems will of course depend upon the speed of the user's machine, the video card they have, the size of the window, and probably a bunch of other factors. There is no single good answer to this. However, if you just drag a window around on your screen, you will notice that it can probably be moved very smoothly (unless your machine is very busy or very low on memory or something); I would not expect 25 times per second to produce a problem on a modern Mac. Not even close, in fact.
#RobNapier's points about Core Animation etc. are fine, but overstated I think; there is nothing inherently wrong with changing your UI using a timer or other periodic update if that is what you actually want to do. CoreAnimation is a toolkit for making some types of animation easier; using it is not required, and it is not suited to every problem. Similarly, if you want to make changes that are actually synched to screen refresh then CVDisplayLink is useful, but it doesn't really sound like that's what you want to do.
For your purposes, your basic approach seems fine, although I would suggest adding an NSDate check in order to skip updates if the previous update was less than, say, 1/60th of a second previous. After all, the calculation appears to take 40mSec on your machine, but it might be much faster on some other machine; you want to throttle your drawing to a reasonable rate just to be a good citizen.
So what is the problem, then? I suspect the issue might actually be your call [window setFrame:_newFrame display:YES]. If you look at Apple's docs for that method, they state "When YES the window sends a displayIfNeeded message down its view hierarchy, thus redrawing all views." Each time you call that method, then, you are not only moving your window (which I gather is your intention); you are redrawing all of the contents of the window, too, and that is slow. If you don't need to do that, then that is the overhead you need to eliminate. Call setFrameOrigin: or setFrameTopLeftPoint: instead (which make the semantics clear, that you are moving the window without resizing it or redrawing it), or perhaps just setFrame:display: passing NO instead of YES, and I'm guessing your performance problem will vanish.
If you do in fact need to redraw the window contents every time, then please edit the problem description to reflect that. In that case, the solution will have to involve profiling why your window drawing is slow, and figuring out ways to optimize that, which is an entirely different problem.
As you've discovered, you should never try to drive the UI from a tight loop. You should let the UI drive you. There are three primary tools for that.
For simple problems, AppKit is capable of moving windows around the screen. Just call [NSWindow setFrame:display:animate:]. You can override animationResizeTime: to modify the timing.
In many cases AppKit doesn't give enough control. In those case, the best tool is almost always Core Animation. You should tell the system using Core Animation how you where you want UI elements to wind up, and over what period and path, and let it do the work of getting them there. See the Core Animation Programming Guide for extensive documentation on how to use that. It focuses on animating CALayer, but the techniques are similar for NSWindow. You'll use [NSWindow setAnimations:] to add your animation. Look at the NSAnimatablePropertyContainer protocol (which NSWindow conforms to) for more information. For a simple sample project of animating NSWindow, see Just Say No from CIMGF.
In a few cases, you really do need to update the screen manually at the screen update frequency. I must stress how rare this situation is. In almost all cases, Core Animation is the correct tool. But in those rare case (some kinds of video for instance), you can use a CVDisplayLink to handle this. That will call you each time the screen would like to refresh, giving you an opportunity to update your content to match.
I'm here because my research and testing lead me nowhere.
I have made a little calendar application and now I want to improve the user interface with nice controls. I'm trying to achieve an interface where you can create an event by dragging over it (as you can do in Google agenda, in fact this a school project and I want to reproduce this week view).
For this purpose I have tried this approach:
For each cells of the area (a GridPane that contain VBoxes) I attach handlers that achieve that feature (setOnDragDetected, setOnMouseDragEntered and setOnMouseDragReleased). And it does the job well but in some case this don't work (if the mouse move over another event, which do no have the handlers, the drag feature stop).
As I saw this too heavy and subject to bogus (3 handlers x 7 columns x 48 rows = 1008 handlers !! ), I thought about other approach but I'm a beginner in javaFX and I don't know if there is other mechanism to perform this. (I thought about a transparent layout/pane that will handle this feature and act like a "touch screen" over my application but I did not found satisfying answers). Can someone enlighten me about this kind of problem ? For a good example of what I try to achieve take the behaviour of the Google agenda for an event creation with the mouse (I do not need to manage overlap of event). Thanks in advance !!
I post a picture of what the actual view look like.
So as Tomas Mikula suggest me I only attached my handlers to the GridPane (and not to each "cell" as I made previously): setOnDragDetected, setOnMouseDragOver, setOnMouseDragReleased and setOnMouseDragExited.
As the handlers are triggered on the GridPane, moving the mouse over other element doesn't stop the feature.
With this I reduced the number of handler, simplified the code (As I do not need to manage extra behaviours as mover over another child).
Thanks !
Most Unity tutorials suggest using Mouse events within the Update function, like this:
function Update () {
if (UnityEngine.Input.GetMouseButton(1)) {
}
}
This strikes me as really inefficient though, similar to using onEnterFrame in AS or setInterval in JS to power the whole application - I'd really prefer to use an events based system.
the OnMouseDown() method is useful, but is only fired when the MouseDown is on the object, not anywhere in the scene.
So here's the question: Is there a MouseEvent in Unity for detecting if the mouse button is down globally, or is the Update solution the recommended option?
This strikes me as really inefficient though, similar to using
onEnterFrame in AS or setInterval in JS to power the whole application
- I'd really prefer to use an events based system.
As already pointed out in comments, this isn't necessary less efficient. Every event based system is probably using a polling routine like that behind the scenes, updated at a given frequency.
In many game engines/frameworks you are going to find a polling based approach for input handling. I think this is related to the fact that input update frequency is directly correlated to the frame rate/update loop frequency. In fact it doesn't make much sense to listen for input at higher or lower frequency than your game loop.
So here's the question: Is there a MouseEvent in Unity for detecting
if the mouse button is down globally, or is the Update solution the
recommended option?
No there isn't. Btw if you want you can wrap mouse input detection inside a single class, and expose events from there where other classes can register to.
Something like:
public class MouseInputHandler : MonoBehavior
{
public event Action<Vector2> MousePressed;
public event Action<Vector2> MouseMoved;
...
void Update()
{
if (Input.GetMouseButton(0))
{
MousePressed(Input.mousePosition);
...
}
}
}
Like stated, you can use it without major concerns, Unity will 'make its magic' internally as to set processing power sensitive code execution for you in terms of polling events. That's the beauty of a modern game engine after all. You normally shouldn't have to be hacking your way around a common feature such a mouse click detection.
However if you don't want to go using the main Update() you can make a CoRoutine if you feel more comfortable with that, just bear in mind that Unity coroutines are not multi-threaded neither, so at the end everything needs to wait anyway.
In a tool such as Photoshop, there is a selection of tools you can click on (e.g. pen, brush etc). Once you click on a tool, you can use that tool to paint, erase etc depending on what tool is selected.
I'm wondering how that would be best implemented in an OO design. I could only think of having a GUIManager that always knows which tool is selected, then when the Canvas (drawing area) detects a mouse click or mouse drag it asks GUIManager which tool is selected and applies that tool's behavior.
Does anyone describe a possible solution in class level detail (or in any detail if you don't have time).
Take a look at the State Pattern which has exactly your example.
However, it's not actually a GUI question but more to an object-oriented approach to how to model this problem. The GUI doesn't really play into this.
I'm not sure OO principles really play into this except in the sense that all graphic elements are probably derived from common base classes in your GUI of choice.
The amount of complexity in an application that needs a hierarchy of screen menus à la photoshop would presumably dwarf the difference between composition vs inheritance vs functional-style vs whatever-you-want.
Although, should you be motivated to write the program twice using different styles, it might be interesting to see the results. The ranking of various programming styles is an open question without real answers at this point, although we think that OO-styles are important in a way we haven't yet completely quantified.
One idea for this would be to have a tool class. Just sketching this in C++-like pseudocode:
class Tool
{
public:
// Keep a pointer to the "document", i.e. some representation of the
// image you are editing
Tool(Document *pDoc);
// Process mouse events -- this need to be overridden to execute
// the appropriate behaviour depending on the concrete type of tool
virtual void OnMouseEvent(const MouseEvent &e) = 0;
// and so on
};
You then inherit from this abstract tool class to provide the concrete tools your application needs. When a certain tool is selected, you instantiate a corresponding tool object and remember it somewhere. The window forwards mouse events to the currently active tool object, which then does the appropriate thing for the tool that was selected.
This is an implementation of the State pattern that Johannes refers to.