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