How to implement callback function in NPAPI Plugin - npapi

I am developing NPAPI Plugin for embedded native browser (Linux) . I want one callback function from javascript that will invoke callback function in my plugin . As per the events generated by pressing the keys of keyboard . I have to send events continously to the browser window. I am completely new to this needs help .
Thanks in advance .

If you are using FireBreath, the documentation on firing events already covers this.
If you are writing a plain NPAPI plugin, your plugin should implement addEventListener(type, listener, ...) & removeEventListener().
As you already know how to add scriptable functions to your plugin, you just need to add support for these two.
For addEventListener() you get the following arguments:
type - should be a string that identifies the event
listener - should be an object, retain & store it
useCapture - should be a boolean, optional, if not present assume false
To store the listeners you could e.g. use a multimap<SomeStringType,NPObject*> member, with the event string as your key and the listener object as the value. Don't forget to retain the listener.
To fire an event you then get the equal_range() for it and use NPN_InvokeDefault() with the listener objects.
removeEventListener() receives the same arguments as addEventListener() and you should then erase() the specified listener for that event string. Don't forget to release the listener object.
To honor useCapture extend the above accordingly.

Related

Extending the native GamepadAPI?

I'm trying to extend the native GamepadAPI to include custom controller code.
Using TypeScript, I implemented a simple function, to dispatch a "gamepadconnected" event.
// simulate gamepadconnected event
function dispatchGamepadConnectedEvent() {
let gamepad = Object.create(Gamepad.prototype);
console.log(gamepad);
let event = new GamepadEvent('gamepadconnected', {
gamepad: gamepad
})
window.dispatchEvent(event);
console.log('Gamepad connect event dispatched.');
}
However, when dispatching the event, I get an error:
Gamepad {}axes: (...)buttons: (...)connected: (...)id: (...)index: (...)mapping: (...)timestamp: (...)vibrationActuator: (...)__proto__: Gamepad
extension.ts:37 Uncaught TypeError: Failed to construct 'GamepadEvent': member gamepad is not of type Gamepad.
at dispatchGamepadConnectedEvent (extension.ts:37)
at extension.ts:48
Even though, the instantiated Gamepad object seems fine, the type of the Gamepad is not correct.
Why is this like that? How can I create a new, proper Gamepad object to fire the native event?
You cannot create a native Gamepad object.
Object.create(Gamepad.prototype) does not create a Gamepad. It creates an object and sets it prototype to Gamepad.prototype. While this trickery often works for application-level APIs, it won't fool native browser APIs.
Your choices are:
Pass null: {gamepad: null}
Pass an actual gamepad reference {gamepad: navigator.getGamepads()[0]}
Dispatch a CustomEvent, not a GamepadEvent.
Try something else entirely.
Not sure about the use case that's behind your question, but one alternative might be to use the WebHID API. I have recently used this API to create a Nintendo Joy-Con driver in JavaScript. If there happen to be reverse engineering efforts for your device in question (hint: check if there is a Linux driver), chances are that you can use this to talk to your device over WebHID.

libgdx: How to stop touchUp event?

As I can see from this article you can easily use "stop" method to stop event propagation, but this doesn't work for "touchUp/touchDown" event (event isn't stopped). I have also tested it for "mousemove" event and found that it works for it. Why? How can i stop "touchUp/touchDown" event?
PS: libgdx version: 1.2.0,
I'm using scene2d.
From github wiki:
The InputMultiplexer will hand any new events to the first InputProcessor that was added to it. If that processor returns false from the method invoked to handle the event, this indicates the event was not handled and the multiplexer will hand the event to the next processor in the chain. Through this mechanism, the MyUiInputProcessor can handle any events that fall inside one of its widgets and pass on any other events to the MyGameInputProcessor.
TL;DR: Return true from your handle function if you want to stop it from propagation.
Also, what version of LibGDX are you using? I use 1.2.0 and the touchUp() method returns a boolean, unline that in the tutaril from your question.

AS3 Event architecture

