SELECT

SELECT

#Overview

name: SELECT

This variable is created as a Console Variable (cvar).

It is referenced in 7 C++ source files.

#Summary

#Usage in the C++ source code

The purpose of SELECT is to perform I/O multiplexing in network programming, specifically within the CSimpleSocket class of the Unreal Engine’s networking system. It is used to monitor multiple file descriptors (typically sockets) to see if they are ready for reading, writing, or have an exceptional condition.

This setting variable is primarily utilized in the networking subsystem of Unreal Engine, particularly in the RiderLink plugin, which appears to be a third-party addition for IDE integration.

The value of this variable is not set directly; instead, it’s used as a function-like macro that wraps the system-specific select() function call. Its definition varies based on the target platform, as seen in the Host.h file.

SELECT interacts with other socket-related macros and variables such as RECVFROM, SEND, SENDTO, and file descriptors (m_socket, m_readFds, m_writeFds, m_errorFds).

Developers must be aware that:

  1. SELECT is platform-dependent and its implementation may vary.
  2. It’s a low-level networking operation that requires careful handling of file descriptors and timeouts.
  3. Incorrect usage can lead to blocking or performance issues in network communication.

Best practices when using this variable include:

  1. Ensure proper error handling and timeout management.
  2. Use it in non-blocking mode when appropriate to prevent hanging the application.
  3. Consider using higher-level abstractions provided by Unreal Engine for network programming when possible.
  4. Be mindful of the performance implications, especially when dealing with a large number of sockets.
  5. Properly initialize and manage the file descriptor sets used with SELECT.

#References in C++ code

#Callsites

This variable is referenced in the following C++ source code:

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:4239

Scope (from outer to inner):

file
function     bool UEditorEngine::Exec_Poly

Source code excerpt:

bool UEditorEngine::Exec_Poly( UWorld* InWorld, const TCHAR* Str, FOutputDevice& Ar )
{
	if( FParse::Command(&Str,TEXT("SELECT")) ) // POLY SELECT [ALL/NONE/INVERSE] FROM [LEVEL/SOLID/GROUP/ITEM/ADJACENT/MATCHING]
	{
		if( FParse::Command(&Str,TEXT("NONE")) )
		{
			return Exec( InWorld, TEXT("SELECT NONE") );
		}
		else if( FParse::Command(&Str,TEXT("ALL")) )

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:5628

Scope (from outer to inner):

file
function     bool UEditorEngine::Exec_Editor

Source code excerpt:

	// SELECT: Rerouted to mode-specific command
	//
	else if( FParse::Command(&Str,TEXT("SELECT")) )
	{
		HandleSelectCommand( Str, Ar, InWorld );
	}
	//------------------------------------------------------------------------------------
	// DELETE: Rerouted to mode-specific command
	//

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/EditorServer.cpp:6081

Scope (from outer to inner):

file
function     bool UEditorEngine::HandleMapCommand

Source code excerpt:

bool UEditorEngine::HandleMapCommand( const TCHAR* Str, FOutputDevice& Ar, UWorld* InWorld )
{
	if (FParse::Command(&Str,TEXT("SELECT")))
	{
		return Map_Select( InWorld, Str, Ar );
	}
	else if( FParse::Command(&Str,TEXT("BRUSH")) )
	{
		return Map_Brush( InWorld, Str, Ar );

#Loc: <Workspace>/Engine/Source/Editor/UnrealEd/Private/UnrealEdSrv.cpp:2392

Scope: file

Source code excerpt:

	}
	//@todo locked levels - handle the rest of these....is this required, or can we assume that actors in locked levels can't be selected
	else if( FParse::Command(&Str,TEXT("SELECT")) )
	{
		if( FParse::Command(&Str,TEXT("NONE")) ) // ACTOR SELECT NONE
		{
			return Exec( InWorld, TEXT("SELECT NONE") );
		}
		else if( FParse::Command(&Str,TEXT("ALL")) ) // ACTOR SELECT ALL

#Loc: <Workspace>/Projects/Lyra/Plugins/Developer/RiderLink/Source/RD/thirdparty/clsocket/src/Host.h:136

Scope: file

Source code excerpt:

#define RECVFROM(a,b,c,d,e,f)  recvfrom(a, (char *)b, c, d, (sockaddr *)e, (int *)f)
#define RECV_FLAGS             MSG_WAITALL
#define SELECT(a,b,c,d,e)      select((int32_t)a,b,c,d,e)
#define SEND(a,b,c,d)          send(a, (const char *)b, (int)c, d)
#define SENDTO(a,b,c,d,e,f)    sendto(a, (const char *)b, (int)c, d, e, f)
#define SEND_FLAGS             0
#define SENDFILE(a,b,c,d)      sendfile(a, b, c, d)
#define SET_SOCKET_ERROR(x,y)  errno=y
#define SOCKET_ERROR_INTERUPT  EINTR

#Loc: <Workspace>/Projects/Lyra/Plugins/Developer/RiderLink/Source/RD/thirdparty/clsocket/src/Host.h:159

Scope: file

Source code excerpt:

#define RECVFROM(a,b,c,d,e,f)  recvfrom(a, (char *)b, c, d, (sockaddr *)e, f)
#define RECV_FLAGS             MSG_WAITALL
#define SELECT(a,b,c,d,e)      select(a,b,c,d,e)
#define SEND(a,b,c,d)          send(a, (const int8_t *)b, c, d)
#define SENDTO(a,b,c,d,e,f)    sendto(a, (const int8_t *)b, c, d, e, f)
#define SEND_FLAGS             0
#define SENDFILE(a,b,c,d)      sendfile(a, b, c, d)
#define SET_SOCKET_ERROR(x,y)  errno=y
#define SOCKET_ERROR_INTERUPT  EINTR

#Loc: <Workspace>/Projects/Lyra/Plugins/Developer/RiderLink/Source/RD/thirdparty/clsocket/src/SimpleSocket.cpp:1150

Scope (from outer to inner):

file
function     bool CSimpleSocket::Select

Source code excerpt:

    }

    nNumDescriptors = SELECT(m_socket+1, &m_readFds, &m_writeFds, &m_errorFds, pTimeout);
//    nNumDescriptors = SELECT(m_socket+1, &m_readFds, NULL, NULL, pTimeout);

    //----------------------------------------------------------------------
    // Handle timeout
    //----------------------------------------------------------------------
    if (nNumDescriptors == 0)