From 36d047d485590b6bd1b32cac19b651e57070c583 Mon Sep 17 00:00:00 2001 From: camh Date: Thu, 6 Jan 2022 22:09:39 -0800 Subject: [PATCH] small fixes --- JS/index.js | 66 ++++++++++++++++++++++++++++++++------ coprocessorjs.c | 15 +++++++++ mac_main.c | 36 ++++++++++++++++----- nuklear.h | 48 ++++++++++++++++++---------- nuklear_app.c | 77 ++++++++++++++++++++++++++++++++++++++++++--- nuklear_quickdraw.h | 1 + 6 files changed, 205 insertions(+), 38 deletions(-) diff --git a/JS/index.js b/JS/index.js index 9239783..29c1347 100644 --- a/JS/index.js +++ b/JS/index.js @@ -4,7 +4,7 @@ const InMemoryCache = require('apollo-cache-inmemory').InMemoryCache; const createHttpLink = require('apollo-link-http').createHttpLink; const gql = require('graphql-tag') -// TEST_MODE can be turned on or off to prevent communications with the Apollo iMessage Server running on your moder Mac +// TEST_MODE can be turned on or off to prevent communications with the Apollo iMessage Server running on your modern Mac const TEST_MODE = false const defaultOptions = { @@ -151,7 +151,7 @@ const widthFor12ptFont = [ 8 ] -// this is tied to Sample.c's message window max width +// this is tied to mac_main.c's message window max width const MAX_WIDTH = 304 const SPACE_WIDTH = widthFor12ptFont[32] @@ -291,9 +291,6 @@ const parseChatsToFriendlyNameString = (chats) => { friendlyNameStrings = friendlyNameStrings.substring(1, friendlyNameStrings.length) - console.log(`chats`) - console.log(friendlyNameStrings) - return friendlyNameStrings } @@ -392,10 +389,6 @@ class iMessageClient { return splitMessages(TEST_MESSAGES) } - console.log(`send message`) - console.log(chatId) - console.log(message) - let result try { @@ -459,6 +452,61 @@ class iMessageClient { return parseChatsToFriendlyNameString(chats) } + async getChatCounts () { + + if (TEST_MODE) { + + return parseChatsToFriendlyNameString(TEST_CHATS) + } + + let result + + try { + + result = await client.query({ + query: gql`query getChatCounts { + getChatCounts { + friendlyName + count + } + }` + }) + } catch (error) { + + console.log(`error with apollo query`) + console.log(error) + + result = { + data: { + } + } + } + + let chats = result.data.getChatCounts + + if (!chats) { + + return `` + } + + let friendlyNameStrings = `` + + if (chats.length === 0) { + + return `` + } + + for (let chat of chats) { + + friendlyNameStrings = `${friendlyNameStrings},${chat.friendlyName.replace(/,/g, '')}:::${chat.count}` + } + + // remove trailing comma + friendlyNameStrings = friendlyNameStrings.substring(1, friendlyNameStrings.length) + + return friendlyNameStrings + } + setIPAddress (IPAddress) { console.log(`instantiate apolloclient with uri ${IPAddress}:4000/`) diff --git a/coprocessorjs.c b/coprocessorjs.c index 1e5a6c1..f0c0839 100644 --- a/coprocessorjs.c +++ b/coprocessorjs.c @@ -195,6 +195,8 @@ void wait(float timeInSeconds) { // printf(log); } +const int MAX_RECIEVE_LOOP_ITERATIONS = 1000; + // void because this function re-assigns respo void readSerialPort(char* output) { @@ -210,9 +212,22 @@ void readSerialPort(char* output) { char tempOutput[MAX_RECEIVE_SIZE]; long int totalByteCount = 0; incomingSerialPortReference.ioReqCount = 0; + int loopCounter = 0; while (!done) { + if (loopCounter++ > MAX_RECIEVE_LOOP_ITERATIONS) { + + char *errorMessage = "TIMEOUT_ERROR"; + + strncat(output, errorMessage, strlen(errorMessage)); + + // once we are done reading the buffer entirely, we need to clear it. i'm not sure if this is the best way or not but seems to work + memset(&GlobalSerialInputBuffer[0], 0, MAX_RECEIVE_SIZE); + + return; + } + long int byteCount = 0; long int lastByteCount = 0; bool doByteCountsMatch = false; diff --git a/mac_main.c b/mac_main.c index c48d21d..24f2c07 100644 --- a/mac_main.c +++ b/mac_main.c @@ -178,7 +178,8 @@ void EventLoop(struct nk_context *ctx) int lastMouseHPos = 0; int lastMouseVPos = 0; - int lastUpdatedTickCount = 0; + int lastUpdatedTickCountMessagesInChat = 0; + int lastUpdatedTickCountChatCounts = 0; do { @@ -191,10 +192,10 @@ void EventLoop(struct nk_context *ctx) // check for new stuff every 10 sec? // note! this is used by some of the functionality in our nuklear_app to trigger // new chat lookups - if (TickCount() - lastUpdatedTickCount > 600) { + if (TickCount() - lastUpdatedTickCountMessagesInChat > 600) { // writeSerialPortDebug(boutRefNum, "update by tick count"); - lastUpdatedTickCount = TickCount(); + lastUpdatedTickCountMessagesInChat = TickCount(); if (strcmp(activeChat, "no active chat")) { @@ -203,6 +204,20 @@ void EventLoop(struct nk_context *ctx) } } + // this should be out of sync with the counter above it so that we dont end up making + // two coprocessor calls on one event loop iteration + if (TickCount() - lastUpdatedTickCountChatCounts > 300) { + + // writeSerialPortDebug(boutRefNum, "update by tick count"); + lastUpdatedTickCountChatCounts = TickCount(); + + if (chatFriendlyNamesCounter > 0) { + + // writeSerialPortDebug(boutRefNum, "check chat counts"); + getChatCounts(activeChat); + } + } + Boolean beganInput = false; GetGlobalMouse(&mouse); @@ -239,7 +254,8 @@ void EventLoop(struct nk_context *ctx) mouse_x = tempPoint.h; mouse_y = tempPoint.v; - lastUpdatedTickCount = TickCount(); + lastUpdatedTickCountChatCounts = TickCount(); + lastUpdatedTickCountMessagesInChat = TickCount(); lastMouseHPos = mouse.h; lastMouseVPos = mouse.v; GetGlobalMouse(&mouse); @@ -252,7 +268,8 @@ void EventLoop(struct nk_context *ctx) // drain all events before rendering -- really this only applies to keyboard events and single mouse clicks now while (gotEvent) { - lastUpdatedTickCount = TickCount(); + lastUpdatedTickCountChatCounts = TickCount(); + lastUpdatedTickCountMessagesInChat = TickCount(); #ifdef MAC_APP_DEBUGGING @@ -305,7 +322,7 @@ void EventLoop(struct nk_context *ctx) #ifdef MAC_APP_DEBUGGING - writeSerialPortDebug(boutRefNum, "nk_quickdraw_render"); + writeSerialPortDebug(boutRefNum, "nuklearApp"); #endif nuklearApp(ctx); @@ -315,6 +332,11 @@ void EventLoop(struct nk_context *ctx) PROFILE_START("nk_quickdraw_render"); #endif + #ifdef MAC_APP_DEBUGGING + + writeSerialPortDebug(boutRefNum, "nk_quickdraw_render"); + #endif + nk_quickdraw_render(FrontWindow(), ctx); #ifdef PROFILING @@ -464,7 +486,7 @@ void DoEvent(EventRecord *event, struct nk_context *ctx) { case osEvt: #ifdef MAC_APP_DEBUGGING - riteSerialPortDebug(boutRefNum, "os"); + writeSerialPortDebug(boutRefNum, "os"); #endif // this should be trigger on mousemove but does not -- if we can figure that out, we should call through to diff --git a/nuklear.h b/nuklear.h index 997d3be..cad255c 100644 --- a/nuklear.h +++ b/nuklear.h @@ -10504,8 +10504,12 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan // NK_ASSERT(ctx); // NK_ASSERT(ctx->current); // NK_ASSERT(ctx->current->layout); - if (!ctx || !ctx->current || !ctx->current->layout) return 0; + if (!ctx || !ctx->current || !ctx->current->layout) { + return 0; + } + nk_zero(ctx->current->layout, sizeof(*ctx->current->layout)); + if ((ctx->current->flags & NK_WINDOW_HIDDEN) || (ctx->current->flags & NK_WINDOW_CLOSED)) { nk_zero(ctx->current->layout, sizeof(struct nk_panel)); ctx->current->layout->type = panel_type; @@ -10638,11 +10642,12 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan } /* window close button */ - {struct nk_rect button; - button.y = header.y + style->window.header.padding.y; - button.h = header.h - 2 * style->window.header.padding.y; - button.w = button.h; + { if (win->flags & NK_WINDOW_CLOSABLE) { + struct nk_rect button; + button.y = header.y + style->window.header.padding.y; + button.h = header.h - 2 * style->window.header.padding.y; + button.w = button.h; nk_flags ws = 0; if (style->window.header.align == NK_HEADER_RIGHT) { button.x = (header.w + header.x) - (button.w + style->window.header.padding.x); @@ -10663,6 +10668,10 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan /* window minimize button */ if (win->flags & NK_WINDOW_MINIMIZABLE) { + struct nk_rect button; + button.y = header.y + style->window.header.padding.y; + button.h = header.h - 2 * style->window.header.padding.y; + button.w = button.h; nk_flags ws = 0; if (style->window.header.align == NK_HEADER_RIGHT) { button.x = (header.w + header.x) - button.w; @@ -10695,7 +10704,7 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan label.h = font->height + 2 * style->window.header.label_padding.y; label.w = t + 2 * style->window.header.spacing.x; label.w = NK_CLAMP(0, label.w, header.x + header.w - label.x); - nk_widget_text(out, label, (const char*)title, text_len, &text, NK_TEXT_LEFT, font, true);} + nk_widget_text(out, label, (const char*)title, text_len, &text, NK_TEXT_ALIGN_MIDDLE, font, true);} } /* draw window background */ @@ -10722,8 +10731,7 @@ nk_panel_begin(struct nk_context *ctx, const char *title, enum nk_panel_type pan /* set clipping rectangle */ {struct nk_rect clip; layout->clip = layout->bounds; - nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y, - layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h); + nk_unify(&clip, &win->buffer.clip, layout->clip.x, layout->clip.y, layout->clip.x + layout->clip.w, layout->clip.y + layout->clip.h); nk_push_scissor(out, clip); layout->clip = clip;} return !(layout->flags & NK_WINDOW_HIDDEN) && !(layout->flags & NK_WINDOW_MINIMIZED); @@ -11182,8 +11190,9 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, // NK_ASSERT(title); // NK_ASSERT(ctx->style.font && ctx->style.font->width && "if this triggers you forgot to add a font"); // NK_ASSERT(!ctx->current && "if this triggers you missed a `nk_end` call"); - if (!ctx || ctx->current || !title || !name) + if (!ctx || ctx->current || !title || !name) { return 0; + } /* find or create window */ style = &ctx->style; @@ -11197,9 +11206,12 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, // NK_ASSERT(win); if (!win) return 0; - if (flags & NK_WINDOW_BACKGROUND) + if (flags & NK_WINDOW_BACKGROUND) { nk_insert_window(ctx, win, NK_INSERT_FRONT); - else nk_insert_window(ctx, win, NK_INSERT_BACK); + } else { + nk_insert_window(ctx, win, NK_INSERT_BACK); + } + nk_command_buffer_init(&win->buffer, &ctx->memory, NK_CLIPPING_ON); win->flags = flags; @@ -11209,14 +11221,16 @@ nk_begin_titled(struct nk_context *ctx, const char *name, const char *title, NK_MEMCPY(win->name_string, name, name_length); win->name_string[name_length] = 0; win->popup.win = 0; - if (!ctx->active) + if (!ctx->active) { ctx->active = win; + } } else { /* update window */ win->flags &= ~(nk_flags)(NK_WINDOW_PRIVATE-1); win->flags |= flags; - if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE))) + if (!(win->flags & (NK_WINDOW_MOVABLE | NK_WINDOW_SCALABLE))) { win->bounds = bounds; + } /* If this assert triggers you either: * * I.) Have more than one window with the same name or @@ -18408,9 +18422,9 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, short l = nk_str_len_char(&edit->string); const char *begin = nk_str_get_const(&edit->string); - const struct nk_style_item *background; - struct nk_color background_color; - struct nk_color text_color; + // const struct nk_style_item *background; + // struct nk_color background_color; + // struct nk_color text_color; nk_push_scissor(out, clip); // if (*state & NK_WIDGET_STATE_ACTIVED) { // background = &style->active; @@ -18434,7 +18448,7 @@ nk_do_edit(nk_flags *state, struct nk_command_buffer *out, whiteTextarea.w = area.w; nk_fill_rect(out, whiteTextarea, 0, nk_rgba(255,255,255,255), false); - nk_edit_draw_text(out, style, area.x - edit->scrollbar.x, area.y - edit->scrollbar.y, 0, begin, l, row_height, font, background->data.color, text_color, nk_false, false); + nk_edit_draw_text(out, style, area.x - edit->scrollbar.x, area.y - edit->scrollbar.y, 0, begin, l, row_height, font, style->normal.data.color, style->text_normal, nk_false, true); } nk_push_scissor(out, old_clip);} diff --git a/nuklear_app.c b/nuklear_app.c index c04fd0d..5bf1600 100644 --- a/nuklear_app.c +++ b/nuklear_app.c @@ -1,8 +1,7 @@ // TODO: -// - IN PROGRESS new message window -- needs to blank out messages, then needs fixes on new mac end -// - get new messages in other chats and display some sort of alert -// - need timeout on serial messages in case the computer at the other end dies (prevent hard reset) -- probably possible in coprocessorjs library -// - delete doesnt work right (leaves characters at end of string) +// - IN PROGRESS new message window -- needs to blank out messages, then needs fixes on new mac end -- this might work +// - IN PROGRESS get new messages in other chats and display some sort of alert +// - IN PROGRESS need timeout on serial messages in case the computer at the other end dies (prevent hard reset) -- probably possible in coprocessorjs library. made an attempt, needs tested #define WINDOW_WIDTH 510 #define WINDOW_HEIGHT 302 @@ -48,6 +47,8 @@ char box_input_buffer[2048]; char chatFriendlyNames[16][64]; char ip_input_buffer[255]; char jsFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE +char chatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE +char previousChatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE char new_message_input_buffer[255]; int activeMessageCounter = 0; int chatFriendlyNamesCounter = 0; @@ -149,6 +150,68 @@ void getMessages(char *thread, int page) { return; } +void getChatCounts() { + + char output[62]; + sprintf(output, ""); + // writeSerialPortDebug(boutRefNum, output); + + callFunctionOnCoprocessor("getChatCounts", output, chatCountFunctionResponse); + // writeSerialPortDebug(boutRefNum, jsFunctionResponse); + + if (!strcmp(chatCountFunctionResponse, previousChatCountFunctionResponse)) { + + writeSerialPortDebug(boutRefNum, "update current chat count"); + writeSerialPortDebug(boutRefNum, chatCountFunctionResponse); + SysBeep(1); + char *token = (char *)strtok(chatCountFunctionResponse, ","); + + // loop through the string to extract all other tokens + while (token != NULL) { + writeSerialPortDebug(boutRefNum, "update current chat count loop"); + writeSerialPortDebug(boutRefNum, token); + // should be in format NAME:::COUNT + + char *name = strtok(token, ":::"); + short count = atoi(strtok(NULL, " ")); + + if (count == 0) { + + continue; + } + + for (int i = 0; i < chatFriendlyNamesCounter; i++) { + + if (strstr(chatFriendlyNames[i], " new) ")) { + + char *tempChatFriendlyName; + strtok(chatFriendlyNames[i], " new) "); + tempChatFriendlyName = strtok(NULL, " "); + + if (strcmp(tempChatFriendlyName, name)) { + + sprintf(chatFriendlyNames[i], "(%d new) %s", count, name); + break; + } + } else { + + if (strcmp(chatFriendlyNames[i], name)) { + + sprintf(chatFriendlyNames[i], "(%d new) %s", count, name); + break; + } + } + } + + token = (char *)strtokm(NULL, ","); + } + + strcpy(previousChatCountFunctionResponse, chatCountFunctionResponse); + } + + return; +} + void getHasNewMessagesInChat(char *thread) { char output[62]; @@ -163,8 +226,9 @@ void getHasNewMessagesInChat(char *thread) { // writeSerialPortDebug(boutRefNum, "update current chat"); SysBeep(1); getMessages(thread, 0); + // force redraw - firstOrMouseMove = true; + forceRedraw = 3; } return; @@ -174,6 +238,8 @@ void getHasNewMessagesInChat(char *thread) { // run it on some interval? make sure user is not typing!!! void getChats() { + writeSerialPortDebug(boutRefNum, "getChats!"); + if (haveRun) { return; @@ -186,6 +252,7 @@ void getChats() { char * token = (char *)strtokm(jsFunctionResponse, ","); // loop through the string to extract all other tokens while (token != NULL) { + writeSerialPortDebug(boutRefNum, token); sprintf(chatFriendlyNames[chatFriendlyNamesCounter++], "%s", token); token = (char *)strtokm(NULL, ","); } diff --git a/nuklear_quickdraw.h b/nuklear_quickdraw.h index 9f785aa..d7fa94e 100644 --- a/nuklear_quickdraw.h +++ b/nuklear_quickdraw.h @@ -26,6 +26,7 @@ #define ENABLED_DOUBLE_BUFFERING #define COMMAND_CACHING +// #define NK_QUICKDRAW_GRAPHICS_DEBUGGING Boolean lastInputWasBackspace;