コード例 #1
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
bool 
Reliable::Init( UdpCommunicator* communicator, UdpConnection* connection )
{
	K_ASSERT( communicator != 0 );
	K_ASSERT( connection != 0 );

	m_communicator 	= communicator;
	m_connection 	= connection;

	m_sendList.clear();
	m_recvList.clear();

	m_sendSeq 			= 0;
	m_recvCumAck 		= 0; 	// suppose seq starts from 1 always
	m_sendCumAck 		= 0; 	// suppose seq starts from 1 always
	m_outstandingSegs 	= 0;
	m_zeroSendCount 	= 0;
	m_averageRtt 		= START_RTT;

	m_cumAckInterval	= CUMULATIVE_ACK_INTERVAL;

	m_tickCumulativeAck.Reset();
	m_tickResend.Reset();

	return true;
}
コード例 #2
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void
Reliable::processZeroSend()
{
	if ( m_zeroSendCount == 0 && 
		 m_outstandingSegs >= MAX_OUTSTANDING_SEGMENTS )
	{
		return;
	}

	SendBlockList::iterator i( m_sendList.begin() );

	for ( ; i != m_sendList.end(); ++i )
	{
		UdpSendBlock* sb = *i;
		K_ASSERT( sb != 0 );

		if ( sb->rxCount == 0 )
		{
			if ( resend( sb ) )
			{
				--m_zeroSendCount;

				K_ASSERT( m_zeroSendCount >= 0 );
			}
			else
			{
				return; // we still cannot send 'cause there are too many outstanding segments
			}
		}
	}
}
コード例 #3
0
ファイル: NetClient.cpp プロジェクト: criptych/gamekernel
void 
NetClient::onGroupPrepare( MessagePtr m )
{
	K_ASSERT( m_groupId == 0 );
	K_ASSERT( m_selfTag == 0 );

	m_groupId = 0;
	m_selfTag = 0;

	NmGroupPrepare* gp = static_cast<NmGroupPrepare*>( m.Get() );

	TcpConnection* c = m_tcp.FindById( gp->remote );

	if ( c == 0 )
	{
		LOG( FT_WARN, 
			 _T("NetClient::onGroupPrepare> Connection %d not found"), 
			 gp->remote );

		return;
	}
	
	m_udp.Fini();

	m_groupId = gp->groupId;
	m_selfTag = gp->connectionId;

	// init udp with c as a relay connection 
	// use same ip:port as TCP connection
	bool rc = m_udp.Init( this, 
						  &m_ios, 
						  c->GetSocket()->GetAddress(), 
						  m_selfTag, 
						  gp->sl, 
						  gp->challenge, 
						  c );

	if ( !rc )
	{
		LOG( FT_WARN, _T("NetClient::onGroupPrepare> Failed to init udp") );

		return;
	}

	NmGroupPrepared* p = new NmGroupPrepared;

	p->remote 		= gp->remote;
	p->groupId 		= gp->groupId;
	p->connectionId = gp->connectionId;
	p->in 			= c->GetSocket()->GetAddress();

	m_tcp.Send( m->remote, MessagePtr( p ) );

	LOG( FT_DEBUG, _T("NetClient::onGroupPrepare> Prepared group %d connection %d"), 
		 gp->groupId, 
		 gp->connectionId );
}
コード例 #4
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::OnAck( const UdpHeader& header )
{
	K_ASSERT( header.ack > 0 );

	if ( m_recvCumAck >= header.ack )
	{
		LOG( FT_DEBUG, 
			 _T("Reliable::OnAck> self[%d] remote[%d] duplicate cum ack %d"), 
			 m_connection->GetSelfTag(), 
			 m_connection->GetRemoteTag(),
			 header.ack );

		return;
	}

	m_recvCumAck = header.ack;

	LOG( FT_DEBUG, 
		 _T("Reliable::OnAck> ack %d"), 
		 header.ack );

	SendBlockList::iterator i( m_sendList.begin() );

	int totalRtt = 0;
	int totalCount = 0;

	for ( ; i != m_sendList.end(); ) 
	{
		UdpSendBlock* sb = *i;
		K_ASSERT( sb != 0 );

		if ( sb->header.seq > header.ack )
		{
			break;
		}

		totalRtt += sb->rxmt.Elapsed(); 
		++totalCount;

		i = m_sendList.erase( i++ );

		--m_outstandingSegs;

		K_ASSERT( m_outstandingSegs >= 0 );

		delete sb;
	}

	if ( totalCount > 0 )
	{
		// moving average. slowly converges.
		m_averageRtt = ( totalRtt / totalCount + m_averageRtt ) / 2;
	}
}
コード例 #5
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
bool 
Reliable::Send( void* data, uint len, bool ordered )
{
	K_ASSERT( data != 0 );
	K_ASSERT( len > 0 );

	processZeroSend(); 		// To send previously asked ones first.

	UdpSendBlock* sb = allocSendBlock();

	sb->header.Set( UdpHeader::RLE );
	sb->header.Set( UdpHeader::ACK );

	if ( ordered )
	{
		sb->header.Set( UdpHeader::ORD );
	}

	sb->header.seq = ++m_sendSeq;
	sb->header.ack = m_sendCumAck;

	sb->header.srcId 	= m_connection->GetSelfTag();
	sb->header.dstId 	= m_connection->GetRemoteTag();
	sb->header.length   = sizeof( UdpHeader );
	sb->header.bodyLen	= len;
	sb->data 			= (byte*)allocData( sizeof( UdpHeader ) + len );

	::memcpy( sb->data, (void*)&sb->header, sizeof( UdpHeader ) );
	::memcpy( (void*)(sb->data + sb->header.length), data, len );

	sb->len 			= sizeof( UdpHeader ) + len;

	if ( m_outstandingSegs < MAX_OUTSTANDING_SEGMENTS )
	{
		m_connection->SendRaw( sb->data, sb->len );

		++sb->rxCount;

		++m_outstandingSegs;
		m_tickCumulativeAck.Reset();
	}
	else
	{
		++m_zeroSendCount;
	}

	m_sendList.push_back( sb );

	return true;
}
コード例 #6
0
ファイル: Acceptor.cpp プロジェクト: criptych/gamekernel
bool 
Acceptor::Init( TcpCommunicator* communicator, Socket* socket, SecurityLevel sl )
{
	K_ASSERT( communicator != 0 );
	K_ASSERT( socket != 0 );

	m_communicator  = communicator;
	m_socket 		= socket;
	m_sl 			= sl;

    Start();

    return true;
}
コード例 #7
0
ファイル: NetClient.cpp プロジェクト: criptych/gamekernel
void 
NetClient::onGroupJoin( MessagePtr m )
{
	K_ASSERT( m_groupId != 0 );

 	NmGroupJoin* join = static_cast<NmGroupJoin*>( m.Get() );

	K_ASSERT( join->groupId == m_groupId );

	LOG( FT_DEBUG, 
		 _T("NetClient::onGroupJoin> Group %d Members %d"), 
		 join->groupId, 
		 join->members.size() );

	NmGroupJoin::MemberList::iterator i( join->members.begin() );
	NmGroupJoin::MemberList::iterator iEnd( join->members.end() );

	for ( ; i != iEnd; ++i )
	{
		NetGroupMember& member = *i;

		if ( member.connectionId != m_selfTag )
		{
			UdpConnection* c = m_udp.FindByTag( member.connectionId );

			if ( c != 0 )
			{
				continue;
			}

			// tag is used for communication
			(void)m_udp.Connect( member.connectionId, member.in, member.ex ); 

			NmGroupJoined* joined = new NmGroupJoined;

			joined->groupId 	 = join->groupId;
			joined->connectionId = member.connectionId;
			joined->extra		 = member.extra;

			m_listener->Notify( MessagePtr( joined ) );

			LOG( FT_DEBUG, 
				_T("NetClient::onGroupJoin> Self %d Tag %d joined In %s Ex %s"), 
				m_selfTag,
				member.connectionId, 
				member.in.ToString().c_str(), 
				member.ex.ToString().c_str() );
		}
	}
}
コード例 #8
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::runRecvBlockList()
{
	RecvBlockList::iterator i( m_recvList.begin() );

	for ( ; i != m_recvList.end(); )
	{
		UdpRecvBlock* p = *i;

		K_ASSERT( p->seq > m_sendCumAck );

		if ( p->seq == ( m_sendCumAck + 1) ) // in order 
		{
			if ( p->ordered ) // ordered QoS
			{
				K_ASSERT( p->data != 0 );
				K_ASSERT( p->len > 0 );

				// deliver and free
				LOG( FT_DEBUG, 
				 	 _T("Reliable::runRecvBlockList> self[%d] remote[%d] seq %d made available in order"), 
		 		 	 m_connection->GetSelfTag(), 
		 		 	 m_connection->GetRemoteTag(),
					 p->seq );
				
				m_communicator->OnRecv( m_connection->GetRemoteTag(), p->data, p->len );

				freeData( p->data, p->len );
			}

			++m_sendCumAck;

			K_ASSERT( p->seq == m_sendCumAck );

			i = m_recvList.erase( i++ );

			freeRecvBlock( p );
		}
		else
		{
			LOG( FT_DEBUG, 
				 _T("Reliable>runRecvBlockList> Not in order %d, Cum %d, waiting..."), 
				 p->seq,
				 m_sendCumAck );

			return;
		}
	}
}
コード例 #9
0
ファイル: NetClient.cpp プロジェクト: criptych/gamekernel
void 
NetClient::Send( MessagePtr m )
{
	K_ASSERT( m.Get() != 0 );

	m_sendQ.Put( m );
}
コード例 #10
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::processResend()
{
	uint rtt = m_averageRtt;

	int resendCount = 0;

	if ( m_tickResend.Elapsed() > RESEND_CHECK_INTERVAL )
	{
		SendBlockList::iterator i( m_sendList.begin() );
		SendBlockList::iterator iEnd( m_sendList.end() );

		for ( ; i != iEnd; ++i )
		{
			UdpSendBlock* sb = *i;
			K_ASSERT( sb != 0 );

			if ( sb->rxmt.Elapsed() > rtt + rtt * sb->rxCount )
			{
				resend( sb, true );

				++resendCount;
			}
		}

		m_tickResend.Reset();
	}
}
コード例 #11
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::freeSendBlock( UdpSendBlock* p )
{
	K_ASSERT( p != 0 );

	delete p;
}
コード例 #12
0
ファイル: NetServer.cpp プロジェクト: criptych/gamekernel
void 
NetServer::onLeaveUdpGroup( const NetGroupOp& op )
{
	NetGroupMap::iterator i = m_groups.find( op.groupId );

	if ( i == m_groups.end() )
	{
		LOG( FT_WARN, _T("NetServer::onLeaveUdpGroup> %d not found"), op.groupId );

		return;
	}

	TcpConnection* c = m_tcp.FindById( op.connectionId );
	
	if ( c != 0 )
	{
		c->SetGroup( 0 );
	}

	NetGroup* group = i->second;
	K_ASSERT( group != 0 );

	group->Leave( op.connectionId );

	LOG( FT_DEBUG, 
		 _T("NetServer::onLeaveUdpGroup> %d left from %d"), 
		 op.connectionId, group->GetId() );
}
コード例 #13
0
ファイル: NetServer.cpp プロジェクト: criptych/gamekernel
void 
NetServer::onStateMessage( MessagePtr m )
{
	K_ASSERT( m.Get() != 0 );

	NetStateMessage* nsm = static_cast<NetStateMessage*>( m.Get() );

	switch ( nsm->state )
	{
	case NetStateMessage::TCP_CLOSED:
		{
			NetGroupMap::iterator i = m_groups.find( nsm->groupId );

			if ( i != m_groups.end() )
			{
				NetGroup* group = i->second;

				if ( group != 0 )
				{
					group->Leave( nsm->connectionId );
				}
			}	
		}
		break;
	}

	m_listener->Notify( m );
}
コード例 #14
0
ファイル: ActionState.cpp プロジェクト: criptych/gamekernel
ActionState* 
ActionState::GetState( int id )
{
	if ( id == m_id )
	{
		return this;
	}

	if ( !HasState( id ) )
	{
		return (ActionState*)0;
	}

	StateList::iterator i( m_childs.begin() );
	StateList::iterator iEnd( m_childs.end() );

	for ( ; i != iEnd; ++i )
	{
		ActionState* child = *i;
		K_ASSERT( child != 0 );

		if ( child->HasState( id ) )
		{
			return child->GetState( id );
		}
	}

	return (ActionState*)0;
}
コード例 #15
0
ファイル: NetServer.cpp プロジェクト: criptych/gamekernel
void 
NetServer::Send( MessagePtr m )
{
	K_ASSERT( m.Get() != 0 );

	m_sendQ.Put( m );
}
コード例 #16
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::freeRecvBlock( UdpRecvBlock* p )
{
	K_ASSERT( p != 0 );
			  
	delete p;
}
コード例 #17
0
ファイル: Acceptor.cpp プロジェクト: criptych/gamekernel
int 
Acceptor::Run()
{
    while ( IsRunning() )
    {
        Socket* socket = m_socket->Accept();
        K_ASSERT( socket != 0 );

		if ( !IsRunning() ) // check running state again
		{
			break;
		}

		NetStateMessage* m = new NetStateMessage;

		m->state  = NetStateMessage::TCP_ACCEPTED;
        m->addr   = socket->GetPeerAddress();
        m->socket = socket;
		m->sl 	  = m_sl;

		m_communicator->Notify( MessagePtr( m ) );

        LOG( FT_DEBUG,
             _T("Accepted new connection %d from %s"),
             socket->GetSystemSocket(),
             m->addr.ToString().c_str() );
    }

    return 0;
}
コード例 #18
0
ファイル: Texture.cpp プロジェクト: antoinechene/FPS-openGL
bool TextureManager::LoadTexture(const KFbxFileTexture * pTexture, unsigned int * pTextureObject)
{
	TextureMapType::RecordType * lTextureRecord = mTextureMap.Find(pTexture);
	if (lTextureRecord)
	{
		if (pTextureObject)
			*pTextureObject = lTextureRecord->GetValue();
		return true;
	}

	const KString lFileName = pTexture->GetFileName();
	unsigned int lTextureObject = 0;
	bool lStatus = LoadTextureFromFile(lFileName, lTextureObject);

	if (!lStatus)
	{
		const KString lRelativeFileName = mWorkingDir + "/" + pTexture->GetFileName();
		lStatus = LoadTextureFromFile(lRelativeFileName, lTextureObject);
	}

	if (lStatus)
	{
		K_ASSERT(glIsTexture(lTextureObject));
		mTextureMap.Insert(pTexture, lTextureObject);
		if (pTextureObject)
			*pTextureObject = lTextureObject;
		return true;
	}

	return false;
}
コード例 #19
0
ファイル: NetClient.cpp プロジェクト: criptych/gamekernel
void 
NetClient::Notify( MessagePtr m )
{
	K_ASSERT( m.Get() != 0 );

	m_recvQ.Put( m );
}
コード例 #20
0
ファイル: NetServer.cpp プロジェクト: criptych/gamekernel
bool 
NetServer::Init( MessageListener* listener )
{
	K_ASSERT( listener != 0 );

	Socket::Startup();

	m_listener = listener;

	bool rc = m_ios.Init();

	if ( !rc )
	{
		LOG( FT_ERROR, _T("NetServer::Init> IoService init failed") );

		return false;
	}

	rc = m_tcp.Init( this, &m_ios );

	if ( !rc )
	{
		LOG( FT_ERROR, _T("NetServer::Init> TcpCommunicator init failed") );

		return false;
	}

	MessageFactory::Instance()->Register( new NmGroupPrepared );
	MessageFactory::Instance()->Register( new NmGroupRelay );

	Start();

	return true;
}
コード例 #21
0
ファイル: AsyncPool.cpp プロジェクト: criptych/gamekernel
bool 
AsyncPool::Init( Node* node, bool luaMode )
{
	K_ASSERT( node != 0 );

	m_node		= node;
	m_luaMode	= luaMode;
	
	return true;
}
コード例 #22
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::freeSendBlocks()
{
	SendBlockList::iterator i( m_sendList.begin() );
	SendBlockList::iterator iEnd( m_sendList.end() );

	for ( ; i != iEnd; ++i )
	{
		UdpSendBlock* sb = *i;

		K_ASSERT( sb->data != 0 );
		K_ASSERT( sb->len > 0 );
		
		freeData( sb->data, sb->len );
		freeSendBlock( sb );
	}

	m_sendList.clear();
}
コード例 #23
0
ファイル: ActionState.cpp プロジェクト: criptych/gamekernel
void 
ActionState::attach( ActionState* state )
{
	K_ASSERT( state != 0 );

	if ( HasState( state->GetId() ) )
	{
		return;
	}

	m_childs.push_back( state );
}
コード例 #24
0
ファイル: ActionState.cpp プロジェクト: criptych/gamekernel
bool 
ActionState::getChildPathTo( int target, Path& path )
{
	StateList::iterator i( m_childs.begin() );
	StateList::iterator iEnd( m_childs.end() );

	for ( ; i != iEnd; ++i )
	{
		ActionState* child = *i;

		K_ASSERT( child != 0 );

		if ( child->HasState( target ) )
		{
			return child->GetTransitionPathTo( target, path );
		}
	}

	K_ASSERT( !_T("Should not reach here") );

	return false; // No child is in the path
}
コード例 #25
0
ファイル: timer.c プロジェクト: ShawnOfMisfit/ambarella
/**
 * Get current count.
 */
