Appendix F. Example Listings

Table of Contents

F.1. Creating Managed Class

This chapter contains listings of all example sources stored in the src/example directory.

F.1. Creating Managed Class

Listings of examples described in Chapter 13, Creating Managed Class. Their sources are in src/example/server_lib.

Example F.1. makefile.gen
    (1)  # "Creating Managed Class" example.
    (2)  # mkgen.pl will generate makefiles for selected platforms from this file.
    (3)
    (4)  # Required for all C++ projects.
    (5)
    (6)  STDCPP
    (7)
    (8)  # Include makefile.gen part generated by genmkgen.pl from idl.list.
    (9)
   (10)  include makefile_idl.gen
   (11)
   (12)  # Directories to include from.
   (13)
   (14)  includes = . ../../core
   (15)
   (16)  # Precompile the massive core.h header if the compiler supports it.
   (17)
   (18)  precompile = core.h
   (19)
   (20)  # Create a library in this directory, containing objects compiled from
   (21)  # all C++ sources, including the generated sources. This library will
   (22)  # reference symbols from the Massiv Core shared library.
   (23)
   (24)  library example_lib_server
   (25)      sources = *.cpp
   (26)      sources += @GENERATED_SOURCES@
   (27)      shlibs = ../../core/massiv
   (28)  endlibrary

Example F.2. idl.list
    (1)  # "Creating Managed Class" example.
    (2)  # Contents of this file are read by genmkgen.pl which
    (3)  # generates parts of makefile.gen.
    (4)
    (5)  # We use managed classes from the Core library.
    (6)
    (7)  depends ../../core
    (8)
    (9)  # List of files containing descriptions of managed classes.
   (10)
   (11)  idl hello_interface.idl
   (12)  idl hello.idl
   (13)
   (14)  # This not the main managed class library,
   (15)  # so do not generate a class list here.
   (16)  #class_list SHARED SERVER

Example F.3. hello_interface.idl
    (1)  #import "core.idl"
    (2)
    (3)  namespace example {
    (4)
    (5)  class
    (6)      <
    (7)      abstract,
    (8)      kind = SERVER,
    (9)      root
   (10)      >
   (11)      HelloInterface : ::Massiv::Core::Object
   (12)      {
   (13)      method< virtual > hello
   (14)          (
   (15)          in string callee_name
   (16)          ) : string;
   (17)      }
   (18)
   (19)  } // namespace example

Example F.4. hello_interface.h
    (1)  #ifndef EXAMPLE_HELLO_INTERFACE_H
    (2)  #define EXAMPLE_HELLO_INTERFACE_H
    (3)
    (4)  #ifndef MASSIV_CORE_H
    (5)  #include "core.h"
    (6)  #endif
    (7)
    (8)  #include <string>
    (9)
   (10)  namespace example {
   (11)  /**
   (12)   * Interface of hello classes.
   (13)   *
   (14)   * This is generic interface of all classes that implement the
   (15)   * hello() method.
   (16)   *
   (17)   * As described in the IDL, all Hello classes should be root objects
   (18)   * of KIND_SERVER kind.
   (19)   */
   (20)  class HelloInterface : public ::Massiv::Core::Object
   (21)      {
   (22)  public:
   (23)
   (24)      /**
   (25)       * The "say hello" method.
   (26)       *
   (27)       * It should generate a hello message for the callee @a callee_name,
   (28)       * print it anywhere it wants and return it.
   (29)       */
   (30)      virtual std::string hello
   (31)          (
   (32)          const std::string & callee_name
   (33)          ) = 0;
   (34)
   (35)      }; // class HelloInterface
   (36)
   (37)  } // namespace example
   (38)
   (39)  #endif // EXAMPLE_HELLO_INTERFACE_H

Example F.5. hello.idl
    (1)  #import "hello_interface.idl"
    (2)
    (3)  namespace example {
    (4)
    (5)  class
    (6)      <
    (7)      simulation_startup_notify
    (8)      >
    (9)      Hello : HelloInterface
   (10)      {
   (11)      method register_to_naming
   (12)          (
   (13)          in string name
   (14)          ) : bool;
   (15)
   (16)      property string   name;
   (17)      property vlint32  total_call_count;
   (18)      property vlint32  current_call_count;
   (19)      }
   (20)
   (21)  } // namespace example

Example F.6. hello.h
    (1)  #ifndef EXAMPLE_HELLO_H
    (2)  #define EXAMPLE_HELLO_H
    (3)
    (4)  #ifndef MASSIV_CORE_H
    (5)  #include "core.h"
    (6)  #endif
    (7)
    (8)  #ifndef EXAMPLE_HELLO_INTERFACE_H
    (9)  #include "hello_interface.h"
   (10)  #endif
   (11)
   (12)  namespace example {
   (13)
   (14)  /**
   (15)   * Simple implementation of the HelloInterface.
   (16)   */
   (17)  class Hello : public HelloInterface
   (18)      {
   (19)  public:
   (20)
   (21)      /**
   (22)       * Object initialization.
   (23)       *
   (24)       * The internal name of the object (not to be confused with
   (25)       * name under which it's registered to the garbarge collector)
   (26)       * will be set to @a the_name.
   (27)       */
   (28)      void initialize
   (29)          (
   (30)          const std::string & the_name
   (31)          );
   (32)
   (33)      /**
   (34)       * The "say hello" method.
   (35)       *
   (36)       * The message generated by this implementation will contain
   (37)       * the callee name, name of the Hello object, and counters
   (38)       * indicating how many times this method has been called since
   (39)       * creation of this object and since last simulation startup.
   (40)       */
   (41)      virtual std::string hello
   (42)          (
   (43)          const std::string & callee_name
   (44)          );
   (45)
   (46)      /**
   (47)       * Register the object to global naming service.
   (48)       *
   (49)       * This method will change name of the object to @a the_name,
   (50)       * and try to register the object to the global naming service
   (51)       * under that name. If the registration fails it will destroy
   (52)       * the object.
   (53)       *
   (54)       * @note This method will fail unless the example library is
   (55)       *       linked with the Massiv Demo. However, because it uses
   (56)       *       dynamic RPC, it can be compiled without the library.
   (57)       */
   (58)      bool register_to_naming
   (59)          (
   (60)          const std::string & the_name
   (61)          );
   (62)
   (63)  protected:
   (64)
   (65)      /**
   (66)       * Object update callback.
   (67)       */
   (68)      virtual void object_updated
   (69)          (
   (70)          UpdateReason reason
   (71)          );
   (72)
   (73)  public:
   (74)
   (75)      Massiv::Core::PString   name;
   (76)          /**< Internal name of the object.
   (77)               It's used to print the hello message and to register
   (78)               the object to the global naming service. */
   (79)
   (80)      Massiv::Core::PVlInt32  total_call_count;
   (81)          /**< Number of calls to hello() since object creation. */
   (82)
   (83)      Massiv::Core::PVlInt32  current_call_count;
   (84)          /**< Number of calls to hello() since node startup. */
   (85)
   (86)      }; // class Hello
   (87)
   (88)  } // namespace example
   (89)
   (90)  #endif // EXAMPLE_HELLO_H

Example F.7. hello.cpp
    (1)  #include "core.h"
    (2)  #include "hello.h"
    (3)  #include "database/well_known_object_id_database.h"
    (4)  #include <sstream>
    (5)
    (6)  using namespace Massiv::Core;
    (7)
    (8)  namespace example {
    (9)
   (10)  void Hello::initialize
   (11)      (
   (12)      const std::string & the_name
   (13)      )
   (14)      {
   (15)      name = the_name;
   (16)      }
   (17)
   (18)  std::string Hello::hello
   (19)      (
   (20)      const std::string & callee_name
   (21)      )
   (22)      {
   (23)      std::ostringstream oss;
   (24)      oss << "Hello to " << callee_name << " from " << name << std::endl;
   (25)      oss << "(called " << total_call_count << " times, " <<
   (26)             current_call_count << " since startup)" << std::endl;
   (27)      const std::string s = oss.str();
   (28)
   (29)      total_call_count++;
   (30)      current_call_count++;
   (31)
   (32)      Global::log_info( Status::FACILITY_LIB, Status::PRIORITY_LOW, s );
   (33)      return s;
   (34)      }
   (35)
   (36)  bool Hello::register_to_naming
   (37)      (
   (38)      const std::string & the_name
   (39)      )
   (40)      {
   (41)      initialize( the_name );
   (42)
   (43)      const WeakPointer< Object > self( this );
   (44)      bool failed = true;
   (45)      try
   (46)          {
   (47)          const ObjectId naming_id = Global::well_known_object_id_database().
   (48)              get_naming_service_object();
   (49)          const Remote< Object > naming( naming_id );
   (50)
   (51)          const MetaObject * const metaobject = Global::class_manager().
   (52)              get_metaobject( "Demo::Lib::NamingService" );
   (53)
   (54)          std::stringstream ss;
   (55)          {
   (56)          TextWriter tw( ss );
   (57)          const Serializer::Description desc;
   (58)          name.text_write( tw, desc );
   (59)          tw.write_space();
   (60)          self.text_write( tw, desc );
   (61)          tw.write_space();
   (62)          const SBool replace = false;
   (63)          replace.text_write( tw, desc );
   (64)          }
   (65)
   (66)          TextReader tr( ss );
   (67)          std::auto_ptr< MethodPacket > results = metaobject->
   (68)              remote_call_method( naming, "register_object", tr );
   (69)
   (70)          if( results->get_argument_value( -1 ) == "true" )
   (71)              {
   (72)              failed = false;
   (73)              }
   (74)          else
   (75)              {
   (76)              std::ostringstream oss;
   (77)              oss << "Object " << name << " already registered "
   (78)                     " to the global naming service." << std::endl;
   (79)              Global::log_warning( Status::FACILITY_LIB,
   (80)                  Status::PRIORITY_HIGH, oss.str() );
   (81)              }
   (82)          }
   (83)      catch( std::exception & e )
   (84)          {
   (85)          std::ostringstream oss;
   (86)          oss << "Failed to register " << name << " to naming service: "
   (87)              << e.what();
   (88)          Global::log_warning( Status::FACILITY_LIB,
   (89)              Status::PRIORITY_HIGH, oss.str() );
   (90)          }
   (91)
   (92)      if( failed )
   (93)          {
   (94)          Massiv::System::dispose_gc_root( self );
   (95)          }
   (96)      return failed ? false : true;
   (97)      }
   (98)
   (99)  void Hello::object_updated
  (100)      (
  (101)      UpdateReason reason
  (102)      )
  (103)      {
  (104)      if( reason == SIMULATION_STARTUP )
  (105)          {
  (106)          current_call_count = 0;
  (107)          }
  (108)      }
  (109)
  (110)  } // namespace example