kjkj
n
This commit is contained in:
parent
bc0007b588
commit
3de83d481e
35
source/datastructures/ringbuffer.c
Normal file
35
source/datastructures/ringbuffer.c
Normal 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;
|
||||||
|
}
|
24
source/datastructures/ringbuffer.h
Normal file
24
source/datastructures/ringbuffer.h
Normal 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) }
|
|
@ -47,8 +47,8 @@ struct ctrl_axis_vec {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Controller {
|
struct Controller {
|
||||||
struct RecordBuffer recs;
|
struct InputRecordBuf recs;
|
||||||
struct StringBuffer str;
|
struct InputStringBuf str;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
struct InputAxis *axes[IO_BUF_SIZE];
|
struct InputAxis *axes[IO_BUF_SIZE];
|
||||||
|
|
|
@ -3,44 +3,12 @@
|
||||||
|
|
||||||
#include "platform.h"
|
#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)
|
void *input_thread_loop(void *arg)
|
||||||
{
|
{
|
||||||
struct InputThreadHandle *hand = arg;
|
struct InputThreadHandle *hand = arg;
|
||||||
|
|
||||||
struct RecordBuffer tmp_in = { .len = 0, .start = 0 };
|
struct InputRecordBuf tmp_in = { .head.len = 0, .head.start = 0 };
|
||||||
struct StringBuffer tmp_str = { .len = 0, .start = 0 };
|
struct InputStringBuf tmp_str = { .head.len = 0, .head.start = 0 };
|
||||||
|
|
||||||
while (!hand->is_terminating) {
|
while (!hand->is_terminating) {
|
||||||
if (!PlatformReadInput(&tmp_in, &tmp_str))
|
if (!PlatformReadInput(&tmp_in, &tmp_str))
|
||||||
|
@ -49,13 +17,13 @@ void *input_thread_loop(void *arg)
|
||||||
if (hand->err = pthread_mutex_lock(&hand->mutex))
|
if (hand->err = pthread_mutex_lock(&hand->mutex))
|
||||||
return nullptr;
|
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))
|
if (hand->err = pthread_cond_wait(&hand->consume, &hand->mutex))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputBufferTransfer(hand->in, &tmp_in);
|
RingBufferTransfer(IO_BUF_T, hand->in, &tmp_in);
|
||||||
StringBufferTransfer(hand->str, &tmp_str);
|
RingBufferTransfer(STR_BUF_T, hand->str, &tmp_str);
|
||||||
|
|
||||||
if (hand->err = pthread_mutex_unlock(&hand->mutex))
|
if (hand->err = pthread_mutex_unlock(&hand->mutex))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -66,8 +34,8 @@ void *input_thread_loop(void *arg)
|
||||||
|
|
||||||
bool BeginInputThread(
|
bool BeginInputThread(
|
||||||
struct InputThreadHandle *hand,
|
struct InputThreadHandle *hand,
|
||||||
struct RecordBuffer *in,
|
struct InputRecordBuf *in,
|
||||||
struct StringBuffer *str
|
struct InputStringBuf *str
|
||||||
) {
|
) {
|
||||||
*hand = (struct InputThreadHandle) {
|
*hand = (struct InputThreadHandle) {
|
||||||
.in = in,
|
.in = in,
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
|
|
||||||
#include "fumotris.h"
|
#include "fumotris.h"
|
||||||
#include "gametime.h"
|
#include "gametime.h"
|
||||||
|
#include "ringbuffer.h"
|
||||||
|
|
||||||
#define IO_BUF_SIZE 16
|
#define IO_BUF_SIZE 16
|
||||||
#define STR_BUF_SIZE (IO_BUF_SIZE * 4)
|
#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];
|
struct InputRecord buf[IO_BUF_SIZE];
|
||||||
u8f len;
|
|
||||||
u8f start;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StringBuffer {
|
struct InputStringBuf {
|
||||||
|
struct RingBufferHead head;
|
||||||
char buf[STR_BUF_SIZE];
|
char buf[STR_BUF_SIZE];
|
||||||
u8f len;
|
|
||||||
u8f start;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct InputThreadHandle {
|
struct InputThreadHandle {
|
||||||
struct RecordBuffer *in;
|
struct InputRecordBuf *in;
|
||||||
struct StringBuffer *str;
|
struct InputStringBuf *str;
|
||||||
|
|
||||||
pthread_t thread;
|
pthread_t thread;
|
||||||
pthread_mutex_t mutex;
|
pthread_mutex_t mutex;
|
||||||
|
@ -91,12 +93,10 @@ struct InputThreadHandle {
|
||||||
bool is_terminating;
|
bool is_terminating;
|
||||||
};
|
};
|
||||||
|
|
||||||
void InputBufferTransfer(struct RecordBuffer *tmp, struct RecordBuffer *dest);
|
|
||||||
|
|
||||||
bool BeginInputThread(
|
bool BeginInputThread(
|
||||||
struct InputThreadHandle *hand,
|
struct InputThreadHandle *hand,
|
||||||
struct RecordBuffer *in,
|
struct InputRecordBuf *in,
|
||||||
struct StringBuffer *str
|
struct InputStringBuf *str
|
||||||
);
|
);
|
||||||
|
|
||||||
bool EndInputThread(struct InputThreadHandle *hand);
|
bool EndInputThread(struct InputThreadHandle *hand);
|
|
@ -16,7 +16,7 @@ bool PlatformInit();
|
||||||
|
|
||||||
bool PlatformGetRefreshRate(u16f *out);
|
bool PlatformGetRefreshRate(u16f *out);
|
||||||
|
|
||||||
bool PlatformReadInput(struct RecordBuffer *in, struct StringBuffer *str);
|
bool PlatformReadInput(struct InputRecordBuf *in, struct InputStringBuf *str);
|
||||||
|
|
||||||
bool PlatformStopInput();
|
bool PlatformStopInput();
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ bool PlatformGetRefreshRate(u16f *out)
|
||||||
|
|
||||||
bool dispatch_rec(
|
bool dispatch_rec(
|
||||||
struct InputRecord *out,
|
struct InputRecord *out,
|
||||||
struct StringBuffer *str,
|
struct InputStringBuf *str,
|
||||||
struct win_rec *rec
|
struct win_rec *rec
|
||||||
) {
|
) {
|
||||||
u8f type = rec->type | (rec->is_mouse & rec->mouse.flags);
|
u8f type = rec->type | (rec->is_mouse & rec->mouse.flags);
|
||||||
|
@ -149,7 +149,7 @@ bool dispatch_rec(
|
||||||
return false;
|
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;
|
DWORD max_records = IO_BUF_SIZE - in->len;
|
||||||
struct win_rec win_buf[max_records];
|
struct win_rec win_buf[max_records];
|
||||||
|
|
Loading…
Reference in a new issue