Fumofumotris/source/io/input.c

112 lines
2.7 KiB
C
Raw Normal View History

#include "input.h"
2024-04-23 20:33:32 +00:00
#include <string.h>
2024-03-25 05:34:59 +00:00
2024-04-16 22:14:53 +00:00
#include "platform.h"
2024-03-25 05:34:59 +00:00
2024-04-23 20:33:32 +00:00
inline size_t min_size(size_t a, size_t b) {
return a < b ? a : b;
2024-04-19 06:38:45 +00:00
}
2024-04-23 20:33:32 +00:00
inline size_t in_buf_empty(struct InputBuffer *in) {
return IO_BUF_SIZE - in->len;
}
struct InputRecord *in_buf_get(struct InputBuffer *in, size_t i) {
return in->buf + (in->start + i) % IO_BUF_SIZE;
2024-04-16 22:14:53 +00:00
}
2024-04-19 06:38:45 +00:00
void InputBufferTransfer(struct InputBuffer *dest, struct InputBuffer *src)
2024-04-16 22:14:53 +00:00
{
2024-04-23 20:33:32 +00:00
size_t copy_amt = min_size(in_buf_empty(dest), src->len);
2024-04-19 06:38:45 +00:00
for (size_t i = 0; i < copy_amt; i++)
2024-04-23 20:33:32 +00:00
*in_buf_get(dest, dest->len + i) = *in_buf_get(src, i);
2024-04-16 22:14:53 +00:00
2024-04-19 06:38:45 +00:00
if (copy_amt < src->len)
src->start += copy_amt;
2024-04-16 22:14:53 +00:00
2024-04-19 06:38:45 +00:00
src->len -= copy_amt;
dest->len += copy_amt;
2024-04-16 22:14:53 +00:00
}
2024-04-19 06:38:45 +00:00
void InputBufferAdd(struct InputBuffer *buf, struct InputRecord *rec)
2024-04-16 22:14:53 +00:00
{
2024-04-23 20:33:32 +00:00
*in_buf_get(buf, buf->len++) = *rec;
}
inline size_t str_buf_empty(struct InputString *str) {
return STR_BUF_SIZE - str->len;
}
inline char *str_buf_get(struct InputString *str, size_t i) {
return (str->start + i) % STR_BUF_SIZE;
}
void InputStringTransfer(struct InputString *dest, struct InputString *src)
{
size_t copy_amt = min_size(str_buf_empty(dest), src->len);
for (size_t i = 0; i < copy_amt; i++) {
*str_buf_get(dest, dest->len + i) = *str_buf_get(src, i);
}
2024-04-16 22:14:53 +00:00
}
2024-04-22 05:19:54 +00:00
void *input_thread_loop(void *arg)
2024-04-16 22:14:53 +00:00
{
2024-04-22 05:19:54 +00:00
struct InputThreadHandle *hand = arg;
2024-04-23 20:33:32 +00:00
struct InputBuffer tmp_in = { .len = 0, .start = 0 };
struct InputString tmp_str = { .len = 0, .start = 0 };
2024-04-01 22:39:21 +00:00
2024-04-19 20:23:11 +00:00
while (!hand->is_terminating) {
2024-04-23 20:33:32 +00:00
if (!PlatformReadInput(&tmp_in, &tmp_str)) {
2024-04-19 20:23:11 +00:00
hand->err = true;
2024-04-22 05:19:54 +00:00
return nullptr;
2024-04-01 22:39:21 +00:00
}
2024-04-19 20:23:11 +00:00
hand->err = pthread_mutex_lock(&hand->mutex);
if (hand->err)
2024-04-22 05:19:54 +00:00
return nullptr;
2024-04-19 20:23:11 +00:00
2024-04-23 20:33:32 +00:00
while (tmp_in.len == IO_BUF_SIZE) {
2024-04-22 22:13:13 +00:00
hand->err = pthread_cond_wait(&hand->buf_read, &hand->mutex);
if (hand->err)
return nullptr;
}
2024-04-23 20:33:32 +00:00
InputBufferTransfer(hand->in, &tmp_in);
InputStringTransfer(hand->str, &tmp_str);
2024-04-19 20:23:11 +00:00
hand->err = pthread_mutex_unlock(&hand->mutex);
if (hand->err)
2024-04-22 05:19:54 +00:00
return nullptr;
2024-04-01 22:39:21 +00:00
}
2024-04-22 05:19:54 +00:00
return nullptr;
2024-04-19 20:23:11 +00:00
}
2024-03-25 05:34:59 +00:00
2024-04-19 20:23:11 +00:00
bool BeginInputThread(struct InputThreadHandle *hand, struct InputBuffer *buf)
{
2024-04-23 20:33:32 +00:00
hand->in = buf;
2024-04-19 20:23:11 +00:00
hand->mutex = PTHREAD_MUTEX_INITIALIZER;
2024-04-22 22:13:13 +00:00
hand->buf_read = PTHREAD_COND_INITIALIZER;
hand->err = 0;
2024-04-19 20:23:11 +00:00
return pthread_create(&hand->thread, nullptr, input_thread_loop, hand) == 0;
2024-03-25 05:34:59 +00:00
}
2024-04-19 20:23:11 +00:00
bool EndInputThread(struct InputThreadHandle *hand)
2024-03-25 05:34:59 +00:00
{
2024-04-19 20:23:11 +00:00
hand->is_terminating = true;
if (!PlatformStopInput())
return false;
if (!pthread_mutex_destroy(&hand->mutex))
return false;
if (!pthread_join(hand->thread, nullptr))
return false;
return true;
2024-03-25 05:34:59 +00:00
}