From b775b1a812db0c7b4150361fbb62260afa3e12a6 Mon Sep 17 00:00:00 2001 From: sol981 Date: Sun, 24 Mar 2024 18:28:20 +0700 Subject: [PATCH 1/7] [TASK1] make _chatLogic is exclusive ownership of chatbot panel dialog --- src/chatgui.cpp | 4 ++-- src/chatgui.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/chatgui.cpp b/src/chatgui.cpp index 6637e562b..ad6556d63 100644 --- a/src/chatgui.cpp +++ b/src/chatgui.cpp @@ -118,7 +118,7 @@ ChatBotPanelDialog::ChatBotPanelDialog(wxWindow *parent, wxWindowID id) //// // create chat logic instance - _chatLogic = new ChatLogic(); + _chatLogic = std::make_unique(); // pass pointer to chatbot dialog so answers can be displayed in GUI _chatLogic->SetPanelDialogHandle(this); @@ -135,7 +135,7 @@ ChatBotPanelDialog::~ChatBotPanelDialog() //// STUDENT CODE //// - delete _chatLogic; + _chatLogic.reset(); //// //// EOF STUDENT CODE diff --git a/src/chatgui.h b/src/chatgui.h index 503c59790..9b7ad1fab 100644 --- a/src/chatgui.h +++ b/src/chatgui.h @@ -2,6 +2,7 @@ #define CHATGUI_H_ #include +#include class ChatLogic; // forward declaration @@ -16,8 +17,7 @@ class ChatBotPanelDialog : public wxScrolledWindow //// STUDENT CODE //// - ChatLogic *_chatLogic; - + std::unique_ptr _chatLogic; //// //// EOF STUDENT CODE @@ -27,7 +27,7 @@ class ChatBotPanelDialog : public wxScrolledWindow ~ChatBotPanelDialog(); // getter / setter - ChatLogic *GetChatLogicHandle() { return _chatLogic; } + ChatLogic *GetChatLogicHandle() { return _chatLogic.get(); } // events void paintEvent(wxPaintEvent &evt); From b8c109538bef58d5b29aa45fde06811c06df2a73 Mon Sep 17 00:00:00 2001 From: sol981 Date: Mon, 25 Mar 2024 10:25:33 +0700 Subject: [PATCH 2/7] TASK2 udpate chatbot follow rule of 5 --- src/chatbot.cpp | 52 +++++++++++++++++++++++++++++++++++++++++++++++++ src/chatbot.h | 4 ++++ 2 files changed, 56 insertions(+) diff --git a/src/chatbot.cpp b/src/chatbot.cpp index 41d1f0c1f..14bf142e0 100644 --- a/src/chatbot.cpp +++ b/src/chatbot.cpp @@ -45,6 +45,58 @@ ChatBot::~ChatBot() //// STUDENT CODE //// +ChatBot::ChatBot(ChatBot& cb) +{ + std::cout << "ChatBot copy constructor" << std::endl; + + // invalidate data handles + _chatLogic = nullptr; + _rootNode = nullptr; + + // load image into heap memory + _image = new wxBitmap(); + _image = cb.GetImageHandle(); + _chatLogic = cb.GetChatLogicHandle(); +} + +ChatBot::ChatBot(ChatBot&& cb) +{ + std::cout << "ChatBot move constructor" << std::endl; + delete _image; + delete _chatLogic; + + // load image into heap memory + _image = std::move(cb.GetImageHandle()); + _chatLogic = std::move(cb.GetChatLogicHandle()); +} + +ChatBot& ChatBot::operator=(ChatBot& cb) +{ + std::cout << "ChatBot copy assignment operator" << std::endl; + if (this == &cb) + { + return *this; + } + delete[] this; + + _image = new wxBitmap(); + _image = cb.GetImageHandle(); + _chatLogic = cb.GetChatLogicHandle(); + + return *this; +} + +ChatBot& ChatBot::operator=(ChatBot&& cb) +{ + std::cout << "ChatBot move assignment operator" << std::endl; + delete[] this; + + _image = std::move(cb.GetImageHandle()); + _chatLogic = std::move(cb.GetChatLogicHandle()); + + return *this; +} + //// //// EOF STUDENT CODE diff --git a/src/chatbot.h b/src/chatbot.h index 0367a93f8..acaa66014 100644 --- a/src/chatbot.h +++ b/src/chatbot.h @@ -30,6 +30,10 @@ class ChatBot //// STUDENT CODE //// + ChatBot(ChatBot& cb); + ChatBot(ChatBot&& cb); + ChatBot& operator=(ChatBot& cb); + ChatBot& operator=(ChatBot&& cb); //// //// EOF STUDENT CODE From 647b6329ee4e05857c42c6535394ab77f7147ef6 Mon Sep 17 00:00:00 2001 From: sol981 Date: Wed, 27 Mar 2024 21:57:01 +0700 Subject: [PATCH 3/7] TASK 3 use unique_ptr for nodes in chatlogic --- src/chatlogic.cpp | 18 +++++++++--------- src/chatlogic.h | 3 ++- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/src/chatlogic.cpp b/src/chatlogic.cpp index 79c58ef41..e9e8504e2 100644 --- a/src/chatlogic.cpp +++ b/src/chatlogic.cpp @@ -38,7 +38,7 @@ ChatLogic::~ChatLogic() // delete all nodes for (auto it = std::begin(_nodes); it != std::end(_nodes); ++it) { - delete *it; + (*it).reset(); } // delete all edges @@ -127,16 +127,16 @@ void ChatLogic::LoadAnswerGraphFromFile(std::string filename) //// // check if node with this ID exists already - auto newNode = std::find_if(_nodes.begin(), _nodes.end(), [&id](GraphNode *node) { return node->GetID() == id; }); + auto newNode = std::find_if(_nodes.begin(), _nodes.end(), [&id](const std::unique_ptr& node) { return node->GetID() == id; }); // create new element if ID does not yet exist if (newNode == _nodes.end()) { - _nodes.emplace_back(new GraphNode(id)); + _nodes.emplace_back(std::make_unique(id)); newNode = _nodes.end() - 1; // get iterator to last element // add all answers to current node - AddAllTokensToElement("ANSWER", tokens, **newNode); + AddAllTokensToElement("ANSWER", tokens, *((*newNode).get())); } //// @@ -156,13 +156,13 @@ void ChatLogic::LoadAnswerGraphFromFile(std::string filename) if (parentToken != tokens.end() && childToken != tokens.end()) { // get iterator on incoming and outgoing node via ID search - auto parentNode = std::find_if(_nodes.begin(), _nodes.end(), [&parentToken](GraphNode *node) { return node->GetID() == std::stoi(parentToken->second); }); - auto childNode = std::find_if(_nodes.begin(), _nodes.end(), [&childToken](GraphNode *node) { return node->GetID() == std::stoi(childToken->second); }); + auto parentNode = std::find_if(_nodes.begin(), _nodes.end(), [&parentToken](const std::unique_ptr& node) { return node->GetID() == std::stoi(parentToken->second); }); + auto childNode = std::find_if(_nodes.begin(), _nodes.end(), [&childToken](const std::unique_ptr& node) { return node->GetID() == std::stoi(childToken->second); }); // create new edge GraphEdge *edge = new GraphEdge(id); - edge->SetChildNode(*childNode); - edge->SetParentNode(*parentNode); + edge->SetChildNode((*childNode).get()); + edge->SetParentNode((*parentNode).get()); _edges.push_back(edge); // find all keywords for current node @@ -206,7 +206,7 @@ void ChatLogic::LoadAnswerGraphFromFile(std::string filename) if (rootNode == nullptr) { - rootNode = *it; // assign current node to root + rootNode = (*it).get(); // assign current node to root } else { diff --git a/src/chatlogic.h b/src/chatlogic.h index e70b0713e..18cc43ea0 100644 --- a/src/chatlogic.h +++ b/src/chatlogic.h @@ -4,6 +4,7 @@ #include #include #include "chatgui.h" +#include // forward declarations class ChatBot; @@ -17,7 +18,7 @@ class ChatLogic //// // data handles (owned) - std::vector _nodes; + std::vector> _nodes; std::vector _edges; //// From e2f8ec00a19022d995f3f8decea2c289fca57c9e Mon Sep 17 00:00:00 2001 From: sol981 Date: Fri, 29 Mar 2024 20:47:17 +0700 Subject: [PATCH 4/7] TASK 4 update graph node --- src/chatlogic.cpp | 11 ++--------- src/chatlogic.h | 1 - src/graphnode.cpp | 6 +++--- src/graphnode.h | 10 +++++----- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/chatlogic.cpp b/src/chatlogic.cpp index e9e8504e2..87b9bc06f 100644 --- a/src/chatlogic.cpp +++ b/src/chatlogic.cpp @@ -41,12 +41,6 @@ ChatLogic::~ChatLogic() (*it).reset(); } - // delete all edges - for (auto it = std::begin(_edges); it != std::end(_edges); ++it) - { - delete *it; - } - //// //// EOF STUDENT CODE } @@ -160,17 +154,16 @@ void ChatLogic::LoadAnswerGraphFromFile(std::string filename) auto childNode = std::find_if(_nodes.begin(), _nodes.end(), [&childToken](const std::unique_ptr& node) { return node->GetID() == std::stoi(childToken->second); }); // create new edge - GraphEdge *edge = new GraphEdge(id); + auto edge = std::make_shared(id); edge->SetChildNode((*childNode).get()); edge->SetParentNode((*parentNode).get()); - _edges.push_back(edge); // find all keywords for current node AddAllTokensToElement("KEYWORD", tokens, *edge); // store reference in child node and parent node (*childNode)->AddEdgeToParentNode(edge); - (*parentNode)->AddEdgeToChildNode(edge); + (*parentNode)->AddEdgeToChildNode(std::move(edge)); } //// diff --git a/src/chatlogic.h b/src/chatlogic.h index 18cc43ea0..2f8c0f3a4 100644 --- a/src/chatlogic.h +++ b/src/chatlogic.h @@ -19,7 +19,6 @@ class ChatLogic // data handles (owned) std::vector> _nodes; - std::vector _edges; //// //// EOF STUDENT CODE diff --git a/src/graphnode.cpp b/src/graphnode.cpp index 65f56060b..e80724fcc 100644 --- a/src/graphnode.cpp +++ b/src/graphnode.cpp @@ -22,12 +22,12 @@ void GraphNode::AddToken(std::string token) _answers.push_back(token); } -void GraphNode::AddEdgeToParentNode(GraphEdge *edge) +void GraphNode::AddEdgeToParentNode(const std::shared_ptr &edge) { _parentEdges.push_back(edge); } -void GraphNode::AddEdgeToChildNode(GraphEdge *edge) +void GraphNode::AddEdgeToChildNode(std::shared_ptr edge) { _childEdges.push_back(edge); } @@ -53,7 +53,7 @@ GraphEdge *GraphNode::GetChildEdgeAtIndex(int index) //// STUDENT CODE //// - return _childEdges[index]; + return _childEdges[index].get(); //// //// EOF STUDENT CODE diff --git a/src/graphnode.h b/src/graphnode.h index ba3910d20..690dc051b 100644 --- a/src/graphnode.h +++ b/src/graphnode.h @@ -4,7 +4,7 @@ #include #include #include "chatbot.h" - +#include // forward declarations class GraphEdge; @@ -16,10 +16,10 @@ class GraphNode //// // data handles (owned) - std::vector _childEdges; // edges to subsequent nodes + std::vector> _childEdges; // edges to subsequent nodes // data handles (not owned) - std::vector _parentEdges; // edges to preceding nodes + std::vector> _parentEdges; // edges to preceding nodes ChatBot *_chatBot; //// @@ -43,8 +43,8 @@ class GraphNode // proprietary functions void AddToken(std::string token); // add answers to list - void AddEdgeToParentNode(GraphEdge *edge); - void AddEdgeToChildNode(GraphEdge *edge); + void AddEdgeToParentNode(const std::shared_ptr& edge); + void AddEdgeToChildNode(std::shared_ptr edge); //// STUDENT CODE //// From f968950553e7af9f2fc49df4b09a41930ed7cd95 Mon Sep 17 00:00:00 2001 From: sol981 Date: Mon, 1 Apr 2024 20:49:19 +0700 Subject: [PATCH 5/7] TASK 5 move chatbot --- src/chatlogic.cpp | 23 ++++++++++++----------- src/graphnode.cpp | 16 +++++++++------- src/graphnode.h | 5 +++-- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/chatlogic.cpp b/src/chatlogic.cpp index 87b9bc06f..1e4f302bc 100644 --- a/src/chatlogic.cpp +++ b/src/chatlogic.cpp @@ -18,10 +18,10 @@ ChatLogic::ChatLogic() //// // create instance of chatbot - _chatBot = new ChatBot("../images/chatbot.png"); + // _chatBot = new ChatBot("../images/chatbot.png"); - // add pointer to chatlogic so that chatbot answers can be passed on to the GUI - _chatBot->SetChatLogicHandle(this); + // // add pointer to chatlogic so that chatbot answers can be passed on to the GUI + // _chatBot->SetChatLogicHandle(this); //// //// EOF STUDENT CODE @@ -33,13 +33,13 @@ ChatLogic::~ChatLogic() //// // delete chatbot instance - delete _chatBot; + // delete _chatBot; // delete all nodes - for (auto it = std::begin(_nodes); it != std::end(_nodes); ++it) - { - (*it).reset(); - } + // for (auto it = std::begin(_nodes); it != std::end(_nodes); ++it) + // { + // (*it).reset(); + // } //// //// EOF STUDENT CODE @@ -208,9 +208,10 @@ void ChatLogic::LoadAnswerGraphFromFile(std::string filename) } } - // add chatbot to graph root node - _chatBot->SetRootNode(rootNode); - rootNode->MoveChatbotHere(_chatBot); + ChatBot lChatBot("../images/chatbot.png"); + lChatBot.SetChatLogicHandle(this); + lChatBot.SetRootNode(rootNode); + rootNode->MoveChatbotHere(std::move(lChatBot)); //// //// EOF STUDENT CODE diff --git a/src/graphnode.cpp b/src/graphnode.cpp index e80724fcc..9a115e688 100644 --- a/src/graphnode.cpp +++ b/src/graphnode.cpp @@ -1,6 +1,6 @@ #include "graphedge.h" #include "graphnode.h" - +#include GraphNode::GraphNode(int id) { _id = id; @@ -11,7 +11,8 @@ GraphNode::~GraphNode() //// STUDENT CODE //// - delete _chatBot; + // delete _chatBot; + // _chatBot.reset(); //// //// EOF STUDENT CODE @@ -34,16 +35,17 @@ void GraphNode::AddEdgeToChildNode(std::shared_ptr edge) //// STUDENT CODE //// -void GraphNode::MoveChatbotHere(ChatBot *chatbot) +void GraphNode::MoveChatbotHere(ChatBot chatbot) { - _chatBot = chatbot; - _chatBot->SetCurrentNode(this); + _chatBot = std::move(chatbot); + _chatBot.GetChatLogicHandle()->SetChatbotHandle(&_chatBot); + _chatBot.SetCurrentNode(this); + } void GraphNode::MoveChatbotToNewNode(GraphNode *newNode) { - newNode->MoveChatbotHere(_chatBot); - _chatBot = nullptr; // invalidate pointer at source + newNode->MoveChatbotHere(std::move(_chatBot)); } //// //// EOF STUDENT CODE diff --git a/src/graphnode.h b/src/graphnode.h index 690dc051b..450884a65 100644 --- a/src/graphnode.h +++ b/src/graphnode.h @@ -4,6 +4,7 @@ #include #include #include "chatbot.h" +#include "chatlogic.h" #include // forward declarations @@ -20,7 +21,7 @@ class GraphNode // data handles (not owned) std::vector> _parentEdges; // edges to preceding nodes - ChatBot *_chatBot; + ChatBot _chatBot; //// //// EOF STUDENT CODE @@ -49,7 +50,7 @@ class GraphNode //// STUDENT CODE //// - void MoveChatbotHere(ChatBot *chatbot); + void MoveChatbotHere(ChatBot chatbot); //// //// EOF STUDENT CODE From 9c355f131d4decceb155410a63524b9ee852d15f Mon Sep 17 00:00:00 2001 From: sol981 Date: Mon, 1 Apr 2024 20:51:10 +0700 Subject: [PATCH 6/7] fix segmetation fault error --- src/chatbot.cpp | 85 ++++++++++++++++++++++++++----------------------- src/chatbot.h | 10 +++--- 2 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/chatbot.cpp b/src/chatbot.cpp index 14bf142e0..15bfdcdb3 100644 --- a/src/chatbot.cpp +++ b/src/chatbot.cpp @@ -45,58 +45,65 @@ ChatBot::~ChatBot() //// STUDENT CODE //// -ChatBot::ChatBot(ChatBot& cb) -{ - std::cout << "ChatBot copy constructor" << std::endl; - - // invalidate data handles - _chatLogic = nullptr; - _rootNode = nullptr; - - // load image into heap memory - _image = new wxBitmap(); - _image = cb.GetImageHandle(); - _chatLogic = cb.GetChatLogicHandle(); -} +ChatBot::ChatBot(const ChatBot &source) { + std::cout << "ChatBot Copy Constructor" << std::endl; -ChatBot::ChatBot(ChatBot&& cb) -{ - std::cout << "ChatBot move constructor" << std::endl; - delete _image; - delete _chatLogic; + // image is owned, so we allocate the memory and copy content + _image = new wxBitmap; + *_image = *source._image; - // load image into heap memory - _image = std::move(cb.GetImageHandle()); - _chatLogic = std::move(cb.GetChatLogicHandle()); + // not-owned, so we just copy pointers + _currentNode = source._currentNode; + _rootNode = source._rootNode; + _chatLogic = source._chatLogic; } -ChatBot& ChatBot::operator=(ChatBot& cb) -{ - std::cout << "ChatBot copy assignment operator" << std::endl; - if (this == &cb) - { - return *this; +ChatBot& ChatBot::operator=(const ChatBot &source) { + std::cout << "ChatBot Copy Assignment" << std::endl; + if (this == &source) { + return *this; } - delete[] this; - _image = new wxBitmap(); - _image = cb.GetImageHandle(); - _chatLogic = cb.GetChatLogicHandle(); + delete _image; + _image = new wxBitmap; + *_image = *source._image; + + _currentNode = source._currentNode; + _rootNode = source._rootNode; + _chatLogic = source._chatLogic; return *this; } -ChatBot& ChatBot::operator=(ChatBot&& cb) -{ - std::cout << "ChatBot move assignment operator" << std::endl; - delete[] this; +ChatBot::ChatBot(ChatBot &&source) noexcept { + std::cout << "ChatBot Move Constructor" << std::endl; + _image = source._image; + _currentNode = source._currentNode; + _rootNode = source._rootNode; + _chatLogic = source._chatLogic; + + source._image = nullptr; + source._currentNode = nullptr; + source._rootNode = nullptr; + source._chatLogic = nullptr; +} + +ChatBot& ChatBot::operator=(ChatBot &&source) noexcept { + std::cout << "ChatBot Move Assignment" << std::endl; + if (this == &source) { + return *this; + } + + delete _image; + _image = new wxBitmap; + *_image = *source._image; + + _currentNode = source._currentNode; + _rootNode = source._rootNode; + _chatLogic = source._chatLogic; - _image = std::move(cb.GetImageHandle()); - _chatLogic = std::move(cb.GetChatLogicHandle()); - return *this; } - //// //// EOF STUDENT CODE diff --git a/src/chatbot.h b/src/chatbot.h index acaa66014..f5ec03f5f 100644 --- a/src/chatbot.h +++ b/src/chatbot.h @@ -29,11 +29,11 @@ class ChatBot //// STUDENT CODE //// - - ChatBot(ChatBot& cb); - ChatBot(ChatBot&& cb); - ChatBot& operator=(ChatBot& cb); - ChatBot& operator=(ChatBot&& cb); + ChatBot(const ChatBot &source); + ChatBot& operator=(const ChatBot &source); + ChatBot(ChatBot &&source) noexcept; + ChatBot& operator=(ChatBot &&source) noexcept; + //// //// EOF STUDENT CODE From 389caf6ef08d09ab4282224b46172f7338040f94 Mon Sep 17 00:00:00 2001 From: sol981 Date: Mon, 1 Apr 2024 20:57:59 +0700 Subject: [PATCH 7/7] fix bug move edge instead of copy it --- src/chatlogic.cpp | 15 --------------- src/graphnode.cpp | 5 +---- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/src/chatlogic.cpp b/src/chatlogic.cpp index 1e4f302bc..9162c3fd4 100644 --- a/src/chatlogic.cpp +++ b/src/chatlogic.cpp @@ -17,12 +17,6 @@ ChatLogic::ChatLogic() //// STUDENT CODE //// - // create instance of chatbot - // _chatBot = new ChatBot("../images/chatbot.png"); - - // // add pointer to chatlogic so that chatbot answers can be passed on to the GUI - // _chatBot->SetChatLogicHandle(this); - //// //// EOF STUDENT CODE } @@ -32,15 +26,6 @@ ChatLogic::~ChatLogic() //// STUDENT CODE //// - // delete chatbot instance - // delete _chatBot; - - // delete all nodes - // for (auto it = std::begin(_nodes); it != std::end(_nodes); ++it) - // { - // (*it).reset(); - // } - //// //// EOF STUDENT CODE } diff --git a/src/graphnode.cpp b/src/graphnode.cpp index 9a115e688..ed5964f26 100644 --- a/src/graphnode.cpp +++ b/src/graphnode.cpp @@ -11,9 +11,6 @@ GraphNode::~GraphNode() //// STUDENT CODE //// - // delete _chatBot; - // _chatBot.reset(); - //// //// EOF STUDENT CODE } @@ -30,7 +27,7 @@ void GraphNode::AddEdgeToParentNode(const std::shared_ptr &edge) void GraphNode::AddEdgeToChildNode(std::shared_ptr edge) { - _childEdges.push_back(edge); + _childEdges.push_back(std::move(edge)); } //// STUDENT CODE