Understanding how keyboard input interfaces with the OS and user processes - input

When keyboard input is sent to the keyboard controller on the motherboard, which in turn creates a hardware interrupt and thus a context switch, what exactly does the operating system do with it at this point (I'm assuming this is when the device driver handler is run)?
After the interrupt, does the OS store the input in some data structure (like a queue) in a dedicated RAM location for which processes can later read from, or do applications (like game engines) simply read directly from the device (USB/Host) controller itself via low-level OS commands?
Furthermore, if I have a game with the following input handler function...
handleInput (Event e) {
if (e.keyPressed && e.value == "W") {
player.setVelocityY = 10;
}
if (e.keyReleased && e.value == "W") {
player.setVelocityY = 0;
}
if (e.keyPressed && e.value == "C") {
player.startAttack();
}
if (e.keyReleased && e.value == "C") {
player.stopAttack();
}
}
Is the OS ever able to "fetch" more than one input value at any given time? What if I wanted to both set velocity and start an attack within the same frame (a single game loop cycle). I'm assuming the engine would have to be able to set "Event e" to an array of values instead of just a single value, which might only be possible if the interrupts are saving the individual values to a queue data structure in memory somewhere to be read from later?
If it is the case that game engines can only process a single input value at a time (one event per game cycle/frame) and I have the following queue (given I have super fast fingers and can press all of these before the next game loop cycle)...
[{"W", "Pressed"}, {"W", "Released"}, {"W", "Pressed"}, {"W", "Released"}, {"C", "Pressed"}, {"C", "Released"}]
Wouldn't my game have to wait until frame #5 until the attack start command was processed? This seems undesirable?
Any insight is greatly appreciated, thanks!

Related

Check the condition when a timer is running in CAPL (CANoe)

I am running a script in CAPL where I am supposed to notice a change in the value of a signal (for example: signal B) coming from the ECU. At the start of the timer, I change the value of another signal (for example: signal A) and sent it to ECU over CAN Bus. While the timer is running, I want to see the changed value of signal B coming from ECU as a response to the changed value of signal A. After the timer has run out, I want to reset the signal A back to its original value.
*Note: I have called the different signals as Signal A and Signal B only for understanding the question more clearly
Signal A changes the value from 2 to 0.
Signal B has original value of 61, and the changed value can be any number between 0-60.
Timer runs for 4 seconds.
I am using while loop and command (isTimerActive(timer)==1), to check for the change in the value of signal B when the timer is running.
Below is the attached Code ->
variables
{
msTimer Execute;
}
on key 'c'
{
setTimer(Execute,4000);
Write("Test starts");
SetSignal(Signal A, 2);
while (isTimerActive(Execute)==1)
{
if ($Signal B != 61)
{
Write("Test pass");
}
else
{
Write("Test fail");
}
}
}
on timer Execute
{
write("Test over");
setSignal(Signal A, 0);
}
I am executing this code and the value of signal A changes to 2 but
there's no change in the value of signal B. I am using the
(isTimerActive (timer) ==1) in the while loop, is it the correct command
for my problem?
Also, when I run (isTimerActive (timer) ==1), CANoe becomes inactive and
I have to stop CANoe using Task manager.
Any ideas how can I correct my code and get the desired response?
Thanks and Best
CAPL is event-driven. Your only choice is to react on events by programming event handlers, i.e. the functions starting with on ....
During execution of an event handler, the system basically blocks everything until the event handler has finished.
Literally nothing else happens, no sysvars change, no signals change, no timers expire, no bus messages are handled, and so on.
For test-modules and -units the story is a little bit different. There you have the possibility to wait during execution of your code using the various testWaitFor... methods.
With your current implementation of on key ‘c‘you basically block the system, since you have an while loop there waiting for an Timer to expire.
As stated above, this blocks everything and you have to kill CANoe.
Fortunately changes of signals are also events that can be handled.
Something like this should do:
Remove the while block and instead add another event handler like this:
on signal SignalB
{
if(isTimerActive(Execute))
{
if ($SignalB != 61)
{
Write("Test pass");
}
else
{
Write("Test fail");
}
}
}
The code is called when SignalB changes. It then checks whether the Timer is still running and checks the value of the signal.
Instead of $SignalB inside of the handler you can also write this.
In an event handler this is always the object that has caused the event.

Communication between objects

If I have Game Class, which has Player object and Board object, Game asks Player what are the coordinates, Player responds, then game checks Board for the coordinates and the result either Hit or Miss.
How can Game forward the result back to Player? so that Player uses the result to set the new coordinates.
I have created code sample below to explain more what i want to do
and also a link to the project here: https://github.com/hythm7/Battleship/tree/master
#!/usr/bin/env perl6
enum Result < Miss Hit >;
class Player {
method fire ( ) {
(^10).pick, (^10).pick
}
}
class Board {
has #.cell = [ +Bool.pick xx ^10 ] xx ^10;
}
class Game {
has Board $.board = Board.new;
has Player $!player = Player.new;
method run ( ) {
loop {
my ($x, $y) = $!player.fire;
if $!board.cell[$y][$x] {
say Hit;
}
else {
say Miss;
}
# How to forward the above result (Hit or Miss) back to the Player object? so
# it can set $y, $x accordingly for the next call to $player.fire
sleep 1;
}
}
}
my $game = Game.new;
$game.run;
Let's see. The main question here is a design one, I think, so let's go for it from this angle. I want to note beforehand that I will describe just a single example of the approach: there are a lot of ways to do it, and I am writing out the simplest I can imagine that works. Also, for the sake of simplicity, code that deals with synchronization, graceful termination and so on is omitted.
Firstly, you have a player to be a separate thing, but in your code it reacts only when it is called from the outside. When it looks like a natural approach when implementing turn-based games, we still want to have some kind of communication. What if a player leaves? What if there is some error condition?
And as you noted the server wants to notify the player about outcome of the game. It seems like we want to have a bi-directional messaging between our Server and Player. Of course, if there is a One Server -> Many Players relation, it is another deal, but we will keep it simple.
Let's prepare some boilerplate code:
# We will get to this `Start` later
enum EventType <Start Hit Miss>;
# A handy class to hold a position, and likely some other data in the future
class Position {
has Int $.x;
has Int $.y;
}
# A board
class Board {
has #.cell = [ +Bool.pick xx ^10 ] xx ^10;
}
Now here is a server:
class Server {
has Board $!board = Board.new;
has Supply $.shots;
has Channel $.player;
method serve {
react {
# Whenever we get a shot coordinates, sent a Hit or Miss to the player
whenever $!shots -> Position $pos {
$!player.send($!board.cell[$pos.y][$pos.x] ?? Hit !! Miss);
# Don't forget to say "I am ready for new events" for the client
$!player.send(Start);
}
# Somebody should start first, and it will be a Server...
$!player.send(Start);
}
}
}
It has a board, and two other attributes - a Supply $.shots and a Channel $.player. If we want to tell something to our player, we are sending a message to the channel. At the same time, we want to know what player wants us to know, so we are listening on everything that comes from our $!shots async stream of values.
The serve method just does our logic - reacts to player's events.
Now to our Player:
class Player {
has Channel $.server;
has Supply $.events;
method play {
react {
whenever $!events {
when Start {
# Here can be user's input
# Simulate answer picking
sleep 1;
$!server.send: Position.new(x => (^10).pick, y => (^10).pick);
# Can be something like:
# my ($x, $y) = get.Int, get.Int;
# $!server.send: Position.new(:$x, :$y);
}
when Hit {
say "I hit that! +1 gold coin!";
}
when Miss {
say "No, that's a miss... -1 bullet!"
}
}
}
}
}
Player has a Channel and a Supply too, as we want a bi-directional relationship. $!server is used to send actions to the server and $!events provides us a stream of events back.
The play method is implemented this way: if the server says that it is ok with our action, we can made our move, if not - we are basically waiting, and when a Hit or Miss event appears, we react to it.
Now we want to tie those two together:
class Game {
has Server $!server;
has Player $!player;
method start {
my $server-to-player = Channel.new;
my $player-to-server = Channel.new;
$!server = Server.new(player => $server-to-player,
shots => $player-to-server.Supply);
$!player = Player.new(server => $player-to-server,
events => $server-to-player.Supply);
start $!server.serve;
sleep 1;
$!player.play;
}
}.new.start;
Firstly, we are creating two channels with self-contained names. Then we create both Server and Player with those channels reversed: player can send to the first one and listen to the second one, server can send to the second one and listen to the first one.
As react is a blocking construct, we cannot run both methods in the same thread, so we start a server in another thread. Then we sleep 1 second to make sure it serves us(that's a hack to avoid negotiation code in this already pretty long answer), and start the player (be it emulation or a real input, you can try both).
Modifying the handlers and the data types sent between Player and Server you can build more complex examples yourself.
One way to do it is to add a Board to the player. If you make it $.board then you get at least a public read accessor which you'll be able to use in the Game class and if you make it is rw you'll get a write accessor so you can just write it.
So, add the Board to Player:
class Player {
has Board $.board is rw = Board.new;
method fire ( ) {
(^10).pick, (^10).pick
}
(And for that to compile you'll need to move the Board class declaration above Player otherwise you'll get a Type 'Board' is not declared error.)
And now you can add a line like this somewhere in the Board class:
$!player.board.cell[$y][$x] = Hit; # or Miss
Also, you need to record one of three states in the cells of the player's board, not two -- Hit, Miss, or unknown. Maybe add Unknown to the enum and initialize the player's board with Unknowns.

Use CMSensorRecorder to continuously collect Accelerometer data in Apple Watch

I want to use CMSensorRecorder to continuously collect the Accelerometer data, also if user didn't open my app on watch\phone.
What I want to do is - "whenever possible" (i.e. watch is awake and I can execute code), do the following:
call recordAccelerometerForDuration to tell watch to keep collecting data for as long as possible
call accelerometerDataFromDate to get data collected so far (or from last time I got the data)
My question is - how to implement the "whenever possible", i.e. how can I cause my watch application to wake up and execute these apis whenever the watch itself wakes up ?
CMSensorRecorder- to recored data continuously use ExtentionDelegate to triger CMSensorRecorder to invoke start recording and reading data.
func applicationDidBecomeActive() {
print("Active")
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
AccelorometerDataReader.sharedReader.sessionEndDate = Date()
AccelorometerDataReader.sharedReader.getRecordedData()
}
func applicationWillResignActive() {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, etc.
print("inactive")
AccelorometerDataReader.sharedReader.startReadingAccelorometerData()
AccelorometerDataReader.sharedReader.sessionStartDate = Date()
}
//AccelorometerReaderCode
func startReadingAccelorometerData()
{
if CMSensorRecorder.isAccelerometerRecordingAvailable()
{
if CMSensorRecorder.isAuthorizedForRecording()
{
print("Authorized.......")
DispatchQueue.global(qos: .background).async
{
self.recorder?.recordAccelerometer(forDuration: 3 * 60) // Record for 3 minutes
}
}
else
{
print("not authorized")
}
}
else
{
print("NOt available for recording")
}
}
func getRecordedData()
{
DispatchQueue.global(qos: .background).async
{
if self.sessionStartDate < self.sessionEndDate
{
if let list = self.recorder?.accelerometerData(from: self.sessionStartDate, to:self.sessionEndDate)
{
for record in list
{
let data = record as! CMRecordedAccelerometerData
print("x: \(data.acceleration.x) y: \(data.acceleration.y) z: \(data.acceleration.z) time :\(data.startDate.getFormattedDate())")
}
}
}
}
}
}
It doesn't seem you can. I have tried the following but none of these really work.
Register for backgroundApplicationRefresh (watchOS 3) and make sure the app is saved to the Dock. Dock apps can rely on getting one call an hour to update themselves.
On completion of the period query for the accelerometer data and archive the result to file and then transfer the file to the iOS companion app. The file transfer will occur in the background independent of the watch kit app assuming you get enough CPU time to write the accelerometer data to file.
Try using ProcessInfo API to keep the process running.
To date the only success I have had is in running an async thread to extract the data and keeping the watch kit app active by tapping on the screen each time the screen blanks.
Hope this helps and please post any better solution you find.

How to catch application titlebar change?

We are running on a Windows Client Platform (generally WinXP) in niche industry program that runs in a 640x480 window back to an AS/400 server. To reduce errors I want to watch for when the title bar of the program changes. Then I need to capture the keyboard entries to validate. I'll then make sure each of the entries is valid since the archaic program does no validation. I'll can then do a pop-up then warning the end-user if errors occur and to reduce/eliminate the exception reports.
My question is how can I capture the event of the application title bar change = 'string' that I need? API call? Aiming to do this in VB unless another would be notable cleaner.
WinEvents should work well here. These are lightweight events that get fired when certain UI changes take place - eg names of objects change - which includes Titlebar text changes. One benefit to this type of hook is that you can set it up to deliver the notifications back to your own process, so you don't need to deal with hooking or IPC. (It also works against both 32-bit and 64-bit processes.)
This is easiest to do in plain C/C++; but can be done in .Net (VB, C#) if you add the appropriate [DllImport]'s.
#include <windows.h>
#include <stdio.h>
#define WM_NAMECHANGED WM_APP
HWND g_hwndTarget; // window we're listening to
void CALLBACK WinEventProc(
HWINEVENTHOOK hWinEventHook,
DWORD event,
HWND hwnd,
LONG idObject,
LONG idChild,
DWORD dwEventThread,
DWORD dwmsEventTime
)
{
// Check this is the window we want. Titlebar name changes result in these
// two values (obtained by looking at some titlebar changes with the
// Accessible Event Watcher tool in the Windows SDK)
if(hwnd == g_hwndTarget && idObject == OBJID_WINDOW && idChild == CHILDID_SELF)
{
// Do minimal work here, just hand off event to mainline.
// If you do anything here that has a message loop - eg display a dialog or
// messagebox, you can get reentrancy.
PostThreadMessage(GetCurrentThreadId(), WM_NAMECHANGED, 0, 0);
}
return;
}
void ReportName(HWND hwnd)
{
WCHAR szName[128];
GetWindowText(hwnd, szName, ARRAYSIZE(szName));
wprintf(L"hwnd 0x%08lx has title: %s\n", HandleToLong(hwnd), szName);
}
int main()
{
wprintf(L"Place mouse pointer over window titlebar to report name changes for and hit return...\n");
getchar();
POINT pt;
GetCursorPos(&pt);
g_hwndTarget = WindowFromPoint(pt);
ReportName(g_hwndTarget);
// Note: this doesn't work for console windows, which are managed by CSRSS.EXE. Simplest (though not efficient) workaround for those
// is to use threadId=0 and filter by hwnd in the callback.
DWORD threadId = GetWindowThreadProcessId(g_hwndTarget, NULL);
// This says: call the callback when any UI elements in the specified thread change
// name. _OUTOFCONTEXT means deliver the notifications in this process, don't hook.
HWINEVENTHOOK hook = SetWinEventHook(EVENT_OBJECT_NAMECHANGE, EVENT_OBJECT_NAMECHANGE, NULL, WinEventProc, 0, threadId, WINEVENT_OUTOFCONTEXT);
// TODO: add error checking as appropriate.
wprintf(L"Waiting...\n");
// Thread needs to have a message loop for SetWinEventHook to work for out-of-context messages.
UINT count = 10;
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
if(msg.message == WM_NAMECHANGED)
{
ReportName(g_hwndTarget);
if(--count == 0)
{
break;
}
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWinEvent(hook);
return 0;
}
Things to watch for: you might get false-positives; and if the name changes rapidly, by the time you get the first event, the name may be at the second value, so you may appear to see two events for the second value. Neither of these should be an issue if you're just using this as a trigger to check for a specified value, however.
I am assuming that you do not own the code for the target application. In this case, there's no easy "call me back when the title changes" event. You then have 2 options to do what you need, which I will outline below.
Easy but not airtight
Have your application get the main window of the target application (this should be easy enough) and poll its title every 100msec or so. When you detect a change, act accordingly.
Difficult but correct
Hook into the target application using e.g. a global CBT hook. Once your code runs in their process subclass their main window, causing all window messages to go through your code first. When your code sees a WM_SETTEXT message going to the main window, you can actively notify your "other" application on the spot using your choice of IPC. If all you need to do is just shout "hey!" to your other application, do so with an auto-reset event (it will be easiest). Of course all this points heavily to unmanaged code.
If the easy solution is not good enough and the difficult one is too much, you can try using an automation library like White (I 've never used it, so I can't really say more than that).

Objective C: Get notifications about a user's idle state

My cocoa app runs background tasks, which I would like to stop when the user becomes idle (no keyboard/mouse input) and then resume when the user becomes active again. Is there a way to register for idle-state notifications?
In case you can't link to Carbon (ie. you want to compile x86_64 bit binary) you can wrap this function (which returns current idle time in seconds resolution as double - CFTimeInterval) in a timer:
#include <IOKit/IOKitLib.h>
CFTimeInterval CFDateGetIdleTimeInterval() {
mach_port_t port;
io_iterator_t iter;
CFTypeRef value = kCFNull;
uint64_t idle = 0;
CFMutableDictionaryRef properties = NULL;
io_registry_entry_t entry;
IOMasterPort(MACH_PORT_NULL, &port);
IOServiceGetMatchingServices(port, IOServiceMatching("IOHIDSystem"), &iter);
if (iter) {
if ((entry = IOIteratorNext(iter))) {
if (IORegistryEntryCreateCFProperties(entry, &properties, kCFAllocatorDefault, 0) == KERN_SUCCESS && properties) {
if (CFDictionaryGetValueIfPresent(properties, CFSTR("HIDIdleTime"), &value)) {
if (CFGetTypeID(value) == CFDataGetTypeID()) {
CFDataGetBytes(value, CFRangeMake(0, sizeof(idle)), (UInt8 *) &idle);
} else if (CFGetTypeID(value) == CFNumberGetTypeID()) {
CFNumberGetValue(value, kCFNumberSInt64Type, &idle);
}
}
CFRelease(properties);
}
IOObjectRelease(entry);
}
IOObjectRelease(iter);
}
return idle / 1000000000.0;
}
You'll need to link your code to IOKit.framework
There's a Carbon API that will send a notification when there hasn't been a user event after a certain duration called EventLoopIdleTimer. Uli Kusterer has written a Cocoa wrapper for here (look for UKIdleTimer).
If you want something lower level, you may be able to implement the behavior you want with a combination of timers and the CoreGraphics function CGEventSourceSecondsSinceLastEventType (available in <CoreGraphics/CGEventSource.h>).
Apple's Technical Q&A QA1340 Registering and unregistering for sleep and wake notifications may be what you are looking for.
If you need more control than NSWorkspaceWillSleepNotification (Listing 1), use I/O Kit and register to receive power notifications (Listing 3).
I used a different approach.
Subclassing UIApplication I override the sendEvent method filtering touches (actually you can filter any kind of event, acceleration, touches, etc.).
Using a shared variable and a background timer I managed the "idle".
Every time the user touch the screen the variable is set with current timeInterval (current time).
The timer fire method checks for the elapsed time since last touch, if greater than the threshold (in my case was around 90seconds) you can POST your own notification.
I used this simple approach to create a custom set of apps that after some idle time automatically call the "screensaver" app.
Nothing clever, it just do the job.
Hope that helps.