Skip to content

Commit

Permalink
Moving events into it's own compliation unit and adding library insta…
Browse files Browse the repository at this point in the history
…ll examples
  • Loading branch information
robrohan committed May 26, 2024
1 parent fad9bd5 commit 93109cd
Show file tree
Hide file tree
Showing 9 changed files with 239 additions and 219 deletions.
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ about:
@echo "make test - run some basic tests."
@echo ""

init:
sudo apt install clang-14
sudo apt install lld-14
sudo apt-get install gcc-multilib

clean:
rm -rf build

Expand All @@ -44,7 +49,7 @@ build: clean
-Wl,-z,stack-size=$(STACK_SIZE) \
$(NO_BUILT_INS) \
-o build/wefx.wasm \
src/walloc.c src/math.c src/wefx.c $(MAIN)
src/walloc.c src/math.c src/events.c src/wefx.c $(MAIN)
cp public/index.html build/index.html

serve: clean build
Expand All @@ -71,9 +76,13 @@ install_linux:
apt-get install groff pandoc texlive-xetex

test: clean_test
@echo "if you get: 'fatal error: 'bits/libc-header-start.h' file not found'"
@echo "you need 32 bit libs installed. Either remove -m32 from the flags below"
@echo "or run 'sudo apt-get install gcc-multilib' or equivalent."

mkdir -p build
# add -lm if you want to test against built in math.h
clang -std=c99 -m32 -g \
$(CC) -std=c99 -m32 -g \
$(NO_BUILT_INS) \
src/math.c src/wefx.c src/test.c \
-o build/test
Expand Down
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ You can also [download the documentation](https://raw.githubusercontent.com/robr

![Example Screenshot](https://raw.githubusercontent.com/robrohan/wefx/main/docs/wefx_shot.png)

## Quick Start

If you are using Ubuntu, you can run `make init` to install the correct version of clang and tools. If you are on another system, you will have to install `clang` yourself.

Once installed, `make build` should compile `examples/example0.c` into WASM (if there are no errors). If successful, and if you have python installed, you can run `make serve` to start a simple HTTP server and browse to http://localhost:8000 to view wasm output.

## Using The Project

The flow of the project has two steps: the build step, and the serve step:
Expand Down
1 change: 1 addition & 0 deletions examples/example0.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../src/wasm.h"
#include "../src/wefx.h"
#include "../src/events.h"

/*
* - the bottom-left is (0,0) and the pixel coordinates increase
Expand Down
1 change: 1 addition & 0 deletions examples/example1.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "../src/wasm.h"
#include "../src/wefx.h"
#include "../src/events.h"

#define W 1024
#define H 768
Expand Down
160 changes: 160 additions & 0 deletions src/events.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
#include "events.h"
#include "wasm.h"
/*
Here we reserve a spot for an event queue where we will store user events from the browser.
E.g. Mouse down, mouse move, key down, etc.
*/
EXPORT wefx_event_queue *wefx_q = NULL;
/*
# Event Queue
In order to process browser events (keyboard and mouse input), we use
a simple Queue. The Javascript that hosts this code will capture events
in the browser and pass them into C using the queue. We can then use the
queue to look at and process those events.
## Open Events - wefx_open_events
Similar to how _wefx\_open_ created screen memory, the _wefx_open_events_
function allocates memory for the event queue.
*/
wefx_event_queue *wefx_open_events()
{
wefx_q = malloc(sizeof(struct wefx_event_queue));
// wefx_q = &(const struct wefx_event_queue){ 0 };
if (wefx_q != NULL)
{
wefx_init_queue(wefx_q);
return wefx_q;
}

return NULL;
}
/*
When we create a new queue, we want to set the head and tail to null to
mark it as empty. This is not strictly necessary, but it will make knowing
if the queue is empty a bit easier.
*/
void wefx_init_queue(wefx_event_queue *q)
{
q->head = NULL;
q->tail = NULL;
}
/*
## Add Events from Javascript
Javascript will call this function directly to register that an event has
occurred.
Here we just take the parameters passed in from Javascript, put them into
the _wefx\_event_ struct, and add it to the end of the queue.
*/
EXPORT void wefx_add_queue_event(int type, int button, int timestamp, int key, int x, int y)
{
// if we don't care about events drop everything
if (wefx_q == NULL)
return;

wefx_event *e = malloc(sizeof(struct wefx_event));
if (e == NULL)
{
// we couldn't create memory for some reason
// this seems to happen a bit when running in
// wasm (or maybe walloc)
return;
}
e->type = type;
e->button = button;
e->timestamp = timestamp;
e->key = (char)key;
e->x = x;
e->y = y;

wefx_enqueue(wefx_q, e);
}
/*
## Add an Event to a Queue
_wefx\_enqueue_ takes an event and adds it to the given queue. It does a number of
checks to make sure the queue is in a valid state, and adds the event if
everything is ok.
*/
int wefx_enqueue(wefx_event_queue *q, wefx_event *event)
{
// create a new node to store the event
wefx_event_node *node = malloc(sizeof(struct wefx_event_node));
if (node == NULL)
{
return -1;
}

node->event = event;
node->next = NULL;

// if the queue has a tail, add us as the next behind the tail
if (q->tail != NULL)
{
q->tail->next = node;
}
// now really make us the last node
q->tail = node;

// if we are first in line, go to the head
if (q->head == NULL)
{
q->head = node;
}

return 1;
}
/*
## Remove an Event from a Queue
Take the first event in the queue off the queue, and return it.
*/
wefx_event *wefx_dequeue(wefx_event_queue *q)
{
if (q == NULL)
return NULL;

wefx_event *e = NULL;

if (q->head == NULL)
return NULL;

wefx_event_node *n = q->head;

if(n->event == NULL) {
goto clean_up;
}

e = n->event;

if(n->next == NULL) {
goto clean_up;
}
q->head = n->next;

// if our new head is null, make sure the
// tail is set to null
if (q->head == NULL)
q->tail = NULL;

clean_up:
if (n != NULL)
free(n);

return e;
}
55 changes: 55 additions & 0 deletions src/events.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef WEFX_EVENTS_H
#define WEFX_EVENTS_H

enum wefx_button_type
{
WEFX_NONE = 0,
WEFX_LEFT,
WEFX_RIGHT,
};

enum wefx_event_type
{
WEFX_KEYDOWN = 0,
WEFX_KEYPRESS = 1,
WEFX_KEYUP = 2,
WEFX_MOUSEMOVE = 3,
WEFX_MOUSEDOWN = 4,
WEFX_MOUSEUP = 5,
WEFX_CLICK = 6
};

typedef struct wefx_event
{
enum wefx_event_type type;
enum wefx_button_type button;
char key; // TODO: this wont work with utf8
// keyCode is deprecated in javascript
int timestamp;
int x;
int y;
} wefx_event;

typedef struct wefx_event_node
{
struct wefx_event *event;
struct wefx_event_node *next;
} wefx_event_node;

typedef struct wefx_event_queue
{
wefx_event_node *head;
wefx_event_node *tail;
} wefx_event_queue;

//////////////////////////////////////////////

wefx_event_queue *wefx_open_events();

void wefx_init_queue(wefx_event_queue *q);

int wefx_enqueue(wefx_event_queue *q, wefx_event *event);

wefx_event *wefx_dequeue(wefx_event_queue *q);

#endif
4 changes: 4 additions & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ to be able to call a C function from within Javascript.
#include "math.h"
#include "walloc.h"

#ifndef NULL
#define NULL ((void *)0)
#endif

#define EXPORT __attribute__((visibility("default")))

#endif
Loading

0 comments on commit 93109cd

Please sign in to comment.