From 73232a16f4b5ed44094f7c03a3f767581be73c19 Mon Sep 17 00:00:00 2001 From: daleharvey Date: Mon, 4 Sep 2006 13:08:27 +0000 Subject: [PATCH] whiteboard working prototype --- src/jabber_whiteboard/defines.cpp | 2 +- src/jabber_whiteboard/defines.h | 17 +++-- src/jabber_whiteboard/inkboard-document.cpp | 29 ++++++--- src/jabber_whiteboard/inkboard-document.h | 5 +- src/jabber_whiteboard/inkboard-node.cpp | 71 +++++++++++++++++++-- src/jabber_whiteboard/inkboard-session.cpp | 25 ++++++-- src/jabber_whiteboard/keynode.cpp | 45 +++++++++++++ src/jabber_whiteboard/keynode.h | 59 ++++++++++++----- src/jabber_whiteboard/node-tracker.h | 6 +- src/jabber_whiteboard/session-manager.h | 5 +- 10 files changed, 212 insertions(+), 52 deletions(-) diff --git a/src/jabber_whiteboard/defines.cpp b/src/jabber_whiteboard/defines.cpp index b1dac9913..ad0641260 100644 --- a/src/jabber_whiteboard/defines.cpp +++ b/src/jabber_whiteboard/defines.cpp @@ -49,7 +49,7 @@ namespace Vars { "<%1><%2 />"); const std::string NEW_MESSAGE( - "%4"); + "%5"); const std::string CONFIGURE_MESSAGE( ""); diff --git a/src/jabber_whiteboard/defines.h b/src/jabber_whiteboard/defines.h index 8b3c56354..a9bc80ca6 100644 --- a/src/jabber_whiteboard/defines.h +++ b/src/jabber_whiteboard/defines.h @@ -13,6 +13,7 @@ #ifndef __INKSCAPE_WHITEBOARD_DEFINES_H__ #define __INKSCAPE_WHITEBOARD_DEFINES_H__ +#include "xml/node.h" #include "jabber_whiteboard/message-tags.h" #include @@ -26,8 +27,6 @@ #include #include -#include "jabber_whiteboard/keynode.h" - #include "gc-alloc.h" // Various specializations of std::less for XMLNodeTracker maps. @@ -42,10 +41,10 @@ using Inkscape::XML::Node; template<> struct less< Node* > : public binary_function < Node*, Node*, bool > { - bool operator()(Node* _x, Node* _y) const - { - return _x < _y; - } + bool operator()(Node* _x, Node* _y) const + { + return _x < _y; + } }; @@ -133,10 +132,10 @@ namespace Dialog { } -// message types -// explicitly numbered to aid protocol description later on - +class KeyNodePair; +class KeyNodeTable; +typedef std::pair Configure; // Message handler modes enum HandlerMode { diff --git a/src/jabber_whiteboard/inkboard-document.cpp b/src/jabber_whiteboard/inkboard-document.cpp index 3c063a382..a8b3567da 100644 --- a/src/jabber_whiteboard/inkboard-document.cpp +++ b/src/jabber_whiteboard/inkboard-document.cpp @@ -38,6 +38,7 @@ InkboardDocument::_initBindings() { this->sm = &SessionManager::instance(); this->state = State::INITIAL; + this->tracker = new KeyNodeTable(); _bindDocument(*this); _bindLogger(*(new InkboardSession(this))); } @@ -106,7 +107,6 @@ InkboardDocument::recieve(Message::Wrapper &wrapper, Pedro::Element* data) this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_BEGIN); // Send Document - this->tracker = new KeyNodeTable(); this->sendDocument(this->root()); this->send(getRecipient(),Message::PROTOCOL, Message::DOCUMENT_END); @@ -270,16 +270,29 @@ InkboardDocument::handleChange(Message::Wrapper &wrapper, Pedro::Element* data) }else if(wrapper == Message::CONFIGURE) { - Glib::ustring target = data->getTagAttribute("configure","target"); - Glib::ustring attribute = data->getTagAttribute("configure","attribute"); - Glib::ustring value = data->getTagAttribute("configure","value"); + if(data->exists("text")) + { + Glib::ustring text = data->getFirstChild()->getValue(); + Glib::ustring target = data->getTagAttribute("configure","target"); + + unsigned int version = atoi + (data->getTagAttribute("configure","version").c_str()); - signed int version = atoi - (data->getTagAttribute("configure","version").c_str()); + if(text.size() > 0 && target.size() > 0) + this->changeConfigureText(target,version,text); - if(target.size() > 0 && attribute.size() > 0 && value.size() > 0) - this->changeConfigure(target,version,attribute,value); + }else + { + Glib::ustring target = data->getTagAttribute("configure","target"); + Glib::ustring attribute = data->getTagAttribute("configure","attribute"); + Glib::ustring value = data->getTagAttribute("configure","value"); + unsigned int version = atoi + (data->getTagAttribute("configure","version").c_str()); + + if(target.size() > 0 && attribute.size() > 0 && value.size() > 0) + this->changeConfigure(target,version,attribute,value); + } }else if(wrapper == Message::MOVE) { }else if(wrapper == Message::REMOVE) diff --git a/src/jabber_whiteboard/inkboard-document.h b/src/jabber_whiteboard/inkboard-document.h index 510f47c6e..5eaeffca8 100644 --- a/src/jabber_whiteboard/inkboard-document.h +++ b/src/jabber_whiteboard/inkboard-document.h @@ -66,12 +66,15 @@ public: Glib::ustring addNodeToTracker(Inkscape::XML::Node* node); Message::Message composeNewMessage(Inkscape::XML::Node *node); - void changeConfigure(Glib::ustring target, signed int target, + void changeConfigure(Glib::ustring target, unsigned int version, Glib::ustring attribute, Glib::ustring value); void changeNew(Glib::ustring target, Glib::ustring, signed int index, Pedro::Element* data); + void changeConfigureText(Glib::ustring target, unsigned int version, + Glib::ustring text); + protected: /** diff --git a/src/jabber_whiteboard/inkboard-node.cpp b/src/jabber_whiteboard/inkboard-node.cpp index bcb6cd981..5f40e3808 100644 --- a/src/jabber_whiteboard/inkboard-node.cpp +++ b/src/jabber_whiteboard/inkboard-node.cpp @@ -14,6 +14,12 @@ #include "util/ucompose.hpp" +#include "pedro/pedrodom.h" + +#include "xml/attribute-record.h" +#include "xml/element-node.h" +#include "xml/text-node.h" + #include "jabber_whiteboard/message-utilities.h" #include "jabber_whiteboard/defines.h" #include "jabber_whiteboard/inkboard-document.h" @@ -26,7 +32,8 @@ namespace Whiteboard { Glib::ustring InkboardDocument::addNodeToTracker(Inkscape::XML::Node *node) { - Glib::ustring key = this->tracker->generateKey(this->getRecipient()); + Glib::ustring rec = this->getRecipient(); + Glib::ustring key = this->tracker->generateKey(rec); this->tracker->put(key,node); return key; } @@ -47,27 +54,77 @@ InkboardDocument::composeNewMessage(Inkscape::XML::Node *node) unsigned int index = parent->_childPosition(*node); Message::Message nodeMessage = MessageUtilities::objectToString(node); - Message::Message message = String::ucompose(Vars::NEW_MESSAGE,parentKey,key,index,nodeMessage); + Message::Message message = String::ucompose(Vars::NEW_MESSAGE,parentKey,key,index,0,nodeMessage); return message; } void -InkboardDocument::changeConfigure(Glib::ustring target, signed int version, +InkboardDocument::changeConfigureText(Glib::ustring target, unsigned int version, + Glib::ustring text) +{ + XML::Node *node = this->tracker->get(target); + unsigned int elementVersion = this->tracker->getVersion(node); + + if(node && version == (elementVersion + 1)) + { + this->tracker->incrementVersion(node); + this->tracker->addHistory(node, "text", text); + node->setContent(text.c_str()); + } +} + +void +InkboardDocument::changeConfigure(Glib::ustring target, unsigned int version, Glib::ustring attribute, Glib::ustring value) { + XML::Node *node = this->tracker->get(target); + unsigned int elementVersion = this->tracker->getVersion(node); + + if(node && version == (elementVersion + 1)) + { + this->tracker->incrementVersion(node); + this->tracker->addHistory(node, attribute, node->attribute(attribute.c_str())); + node->setAttribute(attribute.c_str(),value.c_str()); + } } void -InkboardDocument::changeNew(Glib::ustring target, Glib::ustring, +InkboardDocument::changeNew(Glib::ustring parentid, Glib::ustring id, signed int index, Pedro::Element* data) { - Glib::ustring name = data->getName(); + + Glib::ustring name(data->getName()); if(name == "text") { - //XML::Node* parent = this->tracker->get(target); - //parent->setContent(date->getValue()); + XML::Node *parent = this->tracker->get(parentid); + XML::Node *node = new XML::TextNode(Util::share_string(data->getValue().c_str())); + + if(parent && node) + { + this->tracker->put(id,node); + parent->appendChild(node); + } + }else + { + XML::Node *node = new XML::ElementNode(g_quark_from_string(name.c_str())); + this->tracker->put(id,node); + + XML::Node *parent = (parentid != "ROOT") + ? this->tracker->get(parentid.c_str()) : this->root(); + + std::vector attributes = data->getAttributes(); + + for (unsigned int i=0; isetAttribute( + (attributes[i].getName()).c_str(), + (attributes[i].getValue()).c_str()); + } + + if(parent != NULL) + parent->appendChild(node); } } diff --git a/src/jabber_whiteboard/inkboard-session.cpp b/src/jabber_whiteboard/inkboard-session.cpp index 6601d5d87..b52b9bd44 100644 --- a/src/jabber_whiteboard/inkboard-session.cpp +++ b/src/jabber_whiteboard/inkboard-session.cpp @@ -88,10 +88,13 @@ void InkboardSession::notifyChildAdded(Node &parent, XML::Node *node = (XML::Node *)&child; - this->doc->addNodeToTracker(node); - Message::Message message = this->doc->composeNewMessage(node); + if(this->doc->tracker->get(node) == "") + { + this->doc->addNodeToTracker(node); + Message::Message message = this->doc->composeNewMessage(node); - this->doc->send(this->doc->getRecipient(),Message::NEW,message); + this->doc->send(this->doc->getRecipient(),Message::NEW,message); + } } } @@ -139,8 +142,10 @@ void InkboardSession::notifyContentChanged(Node &node, if(new_content.pointer()) { + unsigned int version = this->doc->tracker->incrementVersion(element); + Message::Message message = String::ucompose(Vars::CONFIGURE_TEXT_MESSAGE, - this->doc->tracker->get(element),"0",new_content.pointer()); + this->doc->tracker->get(element),version,new_content.pointer()); this->doc->send(this->doc->getRecipient(),Message::CONFIGURE,message); } @@ -156,10 +161,20 @@ void InkboardSession::notifyAttributeChanged(Node &node, { XML::Node *element = (XML::Node *)&node; + Glib::ustring value(new_value.pointer()); + Glib::ustring attribute(g_quark_to_string(name)); + + Configure change = this->doc->tracker->getLastHistory(element); + + if(change.first == attribute && change.second == value) + return; + if(name && new_value.pointer()) { + unsigned int version = this->doc->tracker->incrementVersion(element); + Message::Message message = String::ucompose(Vars::CONFIGURE_MESSAGE, - this->doc->tracker->get(element),"0",g_quark_to_string(name),new_value.pointer()); + this->doc->tracker->get(element),version,attribute.c_str(),value.c_str()); this->doc->send(this->doc->getRecipient(),Message::CONFIGURE,message); } diff --git a/src/jabber_whiteboard/keynode.cpp b/src/jabber_whiteboard/keynode.cpp index 6f0a5226f..af2c0762e 100644 --- a/src/jabber_whiteboard/keynode.cpp +++ b/src/jabber_whiteboard/keynode.cpp @@ -89,6 +89,51 @@ Glib::ustring KeyNodeTable::get(XML::Node *node) const return ""; } +unsigned int KeyNodeTable::incrementVersion(XML::Node *node) +{ + std::vector::iterator iter; + for (iter = items.begin() ; iter != items.end() ; iter++) + { + if (node == iter->node) + break; + } + return ++iter->version; +} + +unsigned int KeyNodeTable::getVersion(XML::Node *node) +{ + std::vector::iterator iter; + for (iter = items.begin() ; iter != items.end() ; iter++) + { + if (node == iter->node) + break; + } + return iter->version; +} + +void KeyNodeTable::addHistory(XML::Node *node, Glib::ustring attribute, Glib::ustring value) +{ + std::vector::iterator iter; + for (iter = items.begin() ; iter != items.end() ; iter++) + { + if (node == iter->node) + { + Configure pair(attribute, value); + iter->history.push_back(pair); + } + } +} + +Configure& KeyNodeTable::getLastHistory(XML::Node *node) +{ + std::vector::iterator iter; + for (iter = items.begin() ; iter != items.end() ; iter++) + { + if (node == iter->node) + break; + } + return iter->history.back(); +} void KeyNodeTable::remove(XML::Node *node) { diff --git a/src/jabber_whiteboard/keynode.h b/src/jabber_whiteboard/keynode.h index f727219d5..df7557fd1 100644 --- a/src/jabber_whiteboard/keynode.h +++ b/src/jabber_whiteboard/keynode.h @@ -15,31 +15,50 @@ #include #include "xml/node.h" - +#include "jabber_whiteboard/defines.h" namespace Inkscape { namespace Whiteboard { - class KeyNodePair { public: - KeyNodePair(const Glib::ustring &keyArg, const XML::Node *nodeArg) - { - key = keyArg; - node = (XML::Node *)nodeArg; - } - KeyNodePair(const KeyNodePair &other) - { - key = other.key; - node = other.node; - } - virtual ~KeyNodePair() - {} - Glib::ustring key; - XML::Node *node; + + KeyNodePair(const Glib::ustring &keyArg, const XML::Node *nodeArg) + { + key = keyArg; + node = (XML::Node *)nodeArg; + version = 0; + index = 0; + } + + KeyNodePair(const Glib::ustring &keyArg, const XML::Node *nodeArg, + unsigned int version, signed int index) + { + key = keyArg; + node = (XML::Node *)nodeArg; + this->version = version; + this->index = index; + } + + KeyNodePair(const KeyNodePair &other) + { + key = other.key; + node = other.node; + version = other.version; + index = other.index; + history = other.history; + } + + virtual ~KeyNodePair() {} + + Glib::ustring key; + XML::Node *node; + unsigned int version; + signed int index; + std::list< Configure > history; }; class KeyNodeTable @@ -80,6 +99,14 @@ public: virtual Glib::ustring generateKey(Glib::ustring); + virtual unsigned int getVersion(XML::Node *node); + + virtual unsigned int incrementVersion(XML::Node *node); + + virtual void addHistory(XML::Node *node, Glib::ustring attribute, Glib::ustring value); + + virtual Configure& getLastHistory(XML::Node *node); + private: std::vector items; diff --git a/src/jabber_whiteboard/node-tracker.h b/src/jabber_whiteboard/node-tracker.h index 2bb61f5a5..75852e98e 100644 --- a/src/jabber_whiteboard/node-tracker.h +++ b/src/jabber_whiteboard/node-tracker.h @@ -199,14 +199,14 @@ public: private: //common code called by constructors void init(); - + void createSpecialNodeTables(); void _clear(); unsigned int _counter; SessionManager* _sm; - - KeyNodeTable keyNodeTable; + + //KeyNodeTable keyNodeTable; std::map< char const*, char const*, strcmpless > _specialnodes; diff --git a/src/jabber_whiteboard/session-manager.h b/src/jabber_whiteboard/session-manager.h index 1ba626685..ed1b5edf6 100644 --- a/src/jabber_whiteboard/session-manager.h +++ b/src/jabber_whiteboard/session-manager.h @@ -53,7 +53,6 @@ public: virtual ~SessionManager(); - static void showClient(); static SessionManager& instance(); @@ -119,7 +118,9 @@ private: }; -SPDocument* makeInkboardDocument(int code, gchar const* rootname, State::SessionType type, Glib::ustring const& to); +SPDocument* makeInkboardDocument(int code, gchar const* rootname, + State::SessionType type, Glib::ustring const& to); + SPDesktop* makeInkboardDesktop(SPDocument* doc); } // namespace Whiteboard -- 2.30.2