finish off module timers

git-svn-id: https://znc.svn.sourceforge.net/svnroot/znc/trunk@327 726aef4b-f618-498e-8847-2d620e286838
This commit is contained in:
imaginos
2005-05-17 04:58:53 +00:00
parent d35fc53064
commit 51440b4b7c
2 changed files with 122 additions and 19 deletions
+84 -4
View File
@@ -101,6 +101,29 @@ typedef vector< PString > VPString;
class CModPerl;
static CModPerl *g_ModPerl = NULL;
class CPerlTimer : public CTimer
{
public:
CPerlTimer( CModule* pModule, unsigned int uInterval, unsigned int uCycles, const CString& sLabel, const CString& sDescription )
: CTimer( pModule, uInterval, uCycles, sLabel, sDescription) {}
virtual ~CPerlTimer() {}
// TODO possibly need to check that the userspace is correct when this goes global
void SetFuncName( const CString & sFuncName ) { m_sFuncName = sFuncName; }
void SetUserName( const CString & sUserName ) { m_sUserName = sUserName; }
void SetModuleName( const CString & sModuleName ) { m_sModuleName = sModuleName; }
protected:
virtual void RunJob();
CString m_sFuncName;
CString m_sUserName;
CString m_sModuleName;
};
class CModPerl : public CModule
{
public:
@@ -275,7 +298,15 @@ public:
return( CBTriple( "OnChanNotice", NICK( Nick ), CHAN( Channel ), sMessage ) );
}
EModRet CallBack( const PString & sHookName, const VPString & vsArgs, bool bLocal = false );
enum ECBTYPES
{
CB_LOCAL = 1,
CB_ONHOOK = 2,
CB_TIMER = 3
};
EModRet CallBack( const PString & sHookName, const VPString & vsArgs, ECBTYPES eCBType = CB_ONHOOK );
EModRet CBNone( const PString & sHookName )
{
VPString vsArgs;
@@ -354,6 +385,34 @@ MODULEDEFS( CModPerl )
//////////////////////////////// PERL GUTS //////////////////////////////
XS(XS_ZNC_COREAddTimer)
{
dXSARGS;
if ( items != 5 )
Perl_croak( aTHX_ "Usage: COREAddTimer( modname, funcname, description, interval, cycles )" );
SP -= items;
ax = (SP - PL_stack_base) + 1 ;
{
if ( g_ModPerl )
{
CString sModName = (char *)SvPV(ST(0),PL_na);
CString sFuncName = (char *)SvPV(ST(1),PL_na);
CString sDesc = (char *)SvPV(ST(2),PL_na);
u_int iInterval = (u_int)SvUV(ST(3));
u_int iCycles = (u_int)SvUV(ST(4));
CString sUserName = g_ModPerl->GetUser()->GetUserName();
CString sLabel = sUserName + sModName + sFuncName;
CPerlTimer *pTimer = new CPerlTimer( g_ModPerl, iInterval, iCycles, sLabel, sDesc );
pTimer->SetFuncName( sFuncName );
pTimer->SetUserName( sUserName );
pTimer->SetModuleName( sModName );
g_ModPerl->AddTimer( pTimer );
}
PUTBACK;
}
}
XS(XS_ZNC_PutIRC)
{
dXSARGS;
@@ -561,7 +620,7 @@ bool CModPerl::Eval( const CString & sScript, const CString & sFuncName )
return( bReturn );
}
CModPerl::EModRet CModPerl::CallBack( const PString & sHookName, const VPString & vsArgs, bool bLocal )
CModPerl::EModRet CModPerl::CallBack( const PString & sHookName, const VPString & vsArgs, ECBTYPES eCBType )
{
if ( !m_pPerl )
return( CONTINUE );
@@ -572,15 +631,26 @@ CModPerl::EModRet CModPerl::CallBack( const PString & sHookName, const VPString
PUSHMARK( SP );
if ( !bLocal )
CString sFuncToCall;
if ( eCBType == CB_LOCAL )
sFuncToCall = sHookName;
else
{
PString sUsername = m_pUser->GetUserName();
XPUSHs( sUsername.GetSV() );
XPUSHs( sHookName.GetSV() );
if ( eCBType == CB_ONHOOK )
sFuncToCall = "ZNC::CallFunc";
else
sFuncToCall = "ZNC::CallTimer";
}
for( VPString::size_type a = 0; a < vsArgs.size(); a++ )
XPUSHs( vsArgs[a].GetSV() );
PUTBACK;
int iCount = call_pv( ( !bLocal ? "ZNC::CallFunc" : sHookName.c_str() ), G_EVAL|G_SCALAR );
int iCount = call_pv( sFuncToCall.c_str(), G_EVAL|G_SCALAR );
SPAGAIN;
int iRet = CONTINUE;
@@ -590,6 +660,8 @@ CModPerl::EModRet CModPerl::CallBack( const PString & sHookName, const VPString
CString sError = SvPV( ERRSV, PL_na);
DumpError( sHookName + ": " + sError );
if ( eCBType == CB_TIMER )
iRet = HALT;
} else
{
if ( iCount == 1 )
@@ -635,6 +707,7 @@ bool CModPerl::OnLoad( const CString & sArgs )
newXS( "ZNC::PutModNotice", XS_ZNC_PutModNotice, (char *)file );
newXS( "ZNC::GetNicks", XS_ZNC_GetNicks, (char *)file );
newXS( "ZNC::GetString", XS_ZNC_GetString, (char *)file );
newXS( "ZNC::COREAddTimer", XS_ZNC_COREAddTimer, (char *)file );
// this sets up the eval CB that we call from here on out. this way we can grab the error produced
SetupZNCScript();
@@ -691,4 +764,11 @@ CModPerl::EModRet CModPerl::OnDCCUserSend(const CNick& RemoteNick, unsigned long
return( CallBack( "OnDCCUserSend", vsArgs ) );
}
void CPerlTimer::RunJob()
{
VPString vArgs;
vArgs.push_back( m_sModuleName );
if ( ((CModPerl *)m_pModule)->CallBack( m_sFuncName, vArgs, CModPerl::CB_TIMER ) != CModPerl::CONTINUE )
Stop();
}
#endif /* HAVE_PERL */
+38 -15
View File
@@ -1,12 +1,11 @@
#
# TODO need to add timer support
# TODO need to add socket support
#
package ZNC;
use strict;
my %Modules;
my @MODS = ();
sub Eval
{
@@ -16,14 +15,16 @@ sub Eval
sub CallFunc
{
my ( $Func, @args ) = @_;
my ( $Username, $Func, @args ) = @_;
my $FinalRet = CONTINUE();
foreach( keys( %Modules ) )
foreach( @MODS )
{
if ( $Modules{$_}->{$Func} )
next if ( $_->{ZNC_Username} ne $Username );
if ( $_->can( $Func ) )
{
my $Ret = $Modules{$_}->$Func( @args );
my $Ret = $_->$Func( @args );
if ( $Ret == HALT() )
{
@@ -76,10 +77,13 @@ sub LoadMod
return( HALTMODS() );
}
if ( $Modules{"$Username|$Module"} )
foreach( @MODS )
{
ZNC::PutModule( "$Module Already Loaded" );
return( HALTMODS() );
if ( ( $_->{ZNC_Username} eq $Username ) && ( $_->{ZNC_Name} eq $Module ) )
{
ZNC::PutModule( "$Module Already Loaded" );
return( HALTMODS() );
}
}
my $pkgcount = 0;
@@ -120,7 +124,7 @@ sub LoadMod
$obj->{ZNC_Name} = $Module;
$obj->{ZNC_ModPath} = $FileName;
$Modules{"$Username|$Module"} = $obj;
push( @MODS, $obj );
ZNC::PutModule( "Loaded $Module" );
}
@@ -136,14 +140,33 @@ sub UnLoadMod
return( HALTMODS() );
}
if ( !$Modules{"$Username|$Module"} )
for( my $i = 0; $i < @MODS; $i++ )
{
ZNC::PutModule( "$Module Isn't Loaded" );
return( HALTMODS() );
if ( ( $MODS[$i]->{ZNC_Username} eq $Username ) && ( $MODS[$i]->{ZNC_Name} eq $Module ) )
{
undef $MODS[$i];
splice( @MODS, $i );
ZNC::PutModule( "UnLoaded $Module" );
return( CONTINUE() );
}
}
ZNC::PutModule( "$Module Isn't Loaded" );
undef $Modules{"$Username|$Module"};
ZNC::PutModule( "UnLoaded $Module" );
}
# the timer is inserted, it just calls this guy and expects it to be here
sub CallTimer
{
my ( $Username, $Func, $ModName ) = @_;
for( my $i = 0; $i < @MODS; $i++ )
{
if ( ( $MODS[$i]->{ZNC_Username} eq $Username ) && ( $MODS[$i]->{ZNC_Name} eq $ModName ) )
{
return( $MODS[$i]->$Func() );
}
}
return( HALTMODS() );
}
1;