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 RecordBuffer recs;
|
||||
struct StringBuffer str;
|
||||
struct InputRecordBuf recs;
|
||||
struct InputStringBuf str;
|
||||
|
||||
struct {
|
||||
struct InputAxis *axes[IO_BUF_SIZE];
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in a new issue