summaryrefslogtreecommitdiff
path: root/src/fruits/cap
diff options
context:
space:
mode:
Diffstat (limited to 'src/fruits/cap')
-rw-r--r--src/fruits/cap/cap.c87
-rw-r--r--src/fruits/cap/cap.h7
2 files changed, 60 insertions, 34 deletions
diff --git a/src/fruits/cap/cap.c b/src/fruits/cap/cap.c
index 2f60cb4..e1d9e13 100644
--- a/src/fruits/cap/cap.c
+++ b/src/fruits/cap/cap.c
@@ -36,28 +36,25 @@ static struct cch_entry *entry_for_unique_id(str *unique_id)
#if CAP_USE_PYTHON
struct sho_search s;
sho_search_init(&s);
+ str query;
+ al_str_from(&query, "");
if (al_str_cmp(unique_id, al_str_c("https://twitter.com"), 0, 19) == 0 ||
al_str_cmp(unique_id, al_str_c("https://x.com"), 0, 13) == 0) {
- str query;
- al_str_from(&query, "tweet:");
+ al_str_cat(&query, al_str_c("tweet:"));
al_str_cat(&query, unique_id);
if (!sho_search_more_results(&s, al_str_c("twitter"), &query)) {
}
- al_str_free(&query);
} else {
- str query;
if (is_search) {
- //al_str_from(&query, "\"");
- al_str_from(&query, "");
al_str_cat(&query, al_str_substr(unique_id, 1, unique_id->len));
- //al_str_cat(&query, al_str_c("\""));
} else {
- al_str_from(&query, "link:");
+ al_str_cat(&query, al_str_c("link:"));
al_str_cat(&query, unique_id);
}
if (!sho_search_more_results(&s, al_str_c("youtube"), &query)) {
}
}
+ al_str_free(&query);
entry = NULL;
struct sho_result_page *page;
al_array_foreach_ptr(s.result.pages, k, page) {
@@ -77,7 +74,7 @@ static struct cch_entry *entry_for_unique_id(str *unique_id)
#else
if (!is_search) entry = cch_handler_http_create(unique_id);
#endif
- entry->handler->maybe_spawn_worker(entry->handler, 0);
+ if (entry) entry->handler->maybe_spawn_worker(entry->handler, 0);
} else // {
#endif
entry = cch_handler_file_create(unique_id);
@@ -87,10 +84,11 @@ static struct cch_entry *entry_for_unique_id(str *unique_id)
static bool buffer_entry(struct cap_runner *cap, struct cap_list *list, struct cap_list_entry *entry)
{
+ if (entry->errored) return false;
if (entry->buffer_requested) return true;
- struct cch_entry *centry = entry_for_unique_id(&entry->unique_id);
- if (!centry) return false;
- if (!cap->callback(cap->userdata, CAP_BUFFER, &list->name, &entry->unique_id, centry)) {
+ entry->entry = entry_for_unique_id(&entry->unique_id);
+ if (!entry->entry) return false;
+ if (!cap->callback(cap->userdata, CAP_BUFFER, &list->name, &entry->unique_id, entry->entry)) {
entry->errored = true;
return false;
}
@@ -102,7 +100,7 @@ static void maybe_cleanup_entries(struct cap_runner *cap, struct cap_list *list)
{
struct cap_list_entry *entry;
al_array_foreach_ptr(list->entries, i, entry) {
- if (entry->buffer_requested && abs((s32)i - list->current) >= 3) {
+ if (entry->buffer_requested && abs(list->current - (s32)i) >= 3) {
cap->callback(cap->userdata, CAP_UNLOAD, &list->name, &entry->unique_id, NULL);
entry->buffer_requested = false;
}
@@ -111,28 +109,34 @@ static void maybe_cleanup_entries(struct cap_runner *cap, struct cap_list *list)
static bool list_skip_internal(struct cap_runner *cap, struct cap_list *list, s32 n);
-static void list_pump_internal(struct cap_runner *cap, struct cap_list *list)
+static void list_pump_internal(struct cap_runner *cap, struct cap_list *list, bool buffer)
{
s32 size = (s32)list->entries.size;
if (size <= list->current) return;
+ if (buffer) list->buffer = true;
if (list->set != list->current) {
struct cap_list_entry *entry = &al_array_at(list->entries, list->current);
+ if (list->swap && !entry->buffer_requested) {
+ list->swap = false;
+ return;
+ }
if (!buffer_entry(cap, list, entry)) {
- list_skip_internal(cap, list, 1);
+ list_skip_internal(cap, list, list->forward ? 1 : -1);
return;
}
+ cap->callback(cap->userdata, list->swap ? CAP_SWAP : CAP_SET, &list->name, &entry->unique_id, NULL);
list->set = list->current;
- if (list->swap && entry->buffer_requested) {
- cap->callback(cap->userdata, CAP_SWAP, &list->name, &entry->unique_id, NULL);
- } else {
- cap->callback(cap->userdata, CAP_SET, &list->name, &entry->unique_id, NULL);
- }
- }
- if (list->current + 1 < size) {
- buffer_entry(cap, list, &al_array_at(list->entries, list->current + 1));
}
- if (list->current - 1 >= 0) {
- buffer_entry(cap, list, &al_array_at(list->entries, list->current - 1));
+ if (list->buffer) {
+ for (s32 i = 1; i <= 2; i++) {
+ if (list->current + i < size) {
+ buffer_entry(cap, list, &al_array_at(list->entries, list->current + i));
+ list->buffer = false;
+ }
+ if (list->current - i >= 0) {
+ buffer_entry(cap, list, &al_array_at(list->entries, list->current - i));
+ }
+ }
}
maybe_cleanup_entries(cap, list);
}
@@ -144,7 +148,8 @@ bool list_skip_internal(struct cap_runner *cap, struct cap_list *list, s32 n)
return false;
}
list->current += n;
- list_pump_internal(cap, list);
+ list->forward = n >= 0;
+ list_pump_internal(cap, list, false);
return true;
}
@@ -153,9 +158,12 @@ void cap_make_list(struct cap_runner *cap, str *name)
struct cap_list list;
al_str_clone(&list.name, name);
list.current = 0;
+ list.forward = true;
list.set = -1;
list.idle = false;
+ list.buffer = false;
list.swap = false;
+ aki_mutex_init(&list.mutex);
al_array_init(list.entries);
al_array_push(cap->lists, list);
}
@@ -164,39 +172,51 @@ void cap_list_add(struct cap_runner *cap, str *name, str *unique_id)
{
struct cap_list *list = list_from_name(cap, name);
if (!list) return;
+ aki_mutex_lock(&list->mutex);
struct cap_list_entry entry;
al_str_clone(&entry.unique_id, unique_id);
- entry.buffer_requested = false;
+ entry.entry = NULL;
entry.errored = false;
+ entry.buffer_requested = false;
al_array_push(list->entries, entry);
if (list->idle && list_skip_internal(cap, list, 1)) {
list->idle = false;
- return;
+ } else {
+ list_pump_internal(cap, list, false);
}
- list_pump_internal(cap, list);
+ aki_mutex_unlock(&list->mutex);
}
bool cap_list_skip(struct cap_runner *cap, str *name, s32 n)
{
struct cap_list *list = list_from_name(cap, name);
if (!list) return false;
- return list_skip_internal(cap, list, n);
+ aki_mutex_lock(&list->mutex);
+ bool ret = list_skip_internal(cap, list, n);
+ aki_mutex_unlock(&list->mutex);
+ return ret;
}
-void cap_list_pump(struct cap_runner *cap, str *name)
+void cap_list_pump(struct cap_runner *cap, str *name, bool buffer)
{
struct cap_list *list = list_from_name(cap, name);
- if (list) list_pump_internal(cap, list);
+ if (!list) return;
+ aki_mutex_lock(&list->mutex);
+ list_pump_internal(cap, list, buffer);
+ aki_mutex_unlock(&list->mutex);
}
bool cap_list_set_completed(struct cap_runner *cap, str *name)
{
struct cap_list *list = list_from_name(cap, name);
if (!list) return false;
+ aki_mutex_lock(&list->mutex);
list->swap = true;
list->idle = !list_skip_internal(cap, list, 1);
+ bool ret = !list->idle && list->swap;
list->swap = false;
- return !list->idle;
+ aki_mutex_unlock(&list->mutex);
+ return ret;
}
static void list_close_internal(struct cap_list *list)
@@ -206,6 +226,7 @@ static void list_close_internal(struct cap_list *list)
al_str_free(&entry->unique_id);
}
al_array_free(list->entries);
+ aki_mutex_destroy(&list->mutex);
al_str_free(&list->name);
}
diff --git a/src/fruits/cap/cap.h b/src/fruits/cap/cap.h
index d522a82..07aa63b 100644
--- a/src/fruits/cap/cap.h
+++ b/src/fruits/cap/cap.h
@@ -4,9 +4,11 @@
#include <al/array.h>
#include <al/str.h>
+#include <aki/thread.h>
struct cap_list_entry {
str unique_id;
+ struct cch_entry *entry;
bool buffer_requested;
bool errored;
};
@@ -14,9 +16,12 @@ struct cap_list_entry {
struct cap_list {
str name;
s32 current;
+ bool forward;
s32 set;
bool idle;
+ bool buffer;
bool swap;
+ struct aki_mutex mutex;
array(struct cap_list_entry) entries;
};
@@ -37,6 +42,6 @@ void cap_init(struct cap_runner *cap, bool (*callback)(void *, u8, str *, str *,
void cap_make_list(struct cap_runner *cap, str *name);
void cap_list_add(struct cap_runner *cap, str *name, str *unique_id);
bool cap_list_skip(struct cap_runner *cap, str *name, s32 n);
-void cap_list_pump(struct cap_runner *cap, str *name);
+void cap_list_pump(struct cap_runner *cap, str *name, bool buffer);
bool cap_list_set_completed(struct cap_runner *cap, str *name);
void cap_close(struct cap_runner *cap);