/*
 * Function:    Constructor
 */
Server::Server(int port) {
	cout << "Running program as server" << endl;
    this->m_nListenPort = port;
    this->m_nLatestIndex = 0;
    this->m_nQueIx = 0;

    // initalize nodeList and its tracker
	for(int i=0; i<10; i++)
	{
		m_nodeList[i].id = i+1;
		m_nodeList[i].state=INACTIVE;
		m_nodeList[i].isServer=false;
	}
    updateIpAddress();
    printf("server IP: %s \n", m_ipAddress);

    // initalize server specific parameters
    FD_ZERO(&m_masterSet);
    FD_ZERO(&m_readSet);
    memset(&m_srvAddr, 0, sizeof(m_srvAddr));

    // starting event handler
    eventHandler();
}
/**
 * Fires a USB event. This calls the callback function set by setEventHandler.
 *
 * @param device the device the events relates to.
 * @param event event type (i.e. connected, disconnected)
 */
void USB::fireEvent(usb_device * device, usb_eventType event)
{
    eventHandler(device, event);
}
Exemple #3
0
void X11AppContext::processEvent(const x11::GenericEvent& ev)
{
	//macro for easier event creation for registered EventHandler
	#define EventHandlerEvent(T, W) \
		auto handler = eventHandler(W); \
		if(!handler) return; \
		auto event = T(handler);

	auto dispatch = [&](Event& event){
		if(event.handler) event.handler->handleEvent(event);
	};

	auto responseType = ev.response_type & ~0x80;
    switch(responseType)
    {

    case XCB_MOTION_NOTIFY:
    {
		auto& motion = reinterpret_cast<const xcb_motion_notify_event_t&>(ev);
		auto pos = nytl::Vec2i(motion.event_x, motion.event_y);
		mouseContext_->move(pos);

		EventHandlerEvent(MouseMoveEvent, motion.event);
        event.position = pos;
        event.screenPosition = nytl::Vec2i(motion.root_x, motion.root_y);

		dispatch(event);
		break;
    }

    case XCB_EXPOSE:
    {
		auto& expose = reinterpret_cast<const xcb_expose_event_t&>(ev);
        if(expose.count == 0)
		{
			EventHandlerEvent(DrawEvent, expose.window);
			dispatch(event);
		}

		break;
    }

    case XCB_MAP_NOTIFY:
    {
		auto& map = reinterpret_cast<const xcb_map_notify_event_t&>(ev);
		EventHandlerEvent(DrawEvent, map.window);
		dispatch(event);
		break;
    }

    case XCB_BUTTON_PRESS:
    {
		auto& button = reinterpret_cast<const xcb_button_press_event_t&>(ev);

		int scroll = 0;
		if(button.detail == 4) scroll = 1;
		else if(button.detail == 5) scroll = -1;

		if(scroll)
		{
			EventHandlerEvent(MouseWheelEvent, button.event);
			event.data = std::make_unique<X11EventData>(ev);
			event.value = scroll;

			mouseContext_->onWheel(*mouseContext_, scroll);
			dispatch(event);

			break;
		}

		auto b = x11ToButton(button.detail);
		mouseContext_->mouseButton(b, true);

		EventHandlerEvent(MouseButtonEvent, button.event);
		event.data = std::make_unique<X11EventData>(ev);
        event.button = b;
        event.position = nytl::Vec2i(button.event_x, button.event_y);
		event.pressed = true;

		dispatch(event);
		break;
    }

    case XCB_BUTTON_RELEASE:
    {
		auto& button = reinterpret_cast<const xcb_button_release_event_t&>(ev);
		if(button.detail == 4 || button.detail == 5) break;

		auto b = x11ToButton(button.detail);
		mouseContext_->mouseButton(b, false);

		EventHandlerEvent(MouseButtonEvent, button.event);
		event.data = std::make_unique<X11EventData>(ev);
        event.button = b;
        event.position = nytl::Vec2i(button.event_x, button.event_y);
		event.pressed = false;

		dispatch(event);
		break;
    }

    case XCB_ENTER_NOTIFY:
    {
		auto& enter = reinterpret_cast<const xcb_enter_notify_event_t&>(ev);
		auto wc = windowContext(enter.event);
		mouseContext_->over(wc);

		EventHandlerEvent(MouseCrossEvent, enter.event);
        event.position = nytl::Vec2i(enter.event_x, enter.event_y);
		event.entered = true;
		dispatch(event);

		break;
    }

    case XCB_LEAVE_NOTIFY:
    {
		auto& leave = reinterpret_cast<const xcb_enter_notify_event_t&>(ev);
		auto wc = windowContext(leave.event);
		if(mouseContext_->over() == wc) mouseContext_->over(nullptr);

		EventHandlerEvent(MouseCrossEvent, leave.event);
        event.position = nytl::Vec2i(leave.event_x, leave.event_y);
		event.entered = false;
		dispatch(event);

		break;
    }

    case XCB_FOCUS_IN:
    {
		auto& focus = reinterpret_cast<const xcb_focus_in_event_t&>(ev);
		auto wc = windowContext(focus.event);
		keyboardContext_->focus(wc);

		EventHandlerEvent(FocusEvent, focus.event);
		event.focus = true;
		dispatch(event);

		break;
    }

    case XCB_FOCUS_OUT:
    {
		auto& focus = reinterpret_cast<const xcb_focus_in_event_t&>(ev);
		auto wc = windowContext(focus.event);
		if(keyboardContext_->focus() == wc)keyboardContext_->focus(nullptr);

		EventHandlerEvent(FocusEvent, focus.event);
		event.focus = false;
		dispatch(event);

		break;
    }

    case XCB_KEY_PRESS:
    {
		auto& key = reinterpret_cast<const xcb_key_press_event_t&>(ev);

		EventHandlerEvent(KeyEvent, key.event);
		event.pressed = true;
		if(!keyboardContext_->keyEvent(key.detail, event)) bell();
		dispatch(event);

		break;
    }

    case XCB_KEY_RELEASE:
    {
		auto& key = reinterpret_cast<const xcb_key_press_event_t&>(ev);

		EventHandlerEvent(KeyEvent, key.event);
		event.pressed = false;
		if(!keyboardContext_->keyEvent(key.detail, event)) bell();
		dispatch(event);

		break;
    }

	case XCB_REPARENT_NOTIFY:
	{
		auto& reparent = reinterpret_cast<const xcb_reparent_notify_event_t&>(ev);
		auto wc = windowContext(reparent.window);
		if(wc) wc->reparentEvent();

		break;
	}

    case XCB_CONFIGURE_NOTIFY:
	{
		auto& configure = reinterpret_cast<const xcb_configure_notify_event_t&>(ev);

        //todo: something about window state
        auto nsize = nytl::Vec2ui(configure.width, configure.height);
        // auto npos = nytl::Vec2i(configure.x, configure.y); //positionEvent

		auto wc = windowContext(configure.window);
		if(wc) wc->sizeEvent(nsize);

        if(!eventHandler(configure.window)) break;

		/* TODO XXX !important
        if(any(windowContext(configure.window)->window().size() != nsize)) //sizeEvent
		{
			EventHandlerEvent(SizeEvent, configure.window);
			event->size = nsize;
			event->change = 0;
			dispatcher.dispatch(std::move(event));

			auto wc = windowContext(configure.window);
			if(!wc) return true;
			auto wevent = std::make_unique<SizeEvent>(wc);
			wevent->size = nsize;
			wevent->change = 0;
			dispatcher.dispatch(std::move(wevent));
		}

        if(any(windowContext(configure.window)->window().position() != npos))
		{
			EventHandlerEvent(PositionEvent, configure.window);
			event->position = npos;
			event->change = 0;
			dispatcher.dispatch(std::move(event));
		}
		*/

		break;
    }

    case XCB_CLIENT_MESSAGE:
    {
		auto& client = reinterpret_cast<const xcb_client_message_event_t&>(ev);
		auto protocol = static_cast<unsigned int>(client.data.data32[0]);
        if(protocol == atoms().wmDeleteWindow)
        {
			EventHandlerEvent(CloseEvent, client.window);
			dispatch(event);
        }

		break;
	}

	case 0u:
	{
		//an error occurred!
		int code = reinterpret_cast<const xcb_generic_error_t&>(ev).error_code;
		auto errorMsg = x11::errorMessage(xDisplay(), code);
		warning("ny::X11AppContext::processEvent: retrieved error code ", code, ", ", errorMsg);

		break;
	}

	default:
	{
		//check for xkb event
		if(ev.response_type == keyboardContext_->xkbEventType())
			keyboardContext_->processXkbEvent(ev);

		// May be needed for gl to work correctly... (TODO: test)
		// XLockDisplay(xDisplay_);
	    // auto proc = XESetWireToEvent(xDisplay_, ev.response_type & ~0x80, nullptr);
	    // if(proc)
		// {
	    //     XESetWireToEvent(xDisplay_, ev.response_type & ~0x80, proc);
	    //     XEvent dummy;
	    //     ev.sequence = LastKnownRequestProcessed(xDisplay_);
	    //     if(proc(xDisplay_, &dummy, (xEvent*) &ev)) //not handled
		// 	{
		// 		//TODO
		// 	}
	    // }
		//
		// XUnlockDisplay(xDisplay_);
	}

	}

	#undef EventHandlerEvent
}
Exemple #4
0
Common::Error MadsEngine::run() {
	// Set up the graphics mode
	initGraphics(320, 200, false);

	// Necessary pre-initialisation
	_resourceManager = new MADSResourceManager(this);

	// Set up needed common functionality
	MadsM4Engine::run();

	_palette->setMadsSystemPalette();

	_mouse->init("cursor.ss", NULL);
	_mouse->setCursorNum(0);

	// Load MADS data files
	MadsGlobals *globs = (MadsGlobals *)_globals;
	globs->loadMadsVocab();			// vocab.dat
	globs->loadQuotes();			// quotes.dat
	globs->loadMadsMessagesInfo();	// messages.dat
	globs->loadMadsObjects();

	// Setup globals
	globs->_config.easyMouse = true;
	globs->_config.invObjectsStill = false;
	globs->_config.textWindowStill = false;
	globs->_config.storyMode = 1;	// Naughty
	globs->_config.screenFades = 0;

	// Test code to dump all messages to the console
	//for (int i = 0; i < _globals->getMessagesSize(); i++)
	//debugCN(kDebugCore, "%s\n----------\n", _globals->loadMessage(i));

	if (getGameType() == GType_RexNebular) {
		MadsGameLogic::initialiseGlobals();

		_scene = NULL;
		loadMenu(MAIN_MENU);
	} else {
		// Test code
		_scene = new MadsScene(this);

		startScene(FIRST_SCENE);
		RGBList *_bgPalData;
		_scene->loadBackground(FIRST_SCENE, &_bgPalData);
		_palette->addRange(_bgPalData);
		_scene->translate(_bgPalData);

		_scene->show();

		_font->setFont(FONT_MAIN_MADS);
		_font->current()->setColors(2, 1, 3);
		_font->current()->writeString(_scene->getBackgroundSurface(), "Testing the M4/MADS ScummVM engine", 5, 160, 310, 2);
		_font->current()->writeString(_scene->getBackgroundSurface(), "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 5, 180, 310, 2);

		if (getGameType() == GType_DragonSphere) {
			//_scene->showMADSV2TextBox("Test", 10, 10, NULL);
		}

		_mouse->cursorOn();
	}

	_viewManager->systemHotkeys().add(Common::KEYCODE_ESCAPE, &escapeHotkeyHandler);
	_viewManager->systemHotkeys().add(Common::KEYCODE_KP_MULTIPLY, &textviewHotkeyHandler);

	uint32 nextFrame = g_system->getMillis();
	while (!_events->quitFlag) {
		eventHandler();

		if (g_system->getMillis() >= nextFrame) {
			nextFrame = g_system->getMillis() + GAME_FRAME_DELAY;
			++_currentTimer;

			// Call the updateState method of all views
			_viewManager->updateState();

			// Refresh the display
			_viewManager->refreshAll();
		}

		g_system->delayMillis(10);

		if (globals()->dialogType != DIALOG_NONE)
			showDialog();
	}

	return Common::kNoError;
}
Exemple #5
0
Common::Error M4Engine::run() {
	// Set up the graphics mode
	initGraphics(640, 480, true);

	// Necessary pre-initialisation
	_resourceManager = new M4ResourceManager(this);

	// Set up needed common functionality
	MadsM4Engine::run();

	// M4 specific initialisation
	_converse = new Converse(this);

	_scene = new M4Scene(this);
	_script->open("m4.dat");

#ifdef SCRIPT_TEST

#if 0
	ScriptFunction *func = _script->loadFunction("room_parser_142");
	_script->runFunction(func);
#endif

#if 1
	ScriptFunction *func = _script->loadFunction("room_daemon_951");
	for (int i = 1; i < 58; i++) {
		_vm->_kernel->trigger = i;
		_script->runFunction(func);
		debugCN(kDebugCore, "=================================\n");
	}
#endif

	return Common::kNoError;
#endif

	// Set up the inventory

	// Set up the game interface view
	//_interfaceView->inventoryAdd("Money", "", 55);	// Sample item

	if (getGameType() == GType_Burger) {
		for (int i = 0; i < ARRAYSIZE(burger_inventory); i++) {
			char* itemName = strdup(burger_inventory[i].name);
			_inventory->registerObject(itemName, burger_inventory[i].scene,
									   burger_inventory[i].icon);
			_inventory->addToBackpack(i);	// debug: this adds ALL objects to the player's backpack
		}
	}

	// Show intro

	if (getGameType() == GType_Burger) {
		_kernel->newRoom = TITLE_SCENE_BURGER;
	} else {
		_scene->getBackgroundSurface()->loadBackgroundRiddle("main menu");
		_ws->setBackgroundSurface(_scene->getBackgroundSurface());
	}

	_viewManager->addView(_scene);

	// Setup game wide hotkeys. Note that Orion Burger used F2/F3 for Save/Restore,
	// but for standardisation with most other games, F5/F7 are also mapped

	_viewManager->systemHotkeys().add(Common::KEYCODE_ESCAPE, &escapeHotkeyHandler);
	_viewManager->systemHotkeys().add(Common::KEYCODE_F2, &saveGameHotkeyHandler);
	_viewManager->systemHotkeys().add(Common::KEYCODE_F3, &loadGameHotkeyHandler);
	_viewManager->systemHotkeys().add(Common::KEYCODE_F5, &saveGameHotkeyHandler);
	_viewManager->systemHotkeys().add(Common::KEYCODE_F7, &loadGameHotkeyHandler);
	_viewManager->systemHotkeys().add(Common::KEYCODE_F9, &gameMenuHotkeyHandler);

	// Start playing Orion Burger intro music
	//_midi->playMusic("999intro", 255, false, -1, -1);

	// TODO: start playing intro animations

	// TODO: Master Lu

	// Test for mouse
	_mouse->init("cursor", NULL);
	_mouse->setCursorNum(0);
	_mouse->cursorOn();

	_ws->assets()->loadAsset("SHOW SCRIPT", NULL);
	_ws->assets()->loadAsset("STREAM SCRIPT", NULL);

#ifdef INTRO_TEST
	int curPart = 0;
	Machine *mach = NULL;
#endif

	_ws->setSurfaceView(_scene);

	uint32 nextFrame = g_system->getMillis();
	while (!_events->quitFlag) {

		// This should probably be moved to either Scene or Kernel
		if (_kernel->currentRoom != _kernel->newRoom) {

			_ws->clear();

			_kernel->currentSection = _kernel->newRoom / 100;
			_kernel->currentRoom = _kernel->newRoom;

			_scene->loadScene(_kernel->currentRoom);

			_ws->setBackgroundSurface(_scene->getBackgroundSurface());
			_ws->setInverseColorTable(scene()->getInverseColorTable());

			_kernel->loadSectionScriptFunctions();
			_kernel->loadRoomScriptFunctions();

			_kernel->roomInit();

			_scene->show();

#ifdef INTRO_TEST
			if (_kernel->currentRoom == 951) {
				curPart = 0;
				mach = _ws->streamSeries("PLANET X HILLTOP A", 1, 0x1000, 0);
			}
#endif

		}

		eventHandler();

		// Call the updateState method of all views
		_viewManager->updateState();

		// Handle frame updates
		if (g_system->getMillis() >= nextFrame) {
#ifdef INTRO_TEST
			// Orion Burger intro test (scene 951)
			// This is ugly and bad, machine is not deleted so there's a huge memory
			// leak too. But hey, we can see some of the intro!
			if (mach && mach->getState() == -1) {
				if (curPart == 0)
					mach = _ws->streamSeries("Planet X Low Ground Shot", 1, 0x1000, 0);
				else if (curPart == 1)
					mach = _ws->streamSeries("Planet X Hilltop B", 1, 0x1000, 0);
				else if (curPart == 2)
					mach = _ws->streamSeries("Space Station Panorama A", 1, 0x1000, 0);
				else if (curPart == 3)
					mach = _ws->streamSeries("Cargo Transfer Area A", 1, 0x1000, 0);
				else if (curPart == 4)
					mach = _ws->streamSeries("VP's Office A", 1, 0x1000, 0);
				else if (curPart == 5)
					mach = _ws->streamSeries("Hologram", 1, 0x1000, 0);
				else if (curPart == 6)
					mach = _ws->streamSeries("VP's Office B", 1, 0x1000, 0);
				else if (curPart == 7)
					mach = _ws->streamSeries("Cargo Transfer Area B", 1, 0x1000, 0);
				else if (curPart == 8)
					mach = _ws->streamSeries("Cargo Transfer Controls", 1, 0x1000, 0);
				else if (curPart == 9)
					mach = _ws->streamSeries("Space Station Panorama B", 1, 0x1000, 0);
				// This last scene is from the rolling demo
				//else if (curPart == 10)
				//	mach = _ws->streamSeries("Call To Action", 1, 0x1000, 0);
				curPart++;
			}
#endif
			_ws->update();
			_viewManager->refreshAll();
			nextFrame = g_system->getMillis();// + GAME_FRAME_DELAY;

			// TEST STUFF ONLY
			if (_player->commandReady) {
				_kernel->roomParser();
				_player->commandReady = false;
			}

		}

		g_system->delayMillis(10);
	}

	return Common::kNoError;
}
void app_testHandler100ms(void)
{
	static UINT8 u8_powerOnDelay = 5;
	static UINT8 u8_keyLongEnterCounter = 0;
	static UINT8 u8_keyEnterTimeCounter = 0;
	static UINT8 b_settingSaveFlag = FALSE;
	static UINT16 u16_agingTestTimeCounter = TIME_45_MIN;
	static BOOL b_agingTestFlag = 0;
	static UINT8 u8_keyTimeDelay = 0;
	static UINT8 u8_keyTempDelay = 0;
	UINT8 temp = hwa_ntcGetTemp();				//经过消抖的温度
	
	if(u8_keyTimeDelay)
	{
		u8_keyTimeDelay--;
	}
	if(u8_keyTempDelay)
	{
		u8_keyTempDelay--;
	}
	
	eventHandler();

	faultHandler(temp);
	
	switch(e_mode)
	{
		case MODE_FAULT:
			switch(e_ntcState)
			{
				case NTC_SHORT_CIRCUIT:
					drv_ledRequest(0xFF, 0xE1);
					break;
					
				case NTC_OPEN_CIRCUIT:
					drv_ledRequest(0xFF, 0xE2);
					break;
					
				default:
					e_mode = MODE_STANDBY;
					e_ntcState = NTC_NORMAL;
					break;
			}
			drv_scrRequest(SCR_OFF);
			break;
			
		case MODE_POWER_ON:
			if(u8_powerOnDelay)
			{
				u8_powerOnDelay--;
				if(u8_powerOnDelay == 0)
				{
					if(b_settingSaveFlag)
					{
						b_settingSaveFlag = FALSE;
						e_mode = MODE_AGING_TEST;
					}
					else
					{
						e_mode = MODE_STANDBY;
					}
				}
				else if(b_keyTimeSet && b_keyTempSet && !b_settingSaveFlag)
				{
					u8_powerOnDelay = 30;
					u8_ledDisBuff[0] = 0;	//O
					u8_ledDisBuff[1] = 1;	//1
					b_settingSaveFlag = TRUE;
				}
			}
			break;
			
		case MODE_STANDBY:
			drv_scrRequest(SCR_OFF);
			u8_ledDisBuff[0] = 0;	//O
			u8_ledDisBuff[1] = 15;	//F
			
			if(temp > 50)
			{
				drv_ledRequest(0xFF, 0xE3);
			}
			else if(e_keyEvent == KEY_EVENT_START)
			{
				drv_ledRequest(3, u8_setTemp);
				e_mode = MODE_WORK;
				e_workState = WORK_OFF;
				
				u8_setTime = s_System.Time;
				u8_workTime = s_System.Time;
				u16_workTimeCounter = 0;
			}
			else
			{
				drv_ledRequest(0, 0);
			}
			
			break;
			
		case MODE_WORK:
			u8_ledDisBuff[0] = temp/10;
			u8_ledDisBuff[1] = temp%10;

			if(temp > 50)
			{
				e_workState = WORK_OVER_TEMP;
			}
			switch(e_workState)
			{
				case WORK_OFF:
					drv_scrRequest(SCR_OFF);
					if(temp < u8_setTemp)
					{
						e_workState = WORK_FULL;
					}
					else
					{
						e_workState = WORK_VVVF_OFF;
					}
					break;
					
				case WORK_FULL:
					drv_scrRequest(SCR_FULL);
					if(temp >= u8_setTemp)
					{
						e_workState = WORK_VVVF_OFF;
					}
					break;
					
				case WORK_VVVF:
					drv_scrRequest(SCR_VVVF);
					if(temp <= u8_setTemp-2)
					{
						e_workState = WORK_FULL;
					}
					else if(temp >= u8_setTemp)
					{
						e_workState = WORK_VVVF_OFF;
					}
					break;
					
				case WORK_VVVF_OFF:
					drv_scrRequest(SCR_VVVF_OFF);
					if(temp < u8_setTemp)
					{
						e_workState = WORK_VVVF;
					}
					break;

				case WORK_OVER_TEMP:
					if(temp < 50)
					{
						drv_ledRequest(0, 0);
						e_mode = MODE_STANDBY;
					}
					else
					{
						drv_scrRequest(SCR_OFF);
						drv_ledRequest(0xFF, 0xE3);
					}
					break;
					
				default:
					e_workState = WORK_OFF;
					break;
			}
			
			if(e_workState != WORK_OVER_TEMP)
			{
				if(e_keyEvent == KEY_EVENT_START)
				{
					e_mode = MODE_STANDBY;
					drv_ledRequest(0, 0);
				}
				else if(e_keyEvent == KEY_EVENT_TIME_SET)
				{
					if(u8_keyTimeDelay)
					{
						u8_keyTimeDelay = 0;
						e_modeOld = e_mode;
						b_settingSaveFlag = TRUE;
						e_mode = MODE_TIME_SET;
					}
					else
					{
						u8_keyTimeDelay = 30;
						drv_ledRequest(3, SHENGXIAWORK_TIME);
					}
				}
				else if(e_keyEvent == KEY_EVENT_TEMP_SET)
				{
					if(u8_keyTempDelay)
					{
						u8_keyTempDelay = 0;
						e_modeOld = e_mode;
						b_settingSaveFlag = TRUE;
						e_mode = MODE_TEMP_SET;
					}
					else
					{
						u8_keyTempDelay = 30;
						drv_ledRequest(3, u8_setTemp);
					}
				}
			}
			
			if(++u16_workTimeCounter >= WORK_TIME)
			{
				e_mode = MODE_STANDBY;
			}
			
			break;
			
		case MODE_TIME_SET:
			if(e_keyEvent == KEY_EVENT_TIME_SET)
			{
				b_settingSaveFlag = TRUE;
			}
			else if(e_keyEvent == KEY_EVENT_TEMP_SET)		//时间设置时按温度保存当前时间
			{
				u8_keyLongEnterCounter = 0;
				u8_keyEnterTimeCounter = 0;
				e_mode = MODE_TEMP_SET;
				setTimeSave();
				drv_ledRequest(3, u8_setTemp);
			}
			else if(b_keyTimeSet)
			{
				if(u8_keyLongEnterCounter < 20)
				{
					u8_keyLongEnterCounter++;
				}
				else
				{
					if(u8_keyEnterTimeCounter < 5)
					{
						u8_keyEnterTimeCounter++;
					}
					else
					{
						u8_keyEnterTimeCounter = 0;
						b_settingSaveFlag = TRUE;
					}
				}
			}
			else
			{
				u8_keyLongEnterCounter = 0;
				u8_keyEnterTimeCounter = 0;
			}
			
			if(b_settingSaveFlag == TRUE)
			{
				b_settingSaveFlag = FALSE;
				u8_setTime+=5;
				if(u8_setTime > 90)
				{
					u8_setTime = 10;
				}
				drv_ledRequest(3, u8_setTime);
			}
			else if(drv_ledGetRequest() == 0)
			{
				drv_ledRequest(0, u8_setTime);
				setTimeSave();
				e_mode = e_modeOld;
			}
			else if(e_keyEvent == KEY_EVENT_START)
			{
				drv_ledRequest(0, u8_setTime);
				setTimeSave();
				e_mode = MODE_STANDBY;
			}
			
			break;
			
		case MODE_TEMP_SET:
			if(e_keyEvent == KEY_EVENT_TEMP_SET)
			{
				b_settingSaveFlag = TRUE;
			}
			else if(e_keyEvent == KEY_EVENT_TIME_SET)		//温度设置时按时间保存当前温度
			{
				u8_keyLongEnterCounter = 0;
				u8_keyEnterTimeCounter = 0;
				e_mode = MODE_TIME_SET;
				setTempSave();
				drv_ledRequest(3, u8_setTime);
			}
			else if(b_keyTempSet)
			{
				if(u8_keyLongEnterCounter < 20)
				{
					u8_keyLongEnterCounter++;
				}
				else
				{
					if(u8_keyEnterTimeCounter < 5)
					{
						u8_keyEnterTimeCounter++;
					}
					else
					{
						u8_keyEnterTimeCounter = 0;
						b_settingSaveFlag = TRUE;
					}
				}
			}
			else
			{
				u8_keyLongEnterCounter = 0;
				u8_keyEnterTimeCounter = 0;
			}
			
			if(b_settingSaveFlag == TRUE)
			{
				b_settingSaveFlag = FALSE;
				u8_setTemp+=1;
				if(u8_setTemp > 48)
				{
					u8_setTemp = 30;
				}
				drv_ledRequest(3, u8_setTemp);
			}
			else if(drv_ledGetRequest() == 0)
			{
				setTempSave();
				e_mode = e_modeOld;
			}
			else if(e_keyEvent == KEY_EVENT_START)
			{
				drv_ledRequest(0, u8_setTemp);
				setTempSave();
				e_mode = MODE_STANDBY;
			}
			
			break;
		
		case MODE_AGING_TEST:
			if(b_agingTestFlag == 0)
			{
				if(u16_agingTestTimeCounter)
				{
					u16_agingTestTimeCounter--;
					if(u16_agingTestTimeCounter == 0)
					{
						b_agingTestFlag = 1;
						u16_agingTestTimeCounter = TIME_15_MIN;
					}
				}
			}
			else
			{
				if(u16_agingTestTimeCounter)
				{
					u16_agingTestTimeCounter--;
					if(u16_agingTestTimeCounter == 0)
					{
						b_agingTestFlag = 0;
						u16_agingTestTimeCounter = TIME_45_MIN;
					}
				}
			}
			
			if(temp > 50)
			{
				drv_scrRequest(SCR_OFF);
				drv_ledRequest(0xFF, 0xE3);
			}
			else
			{
				if(b_agingTestFlag == 0)
				{
					if(temp < 48)
					{
						drv_scrRequest(SCR_FULL);
					}
					else
					{
						drv_scrRequest(SCR_VVVF_OFF);
					}
				}
				else
				{
					drv_scrRequest(SCR_OFF);
				}
				drv_ledRequest(0xFF, temp);
			}
			
			if(e_keyEvent == KEY_EVENT_START)
			{
				drv_ledRequest(0, temp);
				e_mode = MODE_STANDBY;
			}
			break;
			
		default:
			e_mode = MODE_STANDBY;
			break;
	}
	e_keyEvent = KEY_EVENT_NONE;
}
Exemple #7
0
 void Server::onThreadStart( sys::ThreadPool::Worker& thread )
 {
     eventHandler().onThreadStarted( thread );
 }
int App::Run()
{
    int r(0);

    // somebody must attach a worker
    BOOST_ASSERT( m_Worker);

    int width(960);
    int height(540);
    SDL_Surface *screen = SDL_SetVideoMode(width, height, 32, SDL_OPENGL|SDL_RESIZABLE);
    ASSERT( screen, "Unable to set %dx%d video! SDL Error: %s\n", width, height, SDL_GetError());

    InitScene(width, height);

    // Run our worker thread
    boost::thread worker(boost::bind(&Worker::Run, m_Worker));
    Renderer* renderer = static_cast<Renderer*>(m_Worker.get());

    bool running(true);
    SDL_Event event;
    do
    {
        int eventsPending(0);
        SDL_WaitEvent(&event);
        do
        {
            bool processed( renderer->HandleEvent( event ) );
            for ( auto entity = m_EntityEventHandlerList.begin(); entity != m_EntityEventHandlerList.end(); )
            {
                processed |= (*entity)->HandleEvent(event);
                if (processed) {
                    break;
                }
                // Remove from event handler as well if marked for deletion
                if ( (*entity)->AreFlagsSet( Entity::F_DELETE ) ) {
                    entity = m_EntityEventHandlerList.erase( entity );
                    continue;
                }
                ++entity;
            }
            if (!processed)
            {
                for ( auto eventHandler : m_EventHandlerList ) {
                    processed |= eventHandler( event );
                    if (processed) {
                        break;
                    }
                }
            }
            if (!processed)
            {
                switch (event.type)
                {
                case SDL_KEYDOWN:
                    switch (event.key.keysym.sym)
                    {
                    case SDLK_ESCAPE:
                        running = false;
                        break;
                    default:
                        break;
                    }
                    break;
                case SDL_JOYBUTTONUP:
                    switch ( event.jbutton.button ) {
                    case JOY_BUTTONS::START:
                        running = false;
                        break;
                    }
                    break;
                case SDL_QUIT:
                    running = false;
                    break;
                }
            }
            if (running)
            {
                eventsPending = SDL_PollEvent(&event);
            }
        } while (eventsPending > 0 && running);
    } while (running);

    // Need to clear this list before renderer destroys entities
    m_EventHandlerList.clear();

    m_Worker->Terminate();
    worker.join();

    return r;
}
//******************************************************* MAIN *******************************
int main(int argc, char* argv[]){
    //set up sdl
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO);

    SDL_Window *Window = SDL_CreateWindow("Handmade Hero",
        SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
        640, 480, SDL_WINDOW_RESIZABLE);
    if(Window){
        SDL_Renderer *Renderer = SDL_CreateRenderer(Window, -1, 0);
    if(Renderer){

    // VIDEO
    sdl_offscreen_buffer Buffer = {}; // if non-initialized, declaring variables in a loop fails on SDLResizeTexture with a pointer error - im blaming the compiler
    sdl_window_dimension Dimension = SDLGetWindowDimension(Window);
    SDLResizeTexture(&Buffer, Renderer, Dimension.Width, Dimension.Height);
    keystates Keys = {};

    //AUDIO
    sdl_sound_output sound_output = sdl_sound_outputH(48000);
    //open audio
    SDLInitAudio(sound_output.SamplesPerSecond, sound_output.SamplesPerSecond * sound_output.BytesPerSample / 60);
    SDL_PauseAudio(0);

    //BW: state area allocation
    void *new_state_area = malloc(128*1024*1024);//need ~2 MB at least; give it 128 MiB -- 2MB for video; dont know audio
    void *prev_state_area = malloc(1024);// should be sizeof(state0), or sizeof(biggest statetype) later
    //apparently we didnt have enough memory, but only crashed sometimes? this fixed it
    void *state;
    
    {
        uint8 *next_ptr = (uint8*)prev_state_area;
        anim_comp *animation = (anim_comp*)next_ptr;
        next_ptr += sizeof(anim_comp);

        init_anim_comp(animation, 0,0);

        state0 *stateptr = (state0*)next_ptr;
        printf("state0 size %ld\n", sizeof(state0));
        uint64 stateptrn = (uint64)stateptr;
        uint64 sizeptr = (uint64)&(stateptr->size);
        uint64 deepc_ptr = (uint64)&(stateptr->deep_count);
        uint64 anim_ptr = (uint64)&(stateptr->animation);
        uint64 tsine_ptr = (uint64)&(stateptr->tSine);
        uint64 tvol_ptr = (uint64)&(stateptr->ToneVolume);
        uint64 thz_ptr = (uint64)&(stateptr->ToneHz);
        uint64 pu_ptr = (uint64)&(stateptr->pitch_up_was_pressed);
        printf("offset begin    %lu\n", sizeptr - stateptrn);
        printf("width of size   %lu\n", deepc_ptr - sizeptr);
        printf("width of deepc  %lu\n", anim_ptr - deepc_ptr);
        printf("width of animpt %lu\n", tsine_ptr - anim_ptr);
        printf("width of tsine  %lu\n", tvol_ptr - tsine_ptr);
        printf("width of tvol   %lu\n", thz_ptr - tvol_ptr);
        printf("width of thz    %lu\n", pu_ptr - thz_ptr);

        next_ptr += sizeof(state0);

        init_state0(stateptr, animation, 3000, 256, 0);

        state = stateptr;
        //return 0;
    }

    uint64 LastCounter = SDL_GetPerformanceCounter();
    uint64 LastCycleCount = _rdtsc();
    uint64 PerfCountFrequency = SDL_GetPerformanceFrequency();

    bool running = true;
    //main loop
    printf("enter main event loop\n");
    while(running){
        ///////NP_UPDATE/////////////
        //event capturing
        event_return events = eventHandler(&Keys);
        if(events.shouldQuit) running = false;
        //setup for p
        state_window_info Wi = {}; Wi.Height = Buffer.Height; Wi.Width = Buffer.Width; Wi.Pitch = Buffer.Pitch;
        int TargetQueueBytes = sound_output.LatencySampleCount * sound_output.BytesPerSample;
        state_sound_info Si = {}; Si.BytesToGet = TargetQueueBytes - SDL_GetQueuedAudioSize(1); Si.BytesPerSample = sound_output.BytesPerSample; Si.SamplesPerSecond = sound_output.SamplesPerSecond;
        uint64 state_size = 0;
        uint64 vbuffer_size = Buffer.Height * Buffer.Pitch;
        uint64 abuffer_size = Si.BytesToGet;
        state_return next;
        { //in case(statetype) or similar
            next = P_update_state0(*(state0*)state, new_state_area, Keys, Wi, Si);
            //p should return state_size? and also, what statetype we are in -> later
            state_size = sizeof(state0);
        }

        //GARBAGE COLLECTOR
        //move this state to previous state
        //fmemcpy(prev_state_area, new_state_area, state_size); //shallow copy, as supposed
        //printf("hi\n");
        deepcopy(prev_state_area, next.state, new_state_area, (uint8*)new_state_area + 128*1024*1024);
        //TODO(md): DEEPCPY

        //queue audio
        if (Si.BytesToGet > 0) SDL_QueueAudio(1, next.abuffer, abuffer_size);

        //render
        SDLUpdateWindow(Window, Renderer, Buffer, next.vbuffer);


        uint64 EndCycleCount = _rdtsc();
        uint64 EndCounter = SDL_GetPerformanceCounter();
        uint64 CounterElapsed = EndCounter - LastCounter;
        uint64 CyclesElapsed = EndCycleCount - LastCycleCount;

        real64 MSPerFrame = (((1000.0f * (real64)CounterElapsed) / (real64)PerfCountFrequency));
        real64 FPS = (real64)PerfCountFrequency / (real64)CounterElapsed;
        real64 MCPF = ((real64)CyclesElapsed / (1000.0f * 1000.0f));

        printf("%.02fms/f, %.02f/s, %.02fmc/f\n", MSPerFrame, FPS, MCPF);

        LastCycleCount = EndCycleCount;
        LastCounter = EndCounter;
    }
    } } //if(Renderer, Window)
    SDL_Quit();
    return 0;
}
/**
 * Fires an HID event.
 * @param connection HID connection. May be NULL in case of global connect/disconnect events.
 * @param type event type.
 * @param length payload length or zero if no payload.
 * @param data payload data if relevant or NULL otherwise.
 */
