Browse Source

Added internal event management

Philipp Hinz 7 năm trước cách đây
mục cha
commit
82af776717

+ 3 - 0
CoffeeCode/Release/subdir.mk

@@ -14,6 +14,7 @@ CPP_SRCS += \
 ../stripe.cpp \
 ../timer.cpp  \
 ../display.cpp  \
+../events.cpp  \
 ../server.cpp 
 
 OBJS += \
@@ -27,6 +28,7 @@ OBJS += \
 ./stripe.o \
 ./timer.o  \
 ./display.o  \
+./events.o  \
 ./server.o 
 
 CPP_DEPS += \
@@ -40,6 +42,7 @@ CPP_DEPS += \
 ./stripe.d \
 ./timer.d  \
 ./display.d  \
+./events.d  \
 ./server.d
 
 

+ 1 - 1
CoffeeCode/buildno

@@ -1 +1 @@
-142
+176

+ 2 - 2
CoffeeCode/coffee.cpp

@@ -22,7 +22,7 @@
 #include "logger.h"
 #include "timer.h"
 #include "database.h"
-#include "display.h"
+#include "events.h"
 
 coffee_status_t state;
 int sigValue;
@@ -264,7 +264,7 @@ void changeState(coffee_status_t newState) {
 	logger(V_BREW, "Changing state to %d\n", newState);
 	state = newState;
 
-	displayPushState(newState);
+	event_trigger("statechange", &state, sizeof(state));
 }
 
 /**

+ 32 - 24
CoffeeCode/display.cpp

@@ -18,6 +18,7 @@
 #include "lcd.h"
 #include "coffee.h"
 #include "hal.h"
+#include "events.h"
 
 display_lang_t displayLang;
 timer displayTimer(displayTimerHandler);
@@ -95,6 +96,34 @@ void displayPrintLn(int line, const char* str, bool centered) {
 	//logger(V_HAL, "Printed out on display: \"%s\"\n", buf);
 }
 
+/**
+ * Updates the display state to the matching coffee state
+ * @param event Event data
+ */
+
+void displayStateUpdated(event_t *event) {
+	if (event->len != sizeof(coffee_status_t)) {
+		logger_error("Invalid use of event %s\n", event->event);
+		return;
+	}
+	coffee_status_t state = *(coffee_status_t*)event->data;
+	if (state != coffeeState) {
+		coffeeState = state;
+		timerScaler--;
+		elapsedCnt = 0;
+		displayTimer.call();
+	}
+}
+
+/**
+ * Handles cleanup before program termination
+ */
+
+void displayTerminate(event_t *e) {
+	displayPrintLn(0, "CoffeePi", true);
+	displayPrintLn(1, displayGetString(str_bye), true);
+}
+
 /**
  * Main thread to handle display data
  * @param *threadid Thread ID
@@ -107,6 +136,8 @@ void* displayThread(void* threadid) {
 		tmp = DEFAULT_LANG;
 	displaySetLang((display_lang_t) tmp);
 	displayTimer.start();
+	event_subscribe("statechange", &displayStateUpdated);
+	event_subscribe("terminate", &displayTerminate);
 	while (1) {
 		pause();
 		if (1) {
@@ -179,15 +210,6 @@ void displayInit(void) {
 	REFRESH_RATE);
 }
 
-/**
- * Handles cleanup before program termination
- */
-
-void displayTerminate(void) {
-	displayPrintLn(0, "CoffeePi", true);
-	displayPrintLn(1, displayGetString(str_bye), true);
-}
-
 /**
  * Sets the language of the display text
  * @param lang New language
@@ -219,7 +241,7 @@ void displayRefresh(void) {
 		break;
 
 	case STATE_BREW:
-		if (elapsedCnt <= 2*REFRESH_RATE) {
+		if (elapsedCnt <= 2 * REFRESH_RATE) {
 			displayPrintLn(0, "CoffeePi", true);
 			displayPrintLn(1, displayGetString(str_brewing), true);
 		} else {
@@ -262,17 +284,3 @@ const char* displayGetString(display_strings_t string) {
 		displayLang = DEFAULT_LANG;
 	return display_strings[string].text[displayLang];
 }
-
-/**
- * Updates the display state to the matching coffee state
- * @param state New state
- */
-
-void displayPushState(coffee_status_t state) {
-	if (state != coffeeState) {
-		coffeeState = state;
-		timerScaler--;
-		elapsedCnt = 0;
-		displayTimer.call();
-	}
-}