I'm having difficulty with the last piece in the puzzle on AS3 events.
I understand target classes inherit from EventDispatch or implement IEventDispatch and can register (amongst other methods) event listeners.
However what do the target classes register with? If an Event happens, how does AS3 know to pass the Event to the target classes?
Regards,
shwell.
Read this article about event phases and it will make more sense:
http://livedocs.adobe.com/flex/3/html/help.html?content=events_02.html
Hope this helps. Have a great day.
You can look at how starling event works
starling even dispatcher
When a displayObject bubbles an event, it will check if the parent of the displayObject exist and add the parent to bubbleList if exist util the ancestor of displayObject is null.
The following code is in starling eventDispatcher
var element:DisplayObject = this as DisplayObject;
var chain:Vector.<EventDispatcher> = new <EventDispatcher>[element];
while ((element = element.parent) != null)
chain[int(length++)] = element;
In AS3, EventDispatcher is an implementation of the observer design pattern. This class implement the addEventLister, removeEventListener, dispatchEvent' andhasEventListener` methods. Internally, it also maintains a dictionary or similar data structure that contains the events which are currently being listened for, and a list of methods which have to be called when the event is dispatched. Something like this -
{"event1": [method7, method5, method3], "event2": [method3, method2], "event3": [method1]};
When addEventListener is called on an object, it creates a new key for the event in question and adds the method reference to its associated value list.
When dispatchEvent is called on the class, it fetches all the methods associated with the event and calls the methods attached with it. Each method is called with an instance of the Event class or its subclasses.
Removing an event listener obviously does the opposite of what adding does.
I guess you're missing of addEventListener() mechanics. This thing has a global side effect on event engine, registering a callback function along with caller this value to provide correct context of a fired event, with possible update of event.localX and event.localY properties by calling globalToLocal() either statically or dynamically, as the event bubbles up and down.
If you are, like me, confused about how does Flash player determine the target of an event - there is an internal "focus" pointer that determines which component of the SWF has keyboard focus, and that one is used to target keyboard events. For mouse events, most likely Flash engine calls getObjectsUnderPoint() to query for topmost IEventDispatcher compatible objects (not all of the DisplayObjects can process events), and that one is sent a mouse event, with the previous event's target to receive a say MouseEvent.ROLL_OUT or MouseEvent.MOUSE_OUT if the target has been changed. For other events, most likely the entire display list can react.
For objects in the display list, the following excerpt from Adobe is the answer "When Adobe® Flash® Player dispatches an Event object, that Event object makes a roundtrip journey from the root of the display list to the target node, checking each node for registered listeners.".
For non display objects, AS3 run time maintains a dictionary of all AS3 events containing bound variables. The bound variables are a reference to the event listeners.

Should I remove listener for SOUND_COMPLETE event?

My application needs to notify UI that sound playback is finished. To accomplish that is attaches listener to the SOUND_COMPLETE event of a SoundChannel object.
Should I remove my SOUND_COMPLETE event listener after event processing is done?
private function playbackCompleteHandler(event:Event):void {
// Notify UI that playback is done etc
channel.removeEventListener(Event.SOUND_COMPLETE, playbackCompleteHandler);
}
Everyone says that we should always remove event listeners so that GC could properly collect objects ('channel' object in this case). But it seems that Adobe doesn't do that in the official documentation [1][2]
[1] http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/media/SoundChannel.html
[2] http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d21.html
Dispatcher holds listeners, so, if your dispatcher is long-living(like Application), you should use weak listeners:
channel.removeEventListener(Event.SOUND_COMPLETE, playbackCompleteHandler,false,0, true)
last true allows your objects to be freed.
If you don't need your temporary objects to process dispatcher's events after you loose all references to temporary objects and until they are collected, you shall remove listeners
Otherwise(when dispatchers are short-living), there is no need to care about listeners: if you are listening to something temporary, it will die without any problems.
It seems that your case is the last one, so it's better not to pollute code with meaningless lines.
You're question states my answer for this
Everyone says that we should always remove event listeners so that GC
could properly collect objects
If you are no longer keeping an instance of the Sound object around; then remove the event listener. If you will still be using the Sound object; then there is no need to remove the listener.

How do I attach a global event listener?

I am working on an AIR application:
The main window is like a dashboard. With the menu bar, I can open other windows with dashboard details. When I close these, I'd like to refresh the main window.
I tried to use an event listener, but the result is not good. If I open detail windows directly from the main window, I know how to add an event listener - and it works - but I don't know how to do it, if the detail window is opening from the menubar!
Thanks for helping me.
A Singleton is what you are looking for. Just put an event dispatcher inside and you will be able to listen from everywhere in the application.
A Singleton is like having a unique instance of an object in memory, so anyone modifying a variable inside that object ( or sending events throught ) will be modified for everyone.
Here is an example of code on how to use it.
http://life.neophi.com/danielr/2006/10/singleton_pattern_in_as3.html
Note: Singletons are powerful and dangerous at the same time, there is a lot of talk about how to use them, please read a little more about that if you are considering building a big project.
Hope it helps!
The issue is that you're performing business logic from a View. Don't do this. Instead, dispatch an event from each menu rather than directly opening the window from within it. Listen for those events at a higher level, and then you can either directly listen to the new windows you have opened, or you can create a base window Class that exposes a variable of type IEventDispatcher. If you populate that variable with the same event dispatcher, what you wind up with is called an "event bus," and you can listen on that for events.
This architecture requires a little more thought than using a Singleton, but it avoids the tight coupling and other issues you'll run into by introducing one into your project.
You can listen to an object (EventDispatcher) directly by adding an event listener to it, or if the dispatcher object is on the displaylist, such as a Sprite, you could listen at the stage level with the capture parameter set to true.
But the main caveat is that the dispatcher must be on stage for you to catch this event.
Your main window listens to stage (with capture = true):
stage.addEventListener("MY_CUSTOM_EVENT", handle_custom_event, true);
private function handle_custom_event(e:Event):void
{
var sub_window:Object = e.target;
// do something to your sub_window
}
Your sub window can dispatch events like this:
dispatchEvent(new Event("MY_CUSTOM_EVENT"));
But (ab)using the stage as a message passing infrastructure for custom events in this way is a little messy. You could consider a more formal message passing architecture if you really want this kind of communication. Even a static MessageBus class would at least quickly help you identify where you use this in your codebase. Either way, you'll have to be careful about references and memory leaks.