BlackBerry PlayBook NDK 2.0样例分析之“HelloWorldDisplay”

  分析了“HelloWorldConsole”样例和PlayBook NDK的事件处理机制后让我们来看看PlayBook NDK中的第二个样例“HelloWorldDisplay”。

 

样例“HelloWorldDisplay”就是之前NDK Beta中的“HelloWorld”样例,之前的博文也介绍过,程序启动后在屏幕上显示一张底图和“HelloWorld”字样。

既然我们已经开始理解PlayBook NDK上的事件处理机制,就让我们更深入看看“HelloWorldDisplay”的代码。

 

“HelloWorldDisplay”项目中有main.c,bbutil.h,bbutil.c三个文件,其中bbutil.h和bbutil.c文件中提供了一些工具函数,用于实现一些具体的工作,本文先不作详细介绍,这里主要先看看main.c中的代码。

 

从main.c中的main函数开始,开始首先是对PlayBook屏幕环境的初始化,代码如下:

 screen_create_context(&screen_cxt, 0);

函数screen_create_context是在头文件<screen/screen.h>中声明的,用于初始化PlayBook得屏幕环境,对于需要图形界面的程序这一步都是需要的。

其中的参数是指向screen_cxt的指针,而screen_cxt在main.c文件开头进行了声明,声明如下:

static screen_context_t screen_cxt;

 

初始化屏幕后就需要进行BPS的初始化工作,主要是为了后面的事件处理。如之前的博文提到的,BPS初始化工作通过调用bps_initialized()函数完成,代码如下: 

 bps_initialize();


完成了BPS的初始化工作后开始为屏幕设置egl,完成egl初始化工作,启动openGL。 

egl的初始化过程比较复杂,样例中这些代码被放在bbutil.c中进行定义,在main.c中就简单调用bbutil_init_egl()函数完成。这里不详细讲述egl的初始化过程,有兴趣的同学可以打开bbutil.c文件仔细看看。

bbutil_init_egl()函数的调用代码如下,调用完成后会对调用结果进行判断,如果调用失败则对screen_cxt进行释放。

    if (EXIT_SUCCESS != bbutil_init_egl(screen_cxt)) {
        fprintf(stderr, "Unable to initialize EGL\n");
        screen_destroy_context(screen_cxt);
        return 0;
    }

 

进一步是样例本身的初始化工作,主要是加载字体,并定义顶点数组和纹理坐标数组,所有初始化代码放在main.c的init()函数中。 

    //Initialize app data
    if (EXIT_SUCCESS != init()) {
        fprintf(stderr, "Unable to initialize app logic\n");
        bbutil_terminate();
        screen_destroy_context(screen_cxt);
        return 0;
    }


 然后是调用navigator_rotation_lock()函数锁定屏幕,不响应PlayBook方向变化的动作。

接着通过screen_request_events()函数和navigator_request_events()函数向BPS请求屏幕事件和“Navigator”事件。这两部分的代码是该样例事件处理的重要部分。

    //Signal BPS library that navigator orientation is to be locked
    if (BPS_SUCCESS != navigator_rotation_lock(true)) {
        fprintf(stderr, "navigator_rotation_lock failed\n");
        bbutil_terminate();
        screen_destroy_context(screen_cxt);
        return 0;
    }

    //Signal BPS library that navigator and screen events will be requested
    if (BPS_SUCCESS != screen_request_events(screen_cxt)) {
        fprintf(stderr, "screen_request_events failed\n");
        bbutil_terminate();
        screen_destroy_context(screen_cxt);
        return 0;
    }

    if (BPS_SUCCESS != navigator_request_events(0)) {
        fprintf(stderr, "navigator_request_events failed\n");
        bbutil_terminate();
        screen_destroy_context(screen_cxt);
        return 0;
    }


 已经完成初始化工作后就进入事件循环,在事件循环中通过bps_get_event()函数获取事件,如果事件获取成功则对事件进行处理。本例对事件的处理很简单,只响应退出事件,当退出事件发生时跳出事件循环。

事件处理完成后调用render()函数完成屏幕绘制工作,所有绘制工作在main.c的update()函数中完成,主要是通过openGL的相关函数展现顶点数组对应的矩形,同时显示纹理。

有关如何通过openGL显示图形我们在之后的文章中继续讨论。

这里还要注意一点的是调用bps_get_event时使用了0为参数,意味着如果没有事件发生,程序不会阻塞,而会继续运行。也就是说该样例一直在重画屏幕上显示的内容,虽然我们看见的只是一张静态的底图和“Hello World”字样。

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

        if ((event) && (bps_event_get_domain(event) == navigator_get_domain())
                && (NAVIGATOR_EXIT == bps_event_get_code(event))) {
            break;
        }

        fprintf(stderr,"Trying to render \n");
        render();
    }

 

如果退出事件发生,程序会跳出事件循环继续执行下面的资源释放代码: 

    //Stop requesting events from libscreen
    screen_stop_events(screen_cxt);

    //Shut down BPS library for this process
    bps_shutdown();

    //Destroy the font
    bbutil_destroy_font(font);

    //Use utility code to terminate EGL setup
    bbutil_terminate();

    //Destroy libscreen context
    screen_destroy_context(screen_cxt);
    return 0;



 通过对“HelloWorldDisplay”样例的分析我们可以完整地看到一个PlayBook NDK应用程序的运行过程,包括应用的初始化,事件循环和资源释放三个重要的部分。

有关如何使用OpenGL在PlayBook上进行绘图,我们后面继续讨论。

你可能感兴趣的:(工作,domain,library,化工,BlackBerry,events)