I have Problem with onTick() method, I have two buttons for two different situations, in each one I will load separate dataSource, just like the czml.html example on Sandcastle. I have two different definition for onTick() method for each button seperately, to do some specific things when we reach at a specific time. In the reset method I am removing entities and dataSources of my viewer, but I cannot remove onTick method implementation.
When I am running my code, the default button is doing perfectly fine, but when I press other button, all those conditions that I mentioned for the first button is also happening at the same time, and it will not let my second onTick method to perform its job correctly. Do you know how I can deactivate the first onTick method?
Take a look at the addEventListener documentation, you'll find two different ways to undo the addition of an event listener: One is to call the matching removeEventListener, and the other is to save the return value from addEventListener and invoke it later.
Here's some code showing both ways. Use whichever option makes more sense for your code, but don't use both at once.
function onTickCallback(clock) {
// ... do stuff with every tick ...
}
var unsubscribeTicks = viewer.clock.onTick.addEventListener(onTickCallback);
function unsubscribeOption1() {
// One option is to call removeEventListener. In this case, you
// don't need to save "var unsubscribeTicks" at all, but you do
// need a reference to the original onTickCallback.
viewer.clock.onTick.removeEventListener(onTickCallback);
}
function unsubscribeOption2() {
// The other option is to save the return value of addEventListener,
// and later invoke it. This could be a cleaner option if the
// onTickCallback was declared anonymously inline.
unsubscribeTicks();
}
Related
I'm developing a canvas game that happens to have several scenes. Each scene might end up being a static final frame after having finished. The circumstances are that the ticker and the listener for the "tick" event are still running and keep on rendering full speed - which is asking for cpu usage.
I have tried to remove the listeners at the end of scene and add them back wenn the user interacts and starts the next scene.
I wonder what would be the "createJS" way of doing this.
I see some other options but am a bit lost how to proceed:
Caching the "whole" last frame. Will it make the ticker do "absolutely nothing" performance-wise?
Pause the ticker and check for the paused attribute in the handleTick method: Seems to not take the CPU usage completely down.
Can somebody recommend a way?
On a side note: I need my real "this" object inside the tick function that is bound to the ticker. How can I achieve this? Right now I use this code:
createjs.Ticker.addEventListener("tick", handleTick);
function handleTick(event) {
// Actions carried out each tick (aka frame)
if (!event.paused) {
// Actions carried out when the Ticker is not paused.
}
}
Inside handleTick "this" is not my object that added the listener.
A simple createjs.Ticker.removeEventListener("tick", handleTick); should do just fine as long as handleTick exists in your current scope. See this example.
There are a couple ways to access the scope of the object that assigned the tick listener. For example, you could simply assign this to a local variable like so:
var _this = this;
function handleTick(){
//"_this" now refers to the scope that defined handleTick.
}
Or you can use a delegate. In this example I'm using jQuery's proxy function to scope handleTick to this.
var handleTick = $.proxy(function(){
//"this" refers to the scope that defined handleTick.
}, this);
createjs.Ticker.addEventListener("tick", tickHandler);
I have one swing code written by other person. For swing tabbed pane, he has added both change and container listener and both calls the same method:
addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent theEvent ) {
someMethod();
}
} );
addContainerListener(new ContainerAdapter() {
public void componentAdded(ContainerEvent theEvent) {
someMethod();
}
public void componentRemoved(ContainerEvent theEvent) {
someMethod();
}
} );
Whenever tab is removed from this tabbed pane, it internally calls JTabbedPane.removeTabAt(int index), which in turn calls fireStateChanged() causing new change event listened by change listener.
Now as new component (tab) is removed from tabbed pane, it also calls componentRemoved(ContainerEvent theEvent) method of container listener.
Both change even and container events, then calls same method someMethod(), which does set background and foreground colors.
I would like to know, if this kind code might cause some issues. Recently we are facing random IndexOutOfBoundException exeptions. I am just wondering, if this is causing this issue.
Also as per my understanding in swing, once event is listened, logic inside it should be executed using worker thread (e.g. SwingWorker). Please let me know if this is correct.
I am new to swing, thus any hint would be appreciated.
Thanks.
Whenever tab is removed from this tabbed pane, it internally calls
JTabbedPane.removeTabAt(int index), which in turn calls
fireStateChanged() causing new change event listened by change
listener.
This is true if the removed tab is also the selected tab. In the other cases, you won't be notified.
You need to choose what event you want to listen to:
Addition/Removal of components?--> go for ContainerListener
Selected tab? --> go for ChangeListener
I would like to know, if this kind code might cause some issues.
Recently we are facing random IndexOutOfBoundException exeptions. I am
just wondering, if this is causing this issue.
Since there is no line in your sample code that could throw that Exception, it is impossible to answer your question. Post an SSCCE that shows your issue.
Also as per my understanding in swing, once event is listened, logic
inside it should be executed using worker thread (e.g. SwingWorker).
Please let me know if this is correct.
It depends:
If you need to modify anything in the UI, anything related to Swing, it needs to be executed on the EDT (Event Dispatching Thread) and thus, SwingWorker is not an option.
If you need to perform business logic operations, and especially if they can be lengthy, then you should indeed use a SwingWorker or any other mechanism to execute that code in another thread than the EDT. Consider visiting the Swing tag wiki on "Concurrency"
I have a class that creates a button and connects a listener to the click event. In a sub class I'd like to replace the superclass handler. This code adds a listener:
row.query("[value='Save']").onClick.listen(handleNewAlert);
How do I remove the existing listener?
The Stream.listen() method returns a StreamSubscription object. Call StreamSubscription.cancel() to cancel the event listener.
var subs = element.onClick.listen((e) => print(e));
// Remove the listener.
subs.cancel();
// Add another listener.
element.onClick.listen((e) => print(e));
See this article for more information.
Greg's answer describes how to unsubscribe from the event source.
This is correct, but IMO a bit awkward, as you need to keep the subscription instance around in case that any derived class wants to cancel it, or you need to provide a method for this on the base class if you want to hide the details.
As you say that you want to replace the handler, which I understand as providing a different implementation, a simpler approach is to simlpy override handleNewAlert method in the derived class.
Of course, it won't work if instead of method name you have specified an anonymous function, as it obviously can't be overridden, but in the scenario shown in your example, this might be an easier approach.
I'm currently working on a project that involve a re-implementation of the Array class.
This object needs to be an Array for compatibility reasons, while I also need to keep control of what is written in.
I cannot seem to find any way to check property creation inside of a dynamic object in AS3. Something that would work like the Event.ADDED_TO_STAGE but, like, ClassEvent.PROPERTY_ADDED.
I override methods like push, splice etc, but I cannot control direct assignation : MyArray[i] = ...
Is such a thing even possible ?
Of course, I could make some kind of validations elsewhere, but this would involve accessing a part of the code I cannot modify.
Thanks for your time !
I'm not sure I follow you entirely but you may be looking for the Proxy class:
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/utils/Proxy.html
An example at the bottom shows you how you can override direct assignment:
override flash_proxy function setProperty(name:*, value:*):void {
_item[name] = value;
}
Using this you would be able to dispatch a custom event that would be fired any time an item was added to your ProxyArray
I'm creating a GUI, but only if things go ok, so can i
addEventListener(Event.Complete, go) to something and in the go function create my GUI (grafical elements such as labels, lists, squares)?
Is it ok to do that?
Technically it's fine. crooksy88 gives a good example of supplying a default value for the event parameter to make the function more versatile.
However, for the sake of semantics, clarity, and maintenance I would usually prefer to separate things more. So mine might be set up more like this:
protected function onLoadComplete(e:Event):void {
initAppSettings();
createUI();
startApp();
}
It makes it much easier to understand the flow of the app and what each part does just by reading the function names. When I come back to this later, I'll know that my UI is created in the function named createUI and not have to figure out that it gets created in an event handler with a cryptic name like go or handleEvent.
Also, if I want to change the flow of my app, say to pop up a dialog once the load is complete before the UI is created, I just have to move around some function calls, instead of moving around large chunks of code.
Yes that is perfectly fine. The go function isn't part of the event listener.
function go(e:Event):void {
// do something
}
The sample above requires the event parameter from the listener (e:Event).
But you can modify the function so that the parameter is optional so you can call the go function any time you want
function go(e:Event = null):void {
// do something
}
The example above will be triggered by the listener and also by typing
go();