Example #1
0
// program setup
void setup() {
    Serial.begin(115200);
    pinSetup();
    sensorSetup();
    I2CSetup();
    USBsetup();
    driveSetup();
    disp.addEventListener(Events::EV_TIME_1000, timeHandler1000);
    //disp.addEventListener(Events::EV_TIME_1000, usbSoftwareTestHandler);
    disp.addEventListener(Events::EV_TIME_1000, IRSensorHandler);
    //disp.addEventListener(Events::EV_TIME_1000, I2CSensorDataHandler);
    disp.addEventListener(Events::EV_TIME_500, timeHandler500);
    //disp.addEventListener(Events::EV_TIME_100, timeHandler100);
    //disp.addEventListener(Events::EV_ANALOG0, analogHandler);
    disp.addEventListener(Events::EV_SERIAL, USBReadHandler);
}
int EventDispatcherBinder::addEventListener(lua_State* L)
{
	StackChecker checker(L, "EventDispatcherBinder::addEventListener", 0);

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

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

    bool hasData = !lua_isnoneornil(L, 4);

	createEventsTable(L, 1);	// create self.__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");		// key is CppLuaBridge*, value is 'event check closure'

	// check if the event is already registered
	bool isFound = false;
	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))
		{
			lua_pop(L, 1);
			isFound = true;
			break;
		}
		else
			lua_pop(L, 1);
	}

	if (isFound == true)
	{
		lua_pop(L, 1);		// pop __events, leave stack as it is
		return 0;
	}

    LuaApplication *application = (LuaApplication*)luaL_getdata(L);
    lua_State *mainL = application->getLuaState();

    CppLuaBridge* bridge = new CppLuaBridge(mainL);

	// create event closure
	luaL_rawgetptr(L, LUA_REGISTRYINDEX, &key_eventClosures);
	lua_pushlightuserdata(L, bridge);	// key=bridge
	if (hasData == false)				// value=closure
	{
        // self ve function'in eventClosure'in icine upvalue olarak koyulmasi garbage collect edilmesini engelliyor
        // bu yuzden {self, function} seklinde bi weak table yaratip ilk upvalue olarak onu set ediyoruz
		luaL_newweaktable(L);

        lua_pushvalue(L, 1);	// self
		lua_rawseti(L, -2, 1);

		lua_pushvalue(L, 3);	// function
        lua_rawseti(L, -2, 2);

        lua_pushcclosure(L, &eventClosure, 1);
	}
	else
	{
        // self, function ve data'nin eventClosure'in icine upvalue olarak koyulmasi garbage collect edilmesini engelliyor
        // bu yuzden {self, function, data} seklinde bi weak table yaratip ilk upvalue olarak onu set ediyoruz
		luaL_newweaktable(L);

        lua_pushvalue(L, 1);	// self
		lua_rawseti(L, -2, 1);

        lua_pushvalue(L, 3);	// function
        lua_rawseti(L, -2, 2);

        lua_pushvalue(L, 4);	// data
        lua_rawseti(L, -2, 3);

        lua_pushcclosure(L, &eventClosureWithData, 1);
	}
	lua_rawset(L, -3);					// envtable["eventClosures"][bridge] = closure
	lua_pop(L, 1);						// pop envtable["eventClosures"]

	// create event check closure
	lua_pushlightuserdata(L, bridge);
	if (hasData == false)
	{
		lua_pushvalue(L, 3);	// function
		lua_pushcclosure(L, &eventCheckClosure, 1);
	}
	else
	{
		lua_pushvalue(L, 3);	// function
		lua_pushvalue(L, 4);	// data
		lua_pushcclosure(L, &eventCheckClosureWithData, 2);
	}
	lua_rawset(L, -3);
	
	map.push_back(eventid, bridge);

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

	lua_pop(L, 1);			// pop __events, leave stack as it is

	return 0;
}