diff options
Diffstat (limited to 'src/administration_writer.cpp')
| -rw-r--r-- | src/administration_writer.cpp | 174 |
1 files changed, 154 insertions, 20 deletions
diff --git a/src/administration_writer.cpp b/src/administration_writer.cpp index 77b1445..c45ec6e 100644 --- a/src/administration_writer.cpp +++ b/src/administration_writer.cpp @@ -18,6 +18,7 @@ #include <xml.h> #include <threads.h> +#include "config.hpp" #include "memops.hpp" #include "logger.hpp" #include "ui.hpp" @@ -28,51 +29,164 @@ #include "tinyfiledialogs.h" #include "file_templates.hpp" -mtx_t _save_file_mutex; +static mtx_t _save_file_mutex; +static bool _is_writing = false; +static write_completed_event _write_completed_ev = 0; + +bool administration_writer::is_writing() +{ + return _is_writing; +} + +void administration_writer::set_write_completed_event_callback(write_completed_event ev) +{ + _write_completed_ev = ev; +} static void on_administration_data_changed() { - if (administration_writer::save_all_administration_info_blocking()) { - ui::set_status(locale::get("status.saved")); - } - else { - ui::set_status(locale::get("status.saveFailed")); - } + _is_writing = true; + + auto* func = new auto([]() { + administration_writer::save_administration_info_blocking(); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, 0); } static void on_administration_data_deleted(char id[MAX_LEN_ID]) { - administration_writer::delete_entry(id); + _is_writing = true; + + char* id_copy = (char*)memops::alloc(MAX_LEN_ID); + strops::copy(id_copy, id, MAX_LEN_ID); + + auto* func = new auto([](void* arg) { + char* id = (char*)arg; + administration_writer::delete_entry(id); + administration_writer::save_administration_info_blocking(); + memops::unalloc(arg); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(arg); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, (void*)id_copy); } -static void on_invoice_changed(invoice* invoice) +static void on_invoice_changed(invoice* inv) { - administration_writer::save_invoice_blocking(*invoice); + _is_writing = true; + + invoice inv_copy = administration::invoice_create_copy(inv); + invoice* inv_copy2 = (invoice*)memops::alloc(sizeof(invoice)); + memops::copy(inv_copy2, &inv_copy, sizeof(invoice)); + + auto* func = new auto([](void* arg) { + invoice* inv = (invoice*)arg; + administration_writer::save_invoice_blocking(*inv); + administration_writer::save_administration_info_blocking(); + administration::invoice_destroy(inv); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(arg); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, (void*)inv_copy2); } -static void on_contact_changed_changed(contact* contact) +static void on_contact_changed_changed(contact* cc) { - administration_writer::save_contact_blocking(*contact); + _is_writing = true; + + contact* cc_copy = (contact*)memops::alloc(sizeof(contact)); + memops::copy(cc_copy, cc, sizeof(contact)); + + auto* func = new auto([](void* arg) { + contact* cc = (contact*)arg; + administration_writer::save_contact_blocking(*cc); + administration_writer::save_administration_info_blocking(); + memops::unalloc(arg); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(arg); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, (void*)cc_copy); } static void on_taxrate_changed_changed(tax_rate* rate) { - administration_writer::save_tax_rate_blocking(*rate); + _is_writing = true; + + tax_rate* rate_copy = (tax_rate*)memops::alloc(sizeof(tax_rate)); + memops::copy(rate_copy, rate, sizeof(tax_rate)); + + auto* func = new auto([](void* arg) { + tax_rate* rate = (tax_rate*)arg; + administration_writer::save_tax_rate_blocking(*rate); + administration_writer::save_administration_info_blocking(); + memops::unalloc(arg); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(arg); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, (void*)rate_copy); } -static void on_costcenter_changed_changed(cost_center* cost_center) +static void on_costcenter_changed_changed(cost_center* cc) { - administration_writer::save_cost_center_blocking(*cost_center); + _is_writing = true; + + cost_center* cc_copy = (cost_center*)memops::alloc(sizeof(cost_center)); + memops::copy(cc_copy, cc, sizeof(cost_center)); + + auto* func = new auto([](void* arg) { + cost_center* cc = (cost_center*)arg; + administration_writer::save_cost_center_blocking(*cc); + memops::unalloc(arg); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(arg); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, (void*)cc_copy); } -static void on_project_changed_changed(project* project) +static void on_project_changed_changed(project* pp) { - administration_writer::save_project_blocking(*project); + _is_writing = true; + + project* pp_copy = (project*)memops::alloc(sizeof(project)); + memops::copy(pp_copy, pp, sizeof(project)); + + auto* func = new auto([](void* arg) { + project* pp = (project*)arg; + administration_writer::save_project_blocking(*pp); + administration_writer::save_administration_info_blocking(); + memops::unalloc(arg); + + _is_writing = false; + if (_write_completed_ev) _write_completed_ev(); + }); + + auto trampoline = [](void* arg) -> int { auto* f = static_cast<decltype(func)>(arg); (*f)(arg); delete f; return 0; }; + thrd_t thr; thrd_create(&thr, trampoline, (void*)pp_copy); } bool administration_writer::create() { - administration::set_data_changed_event_callback(on_administration_data_changed); + administration::set_administration_data_changed_event_callback(on_administration_data_changed); administration::set_data_deleted_event_callback(on_administration_data_deleted); administration::set_invoice_changed_event_callback(on_invoice_changed); administration::set_contact_changed_event_callback(on_contact_changed_changed); @@ -80,7 +194,7 @@ bool administration_writer::create() administration::set_costcenter_changed_event_callback(on_costcenter_changed_changed); administration::set_project_changed_event_callback(on_project_changed_changed); - return mtx_init(&_save_file_mutex, mtx_plain) == thrd_success; + return mtx_init(&_save_file_mutex, mtx_plain|mtx_recursive) == thrd_success; } void administration_writer::destroy() @@ -101,17 +215,23 @@ static char* copy_template(const char* template_str, int* buf_size) static bool zip_entry_exists(char* entry) { + mtx_lock(&_save_file_mutex); + struct zip_t *zip_read = zip_open(administration::get_file_path(), 0, 'r'); int result = zip_entry_open(zip_read, entry); zip_entry_close(zip_read); zip_close(zip_read); + mtx_unlock(&_save_file_mutex); + return result == 0; } static bool delete_entry_by_name(char* entry) { STOPWATCH_START; + + mtx_lock(&_save_file_mutex); bool result = 1; struct zip_t *zip_write = zip_open(administration::get_file_path(), 0, 'a'); @@ -124,6 +244,8 @@ static bool delete_entry_by_name(char* entry) if (result) logger::info("Deleted entry '%s' in %.3fms.", entry, STOPWATCH_TIME); else logger::error("Failed to delete entry '%s'.", entry); + mtx_unlock(&_save_file_mutex); + return result; } @@ -137,6 +259,8 @@ bool administration_writer::delete_entry(char* id) static bool write_to_zip(char* entry_to_replace, char* orig_content, int final_length) { + mtx_lock(&_save_file_mutex); + bool result = 1; bool entry_exists = zip_entry_exists(entry_to_replace); if (entry_exists) delete_entry_by_name(entry_to_replace); @@ -149,6 +273,16 @@ static bool write_to_zip(char* entry_to_replace, char* orig_content, int final_l zip_entry_close(zip_write); zip_close(zip_write); + + #if WRITE_DELAY_SEC != 0 + struct timespec time; + time.tv_sec = WRITE_DELAY_SEC; + time.tv_nsec = 0; + thrd_sleep(&time, NULL); + #endif + + mtx_unlock(&_save_file_mutex); + return result; } @@ -705,7 +839,7 @@ bool administration_writer::save_contact_blocking(contact c) ///////////////////////////// //// Administration info ///////////////////////////// -bool administration_writer::save_all_administration_info_blocking() +bool administration_writer::save_administration_info_blocking() { STOPWATCH_START; |