u32 timer_get_count(int tmr_id)
{
	switch (tmr_id) {
	case TIMER1_ID:
		return timer1_count;
	case TIMER2_ID:
		return timer2_count;
	case TIMER3_ID:
		return timer3_count;
	default:
		K_ASSERT(0);
	}
}
コード例 #26
0
ファイル: timer.c プロジェクト: ShawnOfMisfit/ambarella
u32 timer_get_tick(int tmr_id)
{
	switch (tmr_id) {
	case TIMER1_ID:
		return readl(TIMER1_STATUS_REG);
	case TIMER2_ID:
		return readl(TIMER2_STATUS_REG);
	case TIMER3_ID:
		return readl(TIMER3_STATUS_REG);
	default:
		K_ASSERT(0);
	}
}
コード例 #27
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::OnEak( const UdpHeader& header, void* data, uint len )
{
	// only 1 EAK under current protocol 
	K_ASSERT( data != 0 );
	K_ASSERT( len > 0 );

	byte* p = (byte*)data;

	byte* head = (byte*)(p + header.length);

	byte eakCount = *head;

	int* eakHead = (int*)((byte*)( head + 1 ));

	for ( byte i=0; i<eakCount; ++i )
	{
		int eak = eakHead[i];	

		runEak( eak );
	}
}
コード例 #28
0
ファイル: Reliable.cpp プロジェクト: criptych/gamekernel
void 
Reliable::insertRecvBlock( UdpRecvBlock* rv )
{
	K_ASSERT( rv != 0 );
	K_ASSERT( !isDuplicateRecv( rv->seq ) );

	RecvBlockList::iterator i( m_recvList.begin() );
	RecvBlockList::iterator iEnd( m_recvList.end() );

	for ( ; i != iEnd; ++i )
	{
		UdpRecvBlock* rb = *i;

		if ( rb->seq > rv->seq )
		{
			m_recvList.insert( i, rv );

			return;
		}
	}

	m_recvList.push_back( rv );
}
コード例 #29
0
void 
TransDispatcher::Subscribe( ushort type, ActionPtr action )
{
	K_ASSERT( type > 0 );
	K_ASSERT( action.Get() != 0 );

	ActionMap::iterator i( m_actions.find( type ) );

	if ( i == m_actions.end() )
	{
		ActionList lst;

		lst.push_back( action );

		m_actions.insert( ActionMap::value_type( type, lst ) );
	}
	else
	{
		ActionList& lst = i->second;

		lst.push_back( action );
	}
}
コード例 #30
0
ファイル: timer.c プロジェクト: ShawnOfMisfit/ambarella
/**
 * Reset the count.
 */
void timer_reset_count(int tmr_id)
{
	switch (tmr_id) {
	case TIMER1_ID:
		timer1_count = 0;
		break;
	case TIMER2_ID:
		timer2_count = 0;
		break;
	case TIMER3_ID:
		timer3_count = 0;
		break;
	default:
		K_ASSERT(0);
	}
}