2007-01-25 07:40:21 +01:00
|
|
|
/*
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
* IRCd (Charybdis): Pushing the envelope since '88
|
2007-01-25 07:40:21 +01:00
|
|
|
* modules.h: A header for the modules functions.
|
|
|
|
*
|
|
|
|
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
|
|
|
|
* Copyright (C) 1996-2002 Hybrid Development Team
|
|
|
|
* Copyright (C) 2002-2004 ircd-ratbox development team
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
* Copyright (C) 2016 Charybdis Development Team
|
|
|
|
* Copyright (C) 2016 Jason Volk <jason@zemos.net>
|
2007-01-25 07:40:21 +01:00
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
|
|
|
* USA
|
|
|
|
*/
|
|
|
|
|
2016-08-13 05:05:54 +02:00
|
|
|
#pragma once
|
|
|
|
#define HAVE_IRCD_MODULES_H
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
namespace ircd {
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
namespace mapi {
|
|
|
|
|
|
|
|
using magic_t = uint16_t;
|
|
|
|
using version_t = uint16_t;
|
|
|
|
struct header;
|
|
|
|
|
|
|
|
} // namespace mapi
|
|
|
|
|
|
|
|
namespace mods {
|
|
|
|
|
|
|
|
using mapi::magic_t;
|
|
|
|
using mapi::version_t;
|
|
|
|
|
|
|
|
IRCD_EXCEPTION(ircd::error, error)
|
|
|
|
IRCD_EXCEPTION(error, filesystem_error)
|
|
|
|
IRCD_EXCEPTION(error, invalid_export)
|
|
|
|
|
|
|
|
struct mod;
|
|
|
|
bool has(const mod &mod, const std::string &symbol);
|
|
|
|
const uint8_t *ptr(const mod &mod, const std::string &symbol);
|
|
|
|
uint8_t *ptr(mod &mod, const std::string &symbol);
|
|
|
|
template<class T> const T *ptr(const mod &mod, const std::string &symbol);
|
|
|
|
template<class T> const T &get(const mod &mod, const std::string &symbol);
|
|
|
|
template<class T> T *ptr(mod &mod, const std::string &symbol);
|
|
|
|
template<class T> T &get(mod &mod, const std::string &symbol);
|
|
|
|
const mapi::header &header(const mod &);
|
2016-09-13 10:29:50 +02:00
|
|
|
const std::string &meta(const mod &, const std::string &key);
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
const version_t &version(const mod &);
|
|
|
|
const int64_t ×tamp(const mod &);
|
2016-09-13 10:29:50 +02:00
|
|
|
const std::string &desc(const mod &);
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
std::string location(const mod &);
|
|
|
|
std::string name(const mod &);
|
|
|
|
|
|
|
|
extern struct log::log log;
|
|
|
|
|
|
|
|
// Symbol handlers
|
|
|
|
struct type_handlers
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
std::function<void (mod &, const std::string &sym)> loader;
|
|
|
|
std::function<void (mod &, const std::string &sym)> unloader;
|
|
|
|
std::function<void (mod &, const std::string &sym)> reloader;
|
2007-01-25 07:40:21 +01:00
|
|
|
};
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T> std::type_index make_index();
|
|
|
|
bool add(const std::type_index &, const type_handlers &handlers);
|
|
|
|
bool del(const std::type_index &);
|
|
|
|
bool has(const std::type_index &);
|
|
|
|
template<class T, class... type_handlers> bool add(type_handlers&&... handlers);
|
|
|
|
template<class T> bool del();
|
|
|
|
template<class T> bool has();
|
|
|
|
|
|
|
|
// The search path vector
|
|
|
|
std::vector<std::string> paths();
|
|
|
|
bool path_added(const std::string &dir);
|
|
|
|
void path_del(const std::string &dir);
|
|
|
|
bool path_add(const std::string &dir, std::nothrow_t); // logs errors and returns false
|
|
|
|
bool path_add(const std::string &dir); // false if exists, throws other errors
|
|
|
|
void path_clear();
|
|
|
|
|
|
|
|
// Dump object data
|
|
|
|
std::vector<std::string> symbols(const std::string &fullpath, const std::string §ion);
|
|
|
|
std::vector<std::string> symbols(const std::string &fullpath);
|
|
|
|
std::vector<std::string> sections(const std::string &fullpath);
|
|
|
|
|
|
|
|
// Checks if loadable module containing a mapi header (does not verify the magic)
|
|
|
|
bool is_module(const std::string &fullpath, std::string &why);
|
|
|
|
bool is_module(const std::string &fullpath, std::nothrow_t);
|
|
|
|
bool is_module(const std::string &fullpath);
|
|
|
|
|
|
|
|
// returns dir/name of first dir containing 'name' (and this will be a loadable module)
|
|
|
|
// Unlike libltdl, the reason each individual candidate failed is presented in a vector.
|
|
|
|
std::string search(const std::string &name, std::vector<std::string> &why);
|
|
|
|
std::string search(const std::string &name);
|
|
|
|
|
|
|
|
// Potential modules available to load
|
|
|
|
std::forward_list<std::string> available();
|
|
|
|
bool available(const std::string &name);
|
|
|
|
|
|
|
|
// Find module names where symbol resides
|
|
|
|
bool has_symbol(const std::string &name, const std::string &symbol);
|
|
|
|
std::vector<std::string> find_symbol(const std::string &symbol);
|
|
|
|
|
|
|
|
// Modules currently loaded
|
|
|
|
const std::map<std::string, std::unique_ptr<mod>> &loaded();
|
|
|
|
bool loaded(const std::string &name);
|
|
|
|
mod &get(const std::string &name);
|
|
|
|
|
|
|
|
bool reload(const std::string name);
|
|
|
|
bool unload(const std::string name);
|
|
|
|
bool load(const std::string &name);
|
|
|
|
void autoload();
|
2016-09-10 01:14:29 +02:00
|
|
|
void unload();
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
bool
|
|
|
|
has()
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return has(make_index<T>());
|
|
|
|
}
|
2007-01-25 07:40:21 +01:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T>
|
|
|
|
bool
|
|
|
|
del()
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return del(make_index<T>());
|
|
|
|
}
|
2016-03-06 23:53:03 +01:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T,
|
|
|
|
class... type_handlers>
|
|
|
|
bool
|
|
|
|
add(type_handlers&&... handlers)
|
2016-03-06 23:53:03 +01:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return add(make_index<T>(), {std::forward<type_handlers>(handlers)...});
|
|
|
|
}
|
2016-03-06 23:53:03 +01:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T>
|
|
|
|
std::type_index
|
|
|
|
make_index()
|
2007-01-25 07:40:21 +01:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return typeid(typename std::add_pointer<T>::type);
|
|
|
|
}
|
2007-01-25 07:40:21 +01:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T>
|
|
|
|
T &
|
|
|
|
get(mod &mod,
|
|
|
|
const std::string &symbol)
|
2016-03-06 23:53:03 +01:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return *reinterpret_cast<T *>(ptr(mod, symbol));
|
|
|
|
}
|
MAPI Version 3
This version leverages a flexible, cleaner key-value strategy
reducing the need to design entire new headers for every feature
addition, change, etc.
* A friendly declaration for the module authors, with minimal
requirements to fill in, and explicit labels of what the fields are.
* Repetition of keys, removing references to (and the requirement to
build) a clist, hlist and hfnlist and caplist and whatever the future
holds.
* Safe deterministic loading and unloading. Keys are evaluated in
order, errors can be recognized, and unloading occurs in reverse
order.
ircd: Refactor internal half of modules.c, with some V3 additions.
Provides better delegation for versions, a cleaner stack with better
error handling, and some functionality deduping. V1 and V2 handlers
are still somewhat unaltered, just factored in.
2016-06-23 03:30:05 +02:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T>
|
|
|
|
T *
|
|
|
|
ptr(mod &mod,
|
|
|
|
const std::string &symbol)
|
MAPI Version 3
This version leverages a flexible, cleaner key-value strategy
reducing the need to design entire new headers for every feature
addition, change, etc.
* A friendly declaration for the module authors, with minimal
requirements to fill in, and explicit labels of what the fields are.
* Repetition of keys, removing references to (and the requirement to
build) a clist, hlist and hfnlist and caplist and whatever the future
holds.
* Safe deterministic loading and unloading. Keys are evaluated in
order, errors can be recognized, and unloading occurs in reverse
order.
ircd: Refactor internal half of modules.c, with some V3 additions.
Provides better delegation for versions, a cleaner stack with better
error handling, and some functionality deduping. V1 and V2 handlers
are still somewhat unaltered, just factored in.
2016-06-23 03:30:05 +02:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return reinterpret_cast<T *>(ptr(mod, symbol));
|
|
|
|
}
|
MAPI Version 3
This version leverages a flexible, cleaner key-value strategy
reducing the need to design entire new headers for every feature
addition, change, etc.
* A friendly declaration for the module authors, with minimal
requirements to fill in, and explicit labels of what the fields are.
* Repetition of keys, removing references to (and the requirement to
build) a clist, hlist and hfnlist and caplist and whatever the future
holds.
* Safe deterministic loading and unloading. Keys are evaluated in
order, errors can be recognized, and unloading occurs in reverse
order.
ircd: Refactor internal half of modules.c, with some V3 additions.
Provides better delegation for versions, a cleaner stack with better
error handling, and some functionality deduping. V1 and V2 handlers
are still somewhat unaltered, just factored in.
2016-06-23 03:30:05 +02:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T>
|
|
|
|
const T &
|
|
|
|
get(const mod &mod,
|
|
|
|
const std::string &symbol)
|
MAPI Version 3
This version leverages a flexible, cleaner key-value strategy
reducing the need to design entire new headers for every feature
addition, change, etc.
* A friendly declaration for the module authors, with minimal
requirements to fill in, and explicit labels of what the fields are.
* Repetition of keys, removing references to (and the requirement to
build) a clist, hlist and hfnlist and caplist and whatever the future
holds.
* Safe deterministic loading and unloading. Keys are evaluated in
order, errors can be recognized, and unloading occurs in reverse
order.
ircd: Refactor internal half of modules.c, with some V3 additions.
Provides better delegation for versions, a cleaner stack with better
error handling, and some functionality deduping. V1 and V2 handlers
are still somewhat unaltered, just factored in.
2016-06-23 03:30:05 +02:00
|
|
|
{
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
return *reinterpret_cast<const T *>(ptr(mod, symbol));
|
|
|
|
}
|
MAPI Version 3
This version leverages a flexible, cleaner key-value strategy
reducing the need to design entire new headers for every feature
addition, change, etc.
* A friendly declaration for the module authors, with minimal
requirements to fill in, and explicit labels of what the fields are.
* Repetition of keys, removing references to (and the requirement to
build) a clist, hlist and hfnlist and caplist and whatever the future
holds.
* Safe deterministic loading and unloading. Keys are evaluated in
order, errors can be recognized, and unloading occurs in reverse
order.
ircd: Refactor internal half of modules.c, with some V3 additions.
Provides better delegation for versions, a cleaner stack with better
error handling, and some functionality deduping. V1 and V2 handlers
are still somewhat unaltered, just factored in.
2016-06-23 03:30:05 +02:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
template<class T>
|
|
|
|
const T *
|
|
|
|
ptr(const mod &mod,
|
|
|
|
const std::string &symbol)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<const T *>(ptr(mod, symbol));
|
|
|
|
}
|
2016-04-07 11:00:25 +02:00
|
|
|
|
MAPI IV. This iteration leverages the C++11 standardized RTTI.
* Simplifies the export declarations for module developers. While
MAPI III utilized a flexible key-value vector to eliminate positional
arguments in a header initializer, now the developer simply makes
a list of pointers to what they want to export for injection into
IRCd. Example:
mapi::header IRCD_MODULE
{
"mymod",
"My module adds a command, a hook, and a CLICAP",
&my_cmdtab,
&some_hook,
&clicaptab
};
* Distributes the handlers for items passed to the above vector.
Anyone can add a type-handler to the module system from anywhere in IRCd
(and other modules?) When your type is encountered a handler is called
providing the symbol name to read out of the module. Example in parser.cc:
mods::add_loader<Message>([]
(mod &loading, const std::string &symbol)
{
auto &msg(get<Message>(loading, symbol));
add_command(msg.name, msg);
});
2016-08-29 21:09:59 +02:00
|
|
|
} // namespace mods
|
2016-08-13 05:05:54 +02:00
|
|
|
} // namespace ircd
|
|
|
|
#endif // __cplusplus
|