Exemple #1
0
/**
 * @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();
}
Exemple #2
0
/**
 * @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();
}
Exemple #3
0
/**
 * \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);
}
Exemple #4
0
/*
 * 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;
}