Skip to content

Instantly share code, notes, and snippets.

Created January 3, 2013 20:06
Show Gist options
  • Save anonymous/4446649 to your computer and use it in GitHub Desktop.
Save anonymous/4446649 to your computer and use it in GitHub Desktop.
/* 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