Exemplo n.º 1
0
static void testCallbacks() {
	EventDispatcher * dispatcher;
	char * sender1 = "1", * sender2 = "2";
	int callback1Context = 0, callback2Context = 0;
	int incrementation = 2;
	bool handled;
	Atom event1Atom, event2Atom;
	
	dispatcher = EventDispatcher_create(sender1);
	
	event1Atom = Atom_fromString("event1");
	event2Atom = Atom_fromString("event2");
	handled = dispatcher->dispatchEvent(dispatcher, event1Atom, &incrementation);
	TestCase_assert(!handled, "Event handled when no callbacks are registered");
	
	dispatcher->registerForEvent(dispatcher, event1Atom, callback1, &callback1Context);
	handled = dispatcher->dispatchEvent(dispatcher, event1Atom, &incrementation);
	TestCase_assert(handled, "Event not handled when appropriate callback was registered");
	TestCase_assert(callback1Context == 2, "Expected 2 but got %d", callback1Context);
	TestCase_assert(lastSender == sender1, "Expected %p but got %p", sender1, lastSender);
	
	incrementation = 3;
	dispatcher->dispatchEvent(dispatcher, event2Atom, &incrementation);
	TestCase_assert(callback1Context == 2, "Callback called for wrong type of event");
	
	dispatcher->registerForEvent(dispatcher, event2Atom, callback2, &callback2Context);
	handled = dispatcher->dispatchEvent(dispatcher, event2Atom, &incrementation);
	TestCase_assert(callback2Context == 3, "Expected 3 but got %d", callback2Context);
	TestCase_assert(!handled, "Expected false but got true");
	
	dispatcher->unregisterForEvent(dispatcher, event1Atom, callback1, NULL);
	handled = dispatcher->dispatchEvent(dispatcher, event1Atom, &incrementation);
	TestCase_assert(handled, "Event not still handled after unregistering callbacks with the wrong context");
	
	dispatcher->unregisterForEvent(dispatcher, event1Atom, callback1, &callback1Context);
	handled = dispatcher->dispatchEvent(dispatcher, event1Atom, &incrementation);
	TestCase_assert(!handled, "Event still handled after unregistering callbacks");
	
	incrementation = 1;
	handled = dispatcher->dispatchEvent(dispatcher, event2Atom, &incrementation);
	TestCase_assert(callback2Context == 4, "Expected 4 but got %d", callback2Context);
	TestCase_assert(!handled, "Expected false but got true");
	
	dispatcher->dispose(dispatcher);
	
	dispatcher = EventDispatcher_create(sender2);
	dispatcher->registerForEvent(dispatcher, event1Atom, callback1, &callback1Context);
	dispatcher->dispatchEvent(dispatcher, event1Atom, &incrementation);
	TestCase_assert(lastSender == sender2, "Expected %p but got %p", sender2, lastSender);
	
	dispatcher->dispose(dispatcher);
}
Exemplo n.º 2
0
bool Preferences_init(Preferences * self) {
	call_super(init, self);
	
	self->private_ivar(hashTable) = hashCreate();
	self->eventDispatcher = EventDispatcher_create();
	
	self->dispose = Preferences_dispose;
	return true;
}
Exemplo n.º 3
0
void StateController_init(StateController * self) {
	call_super(init, self);
	self->dispose = StateController_dispose;
	self->addState = StateController_addState;
	self->setState = StateController_setState;
	self->addTransition = StateController_addTransition;
	self->transition = StateController_transition;
	
	self->eventDispatcher = EventDispatcher_create(self);
	self->currentState = NULL;
	self->validStateCount = 0;
	self->validStates = NULL;
	self->transitionCount = 0;
	self->transitions = NULL;
}
Exemplo n.º 4
0
bool InputPlayback_init(InputPlayback * self, InputController * inputController, InputSession * inputSession) {
	call_super(init, self);
	self->dispose = InputPlayback_dispose;
	self->step = InputPlayback_step;
	self->rewind = InputPlayback_rewind;
	self->inputController = inputController;
	self->inputSession = inputSession;
	self->eventDispatcher = EventDispatcher_create(self);
	self->frameIndex = 0;
	self->lastFrameIndex = 0;
	if (inputSession == NULL || inputSession->actionCount == 0) {
		self->actionsTriggered = NULL;
	} else {
		self->actionsTriggered = calloc(sizeof(bool), inputSession->actionCount);
	}
	self->eventIndex = 0;
	return true;
}
Exemplo n.º 5
0
bool InputController_vinit(InputController * self, InputMap * inputMap, va_list args) {
	va_list argsCopy;
	
	call_super(init, self);
	self->dispose = InputController_dispose;
	self->keyDown = InputController_keyDown;
	self->keyUp = InputController_keyUp;
	self->keyModifiersChanged = InputController_keyModifiersChanged;
	self->gamepadButtonDown = InputController_gamepadButtonDown;
	self->gamepadButtonUp = InputController_gamepadButtonUp;
	self->gamepadAxisMoved = InputController_gamepadAxisMoved;
	self->triggerAction = InputController_triggerAction;
	self->releaseAction = InputController_releaseAction;
	self->reset = InputController_reset;
	
	self->eventDispatcher = EventDispatcher_create(self);
	self->inputMap = inputMap;
	self->lastModifiers = 0x0;
	self->actionCount = 0;
	self->actions = NULL;
	
	va_copy(argsCopy, args);
	while (va_arg(argsCopy, const char *) != NULL) {
		self->actionCount++;
	}
	va_end(argsCopy);
	
	if (self->actionCount > 0) {
		unsigned int actionIndex;
		
		self->actions = malloc(sizeof(struct InputController_action) * self->actionCount);
		for (actionIndex = 0; actionIndex < self->actionCount; actionIndex++) {
			self->actions[actionIndex].actionID = Atom_fromString(va_arg(args, const char *));
			self->actions[actionIndex].triggered = false;
		}
	}
Exemplo n.º 6
0
void Gamepad_detectDevices() {
    unsigned int numPaths;
    char ** gamepadPaths;
    bool duplicate;
    unsigned int pathIndex, gamepadIndex;
    struct stat statBuf;
    struct Gamepad_device * deviceRecord;
    struct Gamepad_devicePrivate * deviceRecordPrivate;
    int fd;
    char name[128];
    char * description;
    int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1];
    int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1];
    int bit;
    struct input_id id;

    if (!inited) {
        return;
    }

    gamepadPaths = findGamepadPaths(&numPaths);

    pthread_mutex_lock(&devicesMutex);
    for (pathIndex = 0; pathIndex < numPaths; pathIndex++) {
        duplicate = false;
        for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
            if (!strcmp(((struct Gamepad_devicePrivate *) devices[gamepadIndex]->privateData)->path, gamepadPaths[pathIndex])) {
                duplicate = true;
                break;
            }
        }
        if (duplicate) {
            free(gamepadPaths[pathIndex]);
            continue;
        }

        if (!stat(gamepadPaths[pathIndex], &statBuf)) {
            deviceRecord = (Gamepad_device*)malloc(sizeof(struct Gamepad_device));
            deviceRecord->deviceID = nextDeviceID++;
            deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
            devices = (Gamepad_device**)realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
            devices[numDevices++] = deviceRecord;

            fd = open(gamepadPaths[pathIndex], O_RDONLY, 0);

            deviceRecordPrivate = (Gamepad_devicePrivate*)malloc(sizeof(struct Gamepad_devicePrivate));
            deviceRecordPrivate->fd = fd;
            deviceRecordPrivate->path = gamepadPaths[pathIndex];
            memset(deviceRecordPrivate->buttonMap, 0xFF, sizeof(deviceRecordPrivate->buttonMap));
            memset(deviceRecordPrivate->axisMap, 0xFF, sizeof(deviceRecordPrivate->axisMap));
            deviceRecord->privateData = deviceRecordPrivate;

            if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) {
                description = (char*)malloc(strlen(name + 1));
                strcpy(description, name);
            } else {
                description = (char*)malloc(strlen(gamepadPaths[pathIndex] + 1));
                strcpy(description, gamepadPaths[pathIndex]);
            }
            deviceRecord->description = description;

            if (!ioctl(fd, EVIOCGID, &id)) {
                deviceRecord->vendorID = id.vendor;
                deviceRecord->productID = id.product;
            } else {
                deviceRecord->vendorID = deviceRecord->productID = 0;
            }

            memset(evKeyBits, 0, sizeof(evKeyBits));
            memset(evAbsBits, 0, sizeof(evAbsBits));
            ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits);
            ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits);

            deviceRecord->numAxes = 0;
            for (bit = 0; bit < ABS_CNT; bit++) {
                if (test_bit(bit, evAbsBits)) {
                    if (ioctl(fd, EVIOCGABS(bit), &deviceRecordPrivate->axisInfo[bit]) < 0 ||
                            deviceRecordPrivate->axisInfo[bit].minimum == deviceRecordPrivate->axisInfo[bit].maximum) {
                        continue;
                    }
                    deviceRecordPrivate->axisMap[bit] = deviceRecord->numAxes;
                    deviceRecord->numAxes++;
                }
            }
            deviceRecord->numButtons = 0;
            for (bit = BTN_MISC; bit < KEY_CNT; bit++) {
                if (test_bit(bit, evKeyBits)) {
                    deviceRecordPrivate->buttonMap[bit - BTN_MISC] = deviceRecord->numButtons;
                    deviceRecord->numButtons++;
                }
            }

            deviceRecord->axisStates = (float*)calloc(sizeof(float), deviceRecord->numAxes);
            deviceRecord->buttonStates = (bool*)calloc(sizeof(bool), deviceRecord->numButtons);

            Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), GAMEPAD_EVENT_DEVICE_ATTACHED, deviceRecord);

            pthread_create(&deviceRecordPrivate->thread, NULL, deviceThread, deviceRecord);
        }
    }
    pthread_mutex_unlock(&devicesMutex);
}
Exemplo n.º 7
0
EventDispatcher * Gamepad_eventDispatcher() {
    if (eventDispatcher == NULL) {
        eventDispatcher = EventDispatcher_create(NULL);
    }
    return eventDispatcher;
}
Exemplo n.º 8
0
static void onDeviceMatched(void * context, IOReturn result, void * sender, IOHIDDeviceRef device) {
	CFArrayRef elements;
	CFIndex elementIndex;
	IOHIDElementRef element;
	CFStringRef cfProductName;
	struct Gamepad_device * deviceRecord;
	struct Gamepad_devicePrivate * hidDeviceRecord;
	IOHIDElementType type;
	char * description;
	struct Gamepad_queuedEvent queuedEvent;
	
	deviceRecord = malloc(sizeof(struct Gamepad_device));
	deviceRecord->deviceID = nextDeviceID++;
	deviceRecord->vendorID = IOHIDDeviceGetVendorID(device);
	deviceRecord->productID = IOHIDDeviceGetProductID(device);
	deviceRecord->numAxes = 0;
	deviceRecord->numButtons = 0;
	deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
	devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
	devices[numDevices++] = deviceRecord;
	
	hidDeviceRecord = malloc(sizeof(struct Gamepad_devicePrivate));
	hidDeviceRecord->deviceRef = device;
	hidDeviceRecord->axisElements = NULL;
	hidDeviceRecord->buttonElements = NULL;
	deviceRecord->privateData = hidDeviceRecord;
	
	cfProductName = IOHIDDeviceGetProperty(device, CFSTR(kIOHIDProductKey));
	if (cfProductName == NULL || CFGetTypeID(cfProductName) != CFStringGetTypeID()) {
		description = malloc(strlen("[Unknown]" + 1));
		strcpy(description, "[Unknown]");
		
	} else {
		const char * cStringPtr;
		
		cStringPtr = CFStringGetCStringPtr(cfProductName, CFStringGetSmallestEncoding(cfProductName));
		description = malloc(strlen(cStringPtr + 1));
		strcpy(description, cStringPtr);
	}
	deviceRecord->description = description;
	
	elements = IOHIDDeviceCopyMatchingElements(device, NULL, kIOHIDOptionsTypeNone);
	for (elementIndex = 0; elementIndex < CFArrayGetCount(elements); elementIndex++) {
		element = (IOHIDElementRef) CFArrayGetValueAtIndex(elements, elementIndex);
		type = IOHIDElementGetType(element);
		
		// All of the axis elements I've ever detected have been kIOHIDElementTypeInput_Misc. kIOHIDElementTypeInput_Axis is only included for good faith...
		if (type == kIOHIDElementTypeInput_Misc ||
		    type == kIOHIDElementTypeInput_Axis) {
			
			hidDeviceRecord->axisElements = realloc(hidDeviceRecord->axisElements, sizeof(struct HIDGamepadAxis) * (deviceRecord->numAxes + 1));
			hidDeviceRecord->axisElements[deviceRecord->numAxes].cookie = IOHIDElementGetCookie(element);
			hidDeviceRecord->axisElements[deviceRecord->numAxes].logicalMin = IOHIDElementGetLogicalMin(element);
			hidDeviceRecord->axisElements[deviceRecord->numAxes].logicalMax = IOHIDElementGetLogicalMax(element);
			hidDeviceRecord->axisElements[deviceRecord->numAxes].hasNullState = !!IOHIDElementHasNullState(element);
			hidDeviceRecord->axisElements[deviceRecord->numAxes].isHatSwitch = IOHIDElementGetUsage(element) == kHIDUsage_GD_Hatswitch;
			hidDeviceRecord->axisElements[deviceRecord->numAxes].isHatSwitchSecondAxis = false;
			deviceRecord->numAxes++;
			
			if (hidDeviceRecord->axisElements[deviceRecord->numAxes - 1].isHatSwitch) {
				hidDeviceRecord->axisElements = realloc(hidDeviceRecord->axisElements, sizeof(struct HIDGamepadAxis) * (deviceRecord->numAxes + 1));
				hidDeviceRecord->axisElements[deviceRecord->numAxes].isHatSwitchSecondAxis = true;
				deviceRecord->numAxes++;
			}
			
		} else if (type == kIOHIDElementTypeInput_Button) {
			hidDeviceRecord->buttonElements = realloc(hidDeviceRecord->buttonElements, sizeof(struct HIDGamepadButton) * (deviceRecord->numButtons + 1));
			hidDeviceRecord->buttonElements[deviceRecord->numButtons].cookie = IOHIDElementGetCookie(element);
			deviceRecord->numButtons++;
		}
	}
	CFRelease(elements);
	
	deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
	deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
	
	IOHIDDeviceRegisterInputValueCallback(device, onDeviceValueChanged, deviceRecord);
	
	queuedEvent.dispatcher = Gamepad_eventDispatcher();
	queuedEvent.eventType = GAMEPAD_EVENT_DEVICE_ATTACHED;
	queuedEvent.eventData = deviceRecord;
	
	if (deviceEventCount >= deviceEventQueueSize) {
		deviceEventQueueSize = deviceEventQueueSize == 0 ? 1 : deviceEventQueueSize * 2;
		deviceEventQueue = realloc(deviceEventQueue, sizeof(struct Gamepad_queuedEvent) * deviceEventQueueSize);
	}
	deviceEventQueue[deviceEventCount++] = queuedEvent;
}
Exemplo n.º 9
0
void Gamepad_detectDevices() {
	unsigned int numPadsSupported;
	unsigned int deviceIndex, deviceIndex2;
	JOYINFOEX info;
	JOYCAPS caps;
	bool duplicate;
	struct Gamepad_device * deviceRecord;
	struct Gamepad_devicePrivate * deviceRecordPrivate;
	UINT joystickID;
	int axisIndex;
	
	if (!inited) {
		return;
	}
	
	numPadsSupported = joyGetNumDevs();
	for (deviceIndex = 0; deviceIndex < numPadsSupported; deviceIndex++) {
		info.dwSize = sizeof(info);
		info.dwFlags = JOY_RETURNALL;
		joystickID = JOYSTICKID1 + deviceIndex;
		if (joyGetPosEx(joystickID, &info) == JOYERR_NOERROR &&
		    joyGetDevCaps(joystickID, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR) {
			
			duplicate = false;
			for (deviceIndex2 = 0; deviceIndex2 < numDevices; deviceIndex2++) {
				if (((struct Gamepad_devicePrivate *) devices[deviceIndex2]->privateData)->joystickID == joystickID) {
					duplicate = true;
					break;
				}
			}
			if (duplicate) {
				continue;
			}
			
			deviceRecord = malloc(sizeof(struct Gamepad_device));
			deviceRecord->deviceID = nextDeviceID++;
			deviceRecord->description = getDeviceDescription(joystickID, caps);
			deviceRecord->vendorID = caps.wMid;
			deviceRecord->productID = caps.wPid;
			deviceRecord->numAxes = caps.wNumAxes + ((caps.wCaps & JOYCAPS_HASPOV) ? 2 : 0);
			deviceRecord->numButtons = caps.wNumButtons;
			deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
			deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
			deviceRecord->eventDispatcher = EventDispatcher_create(deviceRecord);
			devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
			devices[numDevices++] = deviceRecord;
			
			deviceRecordPrivate = malloc(sizeof(struct Gamepad_devicePrivate));
			deviceRecordPrivate->joystickID = joystickID;
			deviceRecordPrivate->lastState = info;
			
			deviceRecordPrivate->xAxisIndex = 0;
			deviceRecordPrivate->yAxisIndex = 1;
			axisIndex = 2;
			deviceRecordPrivate->zAxisIndex = (caps.wCaps & JOYCAPS_HASZ) ? axisIndex++ : -1;
			deviceRecordPrivate->rAxisIndex = (caps.wCaps & JOYCAPS_HASR) ? axisIndex++ : -1;
			deviceRecordPrivate->uAxisIndex = (caps.wCaps & JOYCAPS_HASU) ? axisIndex++ : -1;
			deviceRecordPrivate->vAxisIndex = (caps.wCaps & JOYCAPS_HASV) ? axisIndex++ : -1;
			
			deviceRecordPrivate->axisRanges = malloc(sizeof(UINT[2]) * axisIndex);
			deviceRecordPrivate->axisRanges[0][0] = caps.wXmin;
			deviceRecordPrivate->axisRanges[0][1] = caps.wXmax;
			deviceRecordPrivate->axisRanges[1][0] = caps.wYmin;
			deviceRecordPrivate->axisRanges[1][1] = caps.wYmax;
			if (deviceRecordPrivate->zAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->zAxisIndex][0] = caps.wZmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->zAxisIndex][1] = caps.wZmax;
			}
			if (deviceRecordPrivate->rAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->rAxisIndex][0] = caps.wRmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->rAxisIndex][1] = caps.wRmax;
			}
			if (deviceRecordPrivate->uAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->uAxisIndex][0] = caps.wUmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->uAxisIndex][1] = caps.wUmax;
			}
			if (deviceRecordPrivate->vAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->vAxisIndex][0] = caps.wVmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->vAxisIndex][1] = caps.wVmax;
			}
			
			deviceRecordPrivate->povXAxisIndex = (caps.wCaps & JOYCAPS_HASPOV) ? axisIndex++ : -1;
			deviceRecordPrivate->povYAxisIndex = (caps.wCaps & JOYCAPS_HASPOV) ? axisIndex++ : -1;
			
			deviceRecord->privateData = deviceRecordPrivate;
			
			Gamepad_eventDispatcher()->dispatchEvent(Gamepad_eventDispatcher(), Atom_fromString(GAMEPAD_EVENT_DEVICE_ATTACHED), deviceRecord);
		}
	}
}
Exemplo n.º 10
0
Preferences * Preferences_create(const char * identifier) {
	stemobject_create_implementation(Preferences, init, identifier)
}

void Preferences_init(compat_type(Preferences *) selfPtr, const char * identifier) {
	Preferences * self = selfPtr;
	char * newIdentifier;
	
	StemObject_init(self);
	
	self->valueCount = 0;
	self->values = NULL;
	newIdentifier = malloc(strlen(identifier) + 1);
	strcpy(newIdentifier, identifier);
	self->identifier = newIdentifier;
	self->eventDispatcher = EventDispatcher_create(self);
	
	self->dispose = Preferences_dispose;
	self->addInteger = Preferences_addInteger;
	self->addFloat = Preferences_addFloat;
	self->addBoolean = Preferences_addBoolean;
	self->addString = Preferences_addString;
	self->addData = Preferences_addData;
	self->getInteger = Preferences_getInteger;
	self->getFloat = Preferences_getFloat;
	self->getBoolean = Preferences_getBoolean;
	self->getString = Preferences_getString;
	self->getData = Preferences_getData;
	self->setInteger = Preferences_setInteger;
	self->setFloat = Preferences_setFloat;
	self->setBoolean = Preferences_setBoolean;