/** * @brief Registers a timer into a context (table or a userdata). * @param timer A timer. * @param context_index Index of the table or userdata in the stack. * @param callback_index Index of the function to call when the timer finishes. */ void LuaContext::add_timer(Timer* timer, int context_index, int callback_index) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLua** userdata = static_cast<ExportableToLua**>( lua_touserdata(l, context_index)); context = *userdata; } else { context = lua_topointer(l, context_index); } lua_pushvalue(l, callback_index); int callback_ref = create_ref(); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != NULL) { // We are during a game: depending on the timer's context, // when the map is suspended, also suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { timer->set_suspended_with_map(true); } } timer->increment_refcount(); }
/** * @brief Registers a timer into a context (table or a userdata). * @param timer A timer. * @param context_index Index of the table or userdata in the stack. * @param callback_index Index of the function to call when the timer finishes. */ void LuaContext::add_timer(Timer* timer, int context_index, int callback_index) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLua** userdata = static_cast<ExportableToLua**>( lua_touserdata(l, context_index)); context = *userdata; } else { context = lua_topointer(l, context_index); } lua_pushvalue(l, callback_index); int callback_ref = create_ref(); #ifndef NDEBUG // Sanity check: check the uniqueness of the ref. std::map<Timer*, LuaTimerData>::iterator it; for (it = timers.begin(); it != timers.end(); ++it) { if (it->second.callback_ref == callback_ref) { Debug::die(StringConcat() << "Callback ref " << callback_ref << " is already used by a timer (duplicate luaL_unref?)"); } } #endif Debug::check_assertion(timers.find(timer) == timers.end(), "Duplicate timer in the system"); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != NULL) { // We are during a game: depending on the timer's context, // suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { // By default, we want the timer to be automatically suspended when a // camera movement, a dialog or the pause menu starts. timer->set_suspended_with_map(true); // But in the initial state, we override that rule. // We initially suspend the timer only during a dialog. // In particular, we don't want to suspend timers created during a // camera movement. // This would be very painful for users. bool initially_suspended = game->is_dialog_enabled(); timer->set_suspended(initially_suspended); } } timer->increment_refcount(); }
/** * \brief Registers a timer into a context (table or a userdata). * \param timer A timer. * \param context_index Index of the table or userdata in the stack. * \param callback_index Index of the function to call when the timer finishes. */ void LuaContext::add_timer(Timer* timer, int context_index, int callback_index) { const void* context; if (lua_type(l, context_index) == LUA_TUSERDATA) { ExportableToLua** userdata = static_cast<ExportableToLua**>( lua_touserdata(l, context_index)); context = *userdata; } else { context = lua_topointer(l, context_index); } lua_pushvalue(l, callback_index); int callback_ref = create_ref(); #ifndef NDEBUG // Sanity check: check the uniqueness of the ref. std::map<Timer*, LuaTimerData>::iterator it; for (it = timers.begin(); it != timers.end(); ++it) { if (it->second.callback_ref == callback_ref) { std::ostringstream oss; oss << "Callback ref " << callback_ref << " is already used by a timer (duplicate luaL_unref?)"; Debug::die(oss.str()); } } #endif Debug::check_assertion(timers.find(timer) == timers.end(), "Duplicate timer in the system"); timers[timer].callback_ref = callback_ref; timers[timer].context = context; Game* game = main_loop.get_game(); if (game != NULL) { // We are during a game: depending on the timer's context, // suspend the timer or not. if (is_map(l, context_index) || is_entity(l, context_index) || is_item(l, context_index)) { bool initially_suspended = false; // By default, we want the timer to be automatically suspended when a // camera movement, a dialog or the pause menu starts. if (!is_entity(l, context_index)) { // The timer normally get suspended/unsuspend with the map. timer->set_suspended_with_map(true); // But in the initial state, we override that rule. // We initially suspend the timer only during a dialog. // In particular, we don't want to suspend timers created during a // camera movement. // This would be very painful for users. initially_suspended = game->is_dialog_enabled(); } else { // Entities are more complex: they also get suspended when disabled // and when far from the camera. Therefore, they don't simply follow // the map suspended state. const MapEntity& entity = check_entity(l, context_index); initially_suspended = entity.is_suspended() || !entity.is_enabled(); } timer->set_suspended(initially_suspended); } } RefCountable::ref(timer); }
/* * Main test entry. */ int resolve_test(void) { pj_pool_t *pool; pj_dns_resolver *resv; pj_str_t nameserver; pj_uint16_t port = 5353; pj_status_t status; pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000); status = pjsip_endpt_create_resolver(endpt, &resv); nameserver = pj_str("192.168.0.106"); pj_dns_resolver_set_ns(resv, 1, &nameserver, &port); pjsip_endpt_set_resolver(endpt, resv); add_dns_entries(resv); /* These all should be resolved as IP addresses (DNS A query) */ { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060); status = test_resolve("IP address without transport and port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 0, &ref); if (status != PJ_SUCCESS) return -100; } { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_UDP, "1.1.1.1", 5060); status = test_resolve("IP address with explicit port", pool, PJSIP_TRANSPORT_UNSPECIFIED, "1.1.1.1", 5060, &ref); if (status != PJ_SUCCESS) return -110; } { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_TCP, "1.1.1.1", 5060); status = test_resolve("IP address without port (TCP)", pool, PJSIP_TRANSPORT_TCP,"1.1.1.1", 0, &ref); if (status != PJ_SUCCESS) return -120; } { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_TLS, "1.1.1.1", 5061); status = test_resolve("IP address without port (TLS)", pool, PJSIP_TRANSPORT_TLS, "1.1.1.1", 0, &ref); if (status != PJ_SUCCESS) return -130; } /* This should be resolved as DNS A record (because port is present) */ { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_UDP, "5.5.5.5", 5060); status = test_resolve("domain name with port should resolve to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "example.com", 5060, &ref); if (status != PJ_SUCCESS) return -140; } /* This will fail to be resolved as SRV, resolver should fallback to * resolving to A record. */ { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_UDP, "2.2.2.2", 5060); status = test_resolve("failure with SRV fallback to A record", pool, PJSIP_TRANSPORT_UNSPECIFIED, "sip02.example.com", 0, &ref); if (status != PJ_SUCCESS) return -150; } /* Same as above, but explicitly for TLS. */ { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_TLS, "2.2.2.2", 5061); status = test_resolve("failure with SRV fallback to A record (for TLS)", pool, PJSIP_TRANSPORT_TLS, "sip02.example.com", 0, &ref); if (status != PJ_SUCCESS) return -150; } /* Standard DNS SRV followed by A recolution */ { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_UDP, "6.6.6.6", 50060); status = test_resolve("standard SRV resolution", pool, PJSIP_TRANSPORT_UNSPECIFIED, "domain.com", 0, &ref); if (status != PJ_SUCCESS) return -155; } /* Standard DNS SRV followed by A recolution (explicit transport) */ { pjsip_server_addresses ref; create_ref(&ref, PJSIP_TRANSPORT_TCP, "6.6.6.6", 50060); add_ref(&ref, PJSIP_TRANSPORT_TCP, "7.7.7.7", 50060); status = test_resolve("standard SRV resolution with explicit transport (TCP)", pool, PJSIP_TRANSPORT_TCP, "domain.com", 0, &ref); if (status != PJ_SUCCESS) return -160; } /* Round robin/load balance test */ if (round_robin_test(pool) != 0) return -170; /* Timeout test */ { status = test_resolve("timeout test", pool, PJSIP_TRANSPORT_UNSPECIFIED, "an.invalid.address", 0, NULL); if (status == PJ_SUCCESS) return -150; } return 0; }