+ 0 - 1
CoffeeCode/display.h

@@ -92,7 +92,6 @@ static const display_string_t display_strings[str_last] =
 void *displayThread(void *threadid);
 void *displayTimerHandler(void *threadid);
 void displayInit(void);
-void displayTerminate(void);
 void displaySetLang(display_lang_t lang);
 
 void displayPushState(coffee_status_t state);

+ 186 - 0
CoffeeCode/events.cpp

@@ -0,0 +1,186 @@
+/*
+ * events.cpp
+ *
+ *  Created on: Jan 7, 2018
+ *      Author: Philipp Hinz
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "events.h"
+#include "logger.h"
+
+/**
+ * Struct for subscribers, contains the pointer to the handler
+ */
+
+struct subscriber_t {
+	void (*handler)(event_t *);
+	subscriber_t *next = NULL;
+};
+
+/**
+ * Struct for the event list
+ */
+
+struct events_t {
+	char event[EVENT_LENGTH];
+	subscriber_t *subscribers = NULL;
+	events_t *next = NULL;
+};
+
+events_t *firstEvent = NULL; /**< The first element in the event list */
+
+/**
+ * Finds the specific event in the list and returns it
+ * @param event Event name
+ * @return Pointer to event, NULL if not found
+ */
+
+events_t * event_find(char *event) {
+	events_t *tmp = firstEvent;
+
+	while (tmp) {
+		if (!strcmp(tmp->event, event))
+			return tmp;
+		tmp = tmp->next;
+	}
+	return NULL;
+}
+
+/**
+ * Finds the last event in the list and returns it
+ * @return Pointer to event, NULL if no event in list
+ */
+
+events_t * event_findlast() {
+	events_t *tmp = firstEvent;
+
+	while (tmp) {
+		if (!tmp->next)
+			return tmp;
+		tmp = tmp->next;
+	}
+	return NULL;
+}
+
+/**
+ * Adds a subscriber to an event
+ * @param event Target event
+ * @param handler Event handler
+ */
+
+void addSubscriber(events_t *event, void (*handler)(event_t *)) {
+	subscriber_t *newSub = (subscriber_t *) malloc(sizeof(subscriber_t)); // Cast is neccesarry in c++
+	if (!newSub)
+		logger_error("Not enough memory\n");
+	newSub->handler = handler;
+	newSub->next = NULL;
+
+	if (event->subscribers) {
+		subscriber_t *tmp = event->subscribers;
+		while (tmp->next) {
+			tmp = tmp->next;
+		}
+
+		tmp->next = newSub;
+	} else {
+		event->subscribers = newSub;
+	}
+}
+
+/**
+ * Adds a subscriber to an event
+ * @param event Target event name
+ * @param handler Event handler
+ */
+
+void event_subscribe(const char *event, void (*handler)(event_t *)) {
+	events_t *newEvent = (events_t *) malloc(sizeof(events_t));
+	if (!newEvent)
+		logger_error("Not enough memory\n");
+	newEvent->next = NULL;
+	newEvent->subscribers = NULL;
+	strcpy(newEvent->event, event);
+	addSubscriber(newEvent, handler);
+	events_t *tmp = event_findlast();
+	if (tmp)
+		tmp->next = newEvent;
+	else
+		firstEvent = newEvent;
+	logger(V_HAL, "New subscriber to event \"%s\"\n", event);
+}
+
+/**
+ * Triggers a specific event
+ * @param event Event data
+ */
+
+void event_trigger(event_t *event) {
+	events_t *tmp = event_find(event->event);
+	if (!tmp) {
+		logger(V_HAL, "No subscribers to event \"%s\"\n", event->event);
+		return;
+	}
+
+	subscriber_t *sub = tmp->subscribers;
+
+	while (sub) {
+		sub->handler(event);
+		sub = sub->next;
+	}
+
+	logger(V_HAL, "Triggered event \"%s\"\n", event->event);
+}
+
+/**
+ * Triggers a specific event
+ * @param event Name of event
+ */
+
+void event_trigger(char *event) {
+	event_t e;
+	e.event = event;
+	event_trigger(&e);
+}
+
+/**
+ * Triggers a specific event
+ * @param event Name of event
+ */
+
+void event_trigger(const char *event) {
+	event_t e;
+	e.event = (char*)event;
+	event_trigger(&e);
+}
+
+/**
+ * Triggers a specific event
+ * @param event Name of event
+ * @param data Pointer to some data
+ * @param len Length of data
+ */
+
+void event_trigger(char *event, void *data, int len) {
+	event_t e;
+	e.event = event;
+	e.data = data;
+	e.len = len;
+	event_trigger(&e);
+}
+
+/**
+ * Triggers a specific event
+ * @param event Name of event
+ * @param data Pointer to some data
+ * @param len Length of data
+ */
+
+void event_trigger(const char *event, void *data, int len) {
+	event_trigger((char *) event, data, len);
+}
+

+ 27 - 0
CoffeeCode/events.h

@@ -0,0 +1,27 @@
+/*
+ * events.h
+ *
+ *  Created on: Jan 5, 2018
+ *      Author: Philipp Hinz
+ */
+
+#ifndef EVENTS_H_
+#define EVENTS_H_
+
+#define EVENT_LENGTH	20 /*< Maximum length of an event */
+
+struct event_t {
+	char *event;
+	void *data = NULL;
+	int len = 0;
+};
+
+void event_subscribe(const char *event, void (*handler)(event_t *));
+void event_trigger(event_t *event);
+void event_trigger(char *event);
+void event_trigger(const char *event);
+void event_trigger(const char *event, void *data, int len);
+void event_trigger(char *event, void *data, int len);
+
+
+#endif /* EVENTS_H_ */

+ 6 - 7
CoffeeCode/main.cpp

@@ -25,6 +25,7 @@
 #include "coffee.h"
 #include "display.h"
 #include "server.h"
+#include "events.h"
 
 const int buildno = (1+(int)(
 #include "buildno"
@@ -162,7 +163,6 @@ int main(int argc, char *argv[]) {
 	// free attribute and wait for the other threads
 	pthread_attr_destroy(&attr);
 
-
 	sleep(2);
 
 	rc = pthread_join(thread[0], &status);
@@ -183,14 +183,13 @@ int main(int argc, char *argv[]) {
 void terminationHandler(int signum) {
 	logger(V_NONE, "Caught signal %d, exiting gracefully..\n", signum);
 	stopTimers();
-	//coffeeTerminate();
-	displayTerminate();
-	serverTerminate();
+
+	event_trigger("terminate");
 
 	/*logger(V_NONE, "Saving my state to the database..\n");
-	sqlExecute("begin");
-	// Save stuff here
-	sqlExecute("end");*/
+	 sqlExecute("begin");
+	 // Save stuff here
+	 sqlExecute("end");*/
 
 	sqlClose(); // Closing DB connection
 

+ 1 - 0
CoffeeCode/makefile.targets

@@ -9,4 +9,5 @@ OBJS2 += \
 ./timer.o \
 ./server.o \
 ./display.o \
+./events.o \
 ./sqlite/sqlite3.o 

+ 12 - 9
CoffeeCode/server.cpp

@@ -20,6 +20,7 @@
 #include "hal.h"
 #include "coffee.h"
 #include "stripe.h"
+#include "events.h"
 
 /**
  * TCP Uses 2 types of sockets, the connection socket and the listen socket.
@@ -38,6 +39,15 @@ void sendACK() {
 	send(sock, buffer_ok, strlen(buffer_ok), 0);
 }
 
+/**
+ * Closes all active connections
+ */
+
+void serverTerminate(event_t *e) {
+	close(sock);
+	close(listen_sock);
+}
+
 /**
  * Main thread to handle networking stuff
  * @param *threadid Thread ID
@@ -79,6 +89,7 @@ void* serverThread(void* threadid) {
 		pthread_exit(0);
 	}
 
+	event_subscribe("terminate", &serverTerminate);
 	logger(V_BASIC, "Now listening for commands on port %d\n", SERVER_PORT);
 
 	// socket address used to store client address
@@ -145,6 +156,7 @@ void* serverThread(void* threadid) {
 				sendACK();
 			}
 
+
 			lastlen = len;
 			// echo received content back
 			//send(sock, buffer, len, 0);
@@ -157,12 +169,3 @@ void* serverThread(void* threadid) {
 	pthread_exit(EXIT_SUCCESS);
 }
 
-/**
- * Closes all active connections
- */
-
-void serverTerminate() {
-	close(sock);
-	close(listen_sock);
-}
-

+ 0 - 2
CoffeeCode/server.h

@@ -18,8 +18,6 @@
 #define SERVER_CMD_STRIPEOFF 	"stripeoff"
 
 void *serverThread(void *threadid);
-void serverTerminate();
-
 
 
 #endif /* SERVER_H_ */