Esempio n. 1
0
void android_main( struct android_app *app )
{
	int ident, events;
	struct android_poll_source *source;
	unsigned int oldtime, newtime, time;

	app_dummy();

	sys_android_app = app;
	app->inputPollSource.process = Sys_Android_ProcessInput;
	ANativeActivity_setWindowFlags( app->activity, AWINDOW_FLAG_KEEP_SCREEN_ON, 0 ); // flags must be set before window creation

	app->onAppCmd = Sys_Android_WaitOnAppCmd;
	while( !sys_android_initialized )
	{
		Sys_Sleep( 0 );
		while( ( ident = ALooper_pollAll( 0, NULL, &events, ( void ** )( &source ) ) ) >= 0 )
		{
			if ( source )
				source->process( app, source );
		}
	}

	Sys_Android_Init();
	Qcommon_Init( 0, NULL );

	oldtime = Sys_Milliseconds();
	for( ;; )
	{
		if( dedicated && dedicated->integer )
			Sys_Sleep( 1 );

		while( ( ident = ALooper_pollAll( 0, NULL, &events, ( void ** )( &source ) ) ) >= 0 )
		{
			if( source )
				source->process( app, source );
		}

		for( ;; )
		{
			newtime = Sys_Milliseconds();
			time = newtime - oldtime;
			if( time > 0 )
				break;
			Sys_Sleep( 0 );
		}
		oldtime = newtime;

		Sys_Android_ExecuteIntent();
		Qcommon_Frame( time );
	}
}
Esempio n. 2
0
void* SkiaAndroidApp::pthread_main(void* arg) {
    SkDebugf("pthread_main begins");

    auto skiaAndroidApp = (SkiaAndroidApp*)arg;

    // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv
    skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr);

    ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
    pipe(skiaAndroidApp->fPipes);
    ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT,
                  message_callback, skiaAndroidApp);

    skiaAndroidApp->fApp = Application::Create(0, nullptr, skiaAndroidApp);

    double currentTime = 0.0;
    double previousTime = 0.0;
    while (true) {
        const int ident = ALooper_pollAll(0, nullptr, nullptr, nullptr);

        if (ident >= 0) {
            SkDebugf("Unhandled ALooper_pollAll ident=%d !", ident);
        } else {
            previousTime = currentTime;
            currentTime = now_ms();
            skiaAndroidApp->fApp->onIdle(currentTime - previousTime);
        }
    }

    SkDebugf("pthread_main ends");

    return nullptr;
}
Esempio n. 3
0
void CEventLoop::run(IActivityHandler &activityHandler, IInputHandler &inputHandler)
{
  int ident;
  int events;
  struct android_poll_source* source;

  m_activityHandler = &activityHandler;
  m_inputHandler = &inputHandler;

  CXBMCApp::android_printf("CEventLoop: starting event loop");
  while (1)
  {
    // We will block forever waiting for events.
    while ((ident = ALooper_pollAll(-1, NULL, &events, (void**)&source)) >= 0)
    {
      // Process this event.
      if (source != NULL)
        source->process(m_application, source);

      // Check if we are exiting.
      if (m_application->destroyRequested)
      {
        CXBMCApp::android_printf("CEventLoop: we are being destroyed");
        return;
      }
    }
  }
}
Esempio n. 4
0
void* SkiaAndroidApp::pthread_main(void* arg) {
    SkDebugf("pthread_main begins");

    auto skiaAndroidApp = (SkiaAndroidApp*)arg;

    // Because JNIEnv is thread sensitive, we need AttachCurrentThread to set our fPThreadEnv
    skiaAndroidApp->fJavaVM->AttachCurrentThread(&(skiaAndroidApp->fPThreadEnv), nullptr);

    ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
    pipe(skiaAndroidApp->fPipes);
    ALooper_addFd(looper, skiaAndroidApp->fPipes[0], LOOPER_ID_MESSAGEPIPE, ALOOPER_EVENT_INPUT,
                  message_callback, skiaAndroidApp);

    int ident;
    int events;
    struct android_poll_source* source;

    skiaAndroidApp->fApp = Application::Create(0, nullptr, skiaAndroidApp);

    while ((ident = ALooper_pollAll(-1, nullptr, &events, (void**)&source)) >= 0) {
        SkDebugf("ALooper_pollAll ident=%d", ident);
    }

    return nullptr;
}
Esempio n. 5
0
inline bool CSensorAndroidBuiltIn::read_xyz(float& x1, float& y1, float& z1)
{
    if (qcn_main::g_iStop) return false;

    if (! m_pSensor || ! m_pLooper | ! m_pSensorEventQueue) {
        fprintf(stderr, "read_xyz error: no sensor %x or looper %x or event queue %x setup!\n", m_pSensor, m_pLooper, m_pSensorEventQueue);
        return false;  // no open file descriptor
    }

    int ident, events;
    float fCtr = 0.0;

    // should probably be while loop but taking too long on some devices
    // set the member vars m_xyz so can be reused if it has a timeout (so x1 etc aren't 0, ie carries over)
    if ((ident = ALooper_pollAll(m_minDelayMsec/2, NULL, &events, NULL)) >= 0) {
        if (ident == LOOPER_ID_QCN) {
            ASensorEvent event;
            if (ASensorEventQueue_getEvents(m_pSensorEventQueue, &event, 1) > 0) {
                m_xyz[0] = event.acceleration.x;
                m_xyz[1] = event.acceleration.y;
                m_xyz[2] = event.acceleration.z;
            }
        }
    }

    // m_xyz (ie android accelerometer return values) are in G's already, so just multiply by earth g 9.8
    x1 = m_xyz[0] * EARTH_G;
    y1 = m_xyz[1] * EARTH_G;
    z1 = m_xyz[2] * EARTH_G;

    //fprintf(stdout, "read_xyz:  %f %f %f\n", x1, y1, z1);

    return true;
}
Esempio n. 6
0
void gtk_android_exit(struct android_app *state)
{
    int ident;
    int events;
    struct android_poll_source* source;

    // replace onDestroy handler to terminate the process AFTER everything is unloaded
    if (!defaultActivityDestroyHandler)
    {
        defaultActivityDestroyHandler = state->activity->callbacks->onDestroy;
        state->activity->callbacks->onDestroy = onActivityDestroy;
    }

    ANativeActivity_finish(state->activity);

    while (!state->destroyRequested)
    {
        // Read all pending events.
        while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
        {
            // Process this event.
            if (source != NULL)
                source->process(state, source);
        }
    }
}
Esempio n. 7
0
void NativeEngine::GameLoop() {
    mApp->userData = this;
    mApp->onAppCmd = _handle_cmd_proxy;
    mApp->onInputEvent = _handle_input_proxy;

    while (1) {
        int ident, events;
        struct android_poll_source* source;
        bool wasAnimating = IsAnimating();

        // If not animating, block until we get an event; if animating, don't block.
        while ((ident = ALooper_pollAll(IsAnimating() ? 0 : -1, NULL, &events,
                (void**)&source)) >= 0) {

            // process event
            if (source != NULL) {
                source->process(mApp, source);
            }

            // are we exiting?
            if (mApp->destroyRequested) {
                return;
            }
        }

        if (IsAnimating()) {
            DoFrame();
        }
    }
}
Esempio n. 8
0
		void run(android_app* _app)
		{
			m_app = _app;
			m_app->userData = (void*)this;
			m_app->onAppCmd = onAppCmdCB;
			m_app->onInputEvent = onInputEventCB;

			const char* argv[1] = { "android.so" };
			m_mte.m_argc = 1;
			m_mte.m_argv = const_cast<char**>(argv);
			
			while (0 == m_app->destroyRequested)
			{
				int32_t num;
				android_poll_source* source;
				/*int32_t id =*/ ALooper_pollAll(-1, NULL, &num, (void**)&source);

				if (NULL != source)
				{
					source->process(m_app, source);
				}
			}

			m_thread.shutdown();
		}
Esempio n. 9
0
void android_main(struct android_app* state) {
    struct engine engine;

    // Make sure glue isn't stripped.
    app_dummy();

    memset(&engine, 0, sizeof(engine));
    state->userData = &engine;
    state->onAppCmd = engine_handle_cmd;
    state->onInputEvent = engine_handle_input;
    engine.app = state;
	PlatfromInit();

	//_InitSensor();
	//InitSensor();
	
	ANativeActivity_setWindowFlags(state->activity, AWINDOW_FLAG_KEEP_SCREEN_ON, 0);

    if (state->savedState != NULL) {
        // We are starting with a previous saved state; restore from it.
        engine.state = *(struct saved_state*)state->savedState;
    }

    // loop waiting for stuff to do.

    while (1) {
        // Read all pending events.
        int ident;
        int events;
        struct android_poll_source* source;

        // If not animating, we will block forever waiting for events.
        // If animating, we loop until all events are read, then continue
        // to draw the next frame of animation.
        while ((ident = ALooper_pollAll(engine.animating ? 0 : -1, 
			NULL, &events,  (void**)&source)) >= 0) {

            // Process this event.
            if (source != NULL) {
                source->process(state, source);
            }

			//_ProcessSensorData(ident);

            // Check if we are exiting.
            if (state->destroyRequested != 0) {
                engine_term_display(&engine);
				PlatfromShutDown();
                return;
            }
        }

        if (engine.animating) {

            // Drawing is throttled to the screen update rate, so there
            // is no need to do timing here.
            engine_draw_frame(&engine);
        }
    }
}
Esempio n. 10
0
gboolean gdk_android_process_events_until_display_ready(struct android_app *app)
{
    int ident;
    int events;
    struct android_poll_source* source;
    while (1)
    {
        // Read all pending events.
        while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
        {
            // Process this event.
            if (source != NULL)
                source->process(app, source);

            // Check if we are exiting.
            if (app->destroyRequested != 0)
            {
                gdk_android_term_display();
                return FALSE;
            }

            if (_gdk_display)
                return TRUE;
        }
    }
}
Esempio n. 11
0
void android_main(struct android_app* state) 
{
	state->onAppCmd     = app_handle_cmd;
	state->onInputEvent = app_handle_input;

	if (state->savedState != NULL) {
		// We are starting with a previous saved state; restore from it.
	}

	// loop waiting for stuff to do.
	while (1) {
		// Read all pending events.
		int ident;
		int events;
		struct android_poll_source* source;

		// If not animating, we will block forever waiting for events.
		// If animating, we loop until all events are read, then continue
		// to draw the next frame of animation.
		while ((ident = ALooper_pollAll(-1, NULL, &events, (void**)&source)) >= 0) {

			// Process this event.
			if (source != NULL) {
				source->process(state, source);
			}

			// Check if we are exiting.
			if (state->destroyRequested != 0) {
				break;
			}
		}
	}
}
Esempio n. 12
0
void EngineCore::mainLoop() {
    int ident;
    int events;
    struct android_poll_source* source;
    shared_ptr<EngineContext> engineContext(getEngineContext());
    app_dummy();

    while (true) {
        // If not animating, block forever waiting for events.
        // otherwise,  loop until all events are read, then continue
        // to draw the next frame of animation.
        while ((ident = ALooper_pollAll(
                    engineContext->isRendering() ? 0 : -1,
                    NULL, &events, (void**)&source)) >= 0) {
            if (ident == LOOPER_ID_MAIN || ident == LOOPER_ID_INPUT) {
                if (source != NULL) {
                    source->process(mApp, source);
                }
            }

            if (mApp->destroyRequested != 0) {
                DEBUG(Log::F_APP_CMD_EVENT, "destroy request received");
                return;
            }
        }

        // check needQuit() to give an early chance to stop drawing.
        if (engineContext->isRendering() && !engineContext->needQuit()) {
            // Drawing is throttled to the screen update rate, so there
            // is no need to do timing here.
            getEngineContext()->updateDisplay();
        }
    }

}
Esempio n. 13
0
void ev_loop(android_app *papp) {
    int32_t lr;
    int32_t le;
    bool first = true;
    android_poll_source *ps;

    log("starting event loop");
    ros::Time::init();

    while (true) {
        lr = ALooper_pollAll(-1, NULL, &le, (void **) &ps);
        if (lr < 0) {
            break;
        }
        if (ps) {
            log("event received");
            if (first) {
                open_bag();
                papp->onInputEvent = handle_event;
                first = false;
            }
            ps->process(papp, ps);
        }
        if (papp->destroyRequested) {
            log("quitting event loop");
            return;
        }
    }
}
Esempio n. 14
0
void _glfwPlatformPollEvents( void )
{
    EGLint w, h;
    int events;
    struct android_poll_source *source;

    // Callback resized window event
    if( _glfwWin.opened == GL_TRUE && _glfwWin.resized == GL_TRUE ){
        _glfwWin.resized = GL_FALSE;
        eglQuerySurface( _glfwWin.display, _glfwWin.surface, EGL_WIDTH, &w );
        eglQuerySurface( _glfwWin.display, _glfwWin.surface, EGL_HEIGHT, &h );
        _glfwWin.width = w;
        _glfwWin.height = h;
        if( _glfwWin.windowSizeCallback )
        {
            _glfwWin.windowSizeCallback( _glfwWin.width, _glfwWin.height );
        }
    }

    // Callback other events
    while (ALooper_pollAll(0, NULL, &events, (void**) &source) >= 0) {
        if (source != NULL) {
            source->process(_glfwWin.app, source);
        }
        if(_glfwWin.app->destroyRequested != 0){
           _glfwWin.app->destroyRequested = 0;
           _glfwWin.opened = GL_FALSE;
           return;
        }
    }
}
Esempio n. 15
0
void ShellAndroid::run()
{
    PosixTimer timer;

    double current_time = timer.get();

    while (true) {
        struct android_poll_source *source;
        while (true) {
            int timeout = (settings_.animate && app_.window) ? 0 : -1;
            if (ALooper_pollAll(timeout, nullptr, nullptr,
                    reinterpret_cast<void **>(&source)) < 0)
                break;

            if (source)
                source->process(&app_, source);
        }

        if (app_.destroyRequested)
            break;

        if (!app_.window)
            continue;

        acquire_back_buffer();

        double t = timer.get();
        add_game_time(static_cast<float>(t - current_time));

        present_back_buffer();

        current_time = t;
    }
}
Esempio n. 16
0
void android_main(android_app* state) {
	app_dummy();

	engine e;
	state->userData = &e;
	state->onAppCmd = [](android_app* app, int32_t cmd) {
		auto e = static_cast<engine*>(app->userData);
		switch (cmd) {
			case APP_CMD_INIT_WINDOW:
				init(e);
				draw(e);
				break;
		}
	};
	e.app = state;

	while (1) {
		int ident, events;
		android_poll_source* source;
		while ((ident=ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0) {
			if (source != NULL) {
				source->process(state, source);
			}
			if (state->destroyRequested != 0) {
				return;
			}
		}
	}
}
Esempio n. 17
0
	void Engine::run()
	{
		app_dummy();

		Timer timer;

		while (true)
		{
			int ident;
			int fdesc;
			int events;
			struct android_poll_source* source;

			while((ident = ALooper_pollAll(0, &fdesc, &events, (void**)&source)) >= 0)
			{
				if (source)
					source->process(mAndroidApp, source);
			}

			unsigned long long nanos = timer.nanos();
			timer.reset();

			if (mInited)
			{
				if (!mApp.update(nanos))
					break;

				mRender.frame();
			}
		}

		mApp.shutdown();
	}
Esempio n. 18
0
		void run(android_app* _app)
		{
			m_app = _app;
			m_app->userData = (void*)this;
			m_app->onAppCmd = onAppCmdCB;
			m_app->onInputEvent = onInputEventCB;
			ANativeActivity_setWindowFlags(m_app->activity, 0
				| AWINDOW_FLAG_FULLSCREEN
				| AWINDOW_FLAG_KEEP_SCREEN_ON
				, 0
				);

			const char* argv[1] = { "android.so" };
			m_mte.m_argc = 1;
			m_mte.m_argv = const_cast<char**>(argv);
			
			while (0 == m_app->destroyRequested)
			{
				int32_t num;
				android_poll_source* source;
				/*int32_t id =*/ ALooper_pollAll(-1, NULL, &num, (void**)&source);

				if (NULL != source)
				{
					source->process(m_app, source);
				}
			}

			m_thread.shutdown();
		}
Esempio n. 19
0
void ProcessAndroidEvents()
{
    do {
        // Read all pending events.
        int ident;
        int events;
        struct android_poll_source* source;
        
        // If not animating, we will block forever waiting for events.
        // If animating, we loop until all events are read, then continue
        // to draw the next frame of animation.
        while ((ident=ALooper_pollAll(g_engine.has_focus ? 0 : -1, NULL, &events,
                (void**)&source)) >= 0) {
    
            // Process this event.
            if (source != NULL) {
                source->process(g_engine.app, source);
            }
        
            // Check if we are exiting.
            if (g_engine.app->destroyRequested != 0) {
                engine_term_display(&g_engine);
                context->quit = true;
                return;
            }
        }
    } while (g_engine.display == NULL);
}
Esempio n. 20
0
Vector3f SensorImpl::update()
{
    // Update our sensor data list
    ALooper_pollAll(0, NULL, NULL, NULL);

    return sensorData[m_index];
}
void CorePlatformAndroid::Run()
{
    willQuit = false;
    while (!willQuit)
    {
        // Read all pending events.
        int ident = 0;
        int events = 0;
        struct android_poll_source* source = NULL;
        
        // If not animating, we will block forever waiting for events.
        // If animating, we loop until all events are read, then continue
        // to draw the next frame of animation.
        while ((ident=ALooper_pollAll(animating ? 0 : -1, NULL, &events, (void**)&source)) >= 0)
        {
            // Process this event.
            if (source != NULL)
            {
                source->process(appHandle, source);
            }
            
            // If a sensor has data, process it now.
            if (ident == LOOPER_ID_USER)
            {
                if (accelerometerSensor != NULL)
                {
                    ASensorEvent event;
                    while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0)
                    {
//                        Logger::Info("accelerometer: x=%f y=%f z=%f", event.acceleration.x, event.acceleration.y, event.acceleration.z);
                    }
                }
            }
            
            // Check if we are exiting.
            if (appHandle->destroyRequested != 0)
            {
                willQuit = true;
                break;
            }
        }

        if (animating && RenderManager::Instance())
        {
            // Drawing is throttled to the screen update rate, so there
            // is no need to do timing here.
//            sleep(1);

        	timespec sleepTime, sleepTime2;
        	sleepTime.tv_nsec = 1000000;

        	nanosleep(&sleepTime, &sleepTime2);
            DoFrame();
        }
    }
    
    Core::Instance()->SystemAppFinished();
    FrameworkWillTerminate();
}
Esempio n. 22
0
static void pollEvent(struct android_app * app) {
    int ident;
    int events;
    struct android_poll_source* source;
    ident=ALooper_pollAll(0, 0, &events, (void**)&source);
    if (ident >= 0 && source)
        source->process(app, source);
}
Esempio n. 23
0
void android_main(struct android_app* state)
{
    app_dummy();
	state->userData = &app;

	// Prepare to monitor accelerometer
	app.sensorManager = ASensorManager_getInstance();
	app.sensorEventQueue = ASensorManager_createEventQueue(app.sensorManager, state->looper, LOOPER_ID_USER, NULL, NULL);

	if (state->savedState != NULL)
	{
		// We are starting with a previous saved state; restore from it.
		app.state = *(AppState*)state->savedState;
	}

	if(gRoot == NULL)
	{
		gRoot = new Ogre::Root();
		#ifdef OGRE_STATIC_LIB
			gStaticPluginLoader = new Ogre::StaticPluginLoader();
			gStaticPluginLoader->load();
		#endif
        gRoot->setRenderSystem(gRoot->getAvailableRenderers().at(0));
        gRoot->initialise(false);	
	}


    state->onAppCmd = &handleCmd;
    state->onInputEvent = &handleInput;

    int ident, events;
    struct android_poll_source* source;
    
    while (true)
    {
        while ((ident = ALooper_pollAll(0, NULL, &events, (void**)&source)) >= 0)
        {
            if (source != NULL)
            {
            	source->process(state, source);
            }
            
            if (state->destroyRequested != 0)
            {
            	return;
            }
        }
        
		if(gRenderWnd != NULL && gRenderWnd->isActive())
		{
			gRenderWnd->windowMovedOrResized();
			gRoot->renderOneFrame();

			InitGameScene();

		}
    }
}
Esempio n. 24
0
bool InputImpl::isMouseButtonPressed(Mouse::Button button)
{
    ALooper_pollAll(0, NULL, NULL, NULL);

    priv::ActivityStates* states = priv::getActivity(NULL);
    Lock lock(states->mutex);

    return states->isButtonPressed[button];
}
Esempio n. 25
0
JNIEXPORT void JNICALL Java_org_nzdis_sensorspeed_CMagneticField_magneticFieldStartup (JNIEnv *e, jclass c, jobject handler) {
	updateHandler = handler;
	env = e;

	jclass handlerClass = env->FindClass("org/nzdis/sensorspeed/CMagneticField");
	if (handlerClass == NULL) {
		LOGI("big error 1");
	}
	mid = env->GetMethodID(handlerClass, "onSensorChanged", "()V");
	if (mid == NULL) {
		LOGI("big error 2");
	}

	ASensorEvent event;
	int events, ident;
	ASensorManager * sensorManager;
	const ASensor* magSensor;
	void* sensor_data = malloc(10000);

	SENSORS_ENABLED = 1;
	ALooper* looper = ALooper_forThread();

	if (looper == NULL) {
		looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
	}

	sensorManager = ASensorManager_getInstance();

	magSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_MAGNETIC_FIELD);

	sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID,
			(ALooper_callbackFunc)get_sensorevents, sensor_data);

	ASensorEventQueue_enableSensor(sensorEventQueue, magSensor);

	int minDelay = ASensor_getMinDelay(magSensor);
	//LOGI("min-delay: %d", minDelay);
	ASensorEventQueue_setEventRate(sensorEventQueue, magSensor, (1000L/SAMP_PER_SEC)*1000);

	while ((ident = ALooper_pollAll(-1, NULL, &events, NULL) >= 0)) {
		// If a sensor has data, process it now.
		if (ident == LOOPER_ID) {
			LOGI("magneticFieldStartup() - LOOPER!!!!!!!!");
			ASensorEvent event;
			while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0) {
				if (event.type == ASENSOR_TYPE_MAGNETIC_FIELD) {
					env->CallVoidMethod(updateHandler, mid);
					magneticfield_x = event.magnetic.x;
					magneticfield_y = event.magnetic.y;
					magneticfield_z = event.magnetic.z;
				}
			}
		} else {
			LOGI("magneticFieldStartup() - else!!!!!!!!!!!!!");
		}
	}
}
Esempio n. 26
0
Vector2i InputImpl::getMousePosition()
{
    ALooper_pollAll(0, NULL, NULL, NULL);

    priv::ActivityStates* states = priv::getActivity(NULL);
    Lock lock(states->mutex);

    return states->mousePosition;
}
Esempio n. 27
0
bool InputImpl::isTouchDown(unsigned int finger)
{
    ALooper_pollAll(0, NULL, NULL, NULL);

    priv::ActivityStates* states = priv::getActivity(NULL);
    Lock lock(states->mutex);

    return states->touchEvents.find(finger) != states->touchEvents.end();
}
Esempio n. 28
0
Vector2i InputImpl::getTouchPosition(unsigned int finger)
{
    ALooper_pollAll(0, NULL, NULL, NULL);

    priv::ActivityStates* states = priv::getActivity(NULL);
    Lock lock(states->mutex);

    return states->touchEvents.find(finger)->second;
}
Esempio n. 29
0
		ReturnValue AndroidEventLoop::Run(ActivityHandler* pActivityHandler)
		{
			int32_t result;
			int32_t events;
			android_poll_source* source;

			// Makes sure native glue is not stripped by the linker.
			app_dummy();
			m_pActivityHandler = pActivityHandler;

			// Global step loop.
			LOGI("Starting event loop");
			while (true)
			{
				Global::pContext->pTimeService->Update();
				Global::pContext->pInputService->Update();

				// Event processing loop.
				while ((result = ALooper_pollAll(m_enabled ? 0 : -1, NULL, &events, (void**) &source)) >= 0)
				{
					// An event has to be processed.
					if (source != NULL)
					{
						source->process(Global::pAndroidApp, source);
					}
					// Application is getting destroyed.
					if (Global::pAndroidApp->destroyRequested)
					{
						LOGI("Exiting event loop");
						return RETURN_VALUE_OK;
					}
				}

				//LOGD("m_enabled = %d",m_enabled);
				//LOGD("m_quit = %d", m_quit);
				//LOGD("context bound? = %d", m_window.IsContextBound());

				// Steps the application.
				if ((m_enabled) && (!m_quit) && (m_window.IsContextBound()))
				{
					//LOGD("TESTING");
					if (m_pActivityHandler->onStep() != RETURN_VALUE_OK)
					{
						m_quit = true;
						ANativeActivity_finish(Global::pAndroidApp->activity);
					}

					if(m_window.SwapBuffers() != RETURN_VALUE_OK)
					{
						m_quit = true;
						ANativeActivity_finish(Global::pAndroidApp->activity);
					}
				}
			}
			return RETURN_VALUE_OK;
		}
/**
 * This is the main entry point of a native application that is using
 * android_native_app_glue.  It runs in its own thread, with its own
 * event loop for receiving input events and doing other things.
 */
void android_main( android_app* state )
{
    app_dummy();

    g_engine.SetState( state );

    //Init helper functions
    ndk_helper::JNIHelper::GetInstance()->Init( state->activity, HELPER_CLASS_NAME );

    state->userData = &g_engine;
    state->onAppCmd = Engine::HandleCmd;
    state->onInputEvent = Engine::HandleInput;

#ifdef USE_NDK_PROFILER
    monstartup("libMoreTeapotsNativeActivity.so");
#endif

    // Prepare to monitor accelerometer
    g_engine.InitSensors();

    // loop waiting for stuff to do.
    while( 1 )
    {
        // Read all pending events.
        int id;
        int events;
        android_poll_source* source;

        // If not animating, we will block forever waiting for events.
        // If animating, we loop until all events are read, then continue
        // to draw the next frame of animation.
        while( (id = ALooper_pollAll( g_engine.IsReady() ? 0 : -1, NULL, &events, (void**) &source ))
                >= 0 )
        {
            // Process this event.
            if( source != NULL )
                source->process( state, source );

            g_engine.ProcessSensors( id );

            // Check if we are exiting.
            if( state->destroyRequested != 0 )
            {
                g_engine.TermDisplay();
                return;
            }
        }

        if( g_engine.IsReady() )
        {
            // Drawing is throttled to the screen update rate, so there
            // is no need to do timing here.
            g_engine.DrawFrame();
        }
    }
}