summaryrefslogtreecommitdiff
path: root/src/administration_writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/administration_writer.cpp')
-rw-r--r--src/administration_writer.cpp174
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;