Home > Software engineering >  Using blockingqueue Between two object of class
Using blockingqueue Between two object of class

Time:05-06

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)
  • Related