From aed0fb34803583fa2615f81d04c8cf808a1f9c33 Mon Sep 17 00:00:00 2001 From: Jonas Suhr Christensen Date: Fri, 30 Mar 2012 12:05:22 +0200 Subject: Updated interfaces. --- src/taskmanager.cc | 265 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/taskmanager.h | 185 +++++++++++++++++++++++++++++++++++++ src/tasktree.cc | 213 ++++++++++++++++++++++++++++++++++++++++++ src/tasktree.h | 69 ++++++++++++++ 4 files changed, 732 insertions(+) create mode 100644 src/taskmanager.cc create mode 100644 src/taskmanager.h create mode 100644 src/tasktree.cc create mode 100644 src/tasktree.h diff --git a/src/taskmanager.cc b/src/taskmanager.cc new file mode 100644 index 0000000..590c5b8 --- /dev/null +++ b/src/taskmanager.cc @@ -0,0 +1,265 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * task.cc + * + * Fri Feb 24 08:16:30 CET 2012 + * Copyright 2012 Bent Bisballe Nyeng + * deva@aasimon.org + ****************************************************************************/ + +/* + * This file is part of Munia. + * + * Munia is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Munia is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Munia; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "taskmanager.h" + +#include + +#define ROOT_ID 0 +#define LOSTFOUND_ID 1 +#define FINISHED_ID 2 +#define BACKLOG_ID 3 +#define PROJECTS_ID 4 +#define FIRST_TASK_ID 10 + +TaskManager::TaskManager() { + idCount = FIRST_TASK_ID; + + task_t t; + t.title = "root"; + tree.insertAsChild(0, ROOT_ID, t); + + t.title = "Finished"; + tree.insertAsChild(ROOT_ID, FINISHED_ID, t); + + t.title = "Backlog"; + tree.insertAsChild(ROOT_ID, FINISHED_ID, t); + + t.title = "Lost+Found"; + tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t); + + t.title = "Projects"; + tree.insertAsChild(ROOT_ID, PROJECTS_ID, t); +} + +TaskManager::~TaskManager() { +} + +taskid_t TaskManager::createId() { + return idCount++; +} + +task_t TaskManager::createTask() { + task_t t; + + t.id = createId(); + + return t; +} + +TaskIdList TaskManager::moveTask(taskid_t id, taskid_t to) + throw (std::exception) { + TaskIdList affectedTasks; + + try { + affectedTasks = tree.move(id, to); + goto finish; + } + catch (std::exception& e) { + + } + + finish: + return affectedTasks; +} + +TaskIdList TaskManager::deleteTask(taskid_t id) + throw (std::exception) { + TaskIdList affectedTasks; + + try { + affectedTasks = tree.remove(id); + goto finish; + } + catch(std::exception& e) { + throw e; + } + + finish: + return affectedTasks; +} + +TaskIdList TaskManager::updateTask(taskid_t id, task_t t) + throw (std::exception) { + + TaskIdList affectedTasks; + + try { + affectedTasks = tree.updateData(id, t); + goto finish; + } + catch (std::exception& e) { + throw e; + } + + finish: + return affectedTasks; +} + +TaskIdList TaskManager::addTask(task_t t, taskid_t id, taskid_t parentid) + throw (std::exception) { + TaskIdList affectedTasks; + + try { + affectedTasks = tree.insertAsChild(parentid, id, t); + goto finish; + } + catch (std::exception& e) { + throw e; + } + + finish: + return affectedTasks; +} + +/* +TaskIdList TaskManager::ancestorList(taskid_t id) + throw (std::exception) { + TaskIdList ancestors; + + try { + ancestors = tree.ancestorList(id); + goto finish; + } + catch (std::exception& e) { + throw e; + } + + finish: + return ancestors; +} +*/ + +#if 0 +TaskList tasklist; + +task_t create_task(std::string title, std::string desc) { + + task_t t; + t.parent_id = current_id_count(); + t.title = title; + t.desc = desc; + t.id = id_count; id_count++; + + return t; +} + +TaskList load_tasklist_from_file(std::string file) { + TaskList list; + + // create MuniaDb class which handles tasks, db-flush and db-init. + + return list; +} + +bool save_tasklist_to_file(TaskList list, std::string file) { + + FILE* fp; + + if(! (fp = fopen(file.c_str(), "w"))) { + return false; + } + + if(!fprintf(fp, "\n")) { + fclose(fp); + return false; + } + + TaskList::iterator it; + for(it = tasklist.begin(); it != tasklist.end(); it++) { + task_t t = *it; + int r = 1; + +// printf("Flushing task %d\n", t.id); + + r |= fprintf(fp, " \n", t.id, t.parent_id); + r |= fprintf(fp, " %s\n", xml_encode(t.title).c_str()); + r |= fprintf(fp, " %s\n", xml_encode(t.desc).c_str()); + r |= fprintf(fp, " )\n"); + + if(!r) { + fclose(fp); + return false; + } + } + + if(!fprintf(fp, "\n")) { + fclose(fp); + return false; + } + + fclose(fp); + return true; +} + +static void delete_task(task_t t, TaskList& graveyard); + +static void delete_children(task_t t, TaskList& graveyard) { + TaskList::iterator it; + for(it = tasklist.begin(); it != tasklist.end(); it++) { + if(it->parent_id == t.id) { + delete_task(*it, graveyard); + } + } +} + + +static void delete_task(task_t t, TaskList& graveyard) { + + TaskList::iterator it; + for(it = tasklist.begin(); it != tasklist.end(); it++) { + if(it->id == t.id) { + break; + } + } + + if(it != tasklist.end()) { + graveyard.push_back(*it); + delete_children(*it, graveyard); + } + +} + +void delete_task(int id, TaskList& graveyard) { + task_t t; + t.id = id; + delete_task(t, graveyard); + + for(TaskList::iterator it = graveyard.begin(); + it != graveyard.end(); it++) { + + for(TaskList::iterator it_tl = tasklist.begin(); + it_tl != tasklist.end(); it_tl++) { + + if(it_tl->id == it->id) { + tasklist.erase(it_tl); + break; + } + } + } +} +#endif diff --git a/src/taskmanager.h b/src/taskmanager.h new file mode 100644 index 0000000..fb8c965 --- /dev/null +++ b/src/taskmanager.h @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * taskmanager.h + * + * Fri Feb 24 08:16:29 CET 2012 + * Copyright 2012 Bent Bisballe Nyeng & Jonas Suhr Christensen + * deva@aasimon.org & jsc@umbraculum.org + ****************************************************************************/ + +/* + * This file is part of Munia. + * + * Munia is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Munia is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Munia; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __MUNIA_TASKMANAGER_H__ +#define __MUNIA_TASKMANAGER_H__ + +#include +#include +#include +#include + +#include "task.h" +#include "tasktree.h" + +class TaskManager { +public: + TaskManager(); + ~TaskManager(); + task_t createTask(); + + TaskIdList addTask(task_t t, taskid_t, taskid_t parentid) throw (std::exception); + TaskIdList updateTask(taskid_t id, task_t task) throw (std::exception); + TaskIdList deleteTask(taskid_t id) throw (std::exception); + TaskIdList moveTask(taskid_t id, taskid_t newParent) throw (std::exception); + +private: + // TaskIdList ancestorList(taskid_t task); + taskid_t createId(); + + TaskTree tree; + taskid_t idCount; +}; + +#if 0 + +/* +Task: + id + subtasks +// tags + title + description +// primary_assignment +// secondary_assignment + + +Protocol: + +Server -> client: + update [id] [title] [description]; + move [id] [x] [y]; + add [id] [title] [description] [x] [y]; + del [id] + +Client -> server: + update [id] [title] [description]; + move [id] [x] [y]; + add [title] [description] [x] [y]; + del [id] + +title and description are " encapsulated utf-8 string with " escaped with a backslash. +x and y are integers as strings +id are an integer as a string + */ + +/* +typedef struct { + int x, y; + int id; + std::string title; + std::string desc; +} task_t; +*/ +/* +protocol: + add_task title description parent_id + del_task id + update_task id title description + move_task id parent + copy_task id parent +*/ + + + +//typedef std::list TaskList; + +class CompareByParentid { +public: + bool operator()(const task_t &a, const task_t &b) const { + return a.parent_id < b.parent_id; + } +}; + + + + +class TaskList : public std::list{ +public: + TaskList() {} + ~TaskList(){} + + void insert(task_t t) { + if(t.id == t.parent_id) return; + printf("inserting task %d with parent %d\n", t.id, t.parent_id); + + if(t.parent_id == -1) { + std::list::push_front(t); + return; + } + + std::list::iterator it; + for(it = begin(); it != end(); ++it) { + printf("\tcomparing %d and %d\n", t.parent_id, it->id); + if(t.parent_id == it->id) { + break; + } + } + assert(it != end()); + + std::list::insert(++it, t); + +// std::list::push_back(t); +// std::list::sort(CompareByParentid()); + + } + + void move(task_t t) { + std::list::iterator it; + for(it = begin(); it != end(); it++) { + if(t.id == it->id) { + break; + } + } + assert(it != end()); + // if(it != end()) { + std::list::erase(it); + // } + insert(t); + } + + void push_back(task_t t) { + insert(t); + } + +private: + std::list list; +}; + + +extern TaskList tasklist; + +//typedef std::priority_queue, CompareByParentid> TaskList; + +task_t create_task(std::string title, std::string desc, + /*int x, int y*/ int parent_id); + +TaskList load_tasklist_from_file(std::string file); +bool save_tasklist_to_file(TaskList t, std::string file); +#endif + +#endif/*__MUNIA_TASK_H__*/ diff --git a/src/tasktree.cc b/src/tasktree.cc new file mode 100644 index 0000000..e44efee --- /dev/null +++ b/src/tasktree.cc @@ -0,0 +1,213 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * tasktree.cc + * + * Tue Mar 27 11:07:48 CEST 2012 + * Copyright 2012 Jonas Suhr Christensen + * jsc@umbraculum.org + ****************************************************************************/ + +/* + * This file is part of Munia. + * + * Munia is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Munia is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Munia; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#include "tasktree.h" + +#include "debug.h" + + +TaskTree::TaskTree() { + root = NULL; +} + +TaskTree::~TaskTree() { + // cleanup tree +} + +TaskIdList TaskTree::insertAsChild(taskid_t parentid, taskid_t id, task_t data) + throw (std::exception) { + + TaskIdList affectedNodes; + + // Initialize + if(!root) { + node_t* node = createNode(id); + root = node; + + affectedNodes.push_back(id); + + goto finish; + } + + try { + node_t* parent = id2node.at(parentid); + node_t* child = createNode(id); + child->data = data; + insertChild(parent, child); + + affectedNodes.push_back(parentid); + affectedNodes.push_back(id); + + goto finish; + } + catch(std::exception& e) { + throw e; + } + + finish: + return affectedNodes; +} + +TaskIdList TaskTree::remove(taskid_t id) + throw (std::exception) { + //todo: move all childrin to lost+found + WARN(tasktree, "Feature not implemneted yet\n"); + TaskIdList affectedNodes; + return affectedNodes; +} + +TaskIdList TaskTree::move(taskid_t id, taskid_t toid) + throw (std::exception) { + + TaskIdList affectedNodes; + + try { + node_t* child = id2node.at(id); + node_t* newparent = id2node.at(toid); + + if(!child->parent) { + throw std::exception(); + } + + child->parent->children.remove(child); + newparent->children.push_back(child); + + affectedNodes.push_back(id); + affectedNodes.push_back(child->parent->id); + affectedNodes.push_back(toid); + + goto finish; + } + catch(std::exception& e) { + throw e; + } + + finish: + return affectedNodes; +} + +TaskIdList TaskTree::updateData(taskid_t id, task_t t) + throw (std::exception) { + + TaskIdList affectedNodes; + + try { + node_t* node = id2node.at(id); + node->data = t; + + affectedNodes.push_back(id); + goto finish; + } + catch(std::exception& e) { + throw e; + } + + finish: + return affectedNodes; +} + +task_t TaskTree::getData(taskid_t id) + throw (std::exception) { + + task_t t; + + try { + node_t* node = id2node.at(id); + t = node->data; + goto finish; + } + catch(std::exception& e) { + throw e; + } + + finish: + return t; +} + +TaskIdList TaskTree::ancestorList(taskid_t id) + throw (std::exception) { + + TaskIdList ancestors; + + try { + node_t* current = id2node.at(id); + while(current->parent) { + ancestors.push_back(current->parent->id); + current = current->parent; + } + goto finish; + } + catch(std::exception& e) { + throw e; + } + + finish: + return ancestors; +} + +node_t* TaskTree::createNode(taskid_t id) { + node_t* node = new node_t(); + node->parent = NULL; + node->id = id; + id2node[id] = node; + return node; +} + +void TaskTree::insertChild(node_t* parent, node_t* child) { + parent->children.push_back(child); + child->parent = parent; +} + + + +#ifdef TEST_TASKTREE +//Additional dependency files +//deps: +//Required cflags (autoconf vars may be used) +//cflags: +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" +#include + +TEST_BEGIN; + +TaskTree tree; + +task_t t; +try { + tree.insertAsChild(-1, t); + } + catch(std::exeception& e) { + } + +// TODO: Put some testcode here (see test.h for usable macros). +TEST_TRUE(false, "No tests yet!"); + +TEST_END; + +#endif/*TEST_TASKTREE*/ diff --git a/src/tasktree.h b/src/tasktree.h new file mode 100644 index 0000000..9a3a45f --- /dev/null +++ b/src/tasktree.h @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * tasktree.h + * + * Tue Mar 27 11:07:48 CEST 2012 + * Copyright 2012 Jonas Suhr Christensen + * jsc@umbraculum.org + ****************************************************************************/ + +/* + * This file is part of Munia. + * + * Munia is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * Munia is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Munia; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ +#ifndef __MUNIA_TASKTREE_H__ +#define __MUNIA_TASKTREE_H__ + +#include +#include +#include + +#include "task.h" + +typedef struct node node_t; + +typedef std::list NodeList; + +struct node { + taskid_t id; + node_t* parent; + task_t data; + NodeList children; +}; + +class TaskTree { +public: + TaskTree(); + ~TaskTree(); + + TaskIdList insertAsChild(taskid_t parentid, taskid_t id, task_t data) throw (std::exception); + TaskIdList remove(taskid_t id) throw (std::exception); + TaskIdList move(taskid_t id, taskid_t newParentId) throw (std::exception); + TaskIdList updateData(taskid_t id, task_t t) throw (std::exception); + task_t getData(taskid_t id) throw (std::exception); + + TaskIdList ancestorList(taskid_t id) throw (std::exception); + +private: + node_t* createNode(taskid_t id); + void insertChild(node_t* parent, node_t* child); + + node_t* root; + std::map id2node; +}; + +#endif/*__MUNIA_TASKTREE_H__*/ -- cgit v1.2.3