In order to send messages between two objects of class!
I implemented a blocking queue that manages the synchronization between two threads to push and pop a message in a synchronized way.
this is the blocking queue class :
template <typename T>
class BlockingQueue
{
public:
void push(T const& val)
{
{
std::unique_lock<std::mutex> lck_(this->m_);
queue_.push(val);
}
this->cv_.notify_one()
}
T pop()
{
std::unique_lock<std::mutex> lck_(this->m_);
while (this->queue_.empty())
{
this->cv_.wait(lck_)
}
T value(std::move(this->queue_.pop()));
this->queue_.pop();
return value;
}
private:
std::mutex m_;
std::condition_variable cv_;
std::queue<T> queue_;
};
BlockingQueue<string> sentQueue = BlockingQueue<string>();
BlockingQueue<string> receivedQueue = BlockingQueue<string>();
class Player
{
public:
virtual void run()
{
while (true)
{
string receivedMessage = receiveMessage();
sendMessage(receivedMessage);
}
}
virtual void sendMessage(string message)
{
sentQueue.push(reply);
};
virtual string receiveMessage()
{
string receivedMessage;
receivedMessage = receivedQueue.pop();
return receivedMessage;
};
private:
};
What I am asking now is where to instantiate this blocking queue to use it between the two objects (Player 1 and Player 2) in order to exchange messages between them
CodePudding user response:
You have a global send queue and a global receive queue. What you need is a receive queue per player.
Have a send method on the player class that writes to their send queue
So player 1 would go
player2.Send("hello player2");
How to do it
class Player
{
BlockingQueue<string> queue_ = BlockingQueue<string>();
public:
void Post(const string& message){
queue_.push(message);
}
virtual void run()
{
while (true)
{
string msg= queue_.pop();
// do something with the message
if(msg == "BangBang")
{
}
}
}
now you can go
Player player1("player1");
Player player2("player2");
thread thread1(&Player::run, player1);
thread thread2(&Player::run, player2);
player1.Post("BangBang");
Probably you should make you message more that a string, something like
class Message{
Player* sender;
string text;
CommandType ct;
}
or have a string syntax like "player1/shoot/0,5"
you need to know who the message cam from so you can react correctly and maybe reply
or maybe the post method is called on the sending player object and includes the destination user. Using my suggested Message class
class Player
{
BlockingQueue<Message> queue_ = BlockingQueue<Message>();
public:
void Post(const string& message, Player *dest){
Message msg;
msg.sender= this; // sender
msg.text = message;
dest->queue_.push(message);
}
virtual void run()
{
while (true)
{
Message msg= queue_.pop();
// do something with the message
if(msg.Text == "BangBang")
{
/// check for hit
// reply to sender
Post("you got me", msg.sender);
}
}
}
now
Player player1("player1");
Player player2("player2");
thread thread1(&Player::run, player1);
thread thread2(&Player::run, player2);
player2.Post("BangBang", &player1); // send message to player2 (from 1)