aboutsummaryrefslogtreecommitdiff
path: root/src/hotload.c
diff options
context:
space:
mode:
authorkoekeishiya <aasvi93@hotmail.com>2017-08-07 20:23:44 +0200
committerkoekeishiya <aasvi93@hotmail.com>2017-08-07 20:23:44 +0200
commitd69056799a399058005b4950751397a31110de4a (patch)
tree1dee43a2f247094c58d1263cee8c8477b893e376 /src/hotload.c
downloadskhd-d69056799a399058005b4950751397a31110de4a.tar.gz
skhd-d69056799a399058005b4950751397a31110de4a.zip
v0.0.1
Diffstat (limited to 'src/hotload.c')
-rw-r--r--src/hotload.c96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/hotload.c b/src/hotload.c
new file mode 100644
index 0000000..8f39b15
--- /dev/null
+++ b/src/hotload.c
@@ -0,0 +1,96 @@
+#include "hotload.h"
+#include "hotkey.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#define internal static
+
+internal char *
+copy_string(const char *s)
+{
+ unsigned length = strlen(s);
+ char *result = malloc(length + 1);
+ memcpy(result, s, length);
+ result[length] = '\0';
+ return result;
+}
+
+char *file_directory(const char *file)
+{
+ char *last_slash = strrchr(file, '/');
+ *last_slash = '\0';
+ char *directory = copy_string(file);
+ *last_slash = '/';
+ return directory;
+}
+
+char *file_name(const char *file)
+{
+ char *last_slash = strrchr(file, '/');
+ char *name = copy_string(last_slash + 1);
+ return name;
+}
+
+void hotloader_add_file(struct hotloader *hotloader, const char *file)
+{
+ if(!hotloader->enabled) {
+ struct watched_file watch_info;
+ watch_info.directory = file_directory(file);
+ watch_info.filename = file_name(file);
+ hotloader->watch_list[hotloader->watch_count++] = watch_info;
+ printf("hotload: watching file '%s' in directory '%s'\n", watch_info.filename, watch_info.directory);
+ }
+}
+
+bool hotloader_begin(struct hotloader *hotloader, hotloader_callback *callback)
+{
+ if(!hotloader->enabled) {
+ if(hotloader->watch_count) {
+ CFStringRef string_refs[hotloader->watch_count];
+ for(unsigned index = 0; index < hotloader->watch_count; ++index) {
+ string_refs[index] = CFStringCreateWithCString(kCFAllocatorDefault,
+ hotloader->watch_list[index].directory,
+ kCFStringEncodingUTF8);
+ }
+
+ FSEventStreamContext context = {};
+ context.info = (void *) hotloader;
+
+ hotloader->enabled = true;
+ hotloader->path = (CFArrayRef) CFArrayCreate(NULL, (const void **) string_refs, hotloader->watch_count, &kCFTypeArrayCallBacks);
+ hotloader->flags = kFSEventStreamCreateFlagNoDefer | kFSEventStreamCreateFlagFileEvents;
+ hotloader->stream = FSEventStreamCreate(NULL,
+ callback,
+ &context,
+ hotloader->path,
+ kFSEventStreamEventIdSinceNow,
+ 0.5,
+ hotloader->flags);
+ FSEventStreamScheduleWithRunLoop(hotloader->stream, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
+ FSEventStreamStart(hotloader->stream);
+ return true;
+ }
+ }
+ return false;
+}
+
+void hotloader_end(struct hotloader *hotloader)
+{
+ if(hotloader->enabled) {
+ FSEventStreamStop(hotloader->stream);
+ FSEventStreamInvalidate(hotloader->stream);
+ FSEventStreamRelease(hotloader->stream);
+
+ CFIndex count = CFArrayGetCount(hotloader->path);
+ for(unsigned index = 0; index < count; ++index) {
+ CFStringRef string_ref = (CFStringRef) CFArrayGetValueAtIndex(hotloader->path, index);
+ free(hotloader->watch_list[index].directory);
+ free(hotloader->watch_list[index].filename);
+ CFRelease(string_ref);
+ }
+
+ CFRelease(hotloader->path);
+ memset(hotloader, 0, sizeof(struct hotloader));
+ }
+}