Commit f6038a61 authored by neverlord's avatar neverlord

documentation

parent 27746169
......@@ -9,6 +9,11 @@
namespace cppa {
/**
* @addtogroup TypeSystem
* @{
*/
/**
* @brief A simple example for @c announce with public accessible members.
*
......@@ -49,6 +54,12 @@ namespace cppa {
* @example announce_example_4.cpp
*/
/**
* @brief An advanced example for @c announce implementing serialization
* for a user-defined tree data type.
* @example announce_example_5.cpp
*/
/**
* @brief Adds a new type mapping to the libcppa type system.
* @param tinfo C++ RTTI for the new type
......@@ -107,6 +118,10 @@ inline bool announce(const Args&... args)
new detail::default_uniform_type_info_impl<T>(args...));
}
/**
* @}
*/
} // namespace cppa
#endif // ANNOUNCE_HPP
......@@ -63,22 +63,42 @@
*
* @section Intro Introduction
*
* This library provides an implementation of the Actor model for C++.
* This library provides an implementation of the actor model for C++.
* It uses a network transparent messaging system to ease development
* of both concurrent and distributed software using C++.
*
* @p libcppa uses a thread pool to schedule actors by default.
* A scheduled actor should not call blocking functions.
* Individual actors can be spawned (created) with a special flag to run in
* an own thread if needed.
* an own thread if one needs to make use of blocking APIs.
*
* In @p libcppa, each context is an actor. Even main is implicitly
* converted to an actor if needed.
* Writing applications in @p libcppa requires a minimum of gluecode.
* You don't have to derive a particular class to implement an actor and
* each context <i>is</i> an actor. Even main is implicitly
* converted to an actor if needed, as the following example shows:
*
* @subsection IntroHelloWorld Hello World Example
*
* @include hello_world_example.cpp
*
* @section GettingStarted Getting started with libcppa
* @section GettingStarted Getting Started
*
* To build @p libcppa, you need <tt>GCC >= 4.6</tt>, @p Automake
* and the <tt>Boost.Thread</tt> library.
*
* The usual build steps on Linux and Mac OS X are:
*
* - <tt>autoreconf -i</tt>
* - <tt>./configure</tt>
* - <tt>make</tt>
* - <tt>make install</tt> (as root, optionally)
*
* Use <tt>./configure --help</tt> if the script doesn't auto-select
* the correct @p GCC binary or doesn't find your <tt>Boost.Thread</tt>
* installation.
*
* Windows is not supported yet, because MVSC++ doesn't implement the
* C++11 features needed to compile @p libcppa.
*
* @namespace cppa
* @brief This is the root namespace of libcppa.
......@@ -160,13 +180,12 @@
*
* receive
* (
* // equal to on(std::string("hello actor!"))
* // equal to: on(std::string("hello actor!"))
* on("hello actor!") >> []() { }
* );
* @endcode
*/
namespace cppa {
/**
......
......@@ -11,6 +11,10 @@ namespace cppa {
class object;
/**
* @ingroup Serialize
* @brief Technology-independent deserialization interface.
*/
class deserializer
{
......@@ -24,8 +28,8 @@ class deserializer
virtual ~deserializer();
/**
* @brief Seeks the beginning of the next object and return its
* uniform type name.
* @brief Seeks the beginning of the next object and return
* its uniform type name.
*/
virtual std::string seek_object() = 0;
......@@ -35,15 +39,43 @@ class deserializer
*/
virtual std::string peek_object() = 0;
/**
* @brief Begins deserialization of an object of type @p type_name.
* @param type_name The platform-independent @p libcppa type name.
*/
virtual void begin_object(const std::string& type_name) = 0;
/**
* @brief Ends deserialization of an object.
*/
virtual void end_object() = 0;
/**
* @brief Begins deserialization of a sequence.
* @returns The size of the sequence.
*/
virtual size_t begin_sequence() = 0;
/**
* @brief Ends deserialization of a sequence.
*/
virtual void end_sequence() = 0;
/**
* @brief Reads a primitive value from the data source of type @p ptype.
* @param ptype Expected primitive data type.
* @returns A primitive value of type @p ptype.
*/
virtual primitive_variant read_value(primitive_type ptype) = 0;
virtual void read_tuple(size_t size,
/**
* @brief Reads a tuple of primitive values from the data
* source of the types @p ptypes.
* @param num The size of the tuple.
* @param ptype Array of expected primitive data types.
* @param storage Array of size @p num, storing the result of this function.
*/
virtual void read_tuple(size_t num,
const primitive_type* ptypes,
primitive_variant* storage ) = 0;
......
......@@ -9,9 +9,17 @@
namespace cppa {
/**
* @defgroup Serialize Serialization of custom data types.
*/
// forward declaration
class primitive_variant;
/**
* @ingroup Serialize
* @brief Technology-independent serialization interface.
*/
class serializer
{
......@@ -24,23 +32,40 @@ class serializer
virtual ~serializer();
/**
* @brief Begins serialization of an object of the type
* named @p type_name.
* @param type_name The platform-independent @p libcppa type name.
*/
virtual void begin_object(const std::string& type_name) = 0;
/**
* @brief Ends serialization of an object.
*/
virtual void end_object() = 0;
virtual void begin_sequence(size_t size) = 0;
/**
* @brief Begins serialization of a sequence of size @p num.
*/
virtual void begin_sequence(size_t num) = 0;
/**
* @brief Ends serialization of a sequence.
*/
virtual void end_sequence() = 0;
/**
* @brief Writes a single value.
* @brief Writes a single value to the data sink.
* @param value A primitive data value.
*/
virtual void write_value(const primitive_variant& value) = 0;
/**
* @brief Writes @p size values.
* @brief Writes @p num values as a tuple to the data sink.
* @param num Size of the array @p values.
* @param values An array of size @p num of primitive data values.
*/
virtual void write_tuple(size_t size, const primitive_variant* values) = 0;
virtual void write_tuple(size_t num, const primitive_variant* values) = 0;
};
......
......@@ -26,6 +26,83 @@ class uniform_type_info;
const uniform_type_info* uniform_typeid(const std::type_info&);
/**
* @defgroup TypeSystem libcppa's platform-independent type system.
*
* @p libcppa provides a fully network transparent communication between
* actors. Thus, @p libcppa needs to serialize and deserialize message objects.
* Unfortunately, this is not possible using the C++ RTTI system.
*
* Since it is not possible to extend <tt>std::type_info</tt>, @p libcppa
* uses its own type abstraction:
* {@link cppa::uniform_type_info uniform_type_info}.
*
* Unlike <tt>std::type_info::name()</tt>,
* {@link cppa::uniform_type_info::name() uniform_type_info::name()}
* is guaranteed to return the same name on all supported platforms.
* Furthermore, it allows to create an instance of a type by name:
*
* @code
* // creates a signed, 32 bit integer
* cppa::object i = cppa::uniform_type_info::by_uniform_name("@i32")->create();
* @endcode
*
* However, you should rarely if ever need to use {@link cppa::object object}
* or {@link cppa::uniform_type_info uniform_type_info}.
*
* There is one exception, though, where you need to care about
* <tt>libcppa</tt>'s type system: using custom data types in messages.
* The source code below compiles fine, but crashes with an exception during
* runtime.
*
* @code
* #include "cppa/cppa.hpp"
* using namespace cppa;
*
* struct foo { int a; int b; };
*
* int main()
* {
* send(self(), foo{1,2});
* return 0;
* }
* @endcode
*
* Depending on your platform, the error message looks somewhat like this:
*
* <tt>
* terminate called after throwing an instance of 'std::runtime_error'
* <br>
* what(): uniform_type_info::by_type_info(): foo is an unknown typeid name
* </tt>
*
* The user-defined struct @p foo is not known by the @p libcppa type system.
* Thus, @p libcppa is unable to serialize/deserialize @p foo and rejects it.
*
* Fortunately, there is an easy way to add @p foo the type system,
* without needing to implement serialize/deserialize by yourself:
*
* @code
* cppa::announce<foo>(&foo::a, &foo::b);
* @endcode
*
* {@link cppa::announce announce()} takes the class as template
* parameter and pointers to all members (or getter/setter pairs)
* as arguments. This works for all primitive data types and STL compliant
* containers. See the announce {@link announce_example_1.cpp example 1},
* {@link announce_example_2.cpp example 2},
* {@link announce_example_3.cpp example 3} and
* {@link announce_example_4.cpp example 4} for more details.
*
* Obviously, there are limitations. If your class does implement
* an unsupported data structure, you have to implement serialize/deserialize
* by yourself. {@link announce_example_5.cpp Example 5} shows, how to
* announce a tree data structure to the @p libcppa type system.
* Make sure to read the @ref Serialize "serialization section" of
* this documentation before.
*/
/**
* @ingroup TypeSystem
* @brief Provides a platform independent type name and a (very primitive)
* kind of reflection in combination with {@link cppa::object object}.
*
......@@ -40,7 +117,6 @@ const uniform_type_info* uniform_typeid(const std::type_info&);
* - the <em>anonymous namespace</em> is named @c \@_ \n
* e.g.: <tt>namespace { class foo { }; }</tt> is mapped to
* @c \@_::foo
* - {@link cppa::util::void_type} is named @c \@0
*/
class uniform_type_info : cppa::util::comparable<uniform_type_info>
{
......@@ -103,7 +179,7 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
/**
* @brief Get instance by uniform name.
* @param uniform_name The libCPPA internal name for a type.
* @param uniform_name The @p libcppa internal name for a type.
* @returns The instance associated to @p uniform_name.
*/
static uniform_type_info* by_uniform_name(const std::string& uniform_name);
......@@ -117,8 +193,8 @@ class uniform_type_info : cppa::util::comparable<uniform_type_info>
virtual ~uniform_type_info();
/**
* @brief Get the internal libCPPA name for this type.
* @returns A string describing the libCPPA internal type name.
* @brief Get the internal @p libcppa name for this type.
* @returns A string describing the @p libcppa internal type name.
*/
inline const std::string& name() const { return m_name; }
......
......@@ -2,7 +2,7 @@
* This example shows how to implement serialize/deserialize to announce *
* non-trivial data structures to the libcppa type system. *
* *
* However, announce() auto-detects STL compliant containers and provides *
* Announce() auto-detects STL compliant containers and provides *
* an easy way to tell libcppa how to serialize user defined types. *
* See announce_example 1-4 for usage examples. *
* *
......@@ -78,7 +78,7 @@ struct tree
};
// tree node are equals if values and all values of all children are equal
// tree nodes are equals if values and all values of all children are equal
bool operator==(const tree_node& lhs, const tree_node& rhs)
{
if (lhs.value == rhs.value && lhs.children.size() == rhs.children.size())
......@@ -145,26 +145,27 @@ class tree_type_info : public util::abstract_uniform_type_info<tree>
void serialize_node(const tree_node& node, serializer* sink) const
{
// serialize { value, number of children } ... children ...
std::uint32_t num_children = node.children.size();
sink->write_value(node.value);
sink->write_value(num_children);
sink->begin_sequence(node.children.size());
for (const tree_node& subnode : node.children)
{
serialize_node(subnode, sink);
}
sink->end_sequence();
}
void deserialize_node(tree_node& node, deserializer* source) const
{
// deserialize { value, number of children } ... children ...
auto value = get<std::uint32_t>(source->read_value(pt_uint32));
auto num_children = get<std::uint32_t>(source->read_value(pt_uint32));
node.value = value;
for (std::uint32_t i = 0; i < num_children; ++i)
auto num_children = source->begin_sequence();
for (size_t i = 0; i < num_children; ++i)
{
node.add_child();
deserialize_node(node.children.back(), source);
}
source->end_sequence();
}
};
......@@ -203,10 +204,12 @@ int main()
on<tree>() >> [](const tree& tmsg)
{
// prints the tree in its serialized format:
// @<> ( { tree ( 0, 2, 10, 3, 11, 0, 12, 0, 13, 0, 20, 2, 21, 0, 22, 0 ) } )
cout << "to_string(last_received()): " << to_string(last_received())
// @<> ( { tree ( 0, { 10, { 11, { }, 12, { }, 13, { } }, 20, { 21, { }, 22, { } } } ) } )
cout << "to_string(last_received()): "
<< to_string(last_received())
<< endl;
// prints: 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } }
// prints the tree using the print member function:
// 0 { 10 { 11, 12, 13 } , 20 { 21, 22 } }
tmsg.print();
}
);
......
......@@ -14,7 +14,7 @@ void echo_actor()
{
// prints "Hello World!"
std::cout << what << std::endl;
// reply "!dlroW olleH"
// replies "!dlroW olleH"
reply(std::string(what.rbegin(), what.rend()));
}
);
......@@ -32,6 +32,7 @@ int main()
(
on<std::string>() >> [](const std::string& what)
{
// prints "!dlroW olleH"
std::cout << what << std::endl;
}
);
......
......@@ -109,6 +109,7 @@ class string_serializer : public serializer
void end_sequence()
{
out << (m_after_value ? " }" : "}");
m_after_value = true;
}
void write_value(const primitive_variant& value)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment