Created
February 19, 2020 04:17
-
-
Save commandblockguy/8eb7fcfca46df2967903c3eb2adeb9db to your computer and use it in GitHub Desktop.
Random incomprehensible scrawlings about hook manager spec
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Currently unnamed CE hook manager: | |
The system will have the following components: | |
Hook executors - Each TI-OS hook has an associated entry point which is responsible for calling all user hooks for that type. | |
Hook arrays - An null-terminated array of pointers to user hooks for a particular hook subtype, sorted by priority. The array is read by the hook executor each time it is called, and is completely overwritten by the hook manager each time a change is necessary. | |
Hook manager - A library that is responsible for installing the hook executors and maintaining the hook arrays. The hook manager is only called when installing, changing, or viewing metadata of user hooks. | |
Hook database - Internal data storage for the hook manager than consists of a list of hooks and their metadata. | |
User hooks: | |
User hooks are like OS hooks, but are called by the hook executor rather than TI-OS | |
Each hook must start with 0x83, like OS hooks | |
All valid OS hooks are valid user hooks provided that they have the lowest priority of all hooks of their type | |
Rather than taking the hook subtype in a, as with OS hooks, the hooks should be registered by subtype whenever possible | |
If a hook needs to process many values of a, a wildcard subtype can be used instead | |
In addition to returning the value that the OS expects, user hooks should return a value in d // is this used by anything? | |
If the return value of the function should be ignored and lower-priority user hooks should be processed, d should contain a non-zero value | |
If the return value of the function should be passed on to TI-OS, ignoring lower-priority user hooks, d should contain zero | |
Example program flow on hook fire: | |
User presses the 1 key | |
TI-OS calls the hook executor for the getcsc hook | |
Hook executor backs up relevant input registers | |
Hook executor calls the first wildcard user hook for the getcsc hook // should subtype-specific be processed before wildcards? | |
User hook indicates that further hooks should be processed rather than returning to the OS | |
Hook executor restores register backup | |
Next wilcard user hook is NULL - hook executor moves on to the specific hook type (a = 0x1B) | |
Hook executor calls the first subtype-specific user hook | |
User hook checks the scan code and decides to take no action | |
User hook indicates that further hooks should be processed rather than returning to the OS | |
Hook executor calls the next subtype-specific user hook | |
User hook checks the scan code and decides to open a menu | |
User hook indicates that control should be given back to the OS | |
Hook executor returns control to the OS | |
User hook installation procedure: | |
Create hook database if it does not exist | |
If hook to be installed is already in database: | |
If the entry is valid, return the pointer to it // should this behave differently? | |
Otherwise, update the entry with the new pointer | |
Otherwise, create a new entry for it | |
Refresh hooks for that OS hook type | |
Refreshing hooks for a particular OS hook type: | |
Check if the existing hook is our own hook executor | |
If not, and hook is valid, create a new minimum-priority wildcard hook entry for it | |
Copy the hook executor code into an appvar, ommitting unncessary portions (e.g. the wildcard checks if there are only subtype-specific hooks, or the return value checker if there is only one hook) | |
Get all addresses of hooks of each subtype from the database, sorted by priority and ignoring invalid hooks, and copy them into the appvar | |
Achive the appvar | |
Get the data pointer from the appvar // Is there a better way of allocating memory than this, besides making an app? - maybe Mateo's relocation table system? | |
Delete the appvar | |
Call the OS sethook call | |
User-facing hook manager functions (probably need some work in terms of interface): | |
(C syntax is used for returns and arguments, though the final library may not use C functions) | |
bool refresh_hooks(void) - regenerates hook executors and hook arrays for all types in the database. call at the beginning of the program to restore functionality. | |
user_hook_entry_t *install_hook(uint24_t id, void *hook, uint8_t type, uint8_t subtype, uint8_t priority, char *description) - installs and enables a user hook from a pointer. returns NULL if installation failed or a pointer to the hook entry in the hook database. if the hook is already installed, a pointer to the existing entry is returned. | |
bool uninstall_hook(user_hook_entry_t *entry) - uninstalls a user hook | |
user_hook_entry_t *get_entry_by_id(uint24_t id) - gets a pointer to a hook database entry by its unique id, or NULL if no such entry exists. | |
bool set_priority(user_hook_entry_t *entry, uint8_t priority) - sets the priority of a hook | |
bool check_hook_validity(user_hook_entry_t *entry) - checks if a user hook is valid | |
The hook database is stored in a regular appvar. | |
user_hook_entry_t: | |
uint24_t id | |
void *hook // pointer to the user hook | |
uint8_t type // enum for which OS hook to use | |
uint8_t subtype // which value of a this user hook should fire for, or a "wildcard" magic value which causes the hook to fire for all subtypes | |
uint8_t priority // process lowest priorities first | |
bool enabled | |
char description[64]; | |
// Maybe add a checksum, in addition to the 0x83 ? |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment