Using InstallApplicationEventHandler and RegisterEventHotKey from Carbon framework, I'm able to catch whatever key I want.
On the contrary I can't find a way to handle correctly the event when a key is held down (kept pressed). I mean, when I held down a key, RegisterEventHotKey responds like if I have pressed and then released the key; I want it, instead, to send the "event" continuously until the key is released.
What I really want to achieve, to be precise, when a key is kept pressed is this:
as soon as the key is pressed and held down I want that InstallApplicationEventHandler and RegisterEventHotKey create an event but not only once (as I have now) but every x milliseconds or so until the key is released.
The particular keys that I'm considering are not modifier keys.
Can you help me? I'm really becoming crazy on this!
You need to use an event tap; RegisterEventHotKey isn't flexible enough to do what you want. Check out Event Taps Testbench and the documentation.
Maybe start firing a timer every 0.25 seconds or something that checks to see if the appropriate keys are still down. If they are, re-invoke the action. Otherwise, invalidate the timer.
Related
Asynchronous usage of RegNotifyChangeKeyValue is simple enough: pass it an event object and wait for the event to be signalled.
What is not so clear, however, is the correct way to cancel a notification request. For example, if a timeout has been set on the wait like so:
RegNotifyChangeKeyValue(hKey, false, REG_NOTIFY_CHANGE_LAST_SET, regEvent.SafeWaitHandle, true);
regEvent.WaitOne(TimeSpan.FromMinutes(30))
If the timeout occurs without the notify firing, this notification is left presumably pending and waiting to fire. This is worse if the notify and wait is within a loop, potentially registering many notifications (one for each expired timeout).
Do I simply close both the event handle (regEvent) and the registry key handle (hKey)? Is there anything else I need to call, e.g. directory change notifications have FindCloseChangeNotification, is there an equivalent here?
I'm currently using P/Invoke with C#, but I do not believe that should make a difference - any answer should be focused on the requirements and usage of the Windows API. This would be much the same question if I had used RegNotifyChangeKeyValue/CreateEvent/WaitForSingleObject from VC++.
Closing the open Registry key is enough. When the key is closed, the event is signaled. This is documented behavior. So, simply be sure to close the Registry key before freeing the event.
I'm still new to C# I use Unity3d. I'm wanting to learn about events, I've been reading on them and have the gist of them. My friend recommended me to use this event handler in unity
http://www.willrmiller.com/?p=87
But I really don't know how to use it because.
None of it derives from MonoBehaviour, so how could I trigger the event with a keypress or a Unity condition when it's not deriving from Unity?
In the event class SomethingHappenedEvent I don't even know what parameters would go in there, because I'm new to events. My guess would be a condition like if a key is pressed or something in Unity happened. But that goes back to 1: it doesn't derive from MonoBehavior so I don't know how to do that.
To sum it up how is this event system even getting ran because Unity3d from what I've done so far requires a script to be on a GameObject.
So can someone tell me how to get this working in Unity and better understand events, especially in Unity3d?
None of it derives from monobehavior, so how could I trigger the event with a keypress or a unity condition when its not deriving from unity?
As the post states, you use
Events.instance.Raise(new SomethingHappenedEvent());
That is, if something happens (your keypress or a certain condition) you raise the event. You tell the manager that something happened, and it will take care of telling all interested parties (the listeners) about it.
From reading your question I assume that is your primary source of confusion. This code will not automagically connect to any events. What it does is provide a framework for you to put events into. And you can specify when objects should listen to which events. Then the framework will take care of informing all the listeners whenever an event happens that they might be interested in. An event that you raise.
This is useful in the sense that you don't have to find those objects/entities/GameObjects that you want to notify. Nor do you have to use broadcast messages or solutions like that.
In the event class SomethingHappenedEvent I don't even know what parameters would go in there, because I'm new to events, my guess would be a condition like if a key is pressed or something in unity happened.
Whatever you want really. You are creating your own event. So what information is relevant for your own event? Is it a HitEvent, where you want to know which enemy was hit? Then store the enemy. Is there an event where location is important? Then store the location. It's up to you.
To sum it up how is this event system even getting ran because unity3d from what I've done so far requires a script to be on a gameobject.
This class relies on the concept of a singleton. It has a static instance. This will be initialized whenever you call your Events.instance.Raise(new SomethingHappenedEvent());for the first time. From wherever you call it. The relevant code here is
public static Events instance
{
get
{
if (eventsInstance == null)
{
eventsInstance = new Events();
}
return eventsInstance;
}
}
That is, when trying to get the instance, if it's not created yet create it and then return it. If it was already created, then just return the existing instance. There is no requirement to make this a component and add it to a GameObject.
I'm trying to understand how to use the kFSEventStreamEventFlagEventIdsWrapped event flag with FSEvents.
According to the documentation, the flag is sent to registered instances when the event id counter wraps around, thus rendering previous event id obsolete.
Now let's imagine the following scenario:
I register for FSEvents in my application;
When done processing FSEvents (my application quits for instance), I save the last event id encountered while processing events to be able to replay changes from that id;
While my application is not running, the event id counter wraps around.
My question is: How am I supposed to know the counter wrapped around? (Thus requiring me to re-scan the whole directory structure.)
I now have an answer directly from Apple.
The scenario was wrong to begin with. When saving the last event id treated, you must also save with it the UUID of the event stream. An event id is valid only for a given event stream, which is identified by its UUID (see FSEventsCopyUUIDForDevice()).
Whenever the event id counter wraps around, a new event stream UUID is generated. So if you relaunch the app after the event id counter wrapped around, your stored last event id won’t be valid anymore, and you’ll know it as the event stream UUID won’t be the same.
If you encounter the kFSEventStreamEventFlagEventIdsWrapped flag, it means the counter wrapped around while your app was open. However, there’s nothing particular to be done. You should just be sure to get the new event stream UUID if you want to save the last event id.
EDIT:
Event IDs do not wrap.
Here is why: Suppose your machine generates 1 filesystem event per millisecond. This means it will generate ms_per_year=31536000000 filesystem events per year. So it will take more than 500 million years before the counter will wrap around the 64bit boundary.
>>> ms_per_year = 1000*60*60*24*365
>>> d64 = 2**64
>>> d64/ms_per_year
584942417L
If kFSEventStreamEventFlagEventIdsWrapped is set, it means the 64-bit event ID counter wrapped around. As a result, previously-issued event ID's are no longer valid arguments for the sinceWhen parameter of the FSEventStreamCreate() functions.[1]
Next time your should use kFSEventStreamEventIdSinceNow for FSEventStreamEventId and you must rescan all directory.
Which event should be used for key press handling key-down/key-up? It is sure that in both case the program will run successfully. But which one will be more user-friendly?
It depends on you. There is no such best practice. Both are used as per the need of your program and as per the convenience of the user.
keyup
Fires when the user releases a key, after the default action of that key has been performed.
keydown
Fires when the user depresses a key. It repeats while the user keeps the key depressed.
Check out this page describing the differences.
I am working on a non-document-based Core Data application.
I would like changes to be saved as they happen. This is what the user expects in this type of application. It is also what Apple has implemented in iPhoto or iTunes.
A brute force approach would be to set up a timer to save frequently. The method triggered by the saving would then swallow all validation errors so as not to bother the user. Only upon quitting, the user will be bugged to arrange the data so it can save. IMHO, that approach stinks.
So I am thinking, there must be a way to somehow hook saving to something like the NSEditor protocol. Every time the user (or a controller) finishes editing data, the application delegate should somehow be notified an trigger a save operation. Thing is I don't quite know where to look.
I would think that for more complicated operations, which may require some cross-validations to go through, I would present the user with bit of interface tied to a dedicated NSManagedObjectContext.
At the end of each event in an AppKit app, CoreData will run a -processPendingTransactions for you.
One side-effect of this is that if you've registered with your NSManagedObjectContext to receive change notifications, you'll get called at the end of each event.
So, for instance, in your notification handler, you could call just tell the context to save.
However, you might be paranoid about doing a save on a context while in a callback from that same context, so you'd probably feel better if you did a performSelector:#selector(save:) afterDelay: to push the save until after the -processPendingTransactions is done.
You could even do a cancel previous on the -save: selector and have the delay be like 5 seconds, so if the user or app is in the middle of a BUNCH of changes they'll all coalesce into a single save.
And, in fact, that's exactly how Delicious Library 1.0-1.09 worked.
-Wil