2024-04-18 21:20:44 +00:00
|
|
|
#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-25 07:04:43 +00:00
|
|
|
void InputBufferTransfer(struct RecordBuffer *dest, struct RecordBuffer *src)
|
2024-04-16 22:14:53 +00:00
|
|
|
{
|
2024-04-25 07:04:43 +00:00
|
|
|
size_t copy_max = min_size(IO_BUF_SIZE - dest->len, src->len);
|
2024-04-16 22:14:53 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
for (size_t i = 0; i < copy_max; i++) {
|
2024-04-24 23:37:47 +00:00
|
|
|
size_t dest_i = (dest->start + dest->len + i) % IO_BUF_SIZE;
|
|
|
|
size_t src_i = (src->start + i) % IO_BUF_SIZE;
|
2024-04-23 20:33:32 +00:00
|
|
|
|
2024-04-24 23:37:47 +00:00
|
|
|
dest->buf[dest_i] = src->buf[src_i];
|
|
|
|
}
|
2024-04-23 20:33:32 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
dest->start += copy_max;
|
|
|
|
if (copy_max < src->len)
|
|
|
|
src->len -= copy_max;
|
2024-04-23 20:33:32 +00:00
|
|
|
}
|
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
void StringBufferTransfer(struct StringBuffer *dest, struct StringBuffer *src)
|
2024-04-23 20:33:32 +00:00
|
|
|
{
|
2024-04-25 07:04:43 +00:00
|
|
|
size_t copy_max = min_size(STR_BUF_SIZE - dest->len, src->len);
|
2024-04-23 20:33:32 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
for (size_t i = 0; i < copy_max; i++) {
|
2024-04-24 23:37:47 +00:00
|
|
|
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];
|
2024-04-23 20:33:32 +00:00
|
|
|
}
|
2024-04-24 23:37:47 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
dest->start += copy_max;
|
|
|
|
if (copy_max < src->len)
|
|
|
|
src->len -= copy_max;
|
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
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
struct RecordBuffer tmp_in = { .len = 0, .start = 0 };
|
|
|
|
struct StringBuffer 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-25 07:04:43 +00:00
|
|
|
if (!PlatformReadInput(&tmp_in, &tmp_str))
|
2024-04-22 05:19:54 +00:00
|
|
|
return nullptr;
|
2024-04-19 20:23:11 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
if (hand->err = pthread_mutex_lock(&hand->mutex))
|
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-25 07:04:43 +00:00
|
|
|
if (hand->err = pthread_cond_wait(&hand->consume, &hand->mutex))
|
2024-04-22 22:13:13 +00:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2024-04-23 20:33:32 +00:00
|
|
|
InputBufferTransfer(hand->in, &tmp_in);
|
2024-04-25 07:04:43 +00:00
|
|
|
StringBufferTransfer(hand->str, &tmp_str);
|
2024-04-19 20:23:11 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
if (hand->err = pthread_mutex_unlock(&hand->mutex))
|
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-25 07:04:43 +00:00
|
|
|
bool BeginInputThread(
|
|
|
|
struct InputThreadHandle *hand,
|
|
|
|
struct RecordBuffer *in,
|
|
|
|
struct StringBuffer *str
|
|
|
|
) {
|
|
|
|
*hand = (struct InputThreadHandle) {
|
|
|
|
.in = in,
|
|
|
|
.str = str,
|
|
|
|
|
|
|
|
.mutex = PTHREAD_MUTEX_INITIALIZER,
|
|
|
|
.consume = PTHREAD_COND_INITIALIZER,
|
|
|
|
|
|
|
|
.err = 0,
|
|
|
|
.is_terminating = false,
|
|
|
|
};
|
2024-04-22 22:13:13 +00:00
|
|
|
|
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
|
|
|
}
|