⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 listener.cpp

📁 this keik game source
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	}
#endif

EXPORT_FROM_DLL qboolean Listener::ValidEvent
	(
	Event &e
	)

	{
	ClassDef	*c;
	int		ev;

	ev = ( int )e;

	c = this->classinfo();
   assert( ( ev >= 0 ) && ( ev < c->numEvents ) );
	if ( ( ev < 0 ) || ( ev >= c->numEvents ) )
		{
      warning( "ValidEvent", "Event '%s' out of response range for class '%s'.  "
         "Event probably invalid or allocated late.\n", e.getName().c_str(), getClassname() );
		return false;
		}

	return ( c->responseLookup[ ev ] != NULL );
   }

EXPORT_FROM_DLL qboolean Listener::ValidEvent
	(
	const char *name
	)

	{
	ClassDef	*c;
	int		ev;

   ev = Event::FindEvent( name );

	c = this->classinfo();
   assert( ( ev >= 0 ) && ( ev < c->numEvents ) );
	if ( ( ev < 0 ) || ( ev >= c->numEvents ) )
		{
      warning( "ValidEvent", "Event '%s' out of response range for class '%s'.  "
         "Event probably invalid or allocated late.\n", name, getClassname() );
		return false;
		}

	return ( c->responseLookup[ ev ] != NULL );
	}

EXPORT_FROM_DLL qboolean Listener::EventPending
	( 
	Event &ev
	)

	{
	eventcache_t *event;
	int eventnum;

	assert( EventQueue );
	assert( EventQueue->next );

	event = EventQueue->next;

	eventnum = ( int )ev;
	while( event != EventQueue )
		{
		if ( ( event->obj == this ) && ( (int)*event->event == eventnum ) )
			{
			return true;
			}
		event = event->next;
		}

	return false;
   }

EXPORT_FROM_DLL inline qboolean Listener::CheckEventFlags
	(
	Event *event
	)

	{
	// Special handling of console events
	if ( event->GetSource() == EV_FROM_CONSOLE )
		{
		if ( !( event->info.flags & (EV_CONSOLE|EV_CHEAT) ) )
			{
			if ( isSubclassOf( Entity ) )
				{
				Entity *ent;

				ent = ( Entity * )this;
				gi.cprintf( ent->edict, PRINT_HIGH, "Command not available from console.\n" );
				}

			// don't process
			return false;
			}

		// don't allow console cheats during deathmatch unless the server says it's ok.
		if ( ( event->info.flags & EV_CHEAT ) && deathmatch->value && !sv_cheats->value )
			{
			if ( isSubclassOf( Entity ) )
				{
				Entity *ent;

				ent = ( Entity * )this;
				gi.cprintf( ent->edict, PRINT_HIGH, "You must run the server with '+set cheats 1' to enable this command.\n" );
				}

			// don't process
			return false;
			}
		}

	// ok to process
	return true;
	}

EXPORT_FROM_DLL qboolean Listener::ProcessEvent
	(
	Event *event
	)

	{
	ClassDef *c;
	int		ev;
	int		i;

	// Prevent overflow of the inuse count
	if ( event->info.inuse >= MAX_EVENT_USE )
		{
		gi.error( "ProcessEvent : Event usage overflow on '%s' event.  Possible infinite loop.\n", event->getName().c_str() );
		}

	if ( g_showevents->value )
		{
		int n;
		str text;

		text = va( "%.1f: %s", level.time, this->getClassname() );
		if ( isSubclassOf( Entity ) )
			{
			text += va( " (*%d) ", ( ( Entity * )this )->entnum );
			if ( ( ( Entity * )this )->Targeted() )
				{
				text += va( "'%s'", ( ( Entity * )this )->TargetName() );
				}
			}
		else if ( isSubclassOf( ScriptThread ) )
			{
			text += va( " #%d:'%s'", ( ( ScriptThread * )this )->ThreadNum(), ( ( ScriptThread * )this )->ThreadName() );
			}
		else if ( isSubclassOf( ScriptVariable ) )
			{
			text += va( " '%s'", ( ( ScriptVariable * )this )->getName() );
			}

		switch( event->GetSource() )
			{
			default :
			case EV_FROM_CODE :
				text += " : Code :";
				break;

			case EV_FROM_SCRIPT :
				assert( event->GetThread() );
				text += va( " : %s(%d) :", event->GetThread()->Filename(), event->info.linenumber );
				break;

			case EV_FROM_CONSOLE :
				text += " : Console :";
				break;
			}

		text += event->getName().c_str();
		n = event->NumArgs();
		for( i = 1; i <= n; i++ )
			{
			text += va( " %s", event->GetToken( i ) );
			}

		text += "\n";

      if ( !g_watch->value || ( isSubclassOf( Entity ) && ( g_watch->value == ( ( Entity * )this )->entnum ) ) )
         {
         if ( g_showevents->value == 2 )
			   {
			   G_DebugPrintf( text.c_str() );
			   }
		   else
			   {
			   gi.dprintf( "%s", text.c_str() );
			   }
         }
		}

	ev = ( int )*event;
	c = this->classinfo();
	if ( ev >= c->numEvents	)
		{
      event->Error( "Event out of response range for class '%s'.  Event probably invalid or allocated late.\n", getClassname() );
		return false;
		}

	if ( c->responseLookup[ ev ] )
		{
      int start;
      int end;

		event->info.inuse++;

      if ( !g_timeevents->value )
         {
         // only process the event if we allow it
		   if ( CheckEventFlags( event ) )
			   {
			   ( this->**c->responseLookup[ ev ] )( event );
			   }
         }
      else
         {
         start = G_Milliseconds();

		   // only process the event if we allow it
		   if ( CheckEventFlags( event ) )
			   {
			   ( this->**c->responseLookup[ ev ] )( event );
			   }

         end = G_Milliseconds();
         if ( g_timeevents->value == 1 )
            {
            gi.printf( "'%s' : %d\n", event->getName().c_str(), end - start );
            }
         else
            {
            G_DebugPrintf( "'%s' : %d\n", event->getName().c_str(), end - start );
            }
         }

		// Prevent an event from being freed twice, in case it's been re-used 
		event->info.inuse--;
		if ( !event->info.inuse )
			{
			delete event;
			}

      return true;
		}

   if ( !event->info.inuse )
		{
		delete event;
		}

	return false;
	}

