/* you must be inside a m_mutex lock to invoke this! */ static bool scanForEvents(NVEventQueue* q) { DEBUG("scanForEvents"); for(int32_t i = 0; i < q->m_waitEventTypeCount; ++i) DEBUG(" event %s", NVEventGetEventStr((NVEventType)q->m_waitEventTypes[i])); // scan events in our queue, return true if found and // set ev if it's not null for(int32_t i = q->m_headIndex; i != q->m_nextInsertIndex; i = NVNextWrapped(i)) { const NVEvent* event = &q->m_events[i]; DEBUG("examining event type [%d]: %s", i, NVEventGetEventStr(event->m_type)); if (isEventType(q, event)) { DEBUG("event matched"); return true; } } DEBUG("event not matched"); return false; }
int32_t NVEventAppMain(int32_t argc, char** argv) { s_glesLoaded = false; bool isAppInBackground = true; NVDEBUG("Application entering main loop"); while (NVEventStatusIsRunning()) { const NVEvent* ev = NULL; while (NVEventStatusIsRunning() && (ev = NVEventGetNextEvent(GetEventQueueTimeout(isAppInBackground)))) { switch (ev->m_type) { case NV_EVENT_KEY: NVDEBUG( "Key event: 0x%02x %s", ev->m_data.m_key.m_code, (ev->m_data.m_key.m_action == NV_KEYACTION_DOWN) ? "down" : "up"); if ((ev->m_data.m_key.m_code == NV_KEYCODE_BACK)) { renderFrame(false); NVEventDoneWithEvent(true); } else { NVEventDoneWithEvent(false); } ev = NULL; break; case NV_EVENT_CHAR: NVDEBUG("Char event: 0x%02x", ev->m_data.m_char.m_unichar); ev = NULL; NVEventDoneWithEvent(false); break; case NV_EVENT_LONG_CLICK: break; case NV_EVENT_TOUCH: { switch (ev->m_data.m_touch.m_action) { case NV_TOUCHACTION_DOWN: g_framework->Move(0, ev->m_data.m_touch.m_x, ev->m_data.m_touch.m_y); break; case NV_TOUCHACTION_MOVE: g_framework->Move(1, ev->m_data.m_touch.m_x, ev->m_data.m_touch.m_y); break; case NV_TOUCHACTION_UP: g_framework->Move(2, ev->m_data.m_touch.m_x, ev->m_data.m_touch.m_y); break; } } break; case NV_EVENT_MULTITOUCH: { int maskOnly = (ev->m_data.m_multi.m_action & NV_MULTITOUCH_POINTER_MASK) >> (NV_MULTITOUCH_POINTER_SHIFT); int action = ev->m_data.m_multi.m_action & NV_MULTITOUCH_ACTION_MASK; g_framework->Touch(action, maskOnly, ev->m_data.m_multi.m_x1, ev->m_data.m_multi.m_y1, ev->m_data.m_multi.m_x2, ev->m_data.m_multi.m_y2); } break; case NV_EVENT_SURFACE_CREATED: case NV_EVENT_SURFACE_SIZE: s_winWidth = ev->m_data.m_size.m_w; s_winHeight = ev->m_data.m_size.m_h; s_densityDpi = ev->m_data.m_size.m_density; g_framework->Resize(s_winWidth, s_winHeight); g_framework->NativeFramework()->Invalidate(true); NVDEBUG( "Surface create/resize event: %d x %d", s_winWidth, s_winHeight); break; case NV_EVENT_SURFACE_DESTROYED: NVDEBUG("Surface destroyed event"); NVEventDestroySurfaceEGL(); break; case NV_EVENT_FOCUS_LOST: NVDEBUG("Focus lost event"); renderFrame(false); break; case NV_EVENT_PAUSE: NVDEBUG("Pause event"); renderFrame(false); break; case NV_EVENT_STOP: NVDEBUG("Stop event"); // As per Google's recommendation, we release GLES resources here ShutdownGLESResources(); isAppInBackground = true; break; case NV_EVENT_QUIT: NVDEBUG("Quit event"); break; case NV_EVENT_START: case NV_EVENT_RESTART: NVDEBUG("Start/restart event: %s", NVEventGetEventStr(ev->m_type)); isAppInBackground = false; break; case NV_EVENT_ACCEL: case NV_EVENT_RESUME: case NV_EVENT_FOCUS_GAINED: NVDEBUG("%s event: no specific app action", NVEventGetEventStr(ev->m_type)); break; case NV_EVENT_MWM: { typedef function<void ()> FnT; FnT * pFn = reinterpret_cast<FnT *>(ev->m_data.m_mwm.m_pFn); (*pFn)(); delete pFn; break; } default: NVDEBUG("UNKNOWN event"); break; }; // if we do not NULL out the event, then we return that // we handled it by default if (ev) NVEventDoneWithEvent(true); } // Do not bother to initialize _any_ of EGL, much less go ahead // and render to the screen unless we have all we need to go // ahead and do our thing. In many cases, // devices will bring us part-way up and then take us down. // So, before we bother to init EGL (much less the rendering // surface, check that: // - we are focused // - we have a rendering surface // - the surface size is not 0x0 // - we are resumed, not paused if (NVEventStatusIsInteractable()) { // This will try to set up EGL if it isn't set up // When we first set up EGL completely, we also load our GLES resources // If these are already set up or we succeed at setting them all up now, then // we go ahead and render. renderFrame(true); } } NVDEBUG("cleanup!!!"); NVEventCleanupEGL(); return 0; }