Wednesday, December 7, 2011

Documentation

Finally! The section about message handling is done and the doxygen documentation is now online at github pages: http://neverlord.github.com/libcppa/.

Send me a mail or leave a comment if you miss something important.
Have fun!

7 comments:

  1. This is really great! Your library would be totally useless without a good doc, since it's so much different from any "common" library. It really looks like more a new language integrated in C++ then a library.

    You often speak about network transparency and automatic serialization of objects. Is that feature already working?
    I am very interested in this as I need to use a networking-friendly actor library. I was thinking to roll my own simple implementation but yours look really fully-featured.

    On a side note, I still don't fully grasp what can be done with your "receive" construct (like what the limits are? Can I "nest" receive constructs?), but that I will ask another time.

    ReplyDelete
  2. I designed libcppa as an internal DSL, so it was my intention to give it that feeling. I think it makes the code much simpler, shorter and cleaner. Sadly, there are clear limitations in C++ for internal DSL. Just have a look at the receive_while statement. Using a lambda as condition is the best you can do (and no: macro-magic is not an option). But it polluts your source code with brackets and a return. One cannot come closer to a "native" while loop in C++ unlike Scala btw. where you can implement a library that is looking like a language extension or even another language: http://www.scala-lang.org/node/1403.

    Network transparency is implemented and working. All you need to do is to "publish" an actor to a port. Afterwards, you use "remote_actor" to get an actor_ptr to the published actor. I don't have an example now but it's really simple:

    auto my_actor = spawn(...);
    publish(my_actor, 4242);

    ... (an another process or node) ...
    auto my_actor = remote_actor("localhost", 4242);


    To answer your side node question: there are no limitations. You can nest receives as much as you like since actors do have their own stacks.

    ReplyDelete
  3. One other question: can I make an actor out of a class? For example, I might want to have my actor to call methods of my class, and such.
    Sure I can create a local instance of my class inside the function used when creating an actor, and then call methods by m_instance.myMethod(), but I don't like it very much...
    Also, is there any better place then those comments for asking questions? I also found a little problem when compiling (make stops at the examples, easily fixable I think), but I prefer not to post long messages here.

    ReplyDelete
  4. Nevermind, I needed to read the docs with more attention: you can use functors with spawn, so yes, you can use your own class as actors. Just one question: when I spawn an actor by using a functor, a brand new copy instance is created using the copy constructor, right? So if I want I can then delete the object used in spawn with no risks. (EG: going out of scope!)

    ReplyDelete
  5. Ah. This feature recently changed (git pull!) so I couldn't update the documentation yet. However, there is a class called "scheduled_actor". Derive this class if you want to use a class-based actor implementation. A short snippet:

    #include
    #include
    #include "cppa/cppa.hpp"
    using namespace cpp;

    class my_actor : public scheduled_actor
    {

    public:

    void act()
    {
    receive
    (
    on() >> [](const std::string& str)
    {
    std::cout << "hello " << str << std::endl;
    }
    );
    }

    void on_exit()
    {
    // ... some cleanup code ...
    // do not send or receive message here any longer!

    }

    };

    int main()
    {
    auto a = spawn(new my_actor);
    send(a, atom("hello"), "world");
    return 0;
    }


    But It's also fine to use a functor. You should be able to use a move constructor to avoid unnecessary copies. However, if not moved to the scheduler, the functor is copied, yes. No dangling pointer.

    There is also a second way to implement class-based actors that uses event-based message processing. There'll be a blog post and a documentation update soon. :)

    Btw, you just can send me emails if you don't want to post here or create a ticket on github if you find a bug.

    ReplyDelete
  6. Sorry, I messed up formatting:

    #include <string>
    #include <iostream>
    #include "cppa/cppa.hpp"
    using namespace cpp;

    class my_actor : public scheduled_actor
    {

     public:

        void act()
        {
            receive
            (
                on() >> [](const std::string& str)
                {
                    std::cout << "hello " << str << std::endl;
                }
            );
        }

        void on_exit()
        {
            // ... some cleanup code ...
            // do not send or receive message here any longer!
        }

    };

    int main()
    {
        auto a = spawn(new my_actor);
        send(a, atom("hello"), "world");
        return 0;
    }

    ReplyDelete
    Replies
    1. ChangeNote for version 0.2: You have to subtype context_switching_actor and override run() instead of act(). However, I would recommend to use always event_based_actor for performance reasons.

      Delete