bool SCA_KeyboardSensor::Evaluate()
{
	bool result    = false;
	bool reset     = m_reset && m_level;
	bool qual	   = true;
	bool qual_change = false;
	short int m_val_orig = m_val;
	
	SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice();
	//  	cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";

	/* See if we need to do logging: togPropState exists and is
	 * different from 0 */
	CValue* myparent = GetParent();
	CValue* togPropState = myparent->GetProperty(m_toggleprop);
	if (togPropState &&
		(((int)togPropState->GetNumber()) != 0) )
	{
		LogKeystrokes();
	}

	m_reset = false;

	/* Now see whether events must be bounced. */
	if (m_bAllKeys)
	{
		bool justactivated = false;
		bool justreleased = false;
		bool active = false;

		for (int i=SCA_IInputDevice::KX_BEGINKEY ; i<= SCA_IInputDevice::KX_ENDKEY;i++)
		{
			const SCA_InputEvent & inevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) i);
			switch (inevent.m_status) 
			{ 
			case SCA_InputEvent::KX_JUSTACTIVATED:
				justactivated = true;
				break;
			case SCA_InputEvent::KX_JUSTRELEASED:
				justreleased = true;
				break;
			case SCA_InputEvent::KX_ACTIVE:
				active = true;
				break;
			case SCA_InputEvent::KX_NO_INPUTSTATUS:
				/* do nothing */
				break;
			}
		}

		if (justactivated)
		{
			m_val=1;
			result = true;
		} else
		{
			if (justreleased)
			{
				m_val=(active)?1:0;
				result = true;
			} else
			{
				if (active)
				{
					if (m_val == 0)
					{
						m_val = 1;
						if (m_level) {
							result = true;
						}
					}
				} else
				{
					if (m_val == 1)
					{
						m_val = 0;
						result = true;
					}
				}
			}
			if (m_tap)
				// special case for tap mode: only generate event for new activation
				result = false;
		}


	} else
	{

	//		cerr << "======= SCA_KeyboardSensor::Evaluate:: peeking at key status" << endl;
		const SCA_InputEvent & inevent = inputdev->GetEventValue(
			(SCA_IInputDevice::KX_EnumInputs) m_hotkey);
	
	//		cerr << "======= SCA_KeyboardSensor::Evaluate:: status: " << inevent.m_status << endl;
		
		
		/* Check qualifier keys
		 * - see if the qualifiers we request are pressed - 'qual' true/false
		 * - see if the qualifiers we request changed their state - 'qual_change' true/false
		 */
		if (m_qual > 0) {
			const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual);
			switch (qualevent.m_status) {
				case SCA_InputEvent::KX_NO_INPUTSTATUS:
					qual = false;
					break;
				case SCA_InputEvent::KX_JUSTRELEASED:
					qual_change = true;
					qual = false;
					break;
				case SCA_InputEvent::KX_JUSTACTIVATED:
					qual_change = true;
				case SCA_InputEvent::KX_ACTIVE:
					/* do nothing */
					break;
			}
		}
		if (m_qual2 > 0 && qual==true) {
			const SCA_InputEvent & qualevent = inputdev->GetEventValue((SCA_IInputDevice::KX_EnumInputs) m_qual2);
			/* copy of above */
			switch (qualevent.m_status) {
				case SCA_InputEvent::KX_NO_INPUTSTATUS:
					qual = false;
					break;
				case SCA_InputEvent::KX_JUSTRELEASED:
					qual_change = true;
					qual = false;
					break;
				case SCA_InputEvent::KX_JUSTACTIVATED:
					qual_change = true;
				case SCA_InputEvent::KX_ACTIVE:
					/* do nothing */
					break;
			}
		}
		/* done reading qualifiers */
		
		if (inevent.m_status == SCA_InputEvent::KX_NO_INPUTSTATUS)
		{
			if (m_val == 1)
			{
				// this situation may occur after a scene suspend: the keyboard release 
				// event was not captured, produce now the event off
				m_val = 0;
				result = true;
			}
		} else
		{
			if (inevent.m_status == SCA_InputEvent::KX_JUSTACTIVATED)
			{
				m_val=1;
				result = true;
			} else
			{
				if (inevent.m_status == SCA_InputEvent::KX_JUSTRELEASED)
				{
					m_val = 0;
					result = true;
				} else 
				{
					if (inevent.m_status == SCA_InputEvent::KX_ACTIVE)
					{
						if (m_val == 0)
						{
							m_val = 1;
							if (m_level) 
							{
								result = true;
							}
						}
					}
				}
			}
		}
		
		/* Modify the key state based on qual(s)
		 * Tested carefully. don't touch unless your really sure.
		 * note, this will only change the results if key modifiers are set.
		 *
		 * When all modifiers and keys are positive
		 *  - pulse true
		 * 
		 * When ANY of the modifiers or main key become inactive,
		 *  - pulse false
		 */
		if (qual==false) { /* one of the qualifiers are not pressed */
			if (m_val_orig && qual_change) { /* we were originally enabled, but a qualifier changed */
				result = true;
			} else {
				result = false;
			}
			m_val = 0; /* since one of the qualifiers is not on, set the state to false */
		} else {						/* we done have any qualifiers or they are all pressed */
			if (m_val && qual_change) {	/* the main key state is true and our qualifier just changed */
				result = true;
			}
		}
		/* done with key quals */
		
	}
	
	if (reset)
		// force an event
		result = true;
	return result;

}
Esempio n. 2
0
bool SCA_KeyboardSensor::Evaluate()
{
	bool result    = false;
	bool reset     = m_reset && m_level;

	SCA_IInputDevice* inputdev = ((SCA_KeyboardManager *)m_eventmgr)->GetInputDevice();
	//  	cerr << "SCA_KeyboardSensor::Eval event, sensing for "<< m_hotkey << " at device " << inputdev << "\n";

	/* See if we need to do logging: togPropState exists and is
	 * different from 0 */
	CValue* myparent = GetParent();
	CValue* togPropState = myparent->GetProperty(m_toggleprop);
	if (togPropState &&
		(((int)togPropState->GetNumber()) != 0) )
	{
		LogKeystrokes();
	}

	m_reset = false;

	/* Now see whether events must be bounced. */
	if (m_bAllKeys)
	{
		bool status = false;
		bool events = false;

		for (int i = SCA_IInputDevice::BEGINKEY; i <= SCA_IInputDevice::ENDKEY; ++i) {
			const SCA_InputEvent& input = inputdev->GetInput((SCA_IInputDevice::SCA_EnumInputs)i);
			if (input.End(SCA_InputEvent::ACTIVE)) {
				status = true;
				break;
			}
		}

		for (int i = SCA_IInputDevice::BEGINKEY; i <= SCA_IInputDevice::ENDKEY; ++i) {
			const SCA_InputEvent& input = inputdev->GetInput((SCA_IInputDevice::SCA_EnumInputs)i);
			if (input.m_queue.size() > 0) {
				events = true;
				break;
			}
		}

		m_val = status;
		result = events;
	}
	else {
		bool status[3] = {false, false, false};
		bool events[3] = {false, false, false};
		const SCA_InputEvent & input = inputdev->GetInput((SCA_IInputDevice::SCA_EnumInputs) m_hotkey);

		/* Check qualifier keys
		 * - see if the qualifiers we request are pressed - 'qual' true/false
		 * - see if the qualifiers we request changed their state - 'qual_change' true/false
		 */
		if (m_qual > 0) {
			const SCA_InputEvent & qualevent = inputdev->GetInput((SCA_IInputDevice::SCA_EnumInputs) m_qual);
			status[1] = qualevent.End(SCA_InputEvent::ACTIVE);
			events[1] = (qualevent.m_queue.size() > 0);
		}
		if (m_qual2 > 0) {
			const SCA_InputEvent & qualevent = inputdev->GetInput((SCA_IInputDevice::SCA_EnumInputs) m_qual2);
			/* copy of above */
			status[2] = qualevent.End(SCA_InputEvent::ACTIVE);
			events[2] = (qualevent.m_queue.size() > 0);
		}
		/* done reading qualifiers */

		status[0] = input.End(SCA_InputEvent::ACTIVE);
		events[0] = (input.m_queue.size() > 0);

		/* Modify the key state based on qual(s)
		 * Tested carefully. don't touch unless your really sure.
		 * note, this will only change the results if key modifiers are set.
		 *
		 * When all modifiers and keys are positive
		 *  - pulse true
		 * 
		 * When ANY of the modifiers or main key become inactive,
		 *  - pulse false
		 */

		// One of the third keys value from last logic frame changed.
		if (events[0] || events[1] || events[2]) {
			result = true;
		}

		if (!status[0] || (m_qual > 0 && !status[0]) || (m_qual2 > 0 && !status[1])) { /* one of the used qualifiers are not pressed */
			m_val = false; /* since one of the qualifiers is not on, set the state to false */
		}
		else {
			m_val = true;
		}
		/* done with key quals */
	}

	if (reset)
		// force an event
		result = true;
	return result;

}