static void hid_fireEvent( hid_eventType type, uint16_t length, hid_bootReport * data)
{
	// Fire the global event handler, if set.
	if (eventHandler!=NULL)
		eventHandler(theConnection, type, length, data);
}
Exemple #11
0
/** fmGlobalEventHandler
 * \ingroup intSwitch
 *
 * \desc            event handler for handling system events
 *
 * \param[in]       args points to the thread arguments
 *
 * \return          Nothing.
 *
 *****************************************************************************/
void *fmGlobalEventHandler(void *args)
{
    fm_thread *               thread;
    fm_event *                event;
    fm_status                 err       = FM_OK;
    fm_eventPort *            portEvent = NULL;
    fm_eventTableUpdateBurst *updateEvent;
    fm_int                    physPort;
    fm_int                    logicalPort;
    fm_eventPktRecv *         rcvPktEvent;
    fm_eventSwitchInserted *  insertEvent;
    fm_eventSwitchRemoved *   removeEvent;
    fm_int                    sw = 0;
    fm_bool                   discardEvent;
    fm_port *                 portPtr = NULL;
    fm_bool                   switchIsProtected;
    fm_switch *               switchPtr;
    fm_int                    mode;
    fm_int                    info[8];
    fm_int                    state;
    fm_int                    numLanes;
    fm_uint32                 i;
    fm_bool                   isPhysicalSwitch;
    fm_switchEventHandler     eventHandler;
    fm_bool                   distributeEvent;
    fm_eventTableUpdate *     fpUpdateEvent;

    /* grab arguments */
    thread = FM_GET_THREAD_HANDLE(args);

    /* wait for initialization to finish before processing events */
    fmCaptureSemaphore(&fmRootApi->startGlobalEventHandler, FM_WAIT_FOREVER);

    enableFramePriority = GET_PROPERTY()->priorityBufQueues;

    while (1)
    {
        /* wait forever for an event */
        err = fmGetThreadEvent(thread, &event, FM_WAIT_FOREVER);

        if (err == FM_ERR_NO_EVENTS_AVAILABLE)
        {
            /* A timeout occurred - should never happen. */
            continue;
        }

        if (event == NULL)
        {
            /* NULL event should never happen. */
            continue;
        }

        sw                = event->sw;
        discardEvent      = FALSE;
        switchIsProtected = FALSE;
        switchPtr         = NULL;

        if (sw < 0 || sw >= fmRootPlatform->cfg.numSwitches)
        {
            discardEvent      = TRUE;
            switchIsProtected = FALSE;
        }
        else if ( SWITCH_LOCK_EXISTS(sw) )
        {
            if ( ( err = PROTECT_SWITCH(sw) ) != FM_OK )
            {
                discardEvent      = TRUE;
                switchIsProtected = FALSE;
            }
            else
            {
                switchIsProtected = TRUE;
                switchPtr         = fmRootApi->fmSwitchStateTable[sw];

                if (!fmRootApi->fmSwitchStateTable[sw])
                {
                    if ((event->type != FM_EVENT_SWITCH_REMOVED) &&
                        (event->type != FM_EVENT_SWITCH_INSERTED) )
                    {
                        discardEvent = TRUE;
                    }
                }
                else if (fmRootApi->fmSwitchStateTable[sw]->state != FM_SWITCH_STATE_UP)
                {
                    if ((event->type != FM_EVENT_SWITCH_REMOVED) &&
                        (event->type != FM_EVENT_SWITCH_INSERTED) )
                    {
                        discardEvent = TRUE;
                    }
                }
            }
        }
        else if (event->type != FM_EVENT_SWITCH_INSERTED)
        {
            discardEvent = TRUE;
        }


        if (discardEvent)
        {
            switch (event->type)
            {
                case FM_EVENT_PKT_RECV:
                case FM_EVENT_SFLOW_PKT_RECV:
                    /* Only dig into the event if the switch is valid */
                    if  ( (sw >= 0) && (sw < fmRootPlatform->cfg.numSwitches) )
                    {
                        rcvPktEvent = &event->info.fpPktEvent;
                        if (enableFramePriority)
                        {
                            err = fmFreeBufferQueueNode(sw, rcvPktEvent);
                            if (err != FM_OK)
                            {
                                FM_LOG_ERROR(FM_LOG_CAT_EVENT_PKT_RX,
                                             "Freeing Buffer queue node from the queue failed"
                                             "status = %d (%s) \n",
                                              err,
                                              fmErrorMsg(err));

                            }
                        }
                        fmFreeBufferChain(sw, rcvPktEvent->pkt);
                        fmDbgDiagCountIncr(sw, FM_CTR_RX_API_PKT_DROPS, 1);
                    }
                    break;

                default:
                    break;
            }

            goto FINISHED;
        }

        eventHandler     = NULL;

        if (switchPtr != NULL)
        {
            /* If the switch state table has an eventHandler pointer,
             * it overrides the global handler.  Call the switch-specific
             * function to handle the event.  This is intended to be used
             * for switches in a switch aggregate (and potentially
             * nested switch aggregates inside other switch aggregates?).
             */
            eventHandler = switchPtr->eventHandler;

            switch (switchPtr->switchModel)
            {
                case FM_SWITCH_MODEL_SWAG:
                    isPhysicalSwitch = FALSE;
                    break;

                default:
                    isPhysicalSwitch = TRUE;
                    break;
            }
        }
        else
        {
            /* Only physical switches should ever get here with a NULL pointer
             * because logical switches such as switch aggregates are always
             * created by application code before any events related to
             * the switch are possible.
             */
            isPhysicalSwitch = TRUE;
        }

        distributeEvent = FALSE;

        switch (event->type)
        {
            case FM_EVENT_SWITCH_INSERTED:
                insertEvent = &event->info.fpSwitchInsertedEvent;
                
                if (switchIsProtected)
                {
                    UNPROTECT_SWITCH(sw);
                    switchIsProtected = FALSE;
                }

                if (switchPtr == NULL)
                {
                    if (fmHandleSwitchInserted(sw, insertEvent) != FM_OK)
                    {
                        /* Don't generate an insert event if there error */
                        goto FINISHED;
                    }
                }

                distributeEvent = TRUE;

                break;

            case FM_EVENT_SWITCH_REMOVED:
                removeEvent = &event->info.fpSwitchRemovedEvent;

                if (switchIsProtected)
                {
                    UNPROTECT_SWITCH(sw);
                    switchIsProtected = FALSE;
                }

                if (switchPtr != NULL)
                {
                    fmHandleSwitchRemoved(sw, removeEvent);
                }

                distributeEvent = TRUE;
                break;

            case FM_EVENT_PORT:
                portEvent = &event->info.fpPortEvent;

                if (isPhysicalSwitch && portEvent->activeMac)
                {
                    logicalPort = portEvent->port;

                    if (switchPtr != NULL)
                    {
                        fmMapLogicalPortToPhysical(switchPtr,
                                                   logicalPort,
                                                   &physPort);

                        portPtr = switchPtr->portTable[logicalPort];
                    }
                    else
                    {
                        portPtr = NULL;
                    }

                    if (portPtr == NULL)
                    {
                        FM_LOG_ERROR(FM_LOG_CAT_EVENT_PORT,
                                     "Unexpected NULL port pointer for logical"
                                     " port %d\n",
                                     logicalPort);
                        break;
                    }

                    /* This attribute indicate whether the API should flush
                     * all the addresses on a port down event or not. */
                    if (GET_PROPERTY()->maFlushOnPortDown)
                    {
                        /* If a link goes down for a non-LAG port, remove any
                         * addresses associated with the port from the MA Table. */
                        if (portEvent->linkStatus == FM_PORT_STATUS_LINK_DOWN)
                        {
                            if (portPtr->portType != FM_PORT_TYPE_LAG)
                            {
                                err = fmFlushPortAddresses(sw, portEvent->port);

                                if (err != FM_OK)
                                {
                                    FM_LOG_WARNING(FM_LOG_CAT_EVENT_PORT,
                                                   "%s\n",
                                                   fmErrorMsg(err));
                                }
                            }
                        }
                    }

                    FM_LOG_DEBUG( FM_LOG_CAT_EVENT_PORT,
                                  "Port %s event reported on port %d.\n",
                                  (portPtr != NULL )
                                    ? ( (portPtr->linkUp) ? "UP  " : "DOWN" )
                                    : "UNKN",
                                  portEvent->port );

                    /* inform LAG module of port state changes */
                    if (portEvent->linkStatus == FM_PORT_STATUS_LINK_UP)
                    {
                        fmInformLAGPortUp(sw, portEvent->port);
                        
                        /* Inform LBGs of port link state change. */
                        FM_API_CALL_FAMILY_VOID(switchPtr->InformLBGLinkChange,
                                                sw, 
                                                portEvent->port, 
                                                FM_PORT_STATUS_LINK_UP);
                    }
                    else if (portEvent->linkStatus == FM_PORT_STATUS_LINK_DOWN)
                    {
                        fmInformLAGPortDown(sw, portEvent->port);
                        
                        /* Inform LBGs of port link state change. */
                        FM_API_CALL_FAMILY_VOID(switchPtr->InformLBGLinkChange,
                                                sw, 
                                                portEvent->port, 
                                                FM_PORT_STATUS_LINK_DOWN);
                    }

                    /* now update all the source masks */
                    fmUpdateSwitchPortMasks(sw);

                    if (switchPtr->UpdateRemoveDownPortsTrigger != NULL)
                    {
                        /**************************************************** 
                         * Update the switchExt->removeDownPortsTrigger
                         * used to drop routed/multicast/special delivery 
                         * frames which can not be handled by the PORT_CFG_2. 
                         * See Bugzilla 11387.
                         ***************************************************/
                        if (portEvent->linkStatus == FM_PORT_STATUS_LINK_UP)
                        {
                            switchPtr->UpdateRemoveDownPortsTrigger(sw, 
                                                                    physPort,
                                                                    FALSE);
                        }
                        else if (portEvent->linkStatus == FM_PORT_STATUS_LINK_DOWN)
                        {
                            if (!portPtr->isPortForceUp)
                            {
                                switchPtr->UpdateRemoveDownPortsTrigger(sw, 
                                                                        physPort,
                                                                        TRUE);
                            }
                        }
                    }

                    if (switchPtr->UpdateMirrorGroups != NULL)
                    {
                        /**************************************************** 
                         * Enable/Disable mirror groups based on the link
                         * status of the mirror port.
                         * See Bugzilla 11387.
                         ***************************************************/
                        if (portEvent->linkStatus == FM_PORT_STATUS_LINK_UP)
                        {
                            switchPtr->UpdateMirrorGroups(sw, 
                                                          logicalPort,
                                                          TRUE);
                        }
                        else if (portEvent->linkStatus == FM_PORT_STATUS_LINK_DOWN)
                        {
                            switchPtr->UpdateMirrorGroups(sw, 
                                                          logicalPort,
                                                          FALSE);
                        }
                    }

                    /* notify anyone else who needs to know */
                    if (portPtr && portPtr->NotifyLinkEvent)
                    {
                        err = portPtr->NotifyLinkEvent(sw, portEvent->port);

                        if (err != FM_OK)
                        {
                            FM_LOG_WARNING(FM_LOG_CAT_EVENT_PORT,
                                           "%s\n",
                                           fmErrorMsg(err));
                        }
                    }

                    /* Get port state and notify platform */

                    err = fmGetPortStateV3( sw,
                                            portEvent->port,
                                            portEvent->mac,
                                            8,
                                            &numLanes,
                                            &mode,
                                            &state,
                                            info );

                    if (err != FM_OK)
                    {
                        FM_LOG_WARNING(FM_LOG_CAT_EVENT_PORT,
                                       "fmGetPortState(%d,%u) failed: %s\n",
                                       sw,
                                       portEvent->port,
                                       fmErrorMsg(err));
                    }

                    fmPlatformNotifyPortState(sw,
                                              portEvent->port,
                                              portEvent->mac,
                                              FALSE,
                                              state);

                    if (switchIsProtected)
                    {
                        UNPROTECT_SWITCH(sw);
                        switchIsProtected = FALSE;
                    }

                }   /* end if (isPhysicalSwitch) */

                distributeEvent = TRUE;
                break;

            case FM_EVENT_PKT_RECV:
            case FM_EVENT_SFLOW_PKT_RECV:
                fmDbgDiagCountIncr(sw, FM_CTR_RX_API_PKT_FWD, 1);
                distributeEvent = TRUE;
                break;

            case FM_EVENT_PURGE_SCAN_COMPLETE:
                distributeEvent = TRUE;
                break; 

            case FM_EVENT_TABLE_UPDATE:
                if (switchPtr == NULL)
                {
                    break;
                }

                /* Update diagnostic counters. */
                updateEvent = &event->info.fpUpdateEvent;
                i = 0;

                while (i < updateEvent->numUpdates)
                {
                    fpUpdateEvent = &updateEvent->updates[i];

                    if (fpUpdateEvent->event == FM_EVENT_ENTRY_LEARNED)
                    {
                        /* Make sure the MA Table entry matches the entry
                         * in the update event. */
                        if (switchPtr->RemoveStaleLearnEvent != NULL &&
                            switchPtr->RemoveStaleLearnEvent(sw, updateEvent, i))
                        {
                            /* The learn event has been removed.
                             * Do not update 'i', since it now contains the 
                             * following event (if any). */
                            fmDbgDiagCountIncr(sw, FM_CTR_MAC_LEARN_DISCARDED, 1);
                        }
                        else
                        {
                            fmDbgDiagCountIncr(sw, FM_CTR_MAC_ALPS_LEARN, 1);
                            i++;
                        }
                    }
                    else
                    {
                        if (fpUpdateEvent->event == FM_EVENT_ENTRY_AGED)
                        {
                            fmDbgDiagCountIncr(sw, FM_CTR_MAC_ALPS_AGE, 1);
                        }
                        i++;
                    }
                }

                /* If all updates have been removed, don't distribute the
                   event */
                if (updateEvent->numUpdates > 0)
                {
                    distributeEvent = TRUE;
                }
                break;

            case FM_EVENT_SECURITY:
            case FM_EVENT_FRAME:
            case FM_EVENT_SOFTWARE:
            case FM_EVENT_PARITY_ERROR:
            case FM_EVENT_FIBM_THRESHOLD:
            case FM_EVENT_CRM:
            case FM_EVENT_ARP:
            case FM_EVENT_EGRESS_TIMESTAMP:
            case FM_EVENT_PLATFORM:
            case FM_EVENT_LOGICAL_PORT:
                distributeEvent = TRUE;
                break;

            default:
                FM_LOG_WARNING(FM_LOG_CAT_EVENT_PORT,
                               "Received unknown event %d\n",
                               event->type);
                break;

        }   /* end switch (event->type) */

        if (distributeEvent)
        {
            if (switchIsProtected)
            {
                UNPROTECT_SWITCH(sw);
                switchIsProtected = FALSE;
            }

            if (eventHandler != NULL)
            {
                if (enableFramePriority && 
                    ( (event->type == FM_EVENT_PKT_RECV) ||
                      (event->type == FM_EVENT_SFLOW_PKT_RECV) ) )
                {
                    rcvPktEvent = &event->info.fpPktEvent;
                    err = fmFreeBufferQueueNode(sw, rcvPktEvent);
                    if (err != FM_OK)
                    {
                        FM_LOG_ERROR(FM_LOG_CAT_EVENT_PKT_RX,
                                     "Freeing Buffer queue node from the queue failed"
                                     "status = %d (%s) \n",
                                      err,
                                      fmErrorMsg(err));

                    }
                }

                eventHandler(event);
            }
            else
            {
                fmDistributeEvent(event);
            }
        }

FINISHED:

        fmReleaseEvent(event);

        /* release the switch lock if any is held */
        if (switchIsProtected)
        {
            UNPROTECT_SWITCH(sw);
        }

    }   /* end while (1) */

    fmExitThread(thread);

    return NULL;

}   /* end fmGlobalEventHandler */