OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-cogserver / opencog / cogserver / server / Module.h

129 lines · c ref:
/*
 * opencog/cogserver/server/Module.h
 *
 * Copyright (C) 2008, 2011 OpenCog Foundation
 * Copyright (C) 2008, 2013, 2022 Linas Vepstas <linasvepstas@gmail.com>
 *
 * SPDX-License-Identifier: AGPL-3.0-or-later
 *
 * Modules are used by by the CogServer as a way of redirecting socket
 * I/O to a line-oriented API that allows module creators to respond to
 * input.  All the details of managing the socket are abstracted away
 * from the module author.
 */

#ifndef _OPENCOG_MODULE_H
#define _OPENCOG_MODULE_H

#include <opencog/atoms/base/Handle.h>

namespace opencog
{
/** \addtogroup grp_server
 *  @{
 */

/**
 * DECLARE_MODULE -- Declare a new module, called MODNAME
 * This macro implements the various routines to allow the module
 * system to work. See below for example use.
 */
#define DECLARE_MODULE(MODNAME)                                       \
    /* load/unload functions for the Module interface */              \
    extern "C" const char* opencog_module_id(void) {                  \
       return #MODNAME;                                               \
    }                                                                 \
    extern "C" Module * opencog_module_load(const Handle& hcsn) {     \
       return new MODNAME(hcsn);                                      \
    }                                                                 \
    extern "C" void opencog_module_unload(Module* m) {                \
       delete m;                                                      \
    }                                                                 \
    inline const char * MODNAME::id(void) {                           \
        return #MODNAME;                                              \
    }

/**
 * This class defines the base abstract class that should be extended
 * by all opencog modules.
 *
 * Since dlopen & co. provide a C API that uses runtime symbols
 * (i.e. strings) to load and unload the modules, it's not possible to
 * enforce full compliance at compile type by inheritance. The class
 * typedefs the function signatures for convenience and declares the
 * symbol names that must be used by derived modules, but the actual
 * creation and destruction functions cannot checked at compile time.
 * The only compile time check that is made is the init() method,
 * which is a late initialization entry point that modules can use to
 * initialize structures that depend on the module's constructor being
 * completed and/or the module's metadata (id, filename, function 
 * pointers, etc).
 *
 * That said, creating a proper module is fairly simple and only
 * requires 2 simple steps:
 *
 * 1. Define a class that derives from opencog::Module. It must provide
 * a static 'const char*' member which will be used to identify this
 * module.
 *
 * @code
 * // DerivedModule.h
 * #include <opencog/cogserver/server/Module.h>
 * class DerivedModule : public opencog::Module
 * {
 *     static const char* id = "DerivedModule"
 * }
 * @endcode
 *
 * 2. In the class implementation, define three external C functions with
 * signatures and names matching those defined in the base Module class:
 *
 * @code
 * // DerivedModule.cc
 * #include "DerivedModule.h"
 * DECLARE_MODULE(DerivedModule);
 * @endcode
 *
 * To implement the module's functionality, you will probably want to
 * write a custom constructor and destructor and perhaps overwrite the
 * init() method (which is called by the cogserver) after the module's
 * initialization has finished and the meta-data properly set.
 */

class Module
{
public:
    static const char* id_function_name(void)
    {
         static const char* s = "opencog_module_id";
         return s;
    }
    static const char* load_function_name(void)
    {
        static const char* s = "opencog_module_load";
        return s;
    }
    static const char* unload_function_name(void)
    {
        static const char* s = "opencog_module_unload";
        return s;
    }

    typedef const char* IdFunction    (void);
    typedef Module*     LoadFunction  (const Handle&);
    typedef void        UnloadFunction(Module*);

    Module(const Handle& hcsn) : _hcsn(hcsn) {}
    virtual ~Module() {}
    virtual void init() = 0;

protected:
    Handle _hcsn;

}; // class

/** @}*/
}  // namespace

#endif // _OPENCOG_MODULE_H