Example #1
0
void Widget::FocusNavigationController::removeKeyboardEventListener()
{
    if (nullptr != _keyboardListener)
    {
        EventDispatcher* dispatcher = Director::getInstance()->getEventDispatcher();
        dispatcher->removeEventListener(_keyboardListener);
        _keyboardListener = nullptr;
    }
}
int EventDispatcherBinder::removeEventListener(lua_State* L)
{
	StackChecker checker(L, "EventDispatcherBinder::removeEventListener", 0);

	Binder binder(L);
	EventDispatcher* eventDispatcher = static_cast<EventDispatcher*>(binder.getInstance("EventDispatcher"));

	luaL_checktype(L, 2, LUA_TSTRING);
	luaL_checktype(L, 3, LUA_TFUNCTION);

	bool hasData = lua_gettop(L) >= 4;

	createEventsTable(L, 1);	// create __events table if it's not created

	EventBinderMap& map = getOrCreateEventBinderMap(eventDispatcher);

	const char* event = lua_tostring(L, 2);
	int eventid = StringId::instance().id(event);

	const std::vector<CppLuaBridge*>& bridges = map[eventid]; 

	lua_getfield(L, 1, "__events");

	// check if the event is already registered
	CppLuaBridge* bridge = 0;
	for (std::size_t i = 0; i < bridges.size(); ++i)
	{
		lua_pushlightuserdata(L, bridges[i]);
		lua_rawget(L, -2);	// we get the event check closure
		if (hasData == false)
		{
			lua_pushvalue(L, 3);	// function
			lua_call(L, 1, 1);
		}
		else
		{
			lua_pushvalue(L, 3);	// function
			lua_pushvalue(L, 4);	// data
			lua_call(L, 2, 1);
		}

		if (lua_toboolean(L, -1))
		{
			bridge = bridges[i];
			lua_pop(L, 1);
			break;
		}
		else
			lua_pop(L, 1);
	}

	if (bridge == 0)	// event is not registered
	{
		lua_pop(L, 1);		// pop __events
		return 0;
	}

	luaL_rawgetptr(L, LUA_REGISTRYINDEX, &key_eventClosures);
	lua_pushlightuserdata(L, bridge);	// key=bridge
	lua_pushnil(L);						// value=nil
	lua_rawset(L, -3);					// envtable["eventClosures"][bridge] = nil
	lua_pop(L, 1);						// pop envtable["eventClosures"]

	lua_pushlightuserdata(L, bridge);	// key=bridge
	lua_pushnil(L);						// value = nil
	lua_settable(L, -3);				// __events[bridge] = nil

	eventDispatcher->removeEventListener(LuaEvent::Type(event), bridge, &CppLuaBridge::luaEvent);

	map.remove(eventid, bridge);
		
	lua_pop(L, 1);		// pop __events

	return 0;
}