package main
-
import "base:runtime"
import "core:encoding/json"
}
App :: struct {
- mutex: sync.Mutex,
- state_mutex: sync.Mutex,
+ ui_mutex: sync.Mutex,
+ data_mutex: sync.Mutex,
running: bool,
}
app_deinit :: proc(app: ^App) {
- sync.mutex_lock(&app.mutex)
- defer sync.mutex_unlock(&app.mutex)
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
delete(app.requests_callbacks)
}
app_update_room_list_window :: proc(app: ^App) {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
room_list_window, ok := app.room_list_window.?
if !ok {
return
}
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
nc.wclear(room_list_window)
c_room_name_buffer: [ROOM_NAME_MAX_SIZE + 1]u8
}
app_update_room_window :: proc(app: ^App) {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
room_window, ok := app.room_window.?
if !ok {
}
app_set_state :: proc(app: ^App, state: State) {
- sync.mutex_lock(&app.state_mutex)
- defer sync.mutex_unlock(&app.state_mutex)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
- nc.clear()
- nc.refresh()
+ nc.clear()
+ nc.refresh()
+ }
app_clear_box_message(app)
app_update_info_bar(app)
app.state = state
- if app.state == .Room_List || app.state == .Room {
- if app.room_list_window == nil {
- app.room_list_window = nc.newwin(screen_height - 2, 34, 0, 0)
- }
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
- if app.room_window == nil {
- app.room_window = nc.newwin(screen_height - 2, screen_width - 34, 0, 34)
- }
- } else {
- if host, ok := app.host.?; ok {
- net.close(host)
- }
+ if app.state == .Room_List || app.state == .Room {
+ if app.room_list_window == nil {
+ app.room_list_window = nc.newwin(screen_height - 2, 34, 0, 0)
+ }
- if room_list_window, ok := app.room_list_window.?; ok {
- nc.wclear(room_list_window)
- nc.wrefresh(room_list_window)
- nc.delwin(room_list_window)
- }
+ if app.room_window == nil {
+ app.room_window = nc.newwin(screen_height - 2, screen_width - 34, 0, 34)
+ }
+ } else {
+ if host, ok := app.host.?; ok {
+ net.close(host)
+ }
- if room_window, ok := app.room_window.?; ok {
- nc.wclear(room_window)
- nc.wrefresh(room_window)
- nc.delwin(room_window)
+ if room_list_window, ok := app.room_list_window.?; ok {
+ nc.wclear(room_list_window)
+ nc.wrefresh(room_list_window)
+ nc.delwin(room_list_window)
+ }
+
+ if room_window, ok := app.room_window.?; ok {
+ nc.wclear(room_window)
+ nc.wrefresh(room_window)
+ nc.delwin(room_window)
+ }
}
}
return
}
- sync.mutex_lock(&app.mutex)
- defer sync.mutex_unlock(&app.mutex)
+ {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
- if app.info_bar_content != "" {
- delete(app.info_bar_content)
+ if app.info_bar_content != "" {
+
+ delete(app.info_bar_content)
+ }
}
defer app_update_info_bar(app)
if format == "" {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
app.info_bar_content = ""
+
return
}
fmt.sbprintf(&info_bar_content_builder, format, ..args)
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
app.info_bar_content = strings.to_string(info_bar_content_builder)
}
color := nc.COLOR_PAIR(2)
- nc.wattron(box_message, color)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
- for line, i in lines {
- c_line := strings.clone_to_cstring(line, context.temp_allocator)
- nc.mvwprintw(box_message, i32(i + 1), 2, c_line)
- }
+ nc.wattron(box_message, color)
- nc.box(box_message, 0, 0)
- nc.wattroff(box_message, color)
+ for line, i in lines {
+ c_line := strings.clone_to_cstring(line, context.temp_allocator)
+ nc.mvwprintw(box_message, i32(i + 1), 2, c_line)
+ }
- nc.wrefresh(box_message)
+ nc.box(box_message, 0, 0)
+ nc.wattroff(box_message, color)
+
+ nc.wrefresh(box_message)
+ }
{
- sync.mutex_lock(&app.mutex)
- defer sync.mutex_unlock(&app.mutex)
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
if box_message, ok := app.box_message.?; ok {
nc.delwin(box_message)
}
app_update_info_bar :: proc(app: ^App) {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
height, width := nc.getmaxyx(app.info_bar)
color := nc.COLOR_PAIR(1)
}
app_clear_box_message :: proc(app: ^App) {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
if box_message, ok := app.box_message.?; ok {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
nc.wclear(box_message)
nc.wrefresh(box_message)
nc.delwin(box_message)
allow_empty := false,
allocator := context.allocator,
) -> string {
- sync.mutex_lock(&app.state_mutex)
- defer sync.mutex_unlock(&app.state_mutex)
-
context.allocator = allocator
for {
- nc.wclear(app.input_window)
- nc.wrefresh(app.input_window)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
+ nc.wclear(app.input_window)
+ nc.wrefresh(app.input_window)
+ }
buffer: [256]u8
buffer_len, cursor_pos: int
screen_height, screen_width := nc.getmaxyx(app.screen)
- nc.curs_set(1)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
+ nc.curs_set(1)
+ }
input_loop: for {
char, ok := handle_getch(app, &buffer_len, &cursor_pos).?
buffer[buffer_len] = 0
output := string(buffer[:buffer_len + 1])
- nc.wclear(app.input_window)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
- if !hidden || (buffer_len != 0 && buffer[0] == ':') {
- nc.mvwprintw(app.input_window, 0, 0, strings.unsafe_string_to_cstring(output))
- nc.wmove(app.input_window, 0, i32(cursor_pos))
- }
+ nc.wclear(app.input_window)
- nc.wrefresh(app.input_window)
+ if !hidden || (buffer_len != 0 && buffer[0] == ':') {
+ nc.mvwprintw(app.input_window, 0, 0, strings.unsafe_string_to_cstring(output))
+ nc.wmove(app.input_window, 0, i32(cursor_pos))
+ }
+
+ nc.wrefresh(app.input_window)
+ }
}
- nc.curs_set(0)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
- nc.wclear(app.input_window)
+ nc.curs_set(0)
+
+ nc.wclear(app.input_window)
+ }
c_input := cstring(raw_data(buffer[:]))
only_command := false,
allocator := context.allocator,
) -> Input_Or_Event {
- sync.mutex_lock(&app.state_mutex)
- defer sync.mutex_unlock(&app.state_mutex)
-
context.allocator = allocator
for {
- nc.wclear(app.input_window)
- nc.wrefresh(app.input_window)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
+ nc.wclear(app.input_window)
+ nc.wrefresh(app.input_window)
+ }
buffer: [256]u8
buffer_len, cursor_pos: int
screen_height, screen_width := nc.getmaxyx(app.screen)
- nc.curs_set(1)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
+ nc.curs_set(1)
+ }
input_loop: for {
char, ok := handle_getch(app, &buffer_len, &cursor_pos).?
output := string(buffer[:buffer_len + 1])
- nc.wclear(app.input_window)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
- nc.mvwprintw(app.input_window, 0, 0, strings.unsafe_string_to_cstring(output))
- nc.wmove(app.input_window, 0, i32(cursor_pos))
+ nc.wclear(app.input_window)
- nc.wrefresh(app.input_window)
+ nc.mvwprintw(app.input_window, 0, 0, strings.unsafe_string_to_cstring(output))
+ nc.wmove(app.input_window, 0, i32(cursor_pos))
+
+ nc.wrefresh(app.input_window)
+ }
}
- nc.curs_set(0)
+ {
+ sync.mutex_lock(&app.ui_mutex)
+ defer sync.mutex_unlock(&app.ui_mutex)
+
+ nc.curs_set(0)
- nc.wclear(app.input_window)
+ nc.wclear(app.input_window)
+ }
c_input := cstring(raw_data(buffer[:]))
entropy_hash: [sha3.DIGEST_SIZE_256]u8
sha3.final(&sha_context, entropy_hash[:])
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
app.seed_phrase_checksum = entropy_hash[0] & 0b1111
}
app_add_room :: proc(app: ^App, room: Room) {
room := room
- append(&app.profile.rooms, room)
+ {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
+ append(&app.profile.rooms, room)
+ profile_update(app.profile, app)
+ }
- profile_update(app.profile, app)
app_update_room_list_window(app)
}
app_remove_room :: proc(app: ^App, index: int) {
- ordered_remove(&app.profile.rooms, index)
- profile_update(app.profile, app)
+ {
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
+
+ ordered_remove(&app.profile.rooms, index)
+
+ if app.selected_room != 0 && app.selected_room >= len(app.profile.rooms) {
+ app.selected_room = len(app.profile.rooms) - 1
+ }
- if app.selected_room >= len(app.profile.rooms) {
- app.selected_room = len(app.profile.rooms) - 1
+ profile_update(app.profile, app)
}
app_update_room_list_window(app)
state: State
{
- sync.mutex_lock(&app.mutex)
- defer sync.mutex_unlock(&app.mutex)
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
state = app.state
}
callback: Request_Callback
{
- sync.mutex_lock(&app.mutex)
- defer sync.mutex_unlock(&app.mutex)
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
callback = app.requests_callbacks[message_id]
delete_key(&app.requests_callbacks, message_id)
home_path := os.get_env("HOME")
defer delete(home_path)
- storage_path := fpath.join({ home_path, "mesange" })
+ storage_path := fpath.join({ home_path, "mesange", "client" })
defer delete(storage_path)
// Setup logger.
free_all(context.temp_allocator)
}
- sync.mutex_lock(&app.mutex)
- defer sync.mutex_unlock(&app.mutex)
+ sync.mutex_lock(&app.data_mutex)
+ defer sync.mutex_unlock(&app.data_mutex)
if !app.running {
break