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-30 21:41:31 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
const struct RingBufferT IO_BUF_T = {
|
2024-04-30 04:43:41 +00:00
|
|
|
.OFFSET = offsetof(struct InputRecordBuf, buf),
|
|
|
|
.SIZE = sizeof(struct InputRecord),
|
|
|
|
.LEN = IO_BUF_SIZE
|
2024-04-29 20:01:48 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct RingBufferT STR_BUF_T = {
|
2024-04-30 04:43:41 +00:00
|
|
|
.OFFSET = offsetof(struct InputStringBuf, buf),
|
|
|
|
.SIZE = sizeof(char),
|
|
|
|
.LEN = STR_BUF_SIZE
|
2024-04-29 20:01:48 +00:00
|
|
|
};
|
|
|
|
|
2024-04-30 21:41:31 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
void *input_worker(void *arg)
|
2024-04-16 22:14:53 +00:00
|
|
|
{
|
2024-04-29 20:01:48 +00:00
|
|
|
struct InputHandle *hand = arg;
|
2024-04-23 20:33:32 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
struct InputRecordBuf tmp_recs = { .head.len = 0, .head.start = 0 };
|
2024-04-30 06:04:25 +00:00
|
|
|
struct InputStringBuf tmp_str = { .head.len = 0, .head.start = 0 };
|
2024-04-01 22:39:21 +00:00
|
|
|
|
2024-04-19 20:23:11 +00:00
|
|
|
while (!hand->is_terminating) {
|
2024-04-30 06:04:25 +00:00
|
|
|
if (!PlatformReadInput(&tmp_recs, &tmp_str)) {
|
2024-04-29 20:01:48 +00:00
|
|
|
hand->err = true;
|
2024-04-22 05:19:54 +00:00
|
|
|
return nullptr;
|
2024-04-29 20:01:48 +00:00
|
|
|
}
|
2024-04-30 04:43:41 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
if (pthread_mutex_lock(&hand->mutex) != 0) {
|
|
|
|
hand->err = true;
|
2024-04-22 05:19:54 +00:00
|
|
|
return nullptr;
|
2024-04-29 20:01:48 +00:00
|
|
|
}
|
2024-04-19 20:23:11 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
while (tmp_recs.head.len == IO_BUF_SIZE) {
|
|
|
|
if (pthread_cond_wait(&hand->is_consumed, &hand->mutex) != 0) {
|
|
|
|
hand->err = true;
|
2024-04-22 22:13:13 +00:00
|
|
|
return nullptr;
|
2024-04-29 20:01:48 +00:00
|
|
|
}
|
2024-04-22 22:13:13 +00:00
|
|
|
}
|
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
RingBufferTransfer(&IO_BUF_T, &hand->recs->head, &tmp_recs.head);
|
2024-04-30 06:04:25 +00:00
|
|
|
RingBufferTransfer(&STR_BUF_T, &hand->str->head, &tmp_str.head);
|
2024-04-19 20:23:11 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
if (pthread_mutex_unlock(&hand->mutex) != 0) {
|
|
|
|
hand->err = true;
|
2024-04-22 05:19:54 +00:00
|
|
|
return nullptr;
|
2024-04-29 20:01:48 +00:00
|
|
|
}
|
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(
|
2024-04-29 20:01:48 +00:00
|
|
|
struct InputHandle *hand,
|
2024-04-25 20:08:24 +00:00
|
|
|
struct InputRecordBuf *in,
|
|
|
|
struct InputStringBuf *str
|
2024-04-25 07:04:43 +00:00
|
|
|
) {
|
2024-04-29 20:01:48 +00:00
|
|
|
*hand = (struct InputHandle) {
|
|
|
|
.recs = in,
|
2024-04-25 07:04:43 +00:00
|
|
|
.str = str,
|
2024-04-29 20:01:48 +00:00
|
|
|
|
2024-04-25 07:04:43 +00:00
|
|
|
.err = 0,
|
|
|
|
.is_terminating = false,
|
|
|
|
};
|
2024-04-22 22:13:13 +00:00
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
if (pthread_mutex_init(&hand->mutex, nullptr) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (pthread_cond_init(&hand->is_consumed, nullptr) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (pthread_create(&hand->thread, nullptr, input_worker, hand) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2024-03-25 05:34:59 +00:00
|
|
|
}
|
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
bool EndInputThread(struct InputHandle *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;
|
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
if (pthread_mutex_destroy(&hand->mutex) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (pthread_join(hand->thread, nullptr) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InputAquire(struct InputHandle *hand)
|
|
|
|
{
|
|
|
|
if (pthread_mutex_lock(&hand->mutex) != 0)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool InputRelease(struct InputHandle *hand)
|
|
|
|
{
|
|
|
|
if (pthread_cond_signal(&hand->is_consumed) != 0)
|
2024-04-19 20:23:11 +00:00
|
|
|
return false;
|
|
|
|
|
2024-04-29 20:01:48 +00:00
|
|
|
if (pthread_mutex_unlock(&hand->mutex) != 0)
|
2024-04-19 20:23:11 +00:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2024-04-30 21:41:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
size_t InputString(struct InputStringBuf *str, size_t n, char *buf)
|
|
|
|
{
|
|
|
|
return RingBufferOut(&STR_BUF_T, n, buf, &str->head);
|
2024-03-25 05:34:59 +00:00
|
|
|
}
|