Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Contributor
Jaime_Barrachina
Posts: 21
Registered: ‎10-25-2012
My Device: Blackberry Playbook 2.0

Checking different events from different places

Hi, 

In my app I'm getting screen and navigator events with a variation of the sample loop:

 

static void handle_events() {
    int rc = BPS_SUCCESS;

    //Request and process available BPS events
    for(;;) {
        bps_event_t *event = NULL;
        rc = bps_get_event(&event, 0);

        assert(rc == BPS_SUCCESS);

        if (event) {
            int domain = bps_event_get_domain(event);

            if (domain == screen_get_domain()) {
                handleScreenEvent(event);
            } else if (domain == navigator_get_domain()) {
                handleNavigatorEvent(event);
            }
        } else {
            break;
        }
    }
}

 

This works fine, but what I need to do is get the screen events (mainly user touching the screen) in one place of my code (where all the input is processed), and the navigator events (app closed, screen innactive, etc...) in another completely different part of my code (where I handle all platform related code).

 

As getting an event with bps_get_event consumes the event, this is more complicated than I initially tought.

 

I tried pushing the event (assuming it was from the wrong domain - a navigation event in my input event loop for example-) back into the event queue with bps_push_event, but this creates an infinite loop as I keep parsing the events with bps_get_event, and the same event as I just pushed pops back out. 

 

I also tried keeping a list of events, storing the unhandled ones in there, and then calling bps_push_event on each of these outside the loop, but this causes a runtime error in the push function probably because (qouting the bps_get_event docs) "The pointer [returned by bps_get_event] to the event is valid until the @c bps_get_event() function is called again."

 

I also tought maybe there where sister functions to navigator_request_events() and screen_request_events(), something like navigator_cancel_request_events() and screen_cancel_request_events() so I could activate one or the other before each event loop, but no luck. 

 

So, any ideas on how to have two different event loops in different parts of the game, one for screen and the other for navigation events?

 

Thanks for the help,

Jaime

Please use plain text.
BlackBerry Development Advisor
nlandry
Posts: 4
Registered: ‎11-08-2011
My Device: 9360

Re: Checking different events from different places

I think BPS channels is the solution that fits the scenario you're describing.

 

I think you'll want to take a look at the following functions (all from bps/bps.h):

 

bps_channel_create():

http://developer.blackberry.com/native/reference/com.qnx.doc.bps.lib_ref/com.qnx.doc.bps.lib_ref/top...

 

bps_channel_set_active():

http://developer.blackberry.com/native/reference/com.qnx.doc.bps.lib_ref/com.qnx.doc.bps.lib_ref/top...

 

and finally, bps_channel_push_event():

http://developer.blackberry.com/native/reference/com.qnx.doc.bps.lib_ref/com.qnx.doc.bps.lib_ref/top...

 

I'll describe event forwarding, in general, using channels (and then later get into specific cases for navigator and screen):

 

Each channel has its own event queue.  When you called bps_initialize() a default channel was created for you and it was set as the thread's active channel (the channel that most BPS functions operate on).  When you call bps_get_event() it is pulling events from this queue.  You can pop an event from this default queue, and push it onto a destination channel you create.  You can then call bps_get_event() when that destination channel is active and out will pop the event.  This is the general event forwarding mechanism.  For a service like navigator it is a little easier.

 

For navigator:

 

You can create a new channel.  Set the new channel as the active one for the thread (bps_channel_set_active()).  Now call navigator_request_events().  You will now start getting navigator events along with the other channel you were already receiving events on.  The event contents are duplicated for you on both channels.

 

For screen:

 

Unfortunately, you can only call screen_request_events() for a single thread and for a single channel.  But rather than forwarding every screen event, I would unwrap each event and create a new one based on what you care about (I'm guessing inputs like touch and keyboard).  You can then push these new events (see bps/event.h) to the destination channel.  I would take this approach rather than simply forwarding the screen event (because forwarding each screen event might cause a bit of a bottle-neck for future screen events).

 

 

You can find code demonstrating channel gymnastics in this sample:

https://github.com/blackberry/NDK-Samples/blob/master/Channels/main.c

 

 

Hope that helps,

 

Nick

Please use plain text.
BlackBerry Development Advisor
smcveigh
Posts: 668
Registered: ‎11-29-2011
My Device: developer

Re: Checking different events from different places

Couple of ways to approach this.

 

1. keep bps event loop in one central spot.  process events and translate to some internal format that you can dispatch to your various threads or components.

 

2. investigate using channels.  I believe you can probably direct the screen events to one channel and others to another channel.  haven't looked into it in much detail, but I have used channels in other code to inject events.

 

3. don't use bps for screen events.  you can receive screen events either via bps or via the screen API, but not both.  you could handle your screen events separately from all other bps events.

 


option 1, while it may seem like a bit of extra work, will probably be your most flexible option unless the channel stuff ends up working as we suspect it may.

 

Cheers,

Sean

Please use plain text.