You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

183 lines
4.5 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
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 3 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, see <http://www.gnu.org/licenses/>.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
//////////////////////////////////////////////////////////////////////////////
// //
// plSoundEvent //
// //
//// Notes ///////////////////////////////////////////////////////////////////
// //
// 10.30.2001 - Created by mcn. //
// //
//////////////////////////////////////////////////////////////////////////////
#include "hsTypes.h"
#include "plSoundEvent.h"
#include "plgDispatch.h"
#include "pnMessage/plEventCallbackMsg.h"
#include "pnMessage/plSoundMsg.h"
#include "plSound.h"
plSoundEvent::plSoundEvent( Types type, plSound *owner )
{
fType = type;
fBytePosTime = 0;
fOwner = owner;
fCallbacks.Reset();
fCallbackEndingFlags.Reset();
}
plSoundEvent::plSoundEvent( Types type, UInt32 bytePos, plSound *owner )
{
fType = type;
fBytePosTime = bytePos;
fOwner = owner;
fCallbacks.Reset();
fCallbackEndingFlags.Reset();
}
plSoundEvent::plSoundEvent()
{
fType = kStart;
fBytePosTime = 0;
fOwner = nil;
fCallbacks.Reset();
fCallbackEndingFlags.Reset();
}
plSoundEvent::~plSoundEvent()
{
int i;
for( i = 0; i < fCallbacks.GetCount(); i++ )
hsRefCnt_SafeUnRef( fCallbacks[ i ] );
}
void plSoundEvent::AddCallback( plEventCallbackMsg *msg )
{
hsRefCnt_SafeRef( msg );
fCallbacks.Append( msg );
fCallbackEndingFlags.Append( 0 );
}
hsBool plSoundEvent::RemoveCallback( plEventCallbackMsg *msg )
{
int idx = fCallbacks.Find( msg );
if( idx != fCallbacks.kMissingIndex )
{
hsRefCnt_SafeUnRef( msg );
fCallbacks.Remove( idx );
fCallbackEndingFlags.Remove( idx );
return true;
}
return false;
}
void plSoundEvent::SendCallbacks( void )
{
int j;
plSoundMsg *sMsg;
for( j = fCallbacks.GetCount() - 1; j >= 0; j-- )
{
plEventCallbackMsg *msg = fCallbacks[ j ];
if (!msg->HasBCastFlag(plMessage::kNetPropagate) || !fOwner ||
fOwner->IsLocallyOwned() == plSynchedObject::kYes )
{
/// Do this a bit differently so we can do our MsgSend last
sMsg = nil;
// Ref to make sure the dispatcher doesn't delete it on us
hsRefCnt_SafeRef( msg );
if( msg->fRepeats == 0 && fCallbackEndingFlags[ j ] == 0 )
{
// Note: we get fancy here. We never want to remove the callback directly,
// because the sound won't know about it. So instead, send it a message to
// remove the callback for us
sMsg = TRACKED_NEW plSoundMsg();
sMsg->SetBCastFlag( plMessage::kLocalPropagate, true );
sMsg->AddReceiver( fOwner->GetKey() );
sMsg->SetCmd( plSoundMsg::kRemoveCallbacks );
sMsg->AddCallback( msg );
}
// If this isn't infinite, decrement the number of repeats
if( msg->fRepeats > 0 )
msg->fRepeats--;
// And finally...
if( fCallbackEndingFlags[ j ] == 0 )
{
plgDispatch::MsgSend( msg, true );
}
if( sMsg != nil )
{
plgDispatch::MsgSend( sMsg, true );
fCallbackEndingFlags[ j ] = 0xff; // Our special flag to mean "hey, don't
// process this, just waiting for
// it to die"
}
}
}
}
UInt32 plSoundEvent::GetNumCallbacks( void ) const
{
return fCallbacks.GetCount();
}
int plSoundEvent::GetType( void ) const
{
return (int)fType;
}
void plSoundEvent::SetType( Types type )
{
fType = type;
}
UInt32 plSoundEvent::GetTime( void ) const
{
return fBytePosTime;
}
plSoundEvent::Types plSoundEvent::GetTypeFromCallbackMsg( plEventCallbackMsg *msg )
{
switch( msg->fEvent )
{
case ::kStart: return kStart;
case ::kTime: return kTime;
case ::kStop: return kStop;
case ::kLoop: return kLoop;
}
return kStop;
}