aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordec05eba <dec05eba@protonmail.com>2018-12-31 12:01:59 +0100
committerdec05eba <dec05eba@protonmail.com>2018-12-31 12:02:02 +0100
commitfe4199dace73ee38262528f7ae88cbfba99120dd (patch)
tree154d3b6f09ee158d31a3dc29379bc906647629fc
parent3a5f81426395f1468e6d88e98da984a3fc2c2e78 (diff)
Make thread-safe
-rw-r--r--include/Window.hpp7
-rwxr-xr-xrun.sh2
-rw-r--r--src/Window.cpp135
-rwxr-xr-xtest.sh26
4 files changed, 134 insertions, 36 deletions
diff --git a/include/Window.hpp b/include/Window.hpp
index 4355fb8..645b578 100644
--- a/include/Window.hpp
+++ b/include/Window.hpp
@@ -10,6 +10,7 @@
#include <mutex>
#include <random>
#include <vector>
+#include <glibmm/dispatcher.h>
namespace dchat
{
@@ -22,7 +23,9 @@ namespace dchat
std::shared_ptr<Rooms> rooms;
WindowNotification *windowNotification;
private:
+ using DispatcherHandler = std::function<void()>;
bool drawBackground(const Cairo::RefPtr<Cairo::Context> &cairo);
+ void dispatchFunction(DispatcherHandler func);
private:
class OverlayDrawable : public Gtk::Overlay
{
@@ -53,5 +56,9 @@ namespace dchat
std::vector<Node> backgroundNodes;
int prevTimeMillis;
sigc::connection drawBackgroundConnection;
+
+ Glib::Dispatcher dispatcher;
+ std::mutex dispatcherMutex;
+ std::vector<DispatcherHandler> dispatcherHandlers;
};
} \ No newline at end of file
diff --git a/run.sh b/run.sh
index 3fca183..c66d369 100755
--- a/run.sh
+++ b/run.sh
@@ -1,5 +1,7 @@
#!/usr/bin/env bash
+set -e
+
script_path=`readlink -f $0`
script_dir=`dirname $script_path`
cd "$script_dir"
diff --git a/src/Window.cpp b/src/Window.cpp
index 5e4930f..255986a 100644
--- a/src/Window.cpp
+++ b/src/Window.cpp
@@ -68,7 +68,10 @@ namespace dchat
{
if(!rooms || !rooms->database)
{
- windowNotification->show("You are not connected to the bootstrap node yet! please wait...");
+ dispatchFunction([this]()
+ {
+ windowNotification->show("You are not connected to the bootstrap node yet! please wait...");
+ });
return;
}
@@ -76,17 +79,23 @@ namespace dchat
{
fprintf(stderr, "Trying to login with username %s\n", username.raw().c_str());
rooms->loginUser(username.raw(), password.raw());
- //windowNotification->show(Glib::ustring("Successfully logged in as ") + username);
- drawBackgroundConnection.disconnect();
- chatWindow.show();
- stack.set_visible_child(chatWindow);
- chatWindow.scrollToBottom();
+ dispatchFunction([this]()
+ {
+ //windowNotification->show(Glib::ustring("Successfully logged in as ") + username);
+ drawBackgroundConnection.disconnect();
+ chatWindow.show();
+ stack.set_visible_child(chatWindow);
+ chatWindow.scrollToBottom();
+ });
}
catch(std::exception &e)
{
Glib::ustring errMsg = "Failed to login, reason: ";
errMsg += e.what();
- windowNotification->show(errMsg);
+ dispatchFunction([this, errMsg]()
+ {
+ windowNotification->show(errMsg);
+ });
}
});
@@ -94,7 +103,10 @@ namespace dchat
{
if(!rooms || !rooms->database)
{
- windowNotification->show("You are not connected to the bootstrap node yet! please wait...");
+ dispatchFunction([this]()
+ {
+ windowNotification->show("You are not connected to the bootstrap node yet! please wait...");
+ });
return;
}
@@ -102,10 +114,13 @@ namespace dchat
{
fprintf(stderr, "Trying to register username %s\n", username.raw().c_str());
rooms->registerUser(username.raw(), password.raw());
- windowNotification->show(Glib::ustring("Successfully registered user ") + username);
- drawBackgroundConnection.disconnect();
- chatWindow.show();
- stack.set_visible_child(chatWindow);
+ dispatchFunction([this]()
+ {
+ //windowNotification->show(Glib::ustring("Successfully registered user ") + username);
+ drawBackgroundConnection.disconnect();
+ chatWindow.show();
+ stack.set_visible_child(chatWindow);
+ });
}
catch(std::exception &e)
{
@@ -113,13 +128,19 @@ namespace dchat
errMsg += username.raw();
errMsg += ", reason: ";
errMsg += e.what();
- windowNotification->show(errMsg);
+ dispatchFunction([this, errMsg]()
+ {
+ windowNotification->show(errMsg);
+ });
}
});
loginWindow.setRegisterPasswordMismatch([this]
{
- windowNotification->show("Passwords do not match");
+ dispatchFunction([this]()
+ {
+ windowNotification->show("Passwords do not match");
+ });
});
auto bootstrapNodes = getBootstrapNodesFromFile();
@@ -136,52 +157,87 @@ namespace dchat
roomCallbackFuncs.connectCallbackFunc = [this, bootstrapNode](std::shared_ptr<Rooms> rooms, const char *errMsg)
{
this->rooms = rooms;
- if(rooms)
+ std::string errMsgStr = errMsg ? errMsg : "unknown";
+ dispatchFunction([this, bootstrapNode, errMsgStr]()
{
- loginWindow.show();
- stack.set_visible_child(loginWindow);
- std::string msg = "Connected to ";
- msg += *bootstrapNode;
- msg += ":27130";
- windowNotification->show(msg);
- loginWindow.loginUsernameInput.grab_focus();
- }
- else
- {
- std::string errMsgToShow = "Failed to connect to boostrap node, reason: ";
- errMsgToShow += errMsg;
- windowNotification->show(errMsgToShow);
- }
+ if(this->rooms)
+ {
+ loginWindow.show();
+ stack.set_visible_child(loginWindow);
+ std::string msg = "Connected to ";
+ msg += *bootstrapNode;
+ msg += ":27130";
+ windowNotification->show(msg);
+ loginWindow.loginUsernameInput.grab_focus();
+ }
+ else
+ {
+ std::string errMsgToShow = "Failed to connect to boostrap node, reason: ";
+ errMsgToShow += errMsgStr;
+ windowNotification->show(errMsgToShow);
+ }
+ });
};
roomCallbackFuncs.createRoomCallbackFunc = [this](std::shared_ptr<Room> room)
{
- chatWindow.addRoom(room);
+ dispatchFunction([this, room]()
+ {
+ chatWindow.addRoom(room);
+ });
};
roomCallbackFuncs.addUserCallbackFunc = [this](const RoomAddUserRequest &request)
{
- chatWindow.addUser(request);
+ dispatchFunction([this, request]()
+ {
+ chatWindow.addUser(request);
+ });
};
roomCallbackFuncs.addMessageCallbackFunc = [this](const RoomAddMessageRequest &request)
{
- chatWindow.addMessage(request);
+ dispatchFunction([this, request]()
+ {
+ chatWindow.addMessage(request);
+ });
};
roomCallbackFuncs.userChangeNicknameCallbackFunc = [this](const UserChangeNicknameRequest &request)
{
- chatWindow.setUserNickname(request);
+ dispatchFunction([this, request]()
+ {
+ chatWindow.setUserNickname(request);
+ });
};
roomCallbackFuncs.userChangeAvatarCallbackFunc = [this](const UserChangeAvatarRequest &request)
{
- chatWindow.setUserAvatar(request);
+ dispatchFunction([this, request]()
+ {
+ chatWindow.setUserAvatar(request);
+ });
};
roomCallbackFuncs.changeRoomNameCallbackFunc = [this](const RoomChangeNameRequest &request)
{
- chatWindow.changeRoomName(request);
+ dispatchFunction([this, request]()
+ {
+ chatWindow.changeRoomName(request);
+ });
};
roomCallbackFuncs.receiveInviteUserCallbackFunc = [this](const InviteUserRequest &request)
{
- chatWindow.addInviteRequest(request);
+ dispatchFunction([this, request]()
+ {
+ chatWindow.addInviteRequest(request);
+ });
};
+ dispatcher.connect([this]()
+ {
+ std::lock_guard<std::mutex> lock(dispatcherMutex);
+ for(DispatcherHandler &dispatcherHandler : dispatcherHandlers)
+ {
+ dispatcherHandler();
+ }
+ dispatcherHandlers.clear();
+ });
+
Rooms::connect(bootstrapNode->c_str(), 27130, roomCallbackFuncs);
backgroundRng.seed(std::random_device()());
@@ -222,6 +278,13 @@ namespace dchat
}
+ void Window::dispatchFunction(DispatcherHandler func)
+ {
+ std::lock_guard<std::mutex> lock(dispatcherMutex);
+ dispatcherHandlers.push_back(func);
+ dispatcher.emit();
+ }
+
static void drawNode(const Cairo::RefPtr<Cairo::Context> &cairo, double x, double y, double radius)
{
cairo->arc(x, y, radius, 0.0, 2.0 * M_PI);
diff --git a/test.sh b/test.sh
new file mode 100755
index 0000000..ad72ae2
--- /dev/null
+++ b/test.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+set -e
+
+if [ "$#" -ne 1 ]; then
+ echo "Expected 1 argument, a home path"
+ exit 1
+fi
+
+script_path=`readlink -f $0`
+script_dir=`dirname $script_path`
+cd "$script_dir"
+
+HOME="$1"
+if [ ! -f ~/.local/share/fonts/Lato-Regular.ttf ]; then
+ mkdir -p ~/.local/share/fonts
+ cp ./fonts/Lato-Regular.ttf ~/.local/share/fonts/Lato-Regular.ttf
+ fc-cache
+fi
+if [ ! -f ~/.local/share/fonts/Lato-Bold.ttf ]; then
+ mkdir -p ~/.local/share/fonts
+ cp ./fonts/Lato-Bold.ttf ~/.local/share/fonts/Lato-Bold.ttf
+ fc-cache
+fi
+platform=`sibs platform`
+env GTK_THEME=Adwaita:light gdb ./sibs-build/$platform/debug/dchat \ No newline at end of file