Ivan Andrus <address@hidden
> schrieb am Do., 26. Nov. 2015 um 07:09 Uhr:
I’ve started writing an Emacs module to access NSSpeechSynthesizer on OS X (and maybe GNUStep though I haven’t tested it there). I’ve been using the mod-test module as an example and I have it working reasonably well except that I don’t have any idea how to run a callback.
When the synthesizer is done speaking it sends an Objective-C message speechSynthesizer:didFinishSpeaking. From there I would like to run an elisp hook, say `ns-speech-finished-speaking-hook`. How can I do this? Do I have to squirrel away a pointer to an emacs_env somehow? I tried naively storing env from a previous call but, not surprisingly, the pointer is invalid when I try to use it.
Yes, that is currently working as designed. Environments are alive only while Emacs calls some module functions.
There are two major issues with allowing callbacks at arbitrary times, which need to be discussed and resolved first. The first is that such a facility would change the execution model of Emacs in a quite fundamental way. Right now all user-defined code inside the Emacs process gets run through a path under the control of Emacs, either as a response to an input event, or a timer, or a process filter etc. Adding a facility to run module code from arbitrary callbacks would remove this invariant, which can have global effects on Emacs. With the current design modules are a pretty localized feature: almost no other part of Emacs has to know about their existence. If we allow callbacks at arbitrary times all parts of Emacs would suddenly have to be prepared for this, and after decades of development there might well be hidden assumptions that such things cannot happen. Therefore I'd be very cautious before introducing such a facility.
The second issue is how such a facility should be made available. Currently all communication between modules and Emacs happens through modules, and there is no facility how modules can request creation of an environment. However, it makes little sense to discuss this issue until the first one is resolved.