Created
January 3, 2013 20:06
-
-
Save anonymous/4446649 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* You could have an actor base class with a protected `receive` and a public `send` function, | |
* which pull and push (respectively) messages out of and into the message queue. Each actor | |
* has a message queue. You then inherit that class and override a virtual function `run`, | |
* which is on a separate thread. | |
*/ | |
// abstract actor base class | |
template<class Message> | |
class actor { | |
public: | |
actor() { | |
/* Because of C++, we are fucked; we cannot call a virtual function from ctor. This | |
* needs to be done in some other way. | |
*/ | |
std::thread thread{[this] { | |
run(); // whoops | |
}}; | |
} | |
virtual ~actor() = default; | |
void send(Message message) { | |
msg_queue.push(message); | |
} | |
void join() { | |
// FIXME: Join thread. | |
} | |
protected: | |
virtual void run() = 0; | |
Message receive() { | |
// this function is blocking | |
return msg_queue.pull(); // removes front object and returns it | |
} | |
private: | |
atomic_queue<Message> msg_queue; | |
}; | |
struct car { | |
car() { | |
age = rand<unsigned>(); | |
weight = random<unsigned>(); | |
} | |
unsigned age, weight; | |
}; | |
// example: car server | |
class car_server : public actor<std::pair<actor&, std::string>> { | |
protected: | |
virtual void run() override { | |
car c; | |
for (;;) { | |
// read message and respond to it | |
auto message = receive(); | |
switch (message.second) { | |
case "get_age": message.first.send(car.age; break; | |
case "get_weight": message.first.send(car.weight); break; | |
case "buy_new_car": c = car{}; break; | |
default: break; // probably log error or send an error back to the consumer | |
} | |
} | |
} | |
}; | |
// example: car server client | |
class car_consumer : public actor<unsigned> { | |
protected: | |
virtual void run() override { | |
car_server srvr; | |
actr.send("get_age"); | |
std::cout << "Car age is " << receive() << '\n'; | |
actr.send("get_weight"); | |
std::cout << "Car weight is " << receive() << '\n'; | |
actr.send("buy_new_car"); | |
std::cout << "Buying a new car...\n"; | |
actr.send("get_age"); | |
std::cout << "Car age is " << receive() << '\n'; | |
actr.send("get_weight"); | |
std::cout << "Car weight is " << receive() << '\n'; | |
// now, consumer is done and exits | |
} | |
} | |
// example: using logger | |
int main() { | |
car_consumer consumer; | |
car_consumer.join(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment