terom@26: #ifndef IRC_CHAN_H terom@26: #define IRC_CHAN_H terom@26: terom@26: /** terom@26: * @file terom@26: * terom@26: * Support for IRC channels, including tracking their state and actions on them. terom@26: */ terom@26: struct irc_chan_info; terom@26: struct irc_chan; terom@26: terom@26: #include "irc_net.h" terom@37: #include "irc_cmd.h" terom@45: #include "irc_proto.h" terom@26: #include "error.h" terom@26: #include terom@26: terom@26: /** terom@26: * IRC channel info, as required to create an irc_chan terom@26: */ terom@26: struct irc_chan_info { terom@26: /** Channel name, with the [#&!] prefix */ terom@26: const char *channel; terom@26: terom@26: }; terom@26: terom@26: /** terom@45: * Semantic IRC channel callbacks. terom@45: * terom@45: * Where callbacks have irc_nm arguments, these are MAY be given as NULL if the prefix could not be parsed. terom@26: */ terom@37: struct irc_chan_callbacks { terom@37: /** Joined the channel */ terom@37: void (*on_self_join) (struct irc_chan *chan, void *arg); terom@38: terom@38: /** Someone sent a message to the channel */ terom@45: void (*on_msg) (struct irc_chan *chan, const struct irc_nm *source, const char *msg, void *arg); terom@26: }; terom@26: terom@26: /** terom@38: * Invoke the given callback with the given args terom@38: */ terom@38: #define IRC_CHAN_INVOKE_CALLBACK(chan, _cb_name_, ...) \ terom@38: do { \ terom@38: struct chain_head *head; \ terom@38: \ terom@38: CHAIN_FOREACH(&(chan)->callbacks, head) { \ terom@38: const struct irc_chan_callbacks *callbacks = head->chain; \ terom@38: \ terom@38: if (callbacks->_cb_name_) \ terom@38: callbacks->_cb_name_((chan), ## __VA_ARGS__, head->arg); \ terom@38: } \ terom@38: } while (0); terom@38: terom@38: /** terom@26: * IRC channel state terom@26: */ terom@26: struct irc_chan { terom@26: /** The irc_net.channels list */ terom@26: TAILQ_ENTRY(irc_chan) node; terom@26: terom@26: /* The network we're on */ terom@26: struct irc_net *net; terom@26: terom@26: /** Our identifying info */ terom@26: struct irc_chan_info info; terom@26: terom@45: /** State flags @{ */ terom@37: /** JOIN request sent, waiting for reply */ terom@37: bool joining; terom@37: terom@37: /** Currently joined to channel */ terom@37: bool joined; terom@37: terom@45: // @} terom@45: terom@37: /** General command handlers */ terom@37: irc_cmd_handlers_t handlers; terom@38: terom@38: /** High-level user callbacks */ terom@38: struct chain_list callbacks; terom@26: }; terom@26: terom@26: /** terom@26: * Return the channel's name terom@26: */ terom@26: const char* irc_chan_name (struct irc_chan *chan); terom@26: terom@26: /** terom@26: * Build/initialize a new irc_chan struct. This does not have any external side-effects. terom@26: * terom@26: * The channel will be in the IRC_CHAN_INIT state after this. terom@26: * terom@26: * @param chan_ptr the new irc_chan is returned via this pointer terom@26: * @param net the irc_net this channel is on terom@26: * @param info the channel's identifying information terom@26: * @param err error codes are returned via this terom@26: */ terom@26: err_t irc_chan_create (struct irc_chan **chan_ptr, struct irc_net *net, const struct irc_chan_info *info, struct error_info *err); terom@26: terom@26: /** terom@37: * Destroy irc_chan state, without doing anything to the network terom@37: */ terom@37: void irc_chan_destroy (struct irc_chan *chan); terom@37: terom@37: /** terom@38: * Add high-level irc_chan callbacks terom@38: */ terom@38: err_t irc_chan_add_callbacks (struct irc_chan *chan, const struct irc_chan_callbacks *callbacks, void *arg); terom@38: terom@38: /** terom@69: * Remove high-level irc_chan callbacks. terom@69: */ terom@69: void irc_chan_remove_callbacks (struct irc_chan *chan, const struct irc_chan_callbacks *callbacks, void *arg); terom@69: terom@69: /** terom@26: * Send the initial JOIN message. terom@26: * terom@26: * The channel must be in the IRC_CHAN_INIT state, and will transition to the IRC_CHAN_JOINING state. terom@26: * terom@26: * @param chan the channel to JOIN terom@26: */ terom@26: err_t irc_chan_join (struct irc_chan *chan); terom@26: terom@37: terom@26: #endif