EXPORT_FROM_DLL void Listener::PostEvent
	(
	Event *ev,
	float time
	)

	{
	eventcache_t *newevent;
	eventcache_t *event;

   if ( LoadingSavegame )
      {
		if ( !ev->info.inuse )
			{
			delete ev;
			}

      return;
      }

	if ( LL_Empty( FreeEvents, next, prev ) )
		{
		gi.error( "PostEvent : No more free events on '%s' event.\n", ev->getName().c_str() );
		return;
		}

	newevent = FreeEvents->next;
	LL_Remove( newevent, next, prev );

	// Probably don't have this many events, but it's a good safety precaution
	if ( ev->info.inuse >= MAX_EVENT_USE )
		{
		gi.error( "PostEvent : Event usage overflow on '%s' event.  Possible infinite loop.\n", ev->getName().c_str() );
		return;
		}

	ev->info.inuse++;

	newevent->obj		= this;
	newevent->event	= ev;
	newevent->time		= level.time + time;

	event = EventQueue->next;
	while( ( event != EventQueue ) && ( newevent->time >= event->time ) )
		{
		event = event->next;
		}

	LL_Add( event, newevent, next, prev );
	numEvents++;
	}

EXPORT_FROM_DLL qboolean Listener::PostponeEvent
	(
	Event &ev,
	float time
	)
	
	{
	eventcache_t *event;
	eventcache_t *node;
	int eventnum;

	assert( EventQueue );
	assert( EventQueue->next );

	eventnum = ( int )ev;

	event = EventQueue->next;
	while( event != EventQueue )
		{
		if ( ( event->obj == this ) && ( ( int )*event->event == eventnum ) )
			{
			event->time	+= time;

			node = event->next;
			while( ( node != EventQueue ) && ( event->time >= node->time ) )
				{
				node = node->next;
				}

			LL_Remove( event, next, prev );
			LL_Add( node, event, next, prev );
			
			return true;
			}
		event = event->next;
		}

	return false;
	}

EXPORT_FROM_DLL void Listener::CancelEventsOfType
	(
	Event *ev
	)

	{
	eventcache_t *event;
	eventcache_t *next;
	int eventnum;

	assert( EventQueue );
	assert( EventQueue->next );

	event = EventQueue->next;

	eventnum = (int)*ev;
	while( event != EventQueue )
		{
		next = event->next;
		if ( ( event->obj == this ) && ( (int)*event->event == eventnum ) )
			{
			delete event->event;
			event->event = NULL;
			LL_Remove( event, next, prev );
			LL_Add( FreeEvents, event, next, prev );
			numEvents--;
			}
		event = next;
		}
	}

EXPORT_FROM_DLL void Listener::CancelPendingEvents
	(
	void
	)

	{
	eventcache_t *event;
	eventcache_t *next;

	assert( EventQueue );
	assert( EventQueue->next );

	event = EventQueue->next;

	while( event != EventQueue )
		{
		next = event->next;
		if ( event->obj == this )
			{
			delete event->event;
			event->event = NULL;
			LL_Remove( event, next, prev );
			LL_Add( FreeEvents, event, next, prev );
			numEvents--;
			}
		event = next;
		}
	}

