From fa5985ed620c3cd4c7b9712b6b80a2e2c1a8ba31 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sat, 6 Jun 2020 18:32:11 +0200 Subject: Rename task to node everywhere. --- handler.js | 36 ++-- munia.css | 2 +- munia.html | 10 +- node.js | 137 ++++++++++++++ proto.js | 10 +- src/Makefile.am | 12 +- src/connectionhandler.cc | 92 ++++----- src/connectionhandler.h | 12 +- src/http.cc | 2 +- src/message.h | 22 +-- src/messagehandler.cc | 62 +++---- src/messageparser.cc | 18 +- src/messageparser.h | 10 +- src/munia_proto.cc | 46 ++--- src/munia_proto.h | 4 +- src/muniacli.cc | 90 ++++----- src/muniad.cc | 6 +- src/node.cc | 46 +++++ src/node.h | 42 +++++ src/nodemanager.cc | 407 ++++++++++++++++++++++++++++++++++++++++ src/nodemanager.h | 214 +++++++++++++++++++++ src/nodetree.cc | 475 +++++++++++++++++++++++++++++++++++++++++++++++ src/nodetree.h | 83 +++++++++ src/task.cc | 46 ----- src/task.h | 42 ----- src/taskmanager.cc | 407 ---------------------------------------- src/taskmanager.h | 214 --------------------- src/tasktree.cc | 475 ----------------------------------------------- src/tasktree.h | 85 --------- src/testclient.cc | 18 +- src/xmlparser.cc | 12 +- src/xmlparser.h | 12 +- task.js | 137 -------------- view.js | 24 +-- 34 files changed, 1654 insertions(+), 1656 deletions(-) create mode 100644 node.js create mode 100644 src/node.cc create mode 100644 src/node.h create mode 100644 src/nodemanager.cc create mode 100644 src/nodemanager.h create mode 100644 src/nodetree.cc create mode 100644 src/nodetree.h delete mode 100644 src/task.cc delete mode 100644 src/task.h delete mode 100644 src/taskmanager.cc delete mode 100644 src/taskmanager.h delete mode 100644 src/tasktree.cc delete mode 100644 src/tasktree.h delete mode 100644 task.js diff --git a/handler.js b/handler.js index 5242cc0..906a03b 100644 --- a/handler.js +++ b/handler.js @@ -5,8 +5,8 @@ document.addEventListener("connectEvent", connectEventHandler, false); function connectEventHandler(e) { - document.getElementById("wstask_status").style.backgroundColor = "#40ff40"; - document.getElementById("wstask_status").textContent = "TaskProto websocket connection opened "; + document.getElementById("wsnode_status").style.backgroundColor = "#40ff40"; + document.getElementById("wsnode_status").textContent = "NodeProto websocket connection opened "; //login("foobar", "hundemad"); //subscribe(0); @@ -15,8 +15,8 @@ function connectEventHandler(e) document.addEventListener("disconnectEvent", disconnectEventHandler, false); function disconnectEventHandler(e) { - document.getElementById("wstask_status").style.backgroundColor = "#ff4040"; - document.getElementById("wstask_status").textContent = "TaskProto websocket connection CLOSED "; + document.getElementById("wsnode_status").style.backgroundColor = "#ff4040"; + document.getElementById("wsnode_status").textContent = "NodeProto websocket connection CLOSED "; } document.addEventListener("removeEvent", removeEventHandler, false); @@ -25,8 +25,8 @@ function removeEventHandler(e) var subscribeid = e.detail.subscribeid; var id = e.detail.id; - var task = findTask(id, subscribeid); - if(task.parent) task.parent.removeChild(task); + var node = findNode(id, subscribeid); + if(node.parent) node.parent.removeChild(node); } document.addEventListener("moveEvent", moveEventHandler, false); @@ -36,9 +36,9 @@ function moveEventHandler(e) var id = e.detail.id; var parentid = e.detail.parentid; - var task = findTask(id, subscribeid); - var new_parent = findTask(parentid, subscribeid); - if(task != null && new_parent != null) new_parent.addChild(task); + var node = findNode(id, subscribeid); + var new_parent = findNode(parentid, subscribeid); + if(node != null && new_parent != null) new_parent.addChild(node); } document.addEventListener("createEvent", createEventHandler, false); @@ -48,19 +48,19 @@ function createEventHandler(e) var id = e.detail.id; var parentid = e.detail.parentid; - var task = new Task(id, subscribeid); - task.create(); + var node = new Node(id, subscribeid); + node.create(); if(parentid == -1) { - tasks.push(task); + nodes.push(node); var board = getBoard(subscribeid); - board.appendChild(task.element); + board.appendChild(node.element); return; } - var parent = findTask(parentid, subscribeid); + var parent = findNode(parentid, subscribeid); if(parent != null) { - parent.addChild(task); + parent.addChild(node); } } @@ -73,10 +73,10 @@ function updateEventHandler(e) var name = e.detail.name; var value = e.detail.value; - var task = findTask(id, subscribeid); - if(task == null) return; + var node = findNode(id, subscribeid); + if(node == null) return; - task.setAttribute(name, value); + node.setAttribute(name, value); } /////// diff --git a/munia.css b/munia.css index 9fab874..f94f4b7 100644 --- a/munia.css +++ b/munia.css @@ -10,7 +10,7 @@ body { cursor: default; } -.task { +.node { -webkit-touch-callout: none; -webkit-user-select: none; -khtml-user-select: none; diff --git a/munia.html b/munia.html index 972f595..669cda7 100644 --- a/munia.html +++ b/munia.html @@ -8,12 +8,12 @@ -
TaskProto not initialized
+
NodeProto not initialized
- TaskProto: -
+
@@ -23,7 +23,7 @@ - + diff --git a/node.js b/node.js new file mode 100644 index 0000000..3cb325c --- /dev/null +++ b/node.js @@ -0,0 +1,137 @@ +/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ + +function createId(boardid, nodeid) +{ + return "b" + boardid + "_t" + nodeid; +} + +function idFromStr(str) +{ + return str.substring(str.search('t') + 1, str.length); +} + +var nodes = new Array(); + +function findNode(id, subscribeid) +{ + for(var i = 0; i < nodes.length; i++) { + var node = nodes[i]; + var child = node.findNode(id, subscribeid); + if(child != null) return child; + } + + return null; +} + +function Node(id, subscribeid) +{ + this.id = id; + this.subscribeid = subscribeid; + this.children = new Array(); + this.attributes = {}; + this.parent = null; + + // Elements: + this.element = document.createElement("div"); + this.div_id = document.createElement("span"); + this.div_title = document.createElement("span"); +} + +Node.prototype.dump = function() +{ + alert(this.id); +} + +Node.prototype.findNode = function(id, subscribeid) +{ + if(this.subscribeid != subscribeid) return null; + + if(this.id == id) return this; + + for(var i = 0; i < this.children.length; i++) { + var node = this.children[i]; + var child = node.findNode(id, subscribeid); + if(child != null) return child; + } + + return null; +} + +Node.prototype.addChild = function(node) +{ + if(node.parent != null) node.parent.removeChild(node); + this.children.push(node); + node.parent = this; + this.element.appendChild(node.element); +} + +Node.prototype.removeChild = function(node) +{ + this.children = this.children.filter( + function(e) { + return e.id != node.id; + }); + node.parent = null; + this.element.removeChild(node.element); +} + +Node.prototype.create = function() +{ + var node = this.element; + + node.name = "node"; + node.setAttribute("class", "node"); + node.setAttribute("ondblclick", "editTitle(this, event)"); + //node.setAttribute("onclick", "showHideChildren(this, event)"); + node.setAttribute("ondrop", "drop(this, event)"); + node.setAttribute("ondragover", "return false"); + node.setAttribute("draggable", true); + node.setAttribute("ondragstart", "drag(this, event)"); + node.setAttribute("title", this.id); + + // This is a hack to make it possible to identify the nodeid and + // oberveid from the node id alone. + node.id = createId(this.subscribeid, this.id); + +/* + var subscribe_button = document.createElement("div"); + subscribe_button.name = "subscribe_button"; + subscribe_button.setAttribute("onclick", "subscribeMe(this, event)"); + subscribe_button.setAttribute("title", this.id); + subscribe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid green 2px; cursor: pointer;"); + var txt_plus = document.createTextNode("+"); + subscribe_button.appendChild(txt_plus); + node.appendChild(subscribe_button); + + var unsubscribe_button = document.createElement("div"); + unsubscribe_button.name = "unsubscribe_button"; + unsubscribe_button.setAttribute("onclick", "unsubscribeMe(this, event)"); + unsubscribe_button.setAttribute("title", this.id); + unsubscribe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid red 2px; cursor: pointer;"); + var txt_minus = document.createTextNode("-"); + unsubscribe_button.appendChild(txt_minus); + node.appendChild(unsubscribe_button); +*/ + + this.element.appendChild(this.div_id); + var id_txt = document.createTextNode(this.id); + this.div_id.appendChild(id_txt); + + this.element.appendChild(this.div_title); + + this.setAttribute("title", "(missing title)"); +} + +Node.prototype.setAttribute = function(name, value) +{ + this.attributes[name] = value; + + if(name == "title") { + if(this.div_title.firstChild != null) { + this.div_title.removeChild(this.div_title.firstChild); + } + var title_txt = document.createTextNode(value); + this.div_title.appendChild(title_txt); + } +} diff --git a/proto.js b/proto.js index 7c44141..5a71157 100644 --- a/proto.js +++ b/proto.js @@ -15,10 +15,10 @@ function get_appropriate_ws_url() return parser.href; } -var socket_task = new WebSocket(get_appropriate_ws_url(), "lws-task-protocol"); +var socket_node = new WebSocket(get_appropriate_ws_url(), "lws-node-protocol"); try { - socket_task.onopen = function() { + socket_node.onopen = function() { var connectEvent = new CustomEvent("connectEvent", { detail: { time: new Date(), @@ -29,7 +29,7 @@ try { document.dispatchEvent(connectEvent); } - socket_task.onmessage = function got_packet(msg) { + socket_node.onmessage = function got_packet(msg) { var messageEvent = new CustomEvent("messageEvent", { detail: { message: "recv [" + msg.data + "]", @@ -138,7 +138,7 @@ try { } } - socket_task.onclose = function(){ + socket_node.onclose = function(){ var disconnectEvent = new CustomEvent("disconnectEvent", { detail: { time: new Date(), @@ -165,7 +165,7 @@ function transmit(msg) }); document.dispatchEvent(messageEvent); - socket_task.send(msg); + socket_node.send(msg); } function login(user, password) diff --git a/src/Makefile.am b/src/Makefile.am index c977d97..c942b75 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -15,9 +15,9 @@ muniad_SOURCES = \ messageparser.cc \ munia_proto.cc \ saxparser.cc \ - task.cc \ - taskmanager.cc \ - tasktree.cc \ + node.cc \ + nodemanager.cc \ + nodetree.cc \ testclient.cc \ xml_encode_decode.cc \ xmlparser.cc \ @@ -38,9 +38,9 @@ EXTRA_DIST = \ messagehandler.h \ munia_proto.h \ saxparser.h \ - task.h \ - taskmanager.h \ - tasktree.h \ + node.h \ + nodemanager.h \ + nodetree.h \ testclient.h \ xml_encode_decode.h \ xmlparser.h \ diff --git a/src/connectionhandler.cc b/src/connectionhandler.cc index 4cf8fc0..d0fb9e1 100644 --- a/src/connectionhandler.cc +++ b/src/connectionhandler.cc @@ -41,7 +41,7 @@ ConnectionHandler::ConnectionHandler() void ConnectionHandler::init(clientid_t clientid) { DEBUG(conn, "Adding client %p to connection list\n", clientid); - connlist[clientid] = std::set(); + connlist[clientid] = std::set(); DEBUG(conn, "Connections (%d):\n", (int)connlist.size()); ConnectionList::iterator it; @@ -74,34 +74,34 @@ bool ConnectionHandler::authenticated(clientid_t clientid) return authlist.find(clientid) != authlist.end() && authlist[clientid]; } -void ConnectionHandler::subscribe(clientid_t clientid, taskid_t taskid) +void ConnectionHandler::subscribe(clientid_t clientid, nodeid_t nodeid) { - connlist[clientid].insert(taskid); - DEBUG(conn, "Added subscriber of %d\n", taskid); + connlist[clientid].insert(nodeid); + DEBUG(conn, "Added subscriber of %d\n", nodeid); } -void ConnectionHandler::unsubscribe(clientid_t clientid, taskid_t taskid) +void ConnectionHandler::unsubscribe(clientid_t clientid, nodeid_t nodeid) { - connlist[clientid].erase(taskid); + connlist[clientid].erase(nodeid); } -SubscriberList ConnectionHandler::subscriberlist(TaskIdList tasks) +SubscriberList ConnectionHandler::subscriberlist(NodeIdList nodes) { - DEBUG(conn, "Subscriberlist request (#tasks: %d)\n", (int)tasks.size()); + DEBUG(conn, "Subscriberlist request (#nodes: %d)\n", (int)nodes.size()); SubscriberList clients; - for(TaskIdList::iterator i = tasks.begin(); i != tasks.end(); i++) + for(NodeIdList::iterator i = nodes.begin(); i != nodes.end(); i++) { - taskid_t tid = *i; + nodeid_t tid = *i; DEBUG(conn, "Locating subscribers of node %d\n", tid); for(ConnectionList::iterator ci = connlist.begin(); ci != connlist.end(); ci++) { - std::set::iterator ti = ci->second.find(tid); + std::set::iterator ti = ci->second.find(tid); if(ti != ci->second.end()) { - std::pair m; + std::pair m; m.first = ci->first; m.second = tid; clients.push_back(m); @@ -125,20 +125,20 @@ TEST_BEGIN; ConnectionHandler &h = connection_handler; h.init((clientid_t)1); -h.subscribe((clientid_t)1, (taskid_t)1); -h.subscribe((clientid_t)1, (taskid_t)2); +h.subscribe((clientid_t)1, (nodeid_t)1); +h.subscribe((clientid_t)1, (nodeid_t)2); h.init((clientid_t)2); -h.subscribe((clientid_t)2, (taskid_t)1); -h.subscribe((clientid_t)2, (taskid_t)2); +h.subscribe((clientid_t)2, (nodeid_t)1); +h.subscribe((clientid_t)2, (nodeid_t)2); h.init((clientid_t)3); -h.subscribe((clientid_t)3, (taskid_t)3); +h.subscribe((clientid_t)3, (nodeid_t)3); { - TaskIdList tasks; - tasks.push_back((taskid_t)1); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)1); + SubscriberList clst = h.subscriberlist(nodes); TEST_TRUE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_TRUE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); @@ -146,9 +146,9 @@ h.subscribe((clientid_t)3, (taskid_t)3); } { - TaskIdList tasks; - tasks.push_back((taskid_t)3); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)3); + SubscriberList clst = h.subscriberlist(nodes); TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); @@ -156,9 +156,9 @@ h.subscribe((clientid_t)3, (taskid_t)3); } { - TaskIdList tasks; - tasks.push_back((taskid_t)4); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)4); + SubscriberList clst = h.subscriberlist(nodes); TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); @@ -166,11 +166,11 @@ h.subscribe((clientid_t)3, (taskid_t)3); } { - TaskIdList tasks; - tasks.push_back((taskid_t)1); - tasks.push_back((taskid_t)2); - tasks.push_back((taskid_t)3); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)1); + nodes.push_back((nodeid_t)2); + nodes.push_back((nodeid_t)3); + SubscriberList clst = h.subscriberlist(nodes); TEST_TRUE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_TRUE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); @@ -179,11 +179,11 @@ h.subscribe((clientid_t)3, (taskid_t)3); h.close((clientid_t)1); { - TaskIdList tasks; - tasks.push_back((taskid_t)1); - tasks.push_back((taskid_t)2); - tasks.push_back((taskid_t)3); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)1); + nodes.push_back((nodeid_t)2); + nodes.push_back((nodeid_t)3); + SubscriberList clst = h.subscriberlist(nodes); TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_TRUE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); @@ -192,11 +192,11 @@ h.close((clientid_t)1); h.close((clientid_t)2); { - TaskIdList tasks; - tasks.push_back((taskid_t)1); - tasks.push_back((taskid_t)2); - tasks.push_back((taskid_t)3); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)1); + nodes.push_back((nodeid_t)2); + nodes.push_back((nodeid_t)3); + SubscriberList clst = h.subscriberlist(nodes); TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); @@ -205,11 +205,11 @@ h.close((clientid_t)2); h.close((clientid_t)3); { - TaskIdList tasks; - tasks.push_back((taskid_t)1); - tasks.push_back((taskid_t)2); - tasks.push_back((taskid_t)3); - SubscriberList clst = h.subscriberlist(tasks); + NodeIdList nodes; + nodes.push_back((nodeid_t)1); + nodes.push_back((nodeid_t)2); + nodes.push_back((nodeid_t)3); + SubscriberList clst = h.subscriberlist(nodes); TEST_FALSE(clst.find((clientid_t)1) != clst.end(), "Got client 1?"); TEST_FALSE(clst.find((clientid_t)2) != clst.end(), "Got client 2?"); diff --git a/src/connectionhandler.h b/src/connectionhandler.h index 482c293..39f1c54 100644 --- a/src/connectionhandler.h +++ b/src/connectionhandler.h @@ -33,13 +33,13 @@ #include -#include "task.h" +#include "node.h" typedef struct lws* clientid_t; typedef std::map AuthList; -typedef std::map > ConnectionList; -typedef std::list > SubscriberList; +typedef std::map > ConnectionList; +typedef std::list > SubscriberList; class ConnectionHandler { @@ -53,10 +53,10 @@ public: void logout(clientid_t clientid); bool authenticated(clientid_t clientid); - void subscribe(clientid_t clientid, taskid_t taskid); - void unsubscribe(clientid_t clientid, taskid_t taskid); + void subscribe(clientid_t clientid, nodeid_t nodeid); + void unsubscribe(clientid_t clientid, nodeid_t nodeid); - SubscriberList subscriberlist(TaskIdList tasklist); + SubscriberList subscriberlist(NodeIdList nodelist); private: ConnectionList connlist; diff --git a/src/http.cc b/src/http.cc index 43d09bc..ffd7912 100644 --- a/src/http.cc +++ b/src/http.cc @@ -100,7 +100,7 @@ int callback_http(struct lws *wsi, // script if(file == "proto.js" || file == "handler.js" || - file == "task.js" || + file == "node.js" || file == "view.js") { return serveFile(wsi, file,"text/javascript"); diff --git a/src/message.h b/src/message.h index bb56932..876631c 100644 --- a/src/message.h +++ b/src/message.h @@ -30,7 +30,7 @@ #include #include -#include "task.h" +#include "node.h" namespace cmd { @@ -59,34 +59,34 @@ typedef struct typedef struct { - taskid_t id; + nodeid_t id; } subscribe_t; typedef struct { - taskid_t id; + nodeid_t id; } unsubscribe_t; typedef struct { - taskid_t id; - taskid_t parentid; + nodeid_t id; + nodeid_t parentid; } create_t; typedef struct { - taskid_t id; + nodeid_t id; } remove_t; typedef struct { - taskid_t id; - taskid_t parentid; + nodeid_t id; + nodeid_t parentid; } move_t; typedef struct { - taskid_t id; + nodeid_t id; std::string attribute; std::string value; } update_t; @@ -104,10 +104,10 @@ typedef struct move_t move; update_t update; - TaskIdList nodes; + NodeIdList nodes; // target node id (subscription node id) used for transmissions only. - taskid_t tid; + nodeid_t tid; } message_t; diff --git a/src/messagehandler.cc b/src/messagehandler.cc index 5ccf3bf..5467df9 100644 --- a/src/messagehandler.cc +++ b/src/messagehandler.cc @@ -29,8 +29,8 @@ #include "hugin.hpp" -// Defines global task_manager object -#include "taskmanager.h" +// Defines global node_manager object +#include "nodemanager.h" #include "messageparser.h" @@ -70,14 +70,14 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) INFO(messagehandler, "Handling create command\n"); try { - taskid_t id = m.create.id; - m.nodes = task_manager.createTask(m.create.parentid, &id); + nodeid_t id = m.create.id; + m.nodes = node_manager.createNode(m.create.parentid, &id); m.create.id = id; outmsgs.push_back(m); } catch (std::exception& e) { - DEBUG(messagehandler, "Error creating task\n"); + DEBUG(messagehandler, "Error creating node\n"); } } break; @@ -87,14 +87,14 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) INFO(messagehandler, "Handling remove command\n"); try { - TaskIdList ids = task_manager.subTasks(m.remove.id); - TaskIdList::reverse_iterator id = ids.rbegin(); + NodeIdList ids = node_manager.subNodes(m.remove.id); + NodeIdList::reverse_iterator id = ids.rbegin(); while(id != ids.rend()) { - task_t task = task_manager.task(*id); + node_t node = node_manager.node(*id); - message_t m = create_msg_remove(task); - m.nodes = task_manager.removeTask(task.id); + message_t m = create_msg_remove(node); + m.nodes = node_manager.removeNode(node.id); outmsgs.push_back(m); id++; @@ -102,7 +102,7 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) } catch (std::exception& e) { - DEBUG(messagehandler, "Error remove task\n"); + DEBUG(messagehandler, "Error remove node\n"); } } break; @@ -112,25 +112,25 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) INFO(messagehandler, "Handling move command\n"); try { - task_t removetask = task_manager.task(m.move.id); - TaskIdListPair tilpair = - task_manager.moveTask(m.move.id, m.move.parentid); - task_t createtask = task_manager.task(m.move.id); - -// TaskIdList commonAncestors; -// TaskIdList removeAncestors; -// TaskIdList createAncestors; + node_t removenode = node_manager.node(m.move.id); + NodeIdListPair tilpair = + node_manager.moveNode(m.move.id, m.move.parentid); + node_t createnode = node_manager.node(m.move.id); + +// NodeIdList commonAncestors; +// NodeIdList removeAncestors; +// NodeIdList createAncestors; // // // find command ancestors and fill ancestors for remove command -// for(TaskIdList::iterator it_remove = tilpair.first.begin(); +// for(NodeIdList::iterator it_remove = tilpair.first.begin(); // it_remove != tilpair.first.end(); it_remove++) // { -// taskid_t removeid = *it; +// nodeid_t removeid = *it; // bool common = false; -// for(TaskIdList::iterator it_create = tilpair.second.begin(); +// for(NodeIdList::iterator it_create = tilpair.second.begin(); // it_create = != tilpair.second.end(); it_create++) // { -// taskid_t createid = *id; +// nodeid_t createid = *id; // if(removeid == createid) // { // commandAncestors.push_back(removeid); @@ -144,10 +144,10 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) // } // // // fill ancestors for create command -// for(TaskIdList::iterator it_create = tilpair.second.begin(); +// for(NodeIdList::iterator it_create = tilpair.second.begin(); // it_create = != tilpair.second.end(); it_create++) // { -// taskid_t createid = *id; +// nodeid_t createid = *id; // if(removeid == createid) // { // commandAncestors.push_back(removeid); @@ -155,9 +155,9 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) // } // } - message_t removemsg = create_msg_remove(removetask); + message_t removemsg = create_msg_remove(removenode); removemsg.nodes = tilpair.first; - message_t createmsg = create_msg_create(createtask); + message_t createmsg = create_msg_create(createnode); createmsg.nodes = tilpair.second; outmsgs.push_back(removemsg); @@ -165,7 +165,7 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) } catch (std::exception& e) { - DEBUG(messagehandler, "Error moving task\n"); + DEBUG(messagehandler, "Error moving node\n"); } } break; @@ -188,13 +188,13 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) INFO(messagehandler, "Handling update command\n"); try { - m.nodes = task_manager.updateTask(m.update.id, + m.nodes = node_manager.updateNode(m.update.id, m.update.attribute, m.update.value); outmsgs.push_back(m); } catch (std::exception& e) { - DEBUG(messagehandler, "Error updating task\n"); + DEBUG(messagehandler, "Error updating node\n"); } } break; @@ -207,7 +207,7 @@ MessageList handle_msg(MessageList msgList, clientid_t wsi) WARN(messagehandler, "!!! Unknown command %d\n", m.cmd); break; } - task_manager.tree.toStdOut(); + node_manager.tree.toStdOut(); DEBUG(messagehandler, "%d affected nodes registered\n", (int)m.nodes.size()); } diff --git a/src/messageparser.cc b/src/messageparser.cc index 75593f9..82477b7 100644 --- a/src/messageparser.cc +++ b/src/messageparser.cc @@ -26,7 +26,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "messageparser.h" -#include "taskmanager.h" +#include "nodemanager.h" #include #include @@ -130,7 +130,7 @@ inline static void parse_into_msg_tokens(std::string& data, } -static taskid_t getId(std::map &sym, std::string token) +static nodeid_t getId(std::map &sym, std::string token) { bool isnumeric = true; for(size_t i = 0; i < token.size(); i++) @@ -142,14 +142,14 @@ static taskid_t getId(std::map &sym, std::string token) if(isnumeric) { - taskid_t id = atoi(token.c_str()); + nodeid_t id = atoi(token.c_str()); DEBUG(getid, "======= id: %d\n", id); return id; } if(sym.find(token) == sym.end()) { - sym[token] = task_manager.createId(); + sym[token] = node_manager.createId(); } return sym[token]; @@ -165,7 +165,7 @@ inline static void create_msg_list(MsgTokensList& msgTokensList, origin = 1; } - std::map sym; + std::map sym; MsgTokensList::iterator it_msg; for(it_msg = msgTokensList.begin(); it_msg != msgTokensList.end(); it_msg++) @@ -364,7 +364,7 @@ std::string msg_tostring(message_t m) return r; } -message_t create_msg_create(task_t t) +message_t create_msg_create(node_t t) { message_t m; m.cmd = cmd::create; @@ -373,7 +373,7 @@ message_t create_msg_create(task_t t) return m; } -message_t create_msg_update(task_t t, const std::string &attr) +message_t create_msg_update(node_t t, const std::string &attr) { message_t m; m.cmd = cmd::update; @@ -383,7 +383,7 @@ message_t create_msg_update(task_t t, const std::string &attr) return m; } -message_t create_msg_remove(task_t t) +message_t create_msg_remove(node_t t) { message_t m; m.cmd = cmd::remove; @@ -391,7 +391,7 @@ message_t create_msg_remove(task_t t) return m; } -message_t create_msg_move(taskid_t id, taskid_t to) +message_t create_msg_move(nodeid_t id, nodeid_t to) { message_t m; m.cmd = cmd::move; diff --git a/src/messageparser.h b/src/messageparser.h index bb9d10f..4d51c87 100644 --- a/src/messageparser.h +++ b/src/messageparser.h @@ -34,10 +34,10 @@ MessageList parse_msg(std::string msg); MessageList parse_msg_client(std::string msg); -//message_t create_msg(cmd::cmd_t type, task_t task); +//message_t create_msg(cmd::cmd_t type, node_t node); std::string msg_tostring(message_t msg); -message_t create_msg_create(task_t task); -message_t create_msg_update(task_t task, const std::string &attr); -message_t create_msg_remove(task_t task); -message_t create_msg_move(taskid_t id, taskid_t to); +message_t create_msg_create(node_t node); +message_t create_msg_update(node_t node, const std::string &attr); +message_t create_msg_remove(node_t node); +message_t create_msg_move(nodeid_t id, nodeid_t to); diff --git a/src/munia_proto.cc b/src/munia_proto.cc index 333e3c9..33de8a3 100644 --- a/src/munia_proto.cc +++ b/src/munia_proto.cc @@ -35,13 +35,13 @@ #include "hugin.hpp" -#include "task.h" +#include "node.h" #include "messageparser.h" #include "messagehandler.h" #include "connectionhandler.h" -// Defines global task_manager object -#include "taskmanager.h" +// Defines global node_manager object +#include "nodemanager.h" #if 0 static void dump_handshake_info(struct lws_tokens *lwst) @@ -93,11 +93,11 @@ typedef std::list msgqueue_t; static std::map msgqueue; struct lws *current_client = NULL; -int callback_lws_task(struct lws *wsi, +int callback_lws_node(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { - task_manager.tree.toStdOut(); + node_manager.tree.toStdOut(); DEBUG(proto, "Callback on %p\n", wsi); @@ -139,8 +139,8 @@ int callback_lws_task(struct lws *wsi, // collapse into move msg if(j != msgqueue[wsi].end()) { - taskid_t id = j->create.id; - taskid_t parentid = j->create.parentid; + nodeid_t id = j->create.id; + nodeid_t parentid = j->create.parentid; msgqueue[wsi].erase(j); // erase create msg msg.cmd = cmd::move; msg.move.id = id; @@ -189,7 +189,7 @@ int callback_lws_task(struct lws *wsi, // case LWS_CALLBACK_BROADCAST: // printf("LWS_CALLBACK_BROADCAST\n"); // n = lws_write(wsi, (unsigned char*)in, len, LWS_WRITE_TEXT); -// if (n < 0) DEBUG(proto, "task write failed\n"); +// if (n < 0) DEBUG(proto, "node write failed\n"); // break; case LWS_CALLBACK_RECEIVE: @@ -214,10 +214,10 @@ int callback_lws_task(struct lws *wsi, if(omi->cmd == cmd::subscribe) { connection_handler.subscribe(wsi, omi->subscribe.id); - TaskIdList ids; + NodeIdList ids; try { - ids = task_manager.subTasks(omi->subscribe.id); + ids = node_manager.subNodes(omi->subscribe.id); } catch(...) { @@ -225,20 +225,20 @@ int callback_lws_task(struct lws *wsi, omi++; continue; } - TaskIdList::iterator id = ids.begin(); + NodeIdList::iterator id = ids.begin(); while(id != ids.end()) { - task_t task = task_manager.task(*id); + node_t node = node_manager.node(*id); - message_t createmsg = create_msg_create(task); + message_t createmsg = create_msg_create(node); createmsg.tid = omi->subscribe.id; msgqueue[wsi].push_back(createmsg); std::map::iterator ai = - task.attributes.begin(); - while(ai != task.attributes.end()) + node.attributes.begin(); + while(ai != node.attributes.end()) { - message_t updatemsg = create_msg_update(task, ai->first); + message_t updatemsg = create_msg_update(node, ai->first); DEBUG(subscribe, "%s\n", ai->first.c_str()); updatemsg.tid = omi->subscribe.id; msgqueue[wsi].push_back(updatemsg); @@ -251,10 +251,10 @@ int callback_lws_task(struct lws *wsi, else if(omi->cmd == cmd::unsubscribe) { connection_handler.unsubscribe(wsi, omi->unsubscribe.id); - TaskIdList ids; + NodeIdList ids; try { - ids = task_manager.subTasks(omi->unsubscribe.id); + ids = node_manager.subNodes(omi->unsubscribe.id); } catch(...) { @@ -262,12 +262,12 @@ int callback_lws_task(struct lws *wsi, omi++; continue; } - TaskIdList::reverse_iterator id = ids.rbegin(); + NodeIdList::reverse_iterator id = ids.rbegin(); while(id != ids.rend()) { - task_t task = task_manager.task(*id); + node_t node = node_manager.node(*id); - message_t removemsg = create_msg_remove(task); + message_t removemsg = create_msg_remove(node); removemsg.tid = omi->unsubscribe.id; msgqueue[wsi].push_back(removemsg); DEBUG(unsubscribe, "remove id: %d\n", *id); @@ -288,9 +288,9 @@ int callback_lws_task(struct lws *wsi, while(ci != clients.end()) { clientid_t clientid = (*ci).first; - taskid_t tid = (*ci).second; + nodeid_t tid = (*ci).second; - DEBUG(proto, "Subscriber id of task: %d\n", tid); + DEBUG(proto, "Subscriber id of node: %d\n", tid); message_t msg = *omi; msg.tid = tid; diff --git a/src/munia_proto.h b/src/munia_proto.h index a2ad38f..a16cb44 100644 --- a/src/munia_proto.h +++ b/src/munia_proto.h @@ -31,11 +31,11 @@ #include -int callback_lws_task(struct lws *wsi, +int callback_lws_node(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len); -struct per_session_data__lws_task +struct per_session_data__lws_node { struct lws *wsi; }; diff --git a/src/muniacli.cc b/src/muniacli.cc index 843c028..d6dcc9d 100644 --- a/src/muniacli.cc +++ b/src/muniacli.cc @@ -42,12 +42,12 @@ static bool run; static std::string msgs; -struct per_session_data__lws_task +struct per_session_data__lws_node { struct lws *wsi; }; -static int callback_lws_task(struct lws *wsi, +static int callback_lws_node(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) { @@ -98,8 +98,8 @@ static int callback_lws_task(struct lws *wsi, static struct lws_protocols protocols[] = { - { "lws-task-protocol", callback_lws_task, - sizeof(struct per_session_data__lws_task) + { "lws-node-protocol", callback_lws_node, + sizeof(struct per_session_data__lws_node) }, { nullptr, nullptr, 0 } // End of list }; @@ -108,7 +108,7 @@ int client(const char *address, int port) { // printf("Connection to %s on port %d\n", address, port); struct lws_context *context; - struct lws *wsi_task = nullptr; + struct lws *wsi_node = nullptr; int ietf_version = -1; // latest lws_set_log_level(0, nullptr); @@ -133,16 +133,16 @@ int client(const char *address, int port) { n = lws_service(context, 10); - if(wsi_task == nullptr) + if(wsi_node == nullptr) { - wsi_task = lws_client_connect(context, address, port, + wsi_node = lws_client_connect(context, address, port, 0, "/", address, address, - "lws-task-protocol", + "lws-node-protocol", ietf_version); - if(wsi_task == nullptr) + if(wsi_node == nullptr) { - fprintf(stderr, "lws task connect failed\n"); + fprintf(stderr, "lws node connect failed\n"); return -1; } else @@ -179,7 +179,7 @@ static struct option options[] = { }; static const char* USAGE = - "Usage: muniacli [OPTION]... TASK COMMAND\n" + "Usage: muniacli [OPTION]... NODE COMMAND\n" "Commandline client to munia." "Options:\n" " -p, --port Port on host\n" @@ -232,7 +232,7 @@ int main(int argc, char** argv) #if 0 enum demo_protocols { - PROTOCOL_TASK + PROTOCOL_NODE }; enum cmd_t @@ -247,7 +247,7 @@ enum cmd_t static bool run; static bool interactive; static std::string msgs; -static int taskid; +static int nodeid; static std::map > structuremap; static std::map titlemap; @@ -316,10 +316,10 @@ static void pretty_print(std::string msgs) } } - rec_pretty_print(taskid); + rec_pretty_print(nodeid); } -static int callback_task(struct lws_context *me, +static int callback_node(struct lws_context *me, struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) @@ -382,14 +382,14 @@ static int callback_task(struct lws_context *me, static struct lws_protocols protocols[] = { - { "lws-task-protocol", callback_task, 0, }, + { "lws-node-protocol", callback_node, 0, }, { nullptr, nullptr, 0 } }; int client(const char *address, int port) { struct lws_context *context; - struct lws *wsi_task = nullptr; + struct lws *wsi_node = nullptr; int ietf_version = -1; // latest context = lws_create_context(CONTEXT_PORT_NO_LISTEN, nullptr, @@ -409,16 +409,16 @@ int client(const char *address, int port) { n = lws_service(context, 10); - if (wsi_task == nullptr) + if (wsi_node == nullptr) { - wsi_task = lws_client_connect(context, address, port, + wsi_node = lws_client_connect(context, address, port, 0, "/", address, address, - protocols[lws-task-protocol].name, + protocols[lws-node-protocol].name, ietf_version); - if(wsi_task == nullptr) + if(wsi_node == nullptr) { - fprintf(stderr, "lws task connect failed\n"); + fprintf(stderr, "lws node connect failed\n"); return -1; } @@ -459,28 +459,28 @@ static struct option options[] = }; static const char* USAGE = - "Usage: muniacli [OPTION]... TASK COMMAND\n" + "Usage: muniacli [OPTION]... NODE COMMAND\n" "Commandline client to munia." "Options:\n" " -p, --port Port on host\n" " -H, --host Host\n" " -i, --interactive Run in interactive/shell mode\n" - "Task:\n" - " -N, --name Select task by name\n" - " -I, --id Select task by id\n" + "Node:\n" + " -N, --name Select node by name\n" + " -I, --id Select node by id\n" "Commands:\n" - " -C, --create Create new subtask in TASK\n" - " -L, --list List subtasks in TASK\n" - " -R, --remove Remove subtask from TASK\n" - " -U, --update Update data in TASK"; + " -C, --create Create new subnode in NODE\n" + " -L, --list List subnodes in NODE\n" + " -R, --remove Remove subnode from NODE\n" + " -U, --update Update data in NODE"; int main(int argc, char** argv) { int port = 7681; std::string host = "localhost"; - std::string taskbyid; - std::string taskbyname; + std::string nodebyid; + std::string nodebyname; cmd_t cmd = DEFAULT; std::string cmd_opts; @@ -510,10 +510,10 @@ int main(int argc, char** argv) fprintf(stderr, "%s\n", USAGE); exit(1); case 'N': - taskbyname = optarg; + nodebyname = optarg; break; case 'I': - taskbyid = optarg; + nodebyid = optarg; break; case 'C': cmd = CREATE; @@ -537,38 +537,38 @@ int main(int argc, char** argv) exit(1); } - if(!interactive && !taskbyname.empty()) + if(!interactive && !nodebyname.empty()) { - taskbyid = -1; + nodebyid = -1; fprintf(stderr, "Option '-N, --name' is not yet supported\n"); fprintf(stderr, "%s\n", USAGE); exit(1); } - if(!interactive && taskbyid.empty()) + if(!interactive && nodebyid.empty()) { fprintf(stderr, "%s\n", USAGE); exit(1); } - taskid = atoi(taskbyid.c_str()); + nodeid = atoi(nodebyid.c_str()); switch(cmd) { case CREATE: - msgs = "subscribe " + taskbyid + ";"; - msgs += "create " + taskbyid + ";"; + msgs = "subscribe " + nodebyid + ";"; + msgs += "create " + nodebyid + ";"; break; case LIST: - msgs = "subscribe " + taskbyid + ";"; //+ - // "; unsubscribe " + task + ";"; + msgs = "subscribe " + nodebyid + ";"; //+ + // "; unsubscribe " + node + ";"; break; case REMOVE: - msgs = "remove " + taskbyid + ";"; + msgs = "remove " + nodebyid + ";"; break; case UPDATE: - msgs = "subscribe " + taskbyid + ";"; - msgs += "update " + taskbyid + " \"" + cmd_opts + "\"; "; + msgs = "subscribe " + nodebyid + ";"; + msgs += "update " + nodebyid + " \"" + cmd_opts + "\"; "; break; case DEFAULT: break; diff --git a/src/muniad.cc b/src/muniad.cc index b5685c2..7e260be 100644 --- a/src/muniad.cc +++ b/src/muniad.cc @@ -38,13 +38,13 @@ #include "http.h" #include "munia_proto.h" #include "hugin.hpp" -#include "taskmanager.h" +#include "nodemanager.h" static struct lws_protocols protocols[] = { // first protocol must always be HTTP handler { "http-only", callback_http, 0 }, - { "lws-task-protocol", callback_lws_task, sizeof(struct per_session_data__lws_task) }, + { "lws-node-protocol", callback_lws_node, sizeof(struct per_session_data__lws_node) }, { nullptr, nullptr, 0 } // End of list }; @@ -122,7 +122,7 @@ int main(int argc, char **argv) //_parse("+all"); - task_manager.init(db_filename); + node_manager.init(db_filename); if(!use_ssl) { diff --git a/src/node.cc b/src/node.cc new file mode 100644 index 0000000..236a511 --- /dev/null +++ b/src/node.cc @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * node.cc + * + * Tue Mar 27 11:41:34 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 "node.h" + +#ifdef TEST_NODE +//Additional dependency files +//deps: +//Required cflags (autoconf vars may be used) +//cflags: +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" + +TEST_BEGIN; + +// TODO: Put some testcode here (see test.h for usable macros). +TEST_TRUE(false, "No tests yet!"); + +TEST_END; + +#endif/*TEST_NODE*/ diff --git a/src/node.h b/src/node.h new file mode 100644 index 0000000..3f81290 --- /dev/null +++ b/src/node.h @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * node.h + * + * Tue Mar 27 11:41:34 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. + */ +#pragma once + +#include +#include +#include + +typedef unsigned int nodeid_t; +typedef std::list NodeIdList; + +typedef struct +{ + nodeid_t id; + nodeid_t parentid; + std::map attributes; +} node_t; diff --git a/src/nodemanager.cc b/src/nodemanager.cc new file mode 100644 index 0000000..32a93b4 --- /dev/null +++ b/src/nodemanager.cc @@ -0,0 +1,407 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * node.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 "nodemanager.h" + +#include + +#include "hugin.hpp" + +// Global NodeManager object. +NodeManager node_manager; + +#define ROOT_ID 0 +#define FINISHED_ID 1 +#define BACKLOG_ID 2 +#define LOSTFOUND_ID 3 +#define PROJECTS_ID 4 +#define FIRST_NODE_ID 10 + +static bool isProtected(nodeid_t id) +{ + return id < FIRST_NODE_ID; +} + +NodeManager::NodeManager() +{ + idCount = FIRST_NODE_ID; +} + +NodeManager::~NodeManager() +{ +} + +void NodeManager::init(std::string filename) +{ + DEBUG(nodemgr, "Reading nodes from file: %s\n", filename.c_str()); + file = filename; + + FILE *fp = fopen(file.c_str(), "r"); + if(fp) + { + std::string xml; + while(!feof(fp)) + { + char buf[64]; + size_t sz = fread(buf, 1, sizeof(buf), fp); + xml.append(buf, sz); + } + tree.fromXML(xml); + fclose(fp); + } + else + { + + // Create new basis config + node_t t; + + t.attributes["title"] = "root"; + t.id = ROOT_ID; + tree.insertAsChild(0, ROOT_ID, t); + + t.attributes["title"] = "Finished"; + t.id = FINISHED_ID; + tree.insertAsChild(ROOT_ID, FINISHED_ID, t); + + t.attributes["title"] = "Backlog"; + t.id = BACKLOG_ID; + tree.insertAsChild(ROOT_ID, BACKLOG_ID, t); + + t.attributes["title"] = "Lost+Found"; + t.id = LOSTFOUND_ID; + tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t); + + t.attributes["title"] = "Projects"; + t.id = PROJECTS_ID; + tree.insertAsChild(ROOT_ID, PROJECTS_ID, t); + } + + tree.toStdOut(); +} + +node_t NodeManager::node(nodeid_t t) +{ + return tree.data(t); +} + +nodeid_t NodeManager::createId() +{ + return tree.createId(); +} + +NodeIdListPair NodeManager::moveNode(nodeid_t id, nodeid_t to) + throw (std::exception) +{ + if(isProtected(id)) + { + return NodeIdListPair(); + } + + if(id == to) + { + throw std::exception(); // Node and new parent are the same node. + } + + //node_t t = tree.data(id); + + // Make sure the new parent exists. This will throw an exception if it doesn't + //node_t t_ = tree.data(to); + + //t.parentid = to; + + //NodeIdList tilremove = tree.remove(id); + NodeIdList tilremove; + tilremove.push_back(id); + NodeIdList ancestors = tree.ancestorList(id); + tilremove.insert(tilremove.end(), ancestors.begin(), ancestors.end()); + + // NodeIdList tilcreate = tree.insertAsChild(to, id, t); + NodeIdList tilcreate; + tilcreate.push_back(to); + ancestors = tree.ancestorList(to); + tilcreate.insert(tilcreate.end(), ancestors.begin(), ancestors.end()); + + tree.move(id, to); + + NodeIdListPair tilpair; + tilpair.first = tilremove; + tilpair.second = tilcreate; + + flushNodes(); + + return tilpair; +} + +NodeIdList NodeManager::removeNode(nodeid_t id) + throw (std::exception) +{ + if(isProtected(id)) + { + return NodeIdList(); + } + + NodeIdList affectedNodes; + + if(tree.bfs(id).size() > 1) + { + throw std::exception(); + } + + try + { + affectedNodes = tree.remove(id); + } + catch(std::exception& e) + { + throw e; + } + + flushNodes(); + + return affectedNodes; +} + +NodeIdList NodeManager::updateNode(nodeid_t id, const std::string &name, + const std::string &value) + throw (std::exception) +{ + if(isProtected(id)) + { + return NodeIdList(); + } + + NodeIdList affectedNodes; + + try + { + affectedNodes = tree.updateData(id, name, value); + } + catch(std::exception& e) + { + throw e; + } + + flushNodes(); + + return affectedNodes; +} + +NodeIdList NodeManager::createNode(nodeid_t parentid, nodeid_t *pid) + throw (std::exception) +{ + NodeIdList affectedNodes; + + node_t t; + nodeid_t id = *pid;//createId(); + t.attributes["title"] = ""; + t.id = id; + if(pid) + { + *pid = id; + } + + try + { + affectedNodes = tree.insertAsChild(parentid, id, t); + } + catch(std::exception& e) + { + throw e; + } + + flushNodes(); + + return affectedNodes; +} + +NodeIdList NodeManager::subNodes(nodeid_t t) + throw (std::exception) +{ + NodeIdList affectedNodes; + + try + { + affectedNodes = tree.bfs(t); + } + catch(std::exception& e) + { + throw e; + } + + return affectedNodes; +} + +//NodeIdList NodeManager::ancestorList(nodeid_t id) +// throw (std::exception) +//{ +// NodeIdList ancestors; +// +// try +// { +// ancestors = tree.ancestorList(id); +// goto finish; +// } +// catch(std::exception& e) +// { +// throw e; +// } +// +//finish: +// return ancestors; +//} + +void NodeManager::flushNodes() +{ + FILE *fp = fopen(file.c_str(), "w"); + if(!fp) + { + return; + } + std::string xml = tree.toXML(); + fwrite(xml.c_str(), xml.size(), 1, fp); + fclose(fp); +} + +#if 0 +NodeList nodelist; + +node_t create_node(std::string title, std::string desc) +{ + node_t t; + t.parent_id = current_id_count(); + t.attributes["title"] = title; + t.desc = desc; + t.id = id_count; id_count++; + + return t; +} + +NodeList load_nodelist_from_file(std::string file) +{ + NodeList list; + + // create MuniaDb class which handles nodes, db-flush and db-init. + + return list; +} + +bool save_nodelist_to_file(NodeList list, std::string file) +{ + FILE* fp; + + if(! (fp = fopen(file.c_str(), "w"))) + { + return false; + } + + if(!fprintf(fp, "\n")) + { + fclose(fp); + return false; + } + + NodeList::iterator it; + for(it = nodelist.begin(); it != nodelist.end(); it++) + { + node_t t = *it; + int r = 1; + + //printf("Flushing node %d\n", t.id); + r |= fprintf(fp, " \n", t.id, t.parent_id); + r |= fprintf(fp, " %s\n", xml_encode(t.attributes["title"]).c_str()); + r |= fprintf(fp, " %s\n", xml_encode(t.attributes["description"]).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_node(node_t t, NodeList& graveyard); + +static void delete_children(node_t t, NodeList& graveyard) +{ + NodeList::iterator it; + for(it = nodelist.begin(); it != nodelist.end(); it++) + { + if(it->parent_id == t.id) { + delete_node(*it, graveyard); + } + } +} + +static void delete_node(node_t t, NodeList& graveyard) +{ + NodeList::iterator it; + for(it = nodelist.begin(); it != nodelist.end(); it++) + { + if(it->id == t.id) + { + break; + } + } + + if(it != nodelist.end()) + { + graveyard.push_back(*it); + delete_children(*it, graveyard); + } +} + +void delete_node(int id, NodeList& graveyard) +{ + node_t t; + t.id = id; + delete_node(t, graveyard); + + for(NodeList::iterator it = graveyard.begin(); + it != graveyard.end(); it++) + { + for(NodeList::iterator it_tl = nodelist.begin(); + it_tl != nodelist.end(); it_tl++) + { + if(it_tl->id == it->id) + { + nodelist.erase(it_tl); + break; + } + } + } +} +#endif diff --git a/src/nodemanager.h b/src/nodemanager.h new file mode 100644 index 0000000..f0bc81e --- /dev/null +++ b/src/nodemanager.h @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * nodemanager.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. + */ +#pragma once + +#include +#include +#include +#include + +#include "node.h" +#include "nodetree.h" + +typedef std::pair NodeIdListPair; + +class NodeManager +{ +public: + NodeManager(); + ~NodeManager(); + + void init(std::string filename); + + NodeIdList createNode(nodeid_t parentid, nodeid_t *id) throw (std::exception); + NodeIdList updateNode(nodeid_t id, const std::string &name, + const std::string &value) throw (std::exception); + NodeIdList removeNode(nodeid_t id) throw (std::exception); + + NodeIdListPair moveNode(nodeid_t id, nodeid_t newParent) throw (std::exception); + + NodeIdList subNodes(nodeid_t) throw (std::exception); + + NodeTree tree; + + node_t node(nodeid_t t); + + void flushNodes(); + + nodeid_t createId(); + +private: + // NodeIdList ancestorList(nodeid_t node); + nodeid_t idCount; + node_t nextNode(); + + std::string file; +}; + +#ifndef FOOBAR +extern NodeManager node_manager; +#endif + + +#if 0 + +/* +Node: + id + subnodes +// 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; +} node_t; +*/ +/* +protocol: + add_node title description parent_id + del_node id + update_node id title description + move_node id parent + copy_node id parent +*/ + + + +//typedef std::list NodeList; + +class CompareByParentid +{ +public: + bool operator()(const node_t &a, const node_t &b) const + { + return a.parent_id < b.parent_id; + } +}; + +class NodeList + : public std::list +{ +public: + NodeList() {} + ~NodeList(){} + + void insert(node_t t) + { + if(t.id == t.parent_id) + { + return; + } + printf("inserting node %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(node_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(node_t t) + { + insert(t); + } + +private: + std::list list; +}; + + +extern NodeList nodelist; + +//typedef std::priority_queue, CompareByParentid> NodeList; + +node_t create_node(std::string title, std::string desc, /*int x, int y*/ int parent_id); + +NodeList load_nodelist_from_file(std::string file); +bool save_nodelist_to_file(NodeList t, std::string file); +#endif/*0*/ diff --git a/src/nodetree.cc b/src/nodetree.cc new file mode 100644 index 0000000..1c3992e --- /dev/null +++ b/src/nodetree.cc @@ -0,0 +1,475 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * nodetree.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 "nodetree.h" + +#include + +#include "xmlparser.h" + +#include "hugin.hpp" + +#include "xml_encode_decode.h" + +#define ROOT_PARENT_ID -1 + +static inline std::string id2str(nodeid_t id) +{ + char buf[32]; + sprintf(buf, "%u", id); + return buf; +} + +std::string Node::toXML(std::string prefix) +{ + std::string xml; + + xml += prefix + "\n"; + xml += prefix + " \n"; + std::map::iterator ai = data.attributes.begin(); + while(ai != data.attributes.end()) + { + xml += prefix + " first) + "\">" + + xml_encode(ai->second) + "\n"; + ai++; + } + xml += prefix + " \n"; + xml += prefix + " \n"; + NodeList::iterator ni = children.begin(); + while(ni != children.end()) + { + xml += (*ni)->toXML(prefix + " "); + ni++; + } + xml += prefix + " \n"; + xml += prefix + "\n"; + + return xml; +} + +static void concatNodeIdLists(NodeIdList& pre, NodeIdList& post) +{ + pre.insert(pre.end(), post.begin(), post.end()); + //for(NodeIdList::iterator it = post.begin(); + //it != post.end(); it++) + //{ + // pre.push_back( + //} +} + +NodeTree::NodeTree() +{ + root = NULL; + nextid = 10; +} + +NodeTree::~NodeTree() +{ + // cleanup tree +} + +nodeid_t NodeTree::createId() +{ + nodeid_t nodeid; + + do + { + nodeid = nextid++; + } + while(id2node.find(nodeid) != id2node.end()); + + return nodeid; +} + +static nodeid_t rootid = -1; + +NodeIdList NodeTree::insertAsChild(nodeid_t parentid, nodeid_t id, node_t data) + throw (std::exception) +{ + NodeIdList affectedNodes; + + // Initialize + if(!root) + { + rootid = id; + Node* node = createNode(id); + root = node; + node->data = data; + affectedNodes.push_back(id); + } + else + { + try + { + Node* parent = id2node.at(parentid); + Node* child = createNode(id); + //DEBUG(nodetree, "!!!!!!!id in insert: %d\n", data.id); + child->data = data; + insertChild(parent, child); + + //affectedNodes.push_back(parentid); + affectedNodes.push_back(id); + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); + } + catch(std::exception& e) + { + throw e; + } + } + + //DEBUG(nodetree, "Child %d added to %d, affecting %d nodes\n", + // id, parentid, affectedNodes.size()); + return affectedNodes; +} + +NodeIdList NodeTree::remove(nodeid_t id) + throw (std::exception) +{ + NodeIdList affectedNodes; + affectedNodes.push_back(id); + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); + + //DEBUG(nodetree, "Removing %d\n", id); + //DEBUG(nodetree, "!!!!!affected nodes %d\n", affectedNodes.size()); + + Node* node = id2node[id]; + + //DEBUG(nodetree, "node: %p, id %d, parent %p\n", node, node->data.id, node->parent); + + //DEBUG(nodetree, "!!!!!size %d\n", node->parent->children.size()); + node->parent->children.remove(node); + for(NodeList::iterator it = node->parent->children.begin(); + it != node->parent->children.end(); + it++) + { + //DEBUG(nodetree, "%p\n", *it); + } + //DEBUG(nodetree, "!!!!!size %d\n", node->parent->children.size()); + + NodeIdList idlist = bfs(id); + NodeIdList::reverse_iterator it = idlist.rbegin(); + while(it != idlist.rend()) + { + node_t node = data(*it); + //Node* n = id2node[node.id]; + //delete(n); + it++; + } + + return affectedNodes; +} + +static bool findNode(Node *needle, Node *haystack) +{ + if(needle == haystack) return true; + NodeList::iterator i = haystack->children.begin(); + while(i != haystack->children.end()) + { + if(findNode(needle, *i)) + { + return true; + } + i++; + } + return false; +} + +NodeIdList NodeTree::move(nodeid_t id, nodeid_t toid) + throw (std::exception) +{ + NodeIdList affectedNodes; + + try + { + Node* child = id2node.at(id); + Node* newparent = id2node.at(toid); + + // Test if new parent is a child of the node itself... + if(findNode(newparent, child)) + { + throw std::exception(); + } + + if(!child->parent) + { + throw std::exception(); + } + + child->parent->children.remove(child); + newparent->children.push_back(child); + + child->parent = newparent; + + affectedNodes.push_back(id); + // affectedNodes.push_back(child->parent->id); + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); + affectedNodes.push_back(toid); + ancestors = ancestorList(toid); + } + catch(std::exception& e) + { + throw e; + } + + return affectedNodes; +} + +NodeIdList NodeTree::updateData(nodeid_t id, const std::string &name, + const std::string &value) + throw (std::exception) +{ + NodeIdList affectedNodes; + + try + { + Node* node = id2node.at(id); + node->data.attributes[name] = value; + + affectedNodes.push_back(id); + NodeIdList ancestors = ancestorList(id); + concatNodeIdLists(affectedNodes, ancestors); + } + catch(std::exception& e) + { + throw e; + } + + return affectedNodes; +} + +node_t NodeTree::data(nodeid_t id) + throw (std::exception) +{ + node_t t; + + try + { + Node* node = id2node.at(id); + node_t tmp = node->data; + t.id = node->id; + t.attributes = tmp.attributes; + //DEBUG(nodetree, "!!!!t.id and tmp.id in data: %d and %d\n", t.id, tmp.id); + if(node->parent) + { + t.parentid = node->parent->id; + } + else + { + if(t.id != rootid) + { + throw std::exception(); + } + t.parentid = -1; + } + } + catch(std::exception& e) + { + throw e; + } + + return t; +} + +// bfs search from id in tree +NodeIdList NodeTree::bfs(nodeid_t id) + throw (std::exception) +{ + NodeIdList lst; + lst.push_back(id); + + std::list queue; + Node* current = id2node.at(id); + while(true) + { + NodeList children = current->children; + for(NodeList::iterator it = children.begin(); it != children.end(); it++) + { + Node* child = *it; + queue.push_back(child); + lst.push_back(child->id); + } + + if(!queue.empty()) + { + current = queue.front(); + queue.pop_front(); + } + else + { + break; + } + } + + return lst; +} + +NodeIdList NodeTree::ancestorList(nodeid_t id) + throw (std::exception) +{ + NodeIdList ancestors; + + try + { + Node* current = id2node.at(id); + while(current->parent) + { + ancestors.push_back(current->parent->id); + current = current->parent; + } + } + catch(std::exception& e) + { + throw e; + } + + //DEBUG(nodetree, "Collected %d ancestors to %u\n", ancestors.size(), id); + //for(NodeIdList::iterator it = ancestors.begin(); + // it != ancestors.end(); it++) + //{ + // DEBUG(nodetree, "\tancestor %u\n", *it); + //} + return ancestors; +} + +Node* NodeTree::createNode(nodeid_t id) +{ + Node* node = new Node(); + node->parent = NULL; + node->id = id; + id2node[id] = node; + return node; +} + +void NodeTree::insertChild(Node* parent, Node* child) +{ + if(parent) + { + parent->children.push_back(child); + } + else + { + rootid = child->id; + root = child; + } + child->parent = parent; +} + +static void printNode(Node* node, std::string prefix) +{ + if(!node) + { + return; + } + node_t t = node->data; + DEBUG(nodetree, "%s- %u - %s (%p)\n", prefix.c_str(), node->id, + t.attributes["title"].c_str(), node); + + NodeList::iterator it; + for(it = node->children.begin(); it != node->children.end(); it++) + { + Node* child = *it; + printNode(child, " " + prefix); + } +} + +void NodeTree::toStdOut() +{ + printNode(root, ""); +} + +std::string NodeTree::toXML() +{ + Node *root = id2node.at(rootid); + + std::string xml; + xml += "\n"; + xml += "\n"; + xml += root->toXML(" "); + xml += ""; + + return xml; +} + +void NodeTree::fromXML(std::string xml) +{ + XmlParser p(this); + p.parse(xml.c_str(), xml.size()); +} + + +#ifdef TEST_NODETREE +//Additional dependency files +//deps: debug.cc log.cc +//Required cflags (autoconf vars may be used) +//cflags: -I.. +//Required link options (autoconf vars may be used) +//libs: +#include "test.h" +#include + +#define ROOT_ID 0 +#define LOSTFOUND_ID 1 +#define FINISHED_ID 2 +#define BACKLOG_ID 3 +#define PROJECTS_ID 4 +#define FIRST_NODE_ID 10 + +TEST_BEGIN; + +NodeTree tree; + +node_t t; +t.attributes["title"] = "root"; +t.id = ROOT_ID; +tree.insertAsChild(0, ROOT_ID, t); + +t.attributes["title"] = "Finished"; +t.id = FINISHED_ID; +tree.insertAsChild(ROOT_ID, FINISHED_ID, t); + +t.attributes["title"] = "Backlog"; +t.id = BACKLOG_ID; +tree.insertAsChild(ROOT_ID, BACKLOG_ID, t); + +t.attributes["title"] = "Lost+Found"; +t.id = LOSTFOUND_ID; +tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t); + +t.attributes["title"] = "Projects"; +t.id = PROJECTS_ID; +tree.insertAsChild(ROOT_ID, PROJECTS_ID, t); + +TEST_EQUAL_INT(5, tree.bfs(0).size(), "Testing BFS function"); +TEST_EQUAL_INT(PROJECTS_ID, tree.data(PROJECTS_ID).id, "Testing project id"); +TEST_EQUAL_INT(ROOT_ID, tree.data(ROOT_ID).id, "Testing root id"); + +TEST_END; + +#endif/*TEST_NODETREE*/ diff --git a/src/nodetree.h b/src/nodetree.h new file mode 100644 index 0000000..8052389 --- /dev/null +++ b/src/nodetree.h @@ -0,0 +1,83 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ +/*************************************************************************** + * nodetree.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. + */ +#pragma once + +#include +#include +#include + +#include "node.h" + +class Node; +typedef std::list NodeList; + +class Node +{ +public: + nodeid_t id; + Node* parent; + node_t data; + NodeList children; + + std::string toXML(std::string prefix); +}; + +class NodeTree +{ + friend class XmlParser; +public: + NodeTree(); + ~NodeTree(); + + nodeid_t createId(); + + NodeIdList insertAsChild(nodeid_t parentid, nodeid_t id, node_t data) throw (std::exception); + NodeIdList remove(nodeid_t id) throw (std::exception); + NodeIdList move(nodeid_t id, nodeid_t newParentId) throw (std::exception); + NodeIdList updateData(nodeid_t id, const std::string &name, + const std::string &value) throw (std::exception); + node_t data(nodeid_t id) throw (std::exception); + + NodeIdList bfs(nodeid_t id) throw (std::exception); + + NodeIdList ancestorList(nodeid_t id) throw (std::exception); + + void toStdOut(); + + std::string toXML(); + void fromXML(std::string xml); + + nodeid_t nextid; + +private: + Node* createNode(nodeid_t id); + void insertChild(Node* parent, Node* child); + + Node* root; + std::map id2node; +}; diff --git a/src/task.cc b/src/task.cc deleted file mode 100644 index 3054e48..0000000 --- a/src/task.cc +++ /dev/null @@ -1,46 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set et sw=2 ts=2: */ -/*************************************************************************** - * task.cc - * - * Tue Mar 27 11:41:34 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 "task.h" - -#ifdef TEST_TASK -//Additional dependency files -//deps: -//Required cflags (autoconf vars may be used) -//cflags: -//Required link options (autoconf vars may be used) -//libs: -#include "test.h" - -TEST_BEGIN; - -// TODO: Put some testcode here (see test.h for usable macros). -TEST_TRUE(false, "No tests yet!"); - -TEST_END; - -#endif/*TEST_TASK*/ diff --git a/src/task.h b/src/task.h deleted file mode 100644 index ec00939..0000000 --- a/src/task.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set et sw=2 ts=2: */ -/*************************************************************************** - * task.h - * - * Tue Mar 27 11:41:34 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. - */ -#pragma once - -#include -#include -#include - -typedef unsigned int taskid_t; -typedef std::list TaskIdList; - -typedef struct -{ - taskid_t id; - taskid_t parentid; - std::map attributes; -} task_t; diff --git a/src/taskmanager.cc b/src/taskmanager.cc deleted file mode 100644 index 1b34dde..0000000 --- a/src/taskmanager.cc +++ /dev/null @@ -1,407 +0,0 @@ -/* -*- 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 - -#include "hugin.hpp" - -// Global TaskManager object. -TaskManager task_manager; - -#define ROOT_ID 0 -#define FINISHED_ID 1 -#define BACKLOG_ID 2 -#define LOSTFOUND_ID 3 -#define PROJECTS_ID 4 -#define FIRST_TASK_ID 10 - -static bool isProtected(taskid_t id) -{ - return id < FIRST_TASK_ID; -} - -TaskManager::TaskManager() -{ - idCount = FIRST_TASK_ID; -} - -TaskManager::~TaskManager() -{ -} - -void TaskManager::init(std::string filename) -{ - DEBUG(taskmgr, "Reading tasks from file: %s\n", filename.c_str()); - file = filename; - - FILE *fp = fopen(file.c_str(), "r"); - if(fp) - { - std::string xml; - while(!feof(fp)) - { - char buf[64]; - size_t sz = fread(buf, 1, sizeof(buf), fp); - xml.append(buf, sz); - } - tree.fromXML(xml); - fclose(fp); - } - else - { - - // Create new basis config - task_t t; - - t.attributes["title"] = "root"; - t.id = ROOT_ID; - tree.insertAsChild(0, ROOT_ID, t); - - t.attributes["title"] = "Finished"; - t.id = FINISHED_ID; - tree.insertAsChild(ROOT_ID, FINISHED_ID, t); - - t.attributes["title"] = "Backlog"; - t.id = BACKLOG_ID; - tree.insertAsChild(ROOT_ID, BACKLOG_ID, t); - - t.attributes["title"] = "Lost+Found"; - t.id = LOSTFOUND_ID; - tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t); - - t.attributes["title"] = "Projects"; - t.id = PROJECTS_ID; - tree.insertAsChild(ROOT_ID, PROJECTS_ID, t); - } - - tree.toStdOut(); -} - -task_t TaskManager::task(taskid_t t) -{ - return tree.data(t); -} - -taskid_t TaskManager::createId() -{ - return tree.createId(); -} - -TaskIdListPair TaskManager::moveTask(taskid_t id, taskid_t to) - throw (std::exception) -{ - if(isProtected(id)) - { - return TaskIdListPair(); - } - - if(id == to) - { - throw std::exception(); // Node and new parent are the same node. - } - - //task_t t = tree.data(id); - - // Make sure the new parent exists. This will throw an exception if it doesn't - //task_t t_ = tree.data(to); - - //t.parentid = to; - - //TaskIdList tilremove = tree.remove(id); - TaskIdList tilremove; - tilremove.push_back(id); - TaskIdList ancestors = tree.ancestorList(id); - tilremove.insert(tilremove.end(), ancestors.begin(), ancestors.end()); - - // TaskIdList tilcreate = tree.insertAsChild(to, id, t); - TaskIdList tilcreate; - tilcreate.push_back(to); - ancestors = tree.ancestorList(to); - tilcreate.insert(tilcreate.end(), ancestors.begin(), ancestors.end()); - - tree.move(id, to); - - TaskIdListPair tilpair; - tilpair.first = tilremove; - tilpair.second = tilcreate; - - flushTasks(); - - return tilpair; -} - -TaskIdList TaskManager::removeTask(taskid_t id) - throw (std::exception) -{ - if(isProtected(id)) - { - return TaskIdList(); - } - - TaskIdList affectedTasks; - - if(tree.bfs(id).size() > 1) - { - throw std::exception(); - } - - try - { - affectedTasks = tree.remove(id); - } - catch(std::exception& e) - { - throw e; - } - - flushTasks(); - - return affectedTasks; -} - -TaskIdList TaskManager::updateTask(taskid_t id, const std::string &name, - const std::string &value) - throw (std::exception) -{ - if(isProtected(id)) - { - return TaskIdList(); - } - - TaskIdList affectedTasks; - - try - { - affectedTasks = tree.updateData(id, name, value); - } - catch(std::exception& e) - { - throw e; - } - - flushTasks(); - - return affectedTasks; -} - -TaskIdList TaskManager::createTask(taskid_t parentid, taskid_t *pid) - throw (std::exception) -{ - TaskIdList affectedTasks; - - task_t t; - taskid_t id = *pid;//createId(); - t.attributes["title"] = ""; - t.id = id; - if(pid) - { - *pid = id; - } - - try - { - affectedTasks = tree.insertAsChild(parentid, id, t); - } - catch(std::exception& e) - { - throw e; - } - - flushTasks(); - - return affectedTasks; -} - -TaskIdList TaskManager::subTasks(taskid_t t) - throw (std::exception) -{ - TaskIdList affectedTasks; - - try - { - affectedTasks = tree.bfs(t); - } - catch(std::exception& e) - { - throw e; - } - - 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; -//} - -void TaskManager::flushTasks() -{ - FILE *fp = fopen(file.c_str(), "w"); - if(!fp) - { - return; - } - std::string xml = tree.toXML(); - fwrite(xml.c_str(), xml.size(), 1, fp); - fclose(fp); -} - -#if 0 -TaskList tasklist; - -task_t create_task(std::string title, std::string desc) -{ - task_t t; - t.parent_id = current_id_count(); - t.attributes["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.attributes["title"]).c_str()); - r |= fprintf(fp, " %s\n", xml_encode(t.attributes["description"]).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 deleted file mode 100644 index 99143f5..0000000 --- a/src/taskmanager.h +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- 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. - */ -#pragma once - -#include -#include -#include -#include - -#include "task.h" -#include "tasktree.h" - -typedef std::pair TaskIdListPair; - -class TaskManager -{ -public: - TaskManager(); - ~TaskManager(); - - void init(std::string filename); - - TaskIdList createTask(taskid_t parentid, taskid_t *id) throw (std::exception); - TaskIdList updateTask(taskid_t id, const std::string &name, - const std::string &value) throw (std::exception); - TaskIdList removeTask(taskid_t id) throw (std::exception); - - TaskIdListPair moveTask(taskid_t id, taskid_t newParent) throw (std::exception); - - TaskIdList subTasks(taskid_t) throw (std::exception); - - TaskTree tree; - - task_t task(taskid_t t); - - void flushTasks(); - - taskid_t createId(); - -private: - // TaskIdList ancestorList(taskid_t task); - taskid_t idCount; - task_t nextTask(); - - std::string file; -}; - -#ifndef FOOBAR -extern TaskManager task_manager; -#endif - - -#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/*0*/ diff --git a/src/tasktree.cc b/src/tasktree.cc deleted file mode 100644 index 30494e9..0000000 --- a/src/tasktree.cc +++ /dev/null @@ -1,475 +0,0 @@ -/* -*- 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 - -#include "xmlparser.h" - -#include "hugin.hpp" - -#include "xml_encode_decode.h" - -#define ROOT_PARENT_ID -1 - -static inline std::string id2str(taskid_t id) -{ - char buf[32]; - sprintf(buf, "%u", id); - return buf; -} - -std::string node::toXML(std::string prefix) -{ - std::string xml; - - xml += prefix + "\n"; - xml += prefix + " \n"; - std::map::iterator ai = data.attributes.begin(); - while(ai != data.attributes.end()) - { - xml += prefix + " first) + "\">" - + xml_encode(ai->second) + "\n"; - ai++; - } - xml += prefix + " \n"; - xml += prefix + " \n"; - NodeList::iterator ni = children.begin(); - while(ni != children.end()) - { - xml += (*ni)->toXML(prefix + " "); - ni++; - } - xml += prefix + " \n"; - xml += prefix + "\n"; - - return xml; -} - -static void concatTaskIdLists(TaskIdList& pre, TaskIdList& post) -{ - pre.insert(pre.end(), post.begin(), post.end()); - //for(TaskIdList::iterator it = post.begin(); - //it != post.end(); it++) - //{ - // pre.push_back( - //} -} - -TaskTree::TaskTree() -{ - root = NULL; - nextid = 10; -} - -TaskTree::~TaskTree() -{ - // cleanup tree -} - -taskid_t TaskTree::createId() -{ - taskid_t taskid; - - do - { - taskid = nextid++; - } - while(id2node.find(taskid) != id2node.end()); - - return taskid; -} - -static taskid_t rootid = -1; - -TaskIdList TaskTree::insertAsChild(taskid_t parentid, taskid_t id, task_t data) - throw (std::exception) -{ - TaskIdList affectedNodes; - - // Initialize - if(!root) - { - rootid = id; - node_t* node = createNode(id); - root = node; - node->data = data; - affectedNodes.push_back(id); - } - else - { - try - { - node_t* parent = id2node.at(parentid); - node_t* child = createNode(id); - //DEBUG(tasktree, "!!!!!!!id in insert: %d\n", data.id); - child->data = data; - insertChild(parent, child); - - //affectedNodes.push_back(parentid); - affectedNodes.push_back(id); - TaskIdList ancestors = ancestorList(id); - concatTaskIdLists(affectedNodes, ancestors); - } - catch(std::exception& e) - { - throw e; - } - } - - //DEBUG(tasktree, "Child %d added to %d, affecting %d nodes\n", - // id, parentid, affectedNodes.size()); - return affectedNodes; -} - -TaskIdList TaskTree::remove(taskid_t id) - throw (std::exception) -{ - TaskIdList affectedNodes; - affectedNodes.push_back(id); - TaskIdList ancestors = ancestorList(id); - concatTaskIdLists(affectedNodes, ancestors); - - //DEBUG(tasktree, "Removing %d\n", id); - //DEBUG(tasktree, "!!!!!affected nodes %d\n", affectedNodes.size()); - - node_t* node = id2node[id]; - - //DEBUG(tasktree, "node: %p, id %d, parent %p\n", node, node->data.id, node->parent); - - //DEBUG(tasktree, "!!!!!size %d\n", node->parent->children.size()); - node->parent->children.remove(node); - for(NodeList::iterator it = node->parent->children.begin(); - it != node->parent->children.end(); - it++) - { - //DEBUG(tasktree, "%p\n", *it); - } - //DEBUG(tasktree, "!!!!!size %d\n", node->parent->children.size()); - - TaskIdList idlist = bfs(id); - TaskIdList::reverse_iterator it = idlist.rbegin(); - while(it != idlist.rend()) - { - task_t task = data(*it); - //node_t* n = id2node[task.id]; - //delete(n); - it++; - } - - return affectedNodes; -} - -static bool findNode(node_t *needle, node_t *haystack) -{ - if(needle == haystack) return true; - NodeList::iterator i = haystack->children.begin(); - while(i != haystack->children.end()) - { - if(findNode(needle, *i)) - { - return true; - } - i++; - } - return false; -} - -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); - - // Test if new parent is a child of the node itself... - if(findNode(newparent, child)) - { - throw std::exception(); - } - - if(!child->parent) - { - throw std::exception(); - } - - child->parent->children.remove(child); - newparent->children.push_back(child); - - child->parent = newparent; - - affectedNodes.push_back(id); - // affectedNodes.push_back(child->parent->id); - TaskIdList ancestors = ancestorList(id); - concatTaskIdLists(affectedNodes, ancestors); - affectedNodes.push_back(toid); - ancestors = ancestorList(toid); - } - catch(std::exception& e) - { - throw e; - } - - return affectedNodes; -} - -TaskIdList TaskTree::updateData(taskid_t id, const std::string &name, - const std::string &value) - throw (std::exception) -{ - TaskIdList affectedNodes; - - try - { - node_t* node = id2node.at(id); - node->data.attributes[name] = value; - - affectedNodes.push_back(id); - TaskIdList ancestors = ancestorList(id); - concatTaskIdLists(affectedNodes, ancestors); - } - catch(std::exception& e) - { - throw e; - } - - return affectedNodes; -} - -task_t TaskTree::data(taskid_t id) - throw (std::exception) -{ - task_t t; - - try - { - node_t* node = id2node.at(id); - task_t tmp = node->data; - t.id = node->id; - t.attributes = tmp.attributes; - //DEBUG(tasktree, "!!!!t.id and tmp.id in data: %d and %d\n", t.id, tmp.id); - if(node->parent) - { - t.parentid = node->parent->id; - } - else - { - if(t.id != rootid) - { - throw std::exception(); - } - t.parentid = -1; - } - } - catch(std::exception& e) - { - throw e; - } - - return t; -} - -// bfs search from id in tree -TaskIdList TaskTree::bfs(taskid_t id) - throw (std::exception) -{ - TaskIdList lst; - lst.push_back(id); - - std::list queue; - node_t* current = id2node.at(id); - while(true) - { - NodeList children = current->children; - for(NodeList::iterator it = children.begin(); it != children.end(); it++) - { - node_t* child = *it; - queue.push_back(child); - lst.push_back(child->id); - } - - if(!queue.empty()) - { - current = queue.front(); - queue.pop_front(); - } - else - { - break; - } - } - - return lst; -} - -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; - } - } - catch(std::exception& e) - { - throw e; - } - - //DEBUG(tasktree, "Collected %d ancestors to %u\n", ancestors.size(), id); - //for(TaskIdList::iterator it = ancestors.begin(); - // it != ancestors.end(); it++) - //{ - // DEBUG(tasktree, "\tancestor %u\n", *it); - //} - 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) -{ - if(parent) - { - parent->children.push_back(child); - } - else - { - rootid = child->id; - root = child; - } - child->parent = parent; -} - -static void printNode(node_t* node, std::string prefix) -{ - if(!node) - { - return; - } - task_t t = node->data; - DEBUG(tasktree, "%s- %u - %s (%p)\n", prefix.c_str(), node->id, - t.attributes["title"].c_str(), node); - - NodeList::iterator it; - for(it = node->children.begin(); it != node->children.end(); it++) - { - node_t* child = *it; - printNode(child, " " + prefix); - } -} - -void TaskTree::toStdOut() -{ - printNode(root, ""); -} - -std::string TaskTree::toXML() -{ - node_t *root = id2node.at(rootid); - - std::string xml; - xml += "\n"; - xml += "\n"; - xml += root->toXML(" "); - xml += ""; - - return xml; -} - -void TaskTree::fromXML(std::string xml) -{ - XmlParser p(this); - p.parse(xml.c_str(), xml.size()); -} - - -#ifdef TEST_TASKTREE -//Additional dependency files -//deps: debug.cc log.cc -//Required cflags (autoconf vars may be used) -//cflags: -I.. -//Required link options (autoconf vars may be used) -//libs: -#include "test.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 - -TEST_BEGIN; - -TaskTree tree; - -task_t t; -t.attributes["title"] = "root"; -t.id = ROOT_ID; -tree.insertAsChild(0, ROOT_ID, t); - -t.attributes["title"] = "Finished"; -t.id = FINISHED_ID; -tree.insertAsChild(ROOT_ID, FINISHED_ID, t); - -t.attributes["title"] = "Backlog"; -t.id = BACKLOG_ID; -tree.insertAsChild(ROOT_ID, BACKLOG_ID, t); - -t.attributes["title"] = "Lost+Found"; -t.id = LOSTFOUND_ID; -tree.insertAsChild(ROOT_ID, LOSTFOUND_ID, t); - -t.attributes["title"] = "Projects"; -t.id = PROJECTS_ID; -tree.insertAsChild(ROOT_ID, PROJECTS_ID, t); - -TEST_EQUAL_INT(5, tree.bfs(0).size(), "Testing BFS function"); -TEST_EQUAL_INT(PROJECTS_ID, tree.data(PROJECTS_ID).id, "Testing project id"); -TEST_EQUAL_INT(ROOT_ID, tree.data(ROOT_ID).id, "Testing root id"); - -TEST_END; - -#endif/*TEST_TASKTREE*/ diff --git a/src/tasktree.h b/src/tasktree.h deleted file mode 100644 index e33cd61..0000000 --- a/src/tasktree.h +++ /dev/null @@ -1,85 +0,0 @@ -/* -*- 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. - */ -#pragma once - -#include -#include -#include - -#include "task.h" - -class node; -typedef std::list NodeList; - -class node -{ -public: - taskid_t id; - node* parent; - task_t data; - NodeList children; - - std::string toXML(std::string prefix); -}; - -typedef node node_t; - -class TaskTree -{ - friend class XmlParser; -public: - TaskTree(); - ~TaskTree(); - - taskid_t createId(); - - 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, const std::string &name, - const std::string &value) throw (std::exception); - task_t data(taskid_t id) throw (std::exception); - - TaskIdList bfs(taskid_t id) throw (std::exception); - - TaskIdList ancestorList(taskid_t id) throw (std::exception); - - void toStdOut(); - - std::string toXML(); - void fromXML(std::string xml); - - taskid_t nextid; - -private: - node_t* createNode(taskid_t id); - void insertChild(node_t* parent, node_t* child); - - node_t* root; - std::map id2node; -}; diff --git a/src/testclient.cc b/src/testclient.cc index 6733978..3bd9d62 100644 --- a/src/testclient.cc +++ b/src/testclient.cc @@ -50,12 +50,12 @@ struct test enum demo_protocols { - PROTOCOL_TASK, + PROTOCOL_NODE, }; struct test *current_test = nullptr; -static int callback_task(struct lws_context *me, +static int callback_node(struct lws_context *me, struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len) @@ -120,7 +120,7 @@ static int callback_task(struct lws_context *me, static struct lws_protocols protocols[] = { - { "lws-task-protocol", callback_task, 0, }, + { "lws-node-protocol", callback_node, 0, }, { nullptr, nullptr, 0 } }; @@ -129,7 +129,7 @@ int client(const char *address, int port, struct test tests[]) current_test = &tests[0]; struct lws_context *context; - struct lws *wsi_task = nullptr; + struct lws *wsi_node = nullptr; int ietf_version = -1; // latest context = lws_create_context(CONTEXT_PORT_NO_LISTEN, nullptr, @@ -149,16 +149,16 @@ int client(const char *address, int port, struct test tests[]) { n = lws_service(context, 1000); - if(wsi_task == nullptr) + if(wsi_node == nullptr) { - wsi_task = lws_client_connect(context, address, port, + wsi_node = lws_client_connect(context, address, port, 0, "/", address, address, - protocols[PROTOCOL_TASK].name, + protocols[PROTOCOL_NODE].name, ietf_version); - if` (wsi_task == nullptr) + if` (wsi_node == nullptr) { - fprintf(stderr, "lws task connect failed\n"); + fprintf(stderr, "lws node connect failed\n"); return -1; } } diff --git a/src/xmlparser.cc b/src/xmlparser.cc index a087c62..e410f88 100644 --- a/src/xmlparser.cc +++ b/src/xmlparser.cc @@ -31,7 +31,7 @@ #include "xml_encode_decode.h" -XmlParser::XmlParser(TaskTree *t) : tree(t) +XmlParser::XmlParser(NodeTree *t) : tree(t) { } @@ -46,16 +46,16 @@ void XmlParser::characterData(const std::string &data) void XmlParser::startTag(std::string name, attributes_t &attr) { - if(name == "tasktree") + if(name == "nodetree") { tree->nextid = atoi(xml_decode(attr["nextid"]).c_str()); } - if(name == "task") + if(name == "node") { - taskid_t id = atoi(xml_decode(attr["id"]).c_str()); + nodeid_t id = atoi(xml_decode(attr["id"]).c_str()); - node_t* parent = NULL; + Node* parent = NULL; if(parents.size() != 0) { parent = tree->id2node.at(parents.top()); @@ -80,7 +80,7 @@ void XmlParser::startTag(std::string name, attributes_t &attr) void XmlParser::endTag(std::string name) { - if(name == "task") + if(name == "node") { } diff --git a/src/xmlparser.h b/src/xmlparser.h index 6247497..b245c6d 100644 --- a/src/xmlparser.h +++ b/src/xmlparser.h @@ -27,17 +27,17 @@ */ #pragma once -#include "task.h" +#include "node.h" #include "saxparser.h" #include -#include "tasktree.h" +#include "nodetree.h" class XmlParser : public SAXParser { public: - XmlParser(TaskTree *tree); + XmlParser(NodeTree *tree); ~XmlParser(); void startTag(std::string name, attributes_t &attr); @@ -45,9 +45,9 @@ public: void characterData(const std::string &data); private: - std::stack parents; + std::stack parents; std::string cdata; - node_t *node; - TaskTree *tree; + Node *node; + NodeTree *tree; std::string attr_name; }; diff --git a/task.js b/task.js deleted file mode 100644 index 64d95ff..0000000 --- a/task.js +++ /dev/null @@ -1,137 +0,0 @@ -/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set et sw=2 ts=2: */ - -function createId(boardid, taskid) -{ - return "b" + boardid + "_t" + taskid; -} - -function idFromStr(str) -{ - return str.substring(str.search('t') + 1, str.length); -} - -var tasks = new Array(); - -function findTask(id, subscribeid) -{ - for(var i = 0; i < tasks.length; i++) { - var task = tasks[i]; - var child = task.findTask(id, subscribeid); - if(child != null) return child; - } - - return null; -} - -function Task(id, subscribeid) -{ - this.id = id; - this.subscribeid = subscribeid; - this.children = new Array(); - this.attributes = {}; - this.parent = null; - - // Elements: - this.element = document.createElement("div"); - this.div_id = document.createElement("span"); - this.div_title = document.createElement("span"); -} - -Task.prototype.dump = function() -{ - alert(this.id); -} - -Task.prototype.findTask = function(id, subscribeid) -{ - if(this.subscribeid != subscribeid) return null; - - if(this.id == id) return this; - - for(var i = 0; i < this.children.length; i++) { - var task = this.children[i]; - var child = task.findTask(id, subscribeid); - if(child != null) return child; - } - - return null; -} - -Task.prototype.addChild = function(task) -{ - if(task.parent != null) task.parent.removeChild(task); - this.children.push(task); - task.parent = this; - this.element.appendChild(task.element); -} - -Task.prototype.removeChild = function(task) -{ - this.children = this.children.filter( - function(e) { - return e.id != task.id; - }); - task.parent = null; - this.element.removeChild(task.element); -} - -Task.prototype.create = function() -{ - var task = this.element; - - task.name = "task"; - task.setAttribute("class", "task"); - task.setAttribute("ondblclick", "editTitle(this, event)"); - //task.setAttribute("onclick", "showHideChildren(this, event)"); - task.setAttribute("ondrop", "drop(this, event)"); - task.setAttribute("ondragover", "return false"); - task.setAttribute("draggable", true); - task.setAttribute("ondragstart", "drag(this, event)"); - task.setAttribute("title", this.id); - - // This is a hack to make it possible to identify the taskid and - // oberveid from the node id alone. - task.id = createId(this.subscribeid, this.id); - -/* - var subscribe_button = document.createElement("div"); - subscribe_button.name = "subscribe_button"; - subscribe_button.setAttribute("onclick", "subscribeMe(this, event)"); - subscribe_button.setAttribute("title", this.id); - subscribe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid green 2px; cursor: pointer;"); - var txt_plus = document.createTextNode("+"); - subscribe_button.appendChild(txt_plus); - task.appendChild(subscribe_button); - - var unsubscribe_button = document.createElement("div"); - unsubscribe_button.name = "unsubscribe_button"; - unsubscribe_button.setAttribute("onclick", "unsubscribeMe(this, event)"); - unsubscribe_button.setAttribute("title", this.id); - unsubscribe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid red 2px; cursor: pointer;"); - var txt_minus = document.createTextNode("-"); - unsubscribe_button.appendChild(txt_minus); - task.appendChild(unsubscribe_button); -*/ - - this.element.appendChild(this.div_id); - var id_txt = document.createTextNode(this.id); - this.div_id.appendChild(id_txt); - - this.element.appendChild(this.div_title); - - this.setAttribute("title", "(missing title)"); -} - -Task.prototype.setAttribute = function(name, value) -{ - this.attributes[name] = value; - - if(name == "title") { - if(this.div_title.firstChild != null) { - this.div_title.removeChild(this.div_title.firstChild); - } - var title_txt = document.createTextNode(value); - this.div_title.appendChild(title_txt); - } -} diff --git a/view.js b/view.js index 6104384..5f98587 100644 --- a/view.js +++ b/view.js @@ -2,22 +2,22 @@ /* vim: set et sw=2 ts=2: */ /* -function createTask() +function createNode() { - var task = new Task(); - task.id = 42; - task.dump = function() { + var node = new Node(); + node.id = 42; + node.dump = function() { alert(this.id); } } */ -function getTask(subscribeid, id) +function getNode(subscribeid, id) { } -function updateTask(subscribeid, id, name, value) +function updateNode(subscribeid, id, name, value) { } @@ -42,7 +42,7 @@ function clear() { document.getElementById("input_data").value = ""; } -function deleteTask(id) { +function deleteNode(id) { remove(id); } @@ -56,7 +56,7 @@ function drop(target, e) { e.stopPropagation(); var id = e.dataTransfer.getData('Text'); - var task = document.getElementById(id); + var node = document.getElementById(id); move(idFromStr(id), idFromStr(target.id)); } @@ -89,16 +89,16 @@ function showHideChildren(target, e) } } -function task_submit() { - var data = document.getElementById("input_task_data"); +function node_submit() { + var data = document.getElementById("input_node_data"); transmit(data.value); data.value = ""; } -function task_submit_KeyUpHandler(target, e) +function node_submit_KeyUpHandler(target, e) { if(e.which == 13) { // enter - task_submit(); + node_submit(); } } -- cgit v1.2.3