Use Taskchampion to store Taskwarrior data
This replaces the TF2 task files with a TaskChampion replica.
This commit is contained in:
committed by
Dustin J. Mitchell
parent
4b814bc602
commit
5bb9857984
@@ -33,6 +33,25 @@
|
||||
|
||||
using namespace tc::ffi;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
tc::ReplicaGuard::ReplicaGuard (Replica &replica, Task &task) :
|
||||
replica(replica),
|
||||
task(task)
|
||||
{
|
||||
// "steal" the reference from the Replica and store it locally, so that any
|
||||
// attempt to use the Replica will fail
|
||||
tcreplica = replica.inner.release();
|
||||
task.to_mut(tcreplica);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
tc::ReplicaGuard::~ReplicaGuard ()
|
||||
{
|
||||
task.to_immut();
|
||||
// return the reference to the Replica.
|
||||
replica.inner.reset(tcreplica);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
tc::Replica::Replica ()
|
||||
{
|
||||
@@ -113,6 +132,45 @@ tc::Task tc::Replica::new_task (tc::Status status, const std::string &descriptio
|
||||
return Task (tctask);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
tc::Task tc::Replica::import_task_with_uuid (const std::string &uuid)
|
||||
{
|
||||
TCTask *tctask = tc_replica_import_task_with_uuid (&*inner, uuid2tc (uuid));
|
||||
if (!tctask) {
|
||||
throw replica_error ();
|
||||
}
|
||||
return Task (tctask);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Replica::undo (int32_t *undone_out)
|
||||
{
|
||||
auto res = tc_replica_undo (&*inner, undone_out);
|
||||
if (res != TC_RESULT_OK) {
|
||||
throw replica_error ();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int64_t tc::Replica::num_local_operations ()
|
||||
{
|
||||
auto num = tc_replica_num_local_operations (&*inner);
|
||||
if (num < 0) {
|
||||
throw replica_error ();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
int64_t tc::Replica::num_undo_points ()
|
||||
{
|
||||
auto num = tc_replica_num_undo_points (&*inner);
|
||||
if (num < 0) {
|
||||
throw replica_error ();
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::vector<tc::Task> tc::Replica::all_tasks ()
|
||||
{
|
||||
@@ -134,14 +192,19 @@ std::vector<tc::Task> tc::Replica::all_tasks ()
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Replica::rebuild_working_set ()
|
||||
void tc::Replica::rebuild_working_set (bool force)
|
||||
{
|
||||
auto res = tc_replica_rebuild_working_set (&*inner, true);
|
||||
auto res = tc_replica_rebuild_working_set (&*inner, force);
|
||||
if (res != TC_RESULT_OK) {
|
||||
throw replica_error ();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
tc::ReplicaGuard tc::Replica::mutate_task (tc::Task &task) {
|
||||
return ReplicaGuard(*this, task);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string tc::Replica::replica_error () {
|
||||
return replica_error (tc_replica_error (&*inner));
|
||||
|
||||
@@ -45,6 +45,28 @@ namespace tc {
|
||||
tc::ffi::TCReplica,
|
||||
std::function<void(tc::ffi::TCReplica*)>>;
|
||||
|
||||
// ReplicaGuard uses RAII to ensure that a Replica is not accessed while it
|
||||
// is mutably borrowed (specifically, to make a task mutable).
|
||||
class ReplicaGuard {
|
||||
protected:
|
||||
friend class Replica;
|
||||
explicit ReplicaGuard (Replica &, Task &);
|
||||
|
||||
public:
|
||||
~ReplicaGuard();
|
||||
|
||||
// No moving or copying allowed
|
||||
ReplicaGuard (const ReplicaGuard &) = delete;
|
||||
ReplicaGuard &operator=(const ReplicaGuard &) = delete;
|
||||
ReplicaGuard (ReplicaGuard &&) = delete;
|
||||
ReplicaGuard &operator=(Replica &&) = delete;
|
||||
|
||||
private:
|
||||
Replica &replica;
|
||||
tc::ffi::TCReplica *tcreplica;
|
||||
Task &task;
|
||||
};
|
||||
|
||||
// Replica wraps the TCReplica type, managing its memory, errors, and so on.
|
||||
//
|
||||
// Except as noted, method names match the suffix to `tc_replica_..`.
|
||||
@@ -67,12 +89,20 @@ namespace tc {
|
||||
tc::WorkingSet working_set ();
|
||||
std::optional<tc::Task> get_task (const std::string &uuid);
|
||||
tc::Task new_task (Status status, const std::string &description);
|
||||
tc::Task import_task_with_uuid (const std::string &uuid);
|
||||
// TODO: struct TCTask *tc_replica_import_task_with_uuid(struct TCReplica *rep, struct TCUuid tcuuid);
|
||||
// TODO: TCResult tc_replica_sync(struct TCReplica *rep, struct TCServer *server, bool avoid_snapshots);
|
||||
// TODO: TCResult tc_replica_undo(struct TCReplica *rep, int32_t *undone_out);
|
||||
void undo (int32_t *undone_out);
|
||||
int64_t num_local_operations ();
|
||||
int64_t num_undo_points ();
|
||||
// TODO: TCResult tc_replica_add_undo_point(struct TCReplica *rep, bool force);
|
||||
void rebuild_working_set ();
|
||||
private:
|
||||
void rebuild_working_set (bool force);
|
||||
|
||||
ReplicaGuard mutate_task(tc::Task &);
|
||||
void immut_task(tc::Task &);
|
||||
|
||||
protected:
|
||||
friend class ReplicaGuard;
|
||||
unique_tcreplica_ptr inner;
|
||||
|
||||
// construct an error message from tc_replica_error, or from the given
|
||||
@@ -82,5 +112,6 @@ namespace tc {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -60,6 +60,18 @@ tc::Task& tc::Task::operator= (Task &&other) noexcept
|
||||
return *this;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Task::to_mut (TCReplica *replica)
|
||||
{
|
||||
tc_task_to_mut(&*inner, replica);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Task::to_immut ()
|
||||
{
|
||||
tc_task_to_immut(&*inner);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string tc::Task::get_uuid () const
|
||||
{
|
||||
@@ -100,6 +112,15 @@ std::string tc::Task::get_description () const
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::optional<std::string> tc::Task::get_value (std::string property) const
|
||||
{
|
||||
auto maybe_desc = tc_task_get_value (&*inner, string2tc(property));
|
||||
if (maybe_desc.ptr == NULL) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return std::make_optional(tc2string(maybe_desc));
|
||||
}
|
||||
|
||||
bool tc::Task::is_waiting () const
|
||||
{
|
||||
return tc_task_is_waiting (&*inner);
|
||||
@@ -123,6 +144,40 @@ bool tc::Task::is_blocking () const
|
||||
return tc_task_is_blocking (&*inner);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Task::set_status (tc::Status status)
|
||||
{
|
||||
TCResult res = tc_task_set_status (&*inner, (TCStatus)status);
|
||||
if (res != TC_RESULT_OK) {
|
||||
throw task_error ();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Task::set_value (std::string property, std::optional<std::string> value)
|
||||
{
|
||||
TCResult res;
|
||||
if (value.has_value()) {
|
||||
res = tc_task_set_value (&*inner, string2tc(property), string2tc(value.value()));
|
||||
} else {
|
||||
TCString nullstr;
|
||||
nullstr.ptr = NULL;
|
||||
res = tc_task_set_value (&*inner, string2tc(property), nullstr);
|
||||
}
|
||||
if (res != TC_RESULT_OK) {
|
||||
throw task_error ();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void tc::Task::set_modified (time_t modified)
|
||||
{
|
||||
TCResult res = tc_task_set_modified (&*inner, modified);
|
||||
if (res != TC_RESULT_OK) {
|
||||
throw task_error ();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
std::string tc::Task::task_error () const {
|
||||
TCString error = tc_task_error (&*inner);
|
||||
|
||||
@@ -31,10 +31,12 @@
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include "tc/ffi.h"
|
||||
|
||||
namespace tc {
|
||||
class Replica;
|
||||
class ReplicaGuard;
|
||||
|
||||
enum Status {
|
||||
Pending = tc::ffi::TC_STATUS_PENDING,
|
||||
@@ -57,10 +59,16 @@ namespace tc {
|
||||
class Task
|
||||
{
|
||||
protected:
|
||||
// Tasks may only be created by tc::Replica
|
||||
// Tasks may only be created and made mutable/immutable
|
||||
// by tc::Replica
|
||||
friend class tc::Replica;
|
||||
explicit Task (tc::ffi::TCTask *);
|
||||
|
||||
// RplicaGuard handles mut/immut
|
||||
friend class tc::ReplicaGuard;
|
||||
void to_mut(tc::ffi::TCReplica *);
|
||||
void to_immut();
|
||||
|
||||
public:
|
||||
// This object "owns" inner, so copy is not allowed.
|
||||
Task (const Task &) = delete;
|
||||
@@ -70,12 +78,11 @@ namespace tc {
|
||||
Task (Task &&) noexcept;
|
||||
Task &operator=(Task &&) noexcept;
|
||||
|
||||
// TODO: void tc_task_to_mut(struct TCTask *task, struct TCReplica *tcreplica);
|
||||
// TODO: void tc_task_to_immut(struct TCTask *task);
|
||||
std::string get_uuid () const;
|
||||
Status get_status () const;
|
||||
std::map <std::string, std::string> get_taskmap() const;
|
||||
std::string get_description() const;
|
||||
std::optional<std::string> get_value(std::string property) const;
|
||||
// TODO: time_t tc_task_get_entry(struct TCTask *task);
|
||||
// TODO: time_t tc_task_get_wait(struct TCTask *task);
|
||||
// TODO: time_t tc_task_get_modified(struct TCTask *task);
|
||||
@@ -90,11 +97,12 @@ namespace tc {
|
||||
// TODO: struct TCString tc_task_get_legacy_uda(struct TCTask *task, struct TCString key);
|
||||
// TODO: struct TCUdaList tc_task_get_udas(struct TCTask *task);
|
||||
// TODO: struct TCUdaList tc_task_get_legacy_udas(struct TCTask *task);
|
||||
// TODO: TCResult tc_task_set_status(struct TCTask *task, enum TCStatus status);
|
||||
void set_status(Status status);
|
||||
// TODO: TCResult tc_task_set_description(struct TCTask *task, struct TCString description);
|
||||
void set_value(std::string property, std::optional<std::string> value);
|
||||
// TODO: TCResult tc_task_set_entry(struct TCTask *task, time_t entry);
|
||||
// TODO: TCResult tc_task_set_wait(struct TCTask *task, time_t wait);
|
||||
// TODO: TCResult tc_task_set_modified(struct TCTask *task, time_t modified);
|
||||
void set_modified(time_t modified);
|
||||
// TODO: TCResult tc_task_start(struct TCTask *task);
|
||||
// TODO: TCResult tc_task_stop(struct TCTask *task);
|
||||
// TODO: TCResult tc_task_done(struct TCTask *task);
|
||||
|
||||
Reference in New Issue
Block a user