Compare commits

...

5 Commits

3 changed files with 69 additions and 67 deletions

View File

@@ -170,19 +170,36 @@ void update(){
status |= (STATUS_RUN_BACKEND | STATUS_UPDATE_SCREEN_MASK | STATUS_RELOAD_DIRECTORY );
}
void select_all(){
TODO;
unsigned long i;
for (i = 0; i < mid_dir.file_count; i++) {
mid_dir.file_list[i].status ^= FILE_STATUS_SELECTED;
}
status |= (STATUS_RUN_BACKEND);
}
void dir_changed(){
unsigned long i;
for(i = 0; i < mid_dir.file_count; i++) {
mid_dir.file_list[i].status = 0;
}
status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY );
}
void move_down(unsigned long passes){
/*bounds checking happens within thread_mid*/
mid_dir.current_file += passes;
if (mid_dir.current_file > mid_dir.file_list + mid_dir.file_count - 1) {
mid_dir.current_file = mid_dir.file_list + mid_dir.file_count - 1;
}
status |= (STATUS_RUN_BACKEND);
}
void move_up(unsigned long passes){
/*bounds checking happens within thread_mid*/
mid_dir.current_file -= passes;
if (mid_dir.current_file < mid_dir.file_list) {
mid_dir.current_file = mid_dir.file_list;
}
status |= (STATUS_RUN_BACKEND);
}
@@ -193,6 +210,7 @@ void move_left(unsigned long passes){
/* TODO(2025-07-09T00:30:05) fix */
FAIL("move_left", "unhandled error of chdir");
}
dir_changed();
}
status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY);
@@ -204,6 +222,7 @@ void move_right(){
/* TODO(2026-05-05T20:12:14) fix */
FAIL("move_right", "unhandled error of chdir");
}
dir_changed();
} else if (mid_dir.current_file->file_type & FILE_TYPE_EXEC) {
} else {
char *mime = get_mimetype(mid_dir.current_file);
@@ -251,8 +270,13 @@ void toggle_hidden_files(){
file_modifiers ^= FILE_MODIFIERS_HIDDEN_FILES;
status |= (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY);
}
void toggle_selection(){
TODO;
void toggle_selection(unsigned long passes){
unsigned long i;
for (i = 0; i < passes; i++) {
mid_dir.current_file->status ^= FILE_STATUS_SELECTED;
move_down(1);
}
status |= (STATUS_RUN_BACKEND);
}
void jump_bottom(){
mid_dir.current_file = mid_dir.file_list + mid_dir.file_count - 1;

38
main.c
View File

@@ -81,7 +81,6 @@ int main(){
/* running through all once manually in order to get an as fast as possible first render on the screen */
pthread_cond_signal(&cond_top);
pthread_cond_signal(&cond_mid);
pthread_cond_signal(&cond_lft);
render_pass();
@@ -160,43 +159,10 @@ void render_pass(){
mvwin(win_b, terminal_height-1, 0);
}
/* render_queue is modified both by this and its associated thread without mutexes, this is intentional.
* reason being that since rendering is done in the same thread as the logic,
* using mutexes actually slows this down more than the result of an unknown state.
* an unknown state may be an incomplete render, which in my tests wont crash, or one too many renders.
* both of these chances are non distructive.
* doing rendering async is done because
* A: its funny
* B: previous render pipelines may have caused win_r to lack behind
* C: slowdown as a result of too many renders */
if (render_queue[RENDER_QUEUE_TOP] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) {
wnoutrefresh(win_t);
render_queue[RENDER_QUEUE_TOP] = 0;
status |= STATUS_UPDATE_ASYNC_REFRESH;
}
if (render_queue[RENDER_QUEUE_LFT] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) {
wnoutrefresh(win_l);
render_queue[RENDER_QUEUE_LFT] = 0;
status |= STATUS_UPDATE_ASYNC_REFRESH;
}
if (render_queue[RENDER_QUEUE_MID] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) {
wnoutrefresh(win_m);
render_queue[RENDER_QUEUE_MID] = 0;
status |= STATUS_UPDATE_ASYNC_REFRESH;
}
if (render_queue[RENDER_QUEUE_RGT] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) {
wnoutrefresh(win_r);
render_queue[RENDER_QUEUE_RGT] = 0;
status |= STATUS_UPDATE_ASYNC_REFRESH;
}
if (render_queue[RENDER_QUEUE_BTM] || status & (STATUS_UPDATE_SCREEN_RESIZE | STATUS_UPDATE_SCREEN_CLEAR)) {
wnoutrefresh(win_b);
render_queue[RENDER_QUEUE_BTM] = 0;
status |= STATUS_UPDATE_ASYNC_REFRESH;
}
if (status & STATUS_UPDATE_SCREEN_MASK) {
if (pthread_mutex_lock(&mutex_render) == 0 || status & STATUS_UPDATE_SCREEN_MASK) {
doupdate();
status &= ~STATUS_UPDATE_SCREEN_MASK;
pthread_mutex_unlock(&mutex_render);
}
}
/*this function exists for things done at startup (initialization, reading config, etc)*/

View File

@@ -18,7 +18,7 @@ pthread_mutex_t mutex_btm;
pthread_mutex_t mutex_lft;
pthread_mutex_t mutex_mid;
pthread_mutex_t mutex_rgt;
pthread_mutex_t mutex_selection;
pthread_mutex_t mutex_render;
pthread_cond_t cond_mid;
pthread_cond_t cond_rgt;
pthread_cond_t cond_lft;
@@ -46,7 +46,6 @@ unsigned long top_width;
extern unsigned int terminal_width;
extern unsigned int status;
volatile char render_queue[RENDER_QUEUE_BTM+1];
extern char *global_path;
unsigned int btm_status;
@@ -62,7 +61,6 @@ void *thread_mid(){
pthread_mutex_lock(&mutex_mid);
pthread_cond_wait(&cond_mid, &mutex_mid);
unsigned int local_status = status;
if (global_path == NULL) {
mid_dir.current_file = NULL;
@@ -73,7 +71,7 @@ void *thread_mid(){
memcpy(path, global_path, strlen(global_path)+1);
if (local_status & STATUS_RELOAD_DIRECTORY) {
if (status & STATUS_RELOAD_DIRECTORY) {
long index = mid_dir.current_file - mid_dir.file_list;
tmp = mid_dir;
@@ -88,6 +86,11 @@ void *thread_mid(){
mid_dir.current_file = NULL;
}
unsigned long i;
for(i = 0; i < mid_dir.file_count && i < tmp.file_count; i++) {
mid_dir.file_list[i].status = tmp.file_list[i].status;
}
}
@@ -98,23 +101,26 @@ void *thread_mid(){
mid_dir.current_file = mid_dir.file_list;
}
pthread_mutex_unlock(&mutex_mid);
pthread_cond_signal(&cond_top);
pthread_cond_signal(&cond_btm);
pthread_cond_signal(&cond_rgt);
/* rendering */
render_queue[RENDER_QUEUE_MID] = 0;
pthread_mutex_lock(&mutex_render);
werase(win_m);
if (mid_dir.file_count == 0) {
mvwaddstr(win_m, 0, 0, "empty");
} else {
print_dir(win_m, 1, &mid_dir);
}
render_queue[RENDER_QUEUE_MID] = 1;
pthread_cond_signal(&cond_rgt);
pthread_cond_signal(&cond_top);
pthread_cond_signal(&cond_btm);
pthread_mutex_unlock(&mutex_mid);
wnoutrefresh(win_m);
pthread_mutex_unlock(&mutex_render);
btm_status = local_status;
unsigned long i;
@@ -133,7 +139,6 @@ void *thread_lft(){
while(!(status & STATUS_QUIT_PROGRAM)){
pthread_mutex_lock(&mutex_lft);
pthread_cond_wait(&cond_lft, &mutex_lft);
unsigned int local_status = status;
if (global_path == NULL) {
lft_dir.current_file = NULL;
@@ -144,13 +149,12 @@ void *thread_lft(){
char *path = malloc(strlen(global_path)+1);
memcpy(path, global_path, strlen(global_path)+1);
render_queue[RENDER_QUEUE_LFT] = 0;
if (strcmp(path, "/") != 0) {
path[strrchr(path, '/')-path+1] = '\0';
path[strrchr(path, '/')-path] = '\0';
path[0] = '/';
if (local_status & STATUS_RELOAD_DIRECTORY) {
if (status & STATUS_RELOAD_DIRECTORY) {
unsigned long i = 0;
for (i = 0; i < lft_dir.file_count; i++) {
free(lft_dir.file_list[i].file_name);
@@ -171,14 +175,15 @@ void *thread_lft(){
}
/* rendering */
pthread_mutex_lock(&mutex_render);
werase(win_l);
print_dir(win_l, 0, &lft_dir);
render_queue[RENDER_QUEUE_LFT] = 1;
wnoutrefresh(win_l);
pthread_mutex_unlock(&mutex_render);
pthread_mutex_unlock(&mutex_lft);
free(path);
pthread_mutex_unlock(&mutex_lft);
}
pthread_exit(0);
@@ -209,7 +214,6 @@ void *thread_rgt(){
pthread_mutex_unlock(&mutex_mid);
render_queue[RENDER_QUEUE_RGT] = 0;
werase(win_r);
if (rgt_dir.current_file->permissions & S_IRUSR) {
if (rgt_dir.current_file->file_type &= FILE_TYPE_DIR) {
@@ -226,22 +230,27 @@ void *thread_rgt(){
} else { /* the hovered dir is empty */
rgt_dir.current_file = NULL;
}
pthread_mutex_lock(&mutex_render);
print_dir(win_r, 0, &rgt_dir);
wnoutrefresh(win_r);
pthread_mutex_unlock(&mutex_render);
} else if ((status & STATUS_DELTA_TIME) != STATUS_DELTA_TIME && rgt_dir.file_count > 0) {
free(rgt_buffer);
rgt_buffer = preview_file(rgt_dir.current_file);
rgt_dir.current_file->file_type |= FILE_TYPE_OPEN_FILE;
pthread_mutex_lock(&mutex_render);
if (rgt_dir.current_file->file_type == FILE_TYPE_OPEN_FILE) {
mvwaddnstr(win_r, 0, 0, rgt_buffer, (terminal_width/2) * terminal_width);
} else if ((rgt_dir.current_file->permissions & S_IRUSR) == 0) {
mvwaddstr(win_r, 0, 0, "not accessible");
}
wnoutrefresh(win_r);
pthread_mutex_unlock(&mutex_render);
}
}
render_queue[RENDER_QUEUE_RGT] = 1;
pthread_mutex_unlock(&mutex_rgt);
unsigned long i;
@@ -263,7 +272,6 @@ void *thread_top(){
pthread_cond_wait(&cond_top, &mutex_top);
render_queue[RENDER_QUEUE_TOP] = 0;
free(top_buffer);
if(global_path == NULL) {
@@ -279,6 +287,8 @@ void *thread_top(){
/* rendering */
pthread_mutex_lock(&mutex_mid);
pthread_mutex_lock(&mutex_render);
werase(win_t);
if (*top_buffer != ' ') { /*printing ' ' (standard initialized value, see threading_init) makes valgrind throw a fuss*/
wattron(win_t, COLOR_PAIR(COLOR_PATH));
@@ -289,7 +299,9 @@ void *thread_top(){
mvwaddstr(win_t, 0, strlen(top_buffer)+1, mid_dir.current_file->file_name);
}
}
render_queue[RENDER_QUEUE_TOP] = 1;
wnoutrefresh(win_t);
pthread_mutex_unlock(&mutex_render);
pthread_mutex_unlock(&mutex_mid);
pthread_mutex_unlock(&mutex_top);
@@ -305,11 +317,9 @@ void *thread_btm(){
while(!(status & STATUS_QUIT_PROGRAM)){
pthread_mutex_lock(&mutex_btm);
pthread_cond_wait(&cond_btm, &mutex_btm);
unsigned int local_status = btm_status;
render_queue[RENDER_QUEUE_BTM] = 0;
if (local_status & (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY)) {
if (status & (STATUS_RUN_BACKEND | STATUS_RELOAD_DIRECTORY)) {
/*{{{ parse storage info; the fold of shame*/
pthread_mutex_lock(&mutex_mid);
unsigned long i;
@@ -405,11 +415,13 @@ void *thread_btm(){
/* rendering */
pthread_mutex_lock(&mutex_render);
werase(win_b);
if (*top_buffer != ' ') { /*printing ' ' (standard initialized value, see threading_init) makes valgrind throw a fuss*/
mvwprintw(win_b, 0, 0, "%s", btm_buffer);
}
render_queue[RENDER_QUEUE_BTM] = 1;
wnoutrefresh(win_b);
pthread_mutex_unlock(&mutex_render);
pthread_mutex_unlock(&mutex_btm);
/*the printing of all possible inputs are done in user_interactions */
@@ -434,7 +446,7 @@ void threading_init(){
pthread_mutex_init(&mutex_lft, NULL);
pthread_mutex_init(&mutex_btm, NULL);
pthread_mutex_init(&mutex_rgt, NULL);
pthread_mutex_init(&mutex_selection, NULL);
pthread_mutex_init(&mutex_render, NULL);
pthread_cond_init(&cond_rgt, NULL);
pthread_cond_init(&cond_lft, NULL);
pthread_cond_init(&cond_mid, NULL);