take care of final todo items and come up with perceptual perf improvements on the coprocessorjs side of the app

This commit is contained in:
camh 2022-01-11 00:00:31 -08:00
parent db302f0b97
commit f3755e40f9
4 changed files with 229 additions and 68 deletions

View File

@ -154,6 +154,7 @@ const widthFor12ptFont = [
// this is tied to mac_main.c's message window max width
const MAX_WIDTH = 304
const SPACE_WIDTH = widthFor12ptFont[32]
let canStart = false
const getNextWordLength = (word) => {
@ -325,10 +326,37 @@ if (TEST_MODE) {
}, 10000)
}
class iMessageClient {
let storedArgsAndResults = {
getMessages: {
args: {},
output: {}
},
hasNewMessagesInChat: {
args: {},
output: {}
},
getChats: {
args: {},
output: {}
},
getChatCounts: {
args: {},
output: {}
}
}
// this is our private interface, meant to communicate with our GraphQL server and fill caches
// we want everything cached as much as possible to cut down on perceived perf issues on the
// classic Macintosh end
class iMessageGraphClientClass {
async getMessages (chatId, page) {
storedArgsAndResults.getMessages.args = {
chatId,
page
}
if (TEST_MODE) {
return splitMessages(TEST_MESSAGES)
@ -361,23 +389,19 @@ class iMessageClient {
let messages = result.data.getMessages
return splitMessages(messages)
storedArgsAndResults.getMessages.output = splitMessages(messages)
}
async hasNewMessagesInChat (chatId) {
storedArgsAndResults.hasNewMessagesInChat.args = {
chatId
}
let currentLastMessageOutput = `${lastMessageOutput}`
let messageOutput = await this.getMessages(chatId, 0)
return (currentLastMessageOutput !== messageOutput).toString()
}
async hasNewMessages (chatId) {
let currentLastMessageOutput = `${lastMessageOutput}`
let messageOutput = await this.getChats(chatId, 0)
return (currentLastMessageOutput !== messageOutput).toString()
storedArgsAndResults.hasNewMessagesInChat.output = (currentLastMessageOutput !== messageOutput).toString()
}
async sendMessage (chatId, message) {
@ -418,6 +442,7 @@ class iMessageClient {
}
async getChats () {
console.log(`getChats`)
if (TEST_MODE) {
@ -452,7 +477,9 @@ class iMessageClient {
console.log(`getChats complete`)
return parseChatsToFriendlyNameString(chats)
storedArgsAndResults.getChats.output = parseChatsToFriendlyNameString(chats)
console.log(storedArgsAndResults.getChats.output)
}
async getChatCounts () {
@ -512,7 +539,7 @@ class iMessageClient {
friendlyNameStrings = friendlyNameStrings.substring(1, friendlyNameStrings.length)
console.log(friendlyNameStrings)
return friendlyNameStrings
storedArgsAndResults.getChatCounts.output = friendlyNameStrings
}
setIPAddress (IPAddress) {
@ -521,6 +548,8 @@ class iMessageClient {
if (TEST_MODE) {
canStart = true
return `success`
}
@ -543,9 +572,107 @@ class iMessageClient {
console.log(`return success`)
canStart = true
return `success`
}
}
let iMessageGraphClient = new iMessageGraphClientClass()
// provide the public interface
class iMessageClient {
constructor () {
// kick off an update interval
setInterval(async () => {
console.log(`run interval`)
if (!canStart) {
console.log(`can't start yet`)
return
}
console.log(`running...`)
if (Object.keys(storedArgsAndResults.getMessages.args).length > 0) {
await iMessageGraphClient.getMessages(storedArgsAndResults.getMessages.args.chatId, storedArgsAndResults.getMessages.args.page)
}
if (Object.keys(storedArgsAndResults.hasNewMessagesInChat.args).length > 0) {
await iMessageGraphClient.hasNewMessagesInChat(storedArgsAndResults.hasNewMessagesInChat.chatId)
}
await iMessageGraphClient.getChats()
await iMessageGraphClient.getChatCounts()
console.log(`complete!`)
}, 2000)
}
async getMessages (chatId, page) {
console.log(`iMessageClient.getMessages`)
if (storedArgsAndResults.getMessages.args.chatId !== chatId || storedArgsAndResults.getMessages.args.page !== page) {
await iMessageGraphClient.getMessages(chatId, page)
}
return storedArgsAndResults.getMessages.output
}
async hasNewMessagesInChat (chatId) {
console.log(`iMessageClient.hasNewMessagesInChat`)
if (storedArgsAndResults.hasNewMessagesInChat.args.chatId !== chatId) {
await iMessageGraphClient.hasNewMessagesInChat(chatId)
}
return storedArgsAndResults.hasNewMessagesInChat.output
}
async sendMessage (chatId, message) {
console.log(`iMessageClient.sendMessage`)
return await iMessageGraphClient.sendMessage(chatId, message)
}
async getChats () {
console.log(`iMessageClient.getChats`)
if (Object.keys(storedArgsAndResults.getChats.output).length === 0) {
await iMessageGraphClient.getChats()
}
return storedArgsAndResults.getChats.output
}
getChatCounts () {
console.log(`iMessageClient.getChatCounts`)
return storedArgsAndResults.getChatCounts.output
}
setIPAddress (IPAddress) {
console.log(`iMessageClient.setIPAddress`)
return iMessageGraphClient.setIPAddress(IPAddress)
}
}
module.exports = iMessageClient

View File

@ -682,7 +682,18 @@ void DoMenuCommand(menuResult)
case mLight:
// note this was co-opted to send new chats instead of the demo functionality. do the
// same thing for other menu items as necessary
sendNewChat = 1;
switch (menuItem) {
case 2:
getChats();
break;
default:
sendNewChat = 1;
break;
}
char x[255];
sprintf(x, "MENU %d", menuItem);
writeSerialPortDebug(boutRefNum, x);
break;
case mHelp:

View File

@ -137,6 +137,8 @@ resource 'MENU' (mLight, preload) {
{
"New Message",
noicon, nokey, nomark, plain;
"Refresh Chat List",
noicon, nokey, nomark, plain;
}
};

View File

@ -1,6 +1,5 @@
// TODO:
// - IN PROGRESS new message window -- need to figure this out
// - 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
// - test, bug fixes, write blog posts
#define WINDOW_WIDTH 510
#define WINDOW_HEIGHT 302
@ -49,13 +48,13 @@ char chatFriendlyNames[16][64];
char ip_input_buffer[255];
char jsFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE
char chatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE
char tempChatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE
char previousChatCountFunctionResponse[102400]; // Matches MAX_RECEIVE_SIZE
char new_message_input_buffer[255];
int activeMessageCounter = 0;
int chatFriendlyNamesCounter = 0;
int coprocessorLoaded = 0;
int forceRedraw = 2; // this is how many 'iterations' of the UI that we need to see every element for
int haveRun = 0;
int ipAddressSet = 0;
int mouse_x;
int mouse_y;
@ -115,6 +114,25 @@ void sendMessage() {
return;
}
// set up function to get available chat (fill buttons on the left hand side)
// interval is set by the event loop in mac_main
void getChats() {
writeSerialPortDebug(boutRefNum, "getChats!");
callFunctionOnCoprocessor("getChats", "", jsFunctionResponse);
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, ",");
}
return;
}
void sendIPAddressToCoprocessor() {
char output[2048];
@ -123,6 +141,9 @@ void sendIPAddressToCoprocessor() {
writeSerialPortDebug(boutRefNum, output);
callFunctionOnCoprocessor("setIPAddress", output, jsFunctionResponse);
// now that the IP is set, we can get all of our chats
getChats();
return;
}
@ -170,8 +191,9 @@ void getChatCounts() {
#endif
SysBeep(1);
char **saveptr;
char *token = strtok_r(chatCountFunctionResponse, ",", saveptr);
char *saveptr;
strcpy(tempChatCountFunctionResponse, chatCountFunctionResponse);
char *token = strtok_r(tempChatCountFunctionResponse, ",", &saveptr);
// loop through the string to extract all other tokens
while (token != NULL) {
@ -182,9 +204,9 @@ void getChatCounts() {
#endif
// should be in format NAME:::COUNT
char **saveptr2;
char *name = strtok_r(token, ":::", saveptr2);
char *countString = strtok_r(NULL, ":::", saveptr2);
char *saveptr2;
char *name = strtok_r(token, ":::", &saveptr2);
char *countString = strtok_r(NULL, ":::", &saveptr2);
short count = atoi(countString);
#ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
@ -193,13 +215,6 @@ void getChatCounts() {
writeSerialPortDebug(boutRefNum, x);
#endif
if (count == 0) {
token = strtok_r(NULL, ",", saveptr);
continue;
}
for (int i = 0; i < chatFriendlyNamesCounter; i++) {
if (strstr(chatFriendlyNames[i], " new) ") != NULL) {
@ -208,9 +223,9 @@ void getChatCounts() {
sprintf(chatName, "%s", chatFriendlyNames[i]);
// we are throwing out the first token
strtok_r(chatName, " new) ", saveptr2);
strtok_r(chatName, " new) ", &saveptr2);
char *tempChatFriendlyName = strtok_r(NULL, " new) ", saveptr2);
char *tempChatFriendlyName = strtok_r(NULL, " new) ", &saveptr2);
if (prefix(tempChatFriendlyName, name)) {
@ -219,7 +234,13 @@ void getChatCounts() {
writeSerialPortDebug(boutRefNum, name);
#endif
sprintf(chatFriendlyNames[i], "(%d new) %s", count, name);
if (count == 0) {
sprintf(chatFriendlyNames[i], "%s", name);
} else {
sprintf(chatFriendlyNames[i], "(%d new) %s", count, name);
}
break;
}
} else {
@ -231,13 +252,19 @@ void getChatCounts() {
writeSerialPortDebug(boutRefNum, name);
#endif
sprintf(chatFriendlyNames[i], "(%d new) %s", count, name);
if (count == 0) {
sprintf(chatFriendlyNames[i], "%s", name);
} else {
sprintf(chatFriendlyNames[i], "(%d new) %s", count, name);
}
break;
}
}
}
token = strtok_r(NULL, ",", saveptr);
token = strtok_r(NULL, ",", &saveptr);
}
strcpy(previousChatCountFunctionResponse, chatCountFunctionResponse);
@ -272,32 +299,6 @@ void getHasNewMessagesInChat(char *thread) {
return;
}
// set up function to get available chat (fill buttons on right hand side)
// run it on some interval? make sure user is not typing!!!
void getChats() {
writeSerialPortDebug(boutRefNum, "getChats!");
if (haveRun) {
return;
}
haveRun = 1;
callFunctionOnCoprocessor("getChats", "", jsFunctionResponse);
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, ",");
}
return;
}
Boolean chatWindowCollision;
Boolean messageWindowCollision;
@ -383,9 +384,9 @@ static void nuklearApp(struct nk_context *ctx) {
nk_layout_row_begin(ctx, NK_STATIC, 30, 1);
{
nk_layout_row_push(ctx, WINDOW_WIDTH - 120);
nk_label(ctx, "this is known to be a bit finnicky,", NK_TEXT_ALIGN_LEFT);
nk_label(ctx, "enter contact name as it would appear", NK_TEXT_ALIGN_LEFT);
nk_layout_row_push(ctx, WINDOW_WIDTH - 120);
nk_label(ctx, "input exact phone number", NK_TEXT_ALIGN_LEFT);
nk_label(ctx, "on your iPhone, iPad, modern Mac, etc", NK_TEXT_ALIGN_LEFT);
}
nk_layout_row_end(ctx);
@ -406,6 +407,8 @@ static void nuklearApp(struct nk_context *ctx) {
memset(&activeChatMessages[i], '\0', 2048);
}
getMessages(activeChat, 0);
}
}
nk_layout_row_end(ctx);
@ -425,8 +428,6 @@ static void nuklearApp(struct nk_context *ctx) {
forceRedraw = 2;
}
getChats();
nk_layout_row_begin(ctx, NK_STATIC, 25, 1);
{
for (int i = 0; i < chatFriendlyNamesCounter; i++) {
@ -445,16 +446,36 @@ static void nuklearApp(struct nk_context *ctx) {
char chatName[96];
sprintf(chatName, "%s", chatFriendlyNames[i]);
writeSerialPortDebug(boutRefNum, chatName);
#ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug(boutRefNum, "clicked1 chatName");
writeSerialPortDebug(boutRefNum, chatName);
#endif
// we are throwing out the first token
strtokm(chatName, " new) ");
char *name = strtokm(NULL, " new) ");
char *name = (char *)strtokm(chatName, " new) ");
#ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug(boutRefNum, "clicked1 portion1 of string, will toss");
writeSerialPortDebug(boutRefNum, name);
#endif
name = (char *)strtokm(NULL, " new) ");
#ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug(boutRefNum, "clicked1 have name to assign to activeChat");
writeSerialPortDebug(boutRefNum, name);
#endif
writeSerialPortDebug(boutRefNum, name);
sprintf(activeChat, "%s", name);
sprintf(chatFriendlyNames[i], "%s", name);
} else {
#ifdef MESSAGES_FOR_MACINTOSH_DEBUGGING
writeSerialPortDebug(boutRefNum, "clicked2 chatName");
writeSerialPortDebug(boutRefNum, chatFriendlyNames[i]);
#endif
sprintf(activeChat, "%s", chatFriendlyNames[i]);
}