HoverRaceCodingStandards – HoverRace – Trac

HoverRace Coding Standards

Source documentation

We're using Doxygen for inline source documentation.

A note on portability

One of the big goals for post-1.x development is portability to other platforms. To that end, new code should keep portability in mind:

  • Use standard C++ idioms where possible:
    • bool instead of BOOL
    • STL containers and algorithms
  • Limit use of MFC to interfaces with existing code
  • Persistent configuration settings should be managed by the MR_Config class instead of directly in the Registry.
  • Prefer portable libraries
    • The Boost library provides portable, C++-style wrappers for filesystem operations, threading, and much more.
    • The libcurl library provides a portable C-style API for HTTP and FTP operations.

One notable exception to the "portable library" rule is the UI. Since it's likely that the UI bits will need to be rewritten entirely for a future OpenGL renderer, we're sticking with standard (non-MFC) Win32 dialogs for now, with the aim of using winelib as a stopgap measure.

Whitespace and indentation

The main coding standard is 4-character tabs (not spaces).

Looking at existing code and imitating its formatting provides a good place to start. Here is an example, from NetInterface.cpp:

BOOL CALLBACK MR_NetworkInterface::WaitGameNameCallBack(HWND pWindow, UINT pMsgId, WPARAM pWParam, LPARAM pLParam)
{
    BOOL lReturnValue = FALSE;

    static SOCKET sNewSocket;

    switch (pMsgId) {
        // Catch environment modification events
        case WM_INITDIALOG:
            {   

                sNewSocket = socket(PF_INET, SOCK_STREAM, 0);

                if(sNewSocket == INVALID_SOCKET) {
                    SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_CANT_CREATE_SOCK));
                }
                else {
                    SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_CONNECTING_SERV));

                    SOCKADDR_IN lAddr;

                    lAddr.sin_family = AF_INET;
                    lAddr.sin_addr.s_addr = GetAddrFromStr(mActiveInterface->mServerAddr);
                    lAddr.sin_port = htons(mActiveInterface->mServerPort);

                    WSAAsyncSelect(sNewSocket, pWindow, MRM_SERVER_CONNECT, FD_CONNECT);

                    // Disable Nangle algo
                    int lCode;
                    int lTrue = 1;

                    lCode = setsockopt(sNewSocket, IPPROTO_TCP, TCP_NODELAY, (char *) &lTrue, sizeof(int));

                    ASSERT(lCode != SOCKET_ERROR);

                    // Reduce output queue to 512 bytes
                    int lQueueSize = 512;

                    lCode = setsockopt(sNewSocket, SOL_SOCKET, SO_SNDBUF, (char *) &lQueueSize, sizeof(int));

                    ASSERT(lCode != SOCKET_ERROR);

                    connect(sNewSocket, (struct sockaddr *) &lAddr, sizeof(lAddr));
                }
            }
            break;

        case MRM_SERVER_CONNECT:
            {
                MR_NetMessageBuffer lOutputBuffer;

                if(WSAGETSELECTERROR(pLParam) == 0) {
                    SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_GET_GAMEINFO));

                    mActiveInterface->mClient[0].Connect(sNewSocket);

                    WSAAsyncSelect(sNewSocket, pWindow, MRM_CLIENT, FD_READ);

                    SOCKADDR_IN lAddr;
                    int lSize = sizeof(lAddr);

                    lAddr.sin_family = AF_INET;

                    getsockname(mActiveInterface->mClient[0].GetSocket(), (struct sockaddr *) &lAddr, &lSize);

                    lAddr.sin_family = AF_INET;
                    // lAddr.sin_addr.s_addr = INADDR_ANY;
                    lAddr.sin_port = 0;

                    if(bind(mActiveInterface->mRegistrySocket, (LPSOCKADDR) & lAddr, sizeof(lAddr)) != 0) {
                        MessageBox(pWindow, MR_LoadString(IDS_CANT_CREATE_SOCK), MR_LoadString(IDS_TCP_CLIENT), MB_ICONERROR | MB_OK | MB_APPLMODAL);
                    }
    
                    lSize = sizeof(lAddr);
                    lAddr.sin_family = AF_INET;

                    getsockname(mActiveInterface->mRegistrySocket, (struct sockaddr *) &lAddr, &lSize);

                    lOutputBuffer.mMessageType = MRNM_GET_GAME_NAME;
                    lOutputBuffer.mDataLen = 8;
                    *(int *) &(lOutputBuffer.mData[0]) = lAddr.sin_addr.s_addr;
                    *(int *) &(lOutputBuffer.mData[4]) = lAddr.sin_port;

                    mActiveInterface->mClient[0].Send(&lOutputBuffer, MR_NET_REQUIRED);

                }   
                else {
                    SetDlgItemText(pWindow, IDC_TEXT, MR_LoadString(IDS_CANT_CONNECT));
                }
            }
            lReturnValue = TRUE;
            break;

        case MRM_CLIENT:
            {
                const MR_NetMessageBuffer *lBuffer = NULL;

                switch (WSAGETSELECTEVENT(pLParam)) {
                    case FD_READ:
                        WSAAsyncSelect(sNewSocket, pWindow, MRM_CLIENT, 0);
                        lBuffer = mActiveInterface->mClient[0].Poll();

                        if((lBuffer != NULL) && (lBuffer->mMessageType == MRNM_GAME_NAME)) {
                            mActiveInterface->mGameName = CString((const char *) lBuffer->mData, lBuffer->mDataLen);
                            EndDialog(pWindow, IDOK);
                        }
                        else {
                            // Bad message, reenable reception
                            WSAAsyncSelect(sNewSocket, pWindow, MRM_CLIENT, FD_READ);
                        }

                        break;

            }

        }
        lReturnValue = TRUE;
        break;

        case WM_COMMAND:
            switch (LOWORD(pWParam)) {
                case IDCANCEL:
                    lReturnValue = TRUE;
                    closesocket(sNewSocket);
                    mActiveInterface->mClient[0].Disconnect();
                    EndDialog(pWindow, IDCANCEL);
                    break;
            }
    }

    return lReturnValue;
}