EXPORT_FROM_DLL qboolean Listener::ProcessPendingEvents
	( 
	void
	)

	{
	eventcache_t *event;
	qboolean processedEvents;
	float t;

	assert( EventQueue );
	assert( EventQueue->next );
	assert( EventQueue->prev );

	processedEvents = false;

	t = level.time + 0.001;

	event = EventQueue->next;
	while( event != EventQueue )
		{
		assert( event );
		assert( event->event );
		assert( event->obj );

		if ( event->time > t )
			{
			break;
			}

		if ( event->obj != this )
			{
			// traverse normally
			event = event->next;
			}
		else
			{
			LL_Remove( event, next, prev );
			numEvents--;

			assert( event->obj );

			// ProcessEvent increments the inuse count, so decrement it since we've already incremented it in PostEvent
			event->event->info.inuse--;

			event->obj->ProcessEvent( event->event );

			event->event = NULL;
			LL_Add( FreeEvents, event, next, prev );

			// start over, since can't guarantee that we didn't process any previous or following events
			event = EventQueue->next;

			processedEvents = true;
			}
		}

	return processedEvents;
   }

EXPORT_FROM_DLL Listener::~Listener()
	{
	CancelPendingEvents();
	}

EXPORT_FROM_DLL void G_ClearEventList
	(
	void
	)

	{
	int i;
	eventcache_t *e;

	LL_Reset( FreeEvents, next, prev );
	LL_Reset( EventQueue, next, prev );
	memset( Events, 0, sizeof( Events ) );

	for( e = &Events[ 0 ], i = 0; i < MAX_EVENTS; i++, e++ )
		{
		LL_Add( FreeEvents, e, next, prev );
		}

	numEvents = 0;
	}

EXPORT_FROM_DLL void G_ProcessPendingEvents
	(
	void
	)

	{
	eventcache_t *event;
	float t;
   int num;
   int maxevents;

	assert( EventQueue );
	assert( EventQueue->next );
	assert( EventQueue->prev );

   maxevents = ( int )g_eventlimit->value;

   num = 0;
	t = level.time + 0.001;
	while( !LL_Empty( EventQueue, next, prev ) )
		{
		event = EventQueue->next;

		assert( event );
		assert( event->event );
		assert( event->obj );

		if ( event->time > t )
			{
			break;
			}

		LL_Remove( event, next, prev );
		numEvents--;

		assert( event->obj );

		// ProcessEvent increments the inuse count, so decrement it since we've already incremented it in PostEvent
      assert( event->event->info.inuse > 0 );
		event->event->info.inuse--;

		event->obj->ProcessEvent( event->event );

		event->event = NULL;
		LL_Add( FreeEvents, event, next, prev );

      // Don't allow ourselves to stay in here too long.  An abnormally high number
      // of events being processed is evidence of an infinite loop of events.
      num++;
      if ( num > maxevents )
         {
         gi.printf( "Event overflow.  Possible infinite loop in script.  "
            "Enable g_showevents to trace.  Aborting frame.\n" );
         break;
         }
		}
	}

EXPORT_FROM_DLL void G_ArchiveEvents
	(
	Archiver &arc
	)

	{
	eventcache_t *event;
   int num;

	assert( EventQueue );
	assert( EventQueue->next );
	assert( EventQueue->prev );

   num = 0;
	for( event = EventQueue->next; event != EventQueue; event = event->next )
		{
		assert( event );
		assert( event->event );
		assert( event->obj );

      if ( event->obj->isSubclassOf( Entity ) &&
         ( ( ( Entity * )event->obj )->flags & FL_DONTSAVE ) )
         {
         continue;
         }

      num++;
		}

   arc.WriteInteger( num );
	for( event = EventQueue->next; event != EventQueue; event = event->next )
		{
		assert( event );
		assert( event->event );
		assert( event->obj );

      if ( event->obj->isSubclassOf( Entity ) &&
         ( ( ( Entity * )event->obj )->flags & FL_DONTSAVE ) )
         {
         continue;
         }

      arc.WriteObjectPointer( event->obj );
      arc.WriteEvent( *event->event );
      arc.WriteFloat( event->time );
		}
	}

EXPORT_FROM_DLL void G_UnarchiveEvents
	(
	Archiver &arc
	)

	{
	eventcache_t *e;
   int i;

   LL_Reset( FreeEvents, next, prev );
	LL_Reset( EventQueue, next, prev );
	memset( Events, 0, sizeof( Events ) );

   arc.ReadInteger( &numEvents );
	for( e = &Events[ 0 ], i = 0; i < numEvents; i++, e++ )
		{
      arc.ReadObjectPointer( ( Class ** )&e->obj );
      e->event = new Event();
      arc.ReadEvent( e->event );
      arc.ReadFloat( &e->time );

      LL_Add( EventQueue, e, next, prev );
		}

   for( ; i < MAX_EVENTS; i++, e++ )
		{
		LL_Add( FreeEvents, e, next, prev );
		}
	}

EXPORT_FROM_DLL void G_InitEvents
	( 
	void 
	)

	{
	g_numevents = gi.cvar ( "g_numevents", "0", 0 );
	g_showevents = gi.cvar ( "g_showevents", "0", 0 );
   g_eventlimit = gi.cvar ( "g_eventlimit", "1500", 0 );
   g_timeevents = gi.cvar ( "g_timeevents", "0", 0 );
   g_watch = gi.cvar ( "g_watch", "0", 0 );

	BuildEventResponses();	
	G_ClearEventList();

	// Sort the list before we go on since we won't be adding any more events
	Event::SortEventList();
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -