n
This commit is contained in:
Julia 2024-04-25 15:08:24 -05:00
parent bc0007b588
commit 3de83d481e
7 changed files with 83 additions and 56 deletions

View file

@ -0,0 +1,35 @@
#pragma once
#include "ringbuffer.h"
#include <string.h>
struct rbuf_generic {
struct RingBufferHead head;
u8 arr[];
};
inline void *rbuf_start(RingBufferT T, struct rbuf_generic *rbuf, size_t i)
{
size_t wrap_i = (rbuf->head.start + i) % T->LEN;
return rbuf->arr + wrap_i * T->SIZE;
}
inline void *rbuf_tail(RingBufferT T, struct rbuf_generic *rbuf, size_t i)
{
size_t wrap_i = (rbuf->head.start + rbuf->head.len + i) % T->LEN;
return rbuf->arr + i * T->SIZE;
}
void RingBufferTransfer(RingBufferT T, RingBuffer *dest, RingBuffer *tmp)
{
struct rbuf_generic *write = dest;
struct rbuf_generic *read = tmp;
size_t copy_max = min_size(T->LEN - write->head.len, read->head.len);
for (size_t i = 0; i < copy_max; i++) {
memcpy(rbuf_tail(T, write, i), rbuf_start(T, read, i), T->LEN);
}
write->head.start += copy_max;
read->head.len -= copy_max;
}

View file

@ -0,0 +1,24 @@
#pragma once
#include <iso646.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "fumotris.h"
typedef void *RingBuffer;
typedef const struct RingBufferT {
size_t LEN;
size_t SIZE;
} *const RingBufferT;
struct RingBufferHead {
u8f len;
u8f start;
};
void RingBufferTransfer(RingBufferT T, RingBuffer *dest, RingBuffer *tmp);
#define INIT_RING_BUF_T(len, type) &(struct RingBufferT) { len, sizeof(type) }

View file

@ -47,8 +47,8 @@ struct ctrl_axis_vec {
};
struct Controller {
struct RecordBuffer recs;
struct StringBuffer str;
struct InputRecordBuf recs;
struct InputStringBuf str;
struct {
struct InputAxis *axes[IO_BUF_SIZE];

View file

@ -3,44 +3,12 @@
#include "platform.h"
void InputBufferTransfer(struct RecordBuffer *dest, struct RecordBuffer *src)
{
size_t copy_max = min_size(IO_BUF_SIZE - dest->len, src->len);
for (size_t i = 0; i < copy_max; i++) {
size_t dest_i = (dest->start + dest->len + i) % IO_BUF_SIZE;
size_t src_i = (src->start + i) % IO_BUF_SIZE;
dest->buf[dest_i] = src->buf[src_i];
}
dest->start += copy_max;
if (copy_max < src->len)
src->len -= copy_max;
}
void StringBufferTransfer(struct StringBuffer *dest, struct StringBuffer *src)
{
size_t copy_max = min_size(STR_BUF_SIZE - dest->len, src->len);
for (size_t i = 0; i < copy_max; i++) {
size_t dest_i = (dest->start + dest->len + i) % STR_BUF_SIZE;
size_t src_i = (src->start + i) % STR_BUF_SIZE;
dest->buf[dest_i] = src->buf[src_i];
}
dest->start += copy_max;
if (copy_max < src->len)
src->len -= copy_max;
}
void *input_thread_loop(void *arg)
{
struct InputThreadHandle *hand = arg;
struct RecordBuffer tmp_in = { .len = 0, .start = 0 };
struct StringBuffer tmp_str = { .len = 0, .start = 0 };
struct InputRecordBuf tmp_in = { .head.len = 0, .head.start = 0 };
struct InputStringBuf tmp_str = { .head.len = 0, .head.start = 0 };
while (!hand->is_terminating) {
if (!PlatformReadInput(&tmp_in, &tmp_str))
@ -49,13 +17,13 @@ void *input_thread_loop(void *arg)
if (hand->err = pthread_mutex_lock(&hand->mutex))
return nullptr;
while (tmp_in.len == IO_BUF_SIZE) {
while (tmp_in.head.len == IO_BUF_SIZE) {
if (hand->err = pthread_cond_wait(&hand->consume, &hand->mutex))
return nullptr;
}
InputBufferTransfer(hand->in, &tmp_in);
StringBufferTransfer(hand->str, &tmp_str);
RingBufferTransfer(IO_BUF_T, hand->in, &tmp_in);
RingBufferTransfer(STR_BUF_T, hand->str, &tmp_str);
if (hand->err = pthread_mutex_unlock(&hand->mutex))
return nullptr;
@ -66,8 +34,8 @@ void *input_thread_loop(void *arg)
bool BeginInputThread(
struct InputThreadHandle *hand,
struct RecordBuffer *in,
struct StringBuffer *str
struct InputRecordBuf *in,
struct InputStringBuf *str
) {
*hand = (struct InputThreadHandle) {
.in = in,

View file

@ -8,6 +8,7 @@
#include "fumotris.h"
#include "gametime.h"
#include "ringbuffer.h"
#define IO_BUF_SIZE 16
#define STR_BUF_SIZE (IO_BUF_SIZE * 4)
@ -67,21 +68,22 @@ struct InputRecord {
};
};
struct RecordBuffer {
RingBufferT IO_BUF_T = INIT_RING_BUF_T(IO_BUF_SIZE, struct InputRecord);
RingBufferT STR_BUF_T = INIT_RING_BUF_T(STR_BUF_SIZE, char);
struct InputRecordBuf {
struct RingBufferHead head;
struct InputRecord buf[IO_BUF_SIZE];
u8f len;
u8f start;
};
struct StringBuffer {
struct InputStringBuf {
struct RingBufferHead head;
char buf[STR_BUF_SIZE];
u8f len;
u8f start;
};
struct InputThreadHandle {
struct RecordBuffer *in;
struct StringBuffer *str;
struct InputRecordBuf *in;
struct InputStringBuf *str;
pthread_t thread;
pthread_mutex_t mutex;
@ -91,12 +93,10 @@ struct InputThreadHandle {
bool is_terminating;
};
void InputBufferTransfer(struct RecordBuffer *tmp, struct RecordBuffer *dest);
bool BeginInputThread(
struct InputThreadHandle *hand,
struct RecordBuffer *in,
struct StringBuffer *str
struct InputRecordBuf *in,
struct InputStringBuf *str
);
bool EndInputThread(struct InputThreadHandle *hand);

View file

@ -16,7 +16,7 @@ bool PlatformInit();
bool PlatformGetRefreshRate(u16f *out);
bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str);
bool PlatformReadInput(struct InputRecordBuf *in, struct InputStringBuf *str);
bool PlatformStopInput();

View file

@ -121,7 +121,7 @@ bool PlatformGetRefreshRate(u16f *out)
bool dispatch_rec(
struct InputRecord *out,
struct StringBuffer *str,
struct InputStringBuf *str,
struct win_rec *rec
) {
u8f type = rec->type | (rec->is_mouse & rec->mouse.flags);
@ -149,7 +149,7 @@ bool dispatch_rec(
return false;
}
bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str)
bool PlatformReadInput(struct InputRecordBuf *in, struct InputStringBuf *str)
{
DWORD max_records = IO_BUF_SIZE - in->len;
struct win_rec win_buf[max_records];