<commit_before>#include <Windows.h>

LPCTSTR WndClassName = "firstwindow";
HWND hwnd = NULL;

const int Width = 800;
const int Height = 600;

bool InitializeWindow(HINSTANCE hInstance, int ShowWnd, int width, int height, bool windowed);
int messageloop();

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	if (!InitializeWindow(hInstance, nShowCmd, Width, Height, true))
	{
		MessageBox(0,  "Window Initialization - Failed",  "Error", MB_OK);
		return 0;
	}

	messageloop();

	return 0;
}
bool InitializeWindow(HINSTANCE hInstance, int ShowWnd, int width, int height, bool windowed)
{
	WNDCLASSEX wc;
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc = WndProc;
	wc.cbClsExtra = NULL;
	wc.cbWndExtra = NULL;
	wc.hInstance = hInstance;
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
	wc.lpszMenuName = NULL;
	wc.lpszClassName = WndClassName;
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL,  "Error registering class",  "Error", MB_OK | MB_ICONERROR);
		return 1;
	}

	hwnd = CreateWindowEx(NULL, WndClassName,  "Window Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);

	if (!hwnd)
	{
		MessageBox(NULL,  "Error creating window",  "Error", MB_OK | MB_ICONERROR);
		return 1;
	}
	ShowWindow(hwnd, ShowWnd);
	UpdateWindow(hwnd);
	return true;
}
int messageloop()
{
	MSG msg;
	ZeroMemory(&msg, sizeof(MSG));
	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT)
			{
				break;
			}
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else
		{
			//run game code
		}
	}
	return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
		{
			if (MessageBox(0,  "Are you sure you want to exit?",  "Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
			{
				DestroyWindow(hwnd);
			}
		}
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}<commit_msg>Updated commenting<commit_after>//Includes
#include <Windows.h>

//Global variables
LPCTSTR WndClassName = "firstwindow";
HWND hwnd = NULL;
const int Width = 800;
const int Height = 600;

//Function prototypes
bool InitializeWindow(HINSTANCE hInstance, int ShowWnd, int width, int height, bool windowed);
int messageloop();
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);

// Entry point
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
	if (!InitializeWindow(hInstance, nShowCmd, Width, Height, true))
	{
		MessageBox(0,  "Window Initialization - Failed",  "Error", MB_OK);
		return 0;
	}

	messageloop();

	return 0;
}
//Create window
bool InitializeWindow(HINSTANCE hInstance, int ShowWnd, int width, int height, bool windowed)
{
	WNDCLASSEX wc; //Wnd class
	wc.cbSize = sizeof(WNDCLASSEX);
	wc.style = CS_HREDRAW | CS_VREDRAW; //Redraw method
	wc.lpfnWndProc = WndProc; //Wnd stuff method
	wc.cbClsExtra = NULL;
	wc.cbWndExtra = NULL;
	wc.hInstance = hInstance; //hInstance to bind to
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); //Title bar icon
	wc.hCursor = LoadCursor(NULL, IDC_ARROW); //Cursor
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2); //Background brush to use
	wc.lpszMenuName = NULL; //Wnd menu
	wc.lpszClassName = WndClassName; //Class name of window
	wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION); //Taskbar icon
	//Check for registration errors
	if (!RegisterClassEx(&wc))
	{
		MessageBox(NULL,  "Error registering class",  "Error", MB_OK | MB_ICONERROR);
		return 1;
	}
	//Create wnd handle
	hwnd = CreateWindowEx(NULL, WndClassName,  "Window Title", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, width, height, NULL, NULL, hInstance, NULL);
	//verify hwnd was bound to an instance of wnd
	if (!hwnd)
	{
		MessageBox(NULL,  "Error creating window",  "Error", MB_OK | MB_ICONERROR);
		return 1;
	}
	ShowWindow(hwnd, ShowWnd); //Show the window
	UpdateWindow(hwnd); //Run the update loop once
	return true;
}
//Infinite message loop
int messageloop()
{
	MSG msg; //Create message memory structure
	ZeroMemory(&msg, sizeof(MSG)); //Clear it
	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) //Check to see if a message is waiting
		{
			if (msg.message == WM_QUIT) //Check to see if something ordered an application shutdown
			{
				break;
			}
			//If not quit, translate and dispatch message to rest of system
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
		else //No message was found
		{
			//run game code
		}
	}
	return msg.wParam;
}
//Wnd stuff
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	switch (msg)
	{
	case WM_KEYDOWN:
		if (wParam == VK_ESCAPE)
		{
			if (MessageBox(0,  "Are you sure you want to exit?",  "Really?", MB_YESNO | MB_ICONQUESTION) == IDYES)
			{
				DestroyWindow(hwnd);
			}
		}
		return 0;
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
	}
	return DefWindowProc(hwnd, msg, wParam, lParam);
}<|endoftext|>


<commit_before>// SYSTEM INCLUDES
//

#include <iostream>

// PROJECT INCLUDES
//

#include "StyleExample.hxx"

namespace SomeNamespace
{
    StyleExample::StyleExample()
    {
        _someValue    = 0;
        _anotherValue = 'a';
        _someString   = "abc";
    }

    StyleExample::~StyleExample()
    {
    }

    bool StyleExample::doSomething(std::string someString, int someNumber)
    {
        for (int i = 0; i < 3; i++) {
            if (someNumber % i)
                someNumber = i;
            std::cout << someString;
        }
        if (someNumber < 30)
            return someNumber * 3 - 23;
        else
            return someNumber * 89;

        // Short return:
        // return (a < 1) ? true : false;

    }

    void StyleExample::doSomethingWithManyArguments(
        int         argA,
        int         argB,
        std::string argC,
        std::string argD)
    {
        if (1 == argA) // I am a comment!
            std::cout << "aaa";

        // I am a long comment for the next statement. Always put the constant
        // on the laft hand side.
        if ("a" == argC)
            std::cout << "bbb";

        switch (argB) {
		case 1:
			std::cout << "foo";
			// FALL THROUGH

		case 2:
			std::cout << "bar" << std::endl;
			break;

		default:
			std::cout << "nothing" << std::endl;
			break;
        }

    }

    uint StyleExample::getSomeValue()
    {
    }

    bool StyleExample::isValid()
    {
        return true;
    }
}
<commit_msg>Fix: Wrong ndenting characters in coding style example<commit_after>// SYSTEM INCLUDES
//

#include <iostream>

// PROJECT INCLUDES
//

#include "StyleExample.hxx"

namespace SomeNamespace
{
    StyleExample::StyleExample()
    {
        _someValue    = 0;
        _anotherValue = 'a';
        _someString   = "abc";
    }

    StyleExample::~StyleExample()
    {
    }

    bool StyleExample::doSomething(std::string someString, int someNumber)
    {
        for (int i = 0; i < 3; i++) {
            if (someNumber % i)
                someNumber = i;
            std::cout << someString;
        }
        if (someNumber < 30)
            return someNumber * 3 - 23;
        else
            return someNumber * 89;

        // Short return:
        // return (a < 1) ? true : false;

    }

    void StyleExample::doSomethingWithManyArguments(
        int         argA,
        int         argB,
        std::string argC,
        std::string argD)
    {
        if (1 == argA) // I am a comment!
            std::cout << "aaa";

        // I am a long comment for the next statement. Always put the constant
        // on the laft hand side.
        if ("a" == argC)
            std::cout << "bbb";

        switch (argB) {
        case 1:
            std::cout << "foo";
            // FALL THROUGH

        case 2:
            std::cout << "bar" << std::endl;
            break;

        default:
            std::cout << "nothing" << std::endl;
            break;
        }

    }

    uint StyleExample::getSomeValue()
    {
    }

    bool StyleExample::isValid()
    {
        return true;
    }
}
<|endoftext|>


<commit_before>/****************************************************************************
 *
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "QGCFileDownload.h"

#include <QFileInfo>
#include <QStandardPaths>
#include <QNetworkProxy>

QGCFileDownload::QGCFileDownload(QObject* parent)
    : QNetworkAccessManager(parent)
{

}

bool QGCFileDownload::download(const QString& remoteFile, bool redirect)
{
    if (!redirect) {
        _originalRemoteFile = remoteFile;
    }

    if (remoteFile.isEmpty()) {
        qWarning() << "downloadFile empty";
        return false;
    }

    // Split out filename from path
    QString remoteFileName = QFileInfo(remoteFile).fileName();
    if (remoteFileName.isEmpty()) {
        qWarning() << "Unabled to parse filename from downloadFile" << remoteFile;
        return false;
    }

    // Strip out parameters from remote filename
    int parameterIndex = remoteFileName.indexOf("?");
    if (parameterIndex != -1) {
        remoteFileName  = remoteFileName.left(parameterIndex);
    }

    // Determine location to download file to
    QString localFile = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    if (localFile.isEmpty()) {
        localFile = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
        if (localFile.isEmpty()) {
            qDebug() << "Unabled to find writable download location. Tried downloads and temp directory.";
            return false;
        }
    }
    localFile += "/"  + remoteFileName;

    QUrl remoteUrl;
    if (remoteFile.startsWith("http:") || remoteFile.startsWith("https:")) {
        remoteUrl.setUrl(remoteFile);
    } else {
        remoteUrl = QUrl::fromLocalFile(remoteFile);
    }
    if (!remoteUrl.isValid()) {
        qWarning() << "Remote URL is invalid" << remoteFile;
        return false;
    }

    QNetworkRequest networkRequest(remoteUrl);

    QNetworkProxy tProxy;
    tProxy.setType(QNetworkProxy::DefaultProxy);
    setProxy(tProxy);

    // Store local file location in user attribute so we can retrieve when the download finishes
    networkRequest.setAttribute(QNetworkRequest::User, localFile);

    QNetworkReply* networkReply = get(networkRequest);
    if (!networkReply) {
        qWarning() << "QNetworkAccessManager::get failed";
        return false;
    }

    connect(networkReply, &QNetworkReply::downloadProgress, this, &QGCFileDownload::downloadProgress);
    connect(networkReply, &QNetworkReply::finished, this, &QGCFileDownload::_downloadFinished);
    connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
            this, &QGCFileDownload::_downloadError);

    return true;
}

void QGCFileDownload::_downloadFinished(void)
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender());

    // When an error occurs or the user cancels the download, we still end up here. So bail out in
    // those cases.
    if (reply->error() != QNetworkReply::NoError) {
        reply->deleteLater();
        return;
    }

    // Check for redirection
    QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (!redirectionTarget.isNull()) {
        QUrl redirectUrl = reply->url().resolved(redirectionTarget.toUrl());
        download(redirectUrl.toString(), true /* redirect */);
        reply->deleteLater();
        return;
    }

    // Download file location is in user attribute
    QString downloadFilename = reply->request().attribute(QNetworkRequest::User).toString();

    if (!downloadFilename.isEmpty()) {
        // Store downloaded file in download location
        QFile file(downloadFilename);
        if (!file.open(QIODevice::WriteOnly)) {
            emit error(tr("Could not save downloaded file to %1. Error: %2").arg(downloadFilename).arg(file.errorString()));
            return;
        }

        file.write(reply->readAll());
        file.close();

        emit downloadFinished(_originalRemoteFile, downloadFilename);
    } else {
        QString errorMsg = "Internal error";
        qWarning() << errorMsg;
        emit error(errorMsg);
    }

    reply->deleteLater();
}

/// @brief Called when an error occurs during download
void QGCFileDownload::_downloadError(QNetworkReply::NetworkError code)
{
    QString errorMsg;

    if (code == QNetworkReply::OperationCanceledError) {
        errorMsg = tr("Download cancelled");

    } else if (code == QNetworkReply::ContentNotFoundError) {
        errorMsg = tr("Error: File Not Found");

    } else {
        errorMsg = tr("Error during download. Error: %1").arg(code);
    }

    emit error(errorMsg);
}
<commit_msg>QGCFileDownload: Add new errorOccurred for Qt 5.15 builds<commit_after>/****************************************************************************
 *
 * (c) 2009-2020 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
 *
 * QGroundControl is licensed according to the terms in the file
 * COPYING.md in the root of the source code directory.
 *
 ****************************************************************************/

#include "QGCFileDownload.h"

#include <QFileInfo>
#include <QStandardPaths>
#include <QNetworkProxy>

QGCFileDownload::QGCFileDownload(QObject* parent)
    : QNetworkAccessManager(parent)
{

}

bool QGCFileDownload::download(const QString& remoteFile, bool redirect)
{
    if (!redirect) {
        _originalRemoteFile = remoteFile;
    }

    if (remoteFile.isEmpty()) {
        qWarning() << "downloadFile empty";
        return false;
    }

    // Split out filename from path
    QString remoteFileName = QFileInfo(remoteFile).fileName();
    if (remoteFileName.isEmpty()) {
        qWarning() << "Unabled to parse filename from downloadFile" << remoteFile;
        return false;
    }

    // Strip out parameters from remote filename
    int parameterIndex = remoteFileName.indexOf("?");
    if (parameterIndex != -1) {
        remoteFileName  = remoteFileName.left(parameterIndex);
    }

    // Determine location to download file to
    QString localFile = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    if (localFile.isEmpty()) {
        localFile = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
        if (localFile.isEmpty()) {
            qDebug() << "Unabled to find writable download location. Tried downloads and temp directory.";
            return false;
        }
    }
    localFile += "/"  + remoteFileName;

    QUrl remoteUrl;
    if (remoteFile.startsWith("http:") || remoteFile.startsWith("https:")) {
        remoteUrl.setUrl(remoteFile);
    } else {
        remoteUrl = QUrl::fromLocalFile(remoteFile);
    }
    if (!remoteUrl.isValid()) {
        qWarning() << "Remote URL is invalid" << remoteFile;
        return false;
    }

    QNetworkRequest networkRequest(remoteUrl);

    QNetworkProxy tProxy;
    tProxy.setType(QNetworkProxy::DefaultProxy);
    setProxy(tProxy);

    // Store local file location in user attribute so we can retrieve when the download finishes
    networkRequest.setAttribute(QNetworkRequest::User, localFile);

    QNetworkReply* networkReply = get(networkRequest);
    if (!networkReply) {
        qWarning() << "QNetworkAccessManager::get failed";
        return false;
    }

    connect(networkReply, &QNetworkReply::downloadProgress, this, &QGCFileDownload::downloadProgress);
    connect(networkReply, &QNetworkReply::finished, this, &QGCFileDownload::_downloadFinished);
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
    connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
            this, &QGCFileDownload::_downloadError);
#else
    connect(networkReply, &QNetworkReply::errorOccurred, this, &QGCFileDownload::_downloadError);
#endif
    return true;
}

void QGCFileDownload::_downloadFinished(void)
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender());

    // When an error occurs or the user cancels the download, we still end up here. So bail out in
    // those cases.
    if (reply->error() != QNetworkReply::NoError) {
        reply->deleteLater();
        return;
    }

    // Check for redirection
    QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
    if (!redirectionTarget.isNull()) {
        QUrl redirectUrl = reply->url().resolved(redirectionTarget.toUrl());
        download(redirectUrl.toString(), true /* redirect */);
        reply->deleteLater();
        return;
    }

    // Download file location is in user attribute
    QString downloadFilename = reply->request().attribute(QNetworkRequest::User).toString();

    if (!downloadFilename.isEmpty()) {
        // Store downloaded file in download location
        QFile file(downloadFilename);
        if (!file.open(QIODevice::WriteOnly)) {
            emit error(tr("Could not save downloaded file to %1. Error: %2").arg(downloadFilename).arg(file.errorString()));
            return;
        }

        file.write(reply->readAll());
        file.close();

        emit downloadFinished(_originalRemoteFile, downloadFilename);
    } else {
        QString errorMsg = "Internal error";
        qWarning() << errorMsg;
        emit error(errorMsg);
    }

    reply->deleteLater();
}

/// @brief Called when an error occurs during download
void QGCFileDownload::_downloadError(QNetworkReply::NetworkError code)
{
    QString errorMsg;

    if (code == QNetworkReply::OperationCanceledError) {
        errorMsg = tr("Download cancelled");

    } else if (code == QNetworkReply::ContentNotFoundError) {
        errorMsg = tr("Error: File Not Found");

    } else {
        errorMsg = tr("Error during download. Error: %1").arg(code);
    }

    emit error(errorMsg);
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#include "libtorrent/socket.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/socket_type.hpp"
#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include <asio/io_service.hpp>

namespace libtorrent
{

	bool instantiate_connection(asio::io_service& ios
		, proxy_settings const& ps, socket_type& s)
	{
		if (ps.type == proxy_settings::none)
		{
			s.instantiate<stream_socket>(ios);
		}
		else if (ps.type == proxy_settings::http
			|| ps.type == proxy_settings::http_pw)
		{
			s.instantiate<http_stream>(ios);
			s.get<http_stream>().set_proxy(ps.hostname, ps.port);
			if (ps.type == proxy_settings::socks5_pw)
				s.get<http_stream>().set_username(ps.username, ps.password);
		}
		else if (ps.type == proxy_settings::socks5
			|| ps.type == proxy_settings::socks5_pw)
		{
			s.instantiate<socks5_stream>(ios);
			s.get<socks5_stream>().set_proxy(ps.hostname, ps.port);
			if (ps.type == proxy_settings::socks5_pw)
				s.get<socks5_stream>().set_username(ps.username, ps.password);
		}
		else if (ps.type == proxy_settings::socks4)
		{
			s.instantiate<socks4_stream>(ios);
			s.get<socks4_stream>().set_proxy(ps.hostname, ps.port);
			s.get<socks4_stream>().set_username(ps.username);
		}
		else
		{
			return false;
		}
		return true;
	}

}

<commit_msg>fixed http proxy (with authentication) bug<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#include "libtorrent/pch.hpp"

#include "libtorrent/socket.hpp"
#include "libtorrent/session_settings.hpp"
#include "libtorrent/socket_type.hpp"
#include <boost/shared_ptr.hpp>
#include <stdexcept>
#include <asio/io_service.hpp>

namespace libtorrent
{

	bool instantiate_connection(asio::io_service& ios
		, proxy_settings const& ps, socket_type& s)
	{
		if (ps.type == proxy_settings::none)
		{
			s.instantiate<stream_socket>(ios);
		}
		else if (ps.type == proxy_settings::http
			|| ps.type == proxy_settings::http_pw)
		{
			s.instantiate<http_stream>(ios);
			s.get<http_stream>().set_proxy(ps.hostname, ps.port);
			if (ps.type == proxy_settings::http_pw)
				s.get<http_stream>().set_username(ps.username, ps.password);
		}
		else if (ps.type == proxy_settings::socks5
			|| ps.type == proxy_settings::socks5_pw)
		{
			s.instantiate<socks5_stream>(ios);
			s.get<socks5_stream>().set_proxy(ps.hostname, ps.port);
			if (ps.type == proxy_settings::socks5_pw)
				s.get<socks5_stream>().set_username(ps.username, ps.password);
		}
		else if (ps.type == proxy_settings::socks4)
		{
			s.instantiate<socks4_stream>(ios);
			s.get<socks4_stream>().set_proxy(ps.hostname, ps.port);
			s.get<socks4_stream>().set_username(ps.username);
		}
		else
		{
			return false;
		}
		return true;
	}

}

<|endoftext|>


<commit_before>#include <climits>
#include <elevator/elevator.h>
#include <wibble/commandline/parser.h>
#include <iostream>

namespace elevator {

using namespace wibble;
using namespace wibble::commandline;

struct Main {

    StandardParser opts;
    OptionGroup *execution;
    IntOption *nodes;
    BoolOption *avoidRecovery;
    IntOption *elevatorId;

    Main( int argc, const char **argv ) : opts( "elevator", "0.1" ) {
        // setup options
        execution = opts.createGroup( "Execution options" );
        nodes = execution->add< IntOption >(
                "nodes", 'n', "nodes", "",
                "specifies number of elevator nodes to expect" );
        elevatorId = execution->add< IntOption >(
                "elevator id", 'i', "elevator-id", "",
                "explicitly set elevator id" );

        avoidRecovery = execution->add< BoolOption >(
                "avoid recovery", 0, "avoid-recovery", "",
                "avoid auto-recovery when program is killed (do not fork)" );

        opts.usage = "";
        opts.description = "Elevator control software as a project for the "
                           "TTK4145 Real-Time Programming at NTNU. Controls "
                           "multiple elevator connected with local network.\n"
                           "(c) 2014, Vladimír Štill and Sameh Khalil\n"
                           "https://github.com/vlstill/ttk4145/tree/master/project";

        opts.add( execution );

        // parse options
        try {
            opts.parse( argc, argv );
        } catch ( exception::BadOption &ex ) {
            std::cerr << "FATAL: " << ex.fullInfo() << std::endl;
            exit( 1 );
        }
        if ( opts.help->boolValue() || opts.version->boolValue() )
            exit( 0 );
    }

    void main() {
        int id = INT_MIN;
        if ( elevatorId->boolValue() ) {
            id = elevatorId->intValue();
        } else {
            // TODO
        }

        if ( avoidRecovery->boolValue() ) {
            runElevator( id );
        } else {
            assert_unimplemented();
        }
    }

    void runElevator( int id ) {
        HeartBeatManager heartbeatManager;

        ConcurrentQueue< Command > commandsToLocalElevator;
        /*
        ConcurrentQueue< Status > statusFromLocalElevator;
        ConcurrentQueue< Command > commandsToOthers;
        ConcurrentQueue< Status > statusFromOthers;
        */

        Elevator elevator{ id, heartbeatManager.getNew( 100 /* ms */ ), &commandsToLocalElevator };

        elevator.run();

        // wait for 2 seconds so that everything has chance to start
        // it something fails to start in this time heartbeat will
        // fail and process will be terminated
        std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
        heartbeatManager.runInThisThread();
    }
};

}

int main( int args, const char **argv ) {
    elevator::Main m( args, argv );
    m.main();
}
<commit_msg>main: Run scheduler also.<commit_after>#include <climits>
#include <elevator/elevator.h>
#include <elevator/scheduler.h>
#include <wibble/commandline/parser.h>
#include <iostream>

namespace elevator {

using namespace wibble;
using namespace wibble::commandline;

struct Main {

    StandardParser opts;
    OptionGroup *execution;
    IntOption *nodes;
    BoolOption *avoidRecovery;
    IntOption *elevatorId;

    Main( int argc, const char **argv ) : opts( "elevator", "0.1" ) {
        // setup options
        execution = opts.createGroup( "Execution options" );
        nodes = execution->add< IntOption >(
                "nodes", 'n', "nodes", "",
                "specifies number of elevator nodes to expect" );
        elevatorId = execution->add< IntOption >(
                "elevator id", 'i', "elevator-id", "",
                "explicitly set elevator id" );

        avoidRecovery = execution->add< BoolOption >(
                "avoid recovery", 0, "avoid-recovery", "",
                "avoid auto-recovery when program is killed (do not fork)" );

        opts.usage = "";
        opts.description = "Elevator control software as a project for the "
                           "TTK4145 Real-Time Programming at NTNU. Controls "
                           "multiple elevator connected with local network.\n"
                           "(c) 2014, Vladimír Štill and Sameh Khalil\n"
                           "https://github.com/vlstill/ttk4145/tree/master/project";

        opts.add( execution );

        // parse options
        try {
            opts.parse( argc, argv );
        } catch ( exception::BadOption &ex ) {
            std::cerr << "FATAL: " << ex.fullInfo() << std::endl;
            exit( 1 );
        }
        if ( opts.help->boolValue() || opts.version->boolValue() )
            exit( 0 );
    }

    void main() {
        int id = INT_MIN;
        if ( elevatorId->boolValue() ) {
            id = elevatorId->intValue();
        } else {
            // TODO
        }

        if ( avoidRecovery->boolValue() ) {
            runElevator( id );
        } else {
            assert_unimplemented();
        }
    }

    void runElevator( int id ) {
        HeartBeatManager heartbeatManager;

        ConcurrentQueue< Command > commandsToLocalElevator;
        ConcurrentQueue< Command > commandsToOthers;
        ConcurrentQueue< StateChange > stateChanges;

        Elevator elevator{ id, heartbeatManager.getNew( 100 /* ms */ ),
            commandsToLocalElevator, stateChanges };
        Scheduler scheduler{ heartbeatManager.getNew( 500 /* ms */ ),
            stateChanges, commandsToLocalElevator, commandsToOthers };

        elevator.run();
        scheduler.run();

        // wait for 2 seconds so that everything has chance to start
        // it something fails to start in this time heartbeat will
        // fail and process will be terminated
        std::this_thread::sleep_for( std::chrono::seconds( 2 ) );
        heartbeatManager.runInThisThread();
    }
};

}

int main( int args, const char **argv ) {
    elevator::Main m( args, argv );
    m.main();
}
<|endoftext|>


<commit_before>#include "eigen-qp.hpp"

#include <Eigen/Eigenvalues>
#include <boost/timer/timer.hpp>
#include <iostream>

using namespace std;
using namespace Eigen;
/*
 *  min 0.5 x.Q.x + c.x
 *
 *  Ax <= b
 *  Ex = d
 *
 * See: http://etd.dtu.dk/thesis/220437/ep08_19.pdf
 */

void solve_qp(MatrixXd &Q, VectorXd &c, MatrixXd &A, VectorXd &b, VectorXd &x)
{
	int N = c.size();
	int m = b.size();

	// Slack vars
	VectorXd s = VectorXd::Random(m).array().abs().matrix();
	VectorXd z = VectorXd::Random(m).array().abs().matrix();
	x.setRandom();

	// Jacobian
	MatrixXd J(N + 2*m, N + 2*m );

	J.setZero();
	J.block(0,0,N,N) = Q;
	J.block(N,N+m,m,m).setIdentity();
	J.block(N,0,m,N) = -1.0*A;
	J.block(0,N,N,m) = -1.0*A.adjoint();

	// Residual thing?
	bool converged=false;

	VectorXd r(N+2*m);

	r.head(N) = Q*x + c - A.transpose()*z;
	r.segment(N,m) = s - A*x + b;
	r.tail(m) = (s.array()*z.array()).matrix();

	double mu = s.dot(z)/m;
	cout << "mu = " << mu << endl;
	for (int iter=0; iter < 100; iter++)
	{
		// Build Jacobian
		J.block(N+m,N,m,m).diagonal() = s;
		J.block(N+m,N+m,m,m).diagonal() = z;
		auto Jinv = J.ldlt();

		VectorXd delt_aff = Jinv.solve(-1.0*r);

		// Compute predictor step length
		double alpha = 1.0;
		for (int jj=0; jj < m; jj++)
		{
			double a = -z(jj)/delt_aff(N+jj);
			alpha = (a < alpha) && (a >= 0) ? a : alpha;
			a = -s(jj)/delt_aff(N+m+jj);
			alpha = (a < alpha) && (a >= 0) ? a : alpha;
		}

		double mu_aff = (s + alpha*delt_aff.tail(m)).dot(z+alpha*delt_aff.segment(N,m))/m;
		double sigma  = (mu_aff/mu);
		sigma *= sigma*sigma; // sigma^3

		r.tail(m) +=  (delt_aff.tail(m).array()*delt_aff.segment(N,m).array() - sigma*mu).matrix();

		VectorXd step = Jinv.solve(-1.0*r);

		// Compute alpha again
		alpha = 1.0;
		for (int jj=0; jj < m; jj++)
		{
			double a = -z(jj)/delt_aff(N+jj);
			alpha = (a < alpha) && (a > 0) ? a : alpha;
			a = -s(jj)/delt_aff(N+m+jj);
			alpha = (a < alpha) && (a > 0) ? a : alpha;
		}

		// Step
		x += alpha*delt_aff.head(N);
		z += alpha*delt_aff.segment(N,m);
		s += alpha*delt_aff.tail(m);

		// Update residuals
		r.head(N) = Q*x + c - A.transpose()*z;
		r.segment(N,m) = s - A*x + b;
		r.tail(m) = (s.array()*z.array()).matrix();

		mu = s.dot(z)/m;
		// cout << "iter: " << iter << " step: " << alpha*delt_aff.head(N).norm() << " mu: " << mu << endl;
	}

}
int main(int argc, char **argv)
{

	// Make a random problem
	int num_vars = 40;
	int num_ineq = 30;
	int num_eq   = 1;

	// Random matrices
	MatrixXd Q = MatrixXd::Random(num_vars,num_vars);
	Q *= Q.adjoint()/sqrt(num_vars); // Make it pos def

	VectorXd c = VectorXd::Random(num_vars);

	MatrixXd A = MatrixXd::Random(num_ineq,num_vars);
	VectorXd b = VectorXd::Random(num_ineq);

	MatrixXd E = MatrixXd::Random(num_eq,num_vars);
	VectorXd d = VectorXd::Random(num_eq);

	// Solve unconstrainted system
	{
		boost::timer::auto_cpu_timer t;
		VectorXd x_unconstrained = Q.ldlt().solve(c);
	}
	// Solve equality constrained system: easy
	{
		boost::timer::auto_cpu_timer t;

		MatrixXd aug_A(num_vars+num_eq,num_vars+num_eq);
		VectorXd aug_b(num_vars+num_eq);

		aug_A.block(0,0,num_vars,num_vars) = Q;
		aug_A.block(num_vars,0,num_eq,num_vars) = E;
		aug_A.block(0,num_vars,num_vars,num_eq) = E.transpose();
		aug_A.block(num_vars,num_vars,num_eq,num_eq).setZero();

		aug_b.head(num_vars) = c;
		aug_b.tail(num_eq)   = d;

		VectorXd x_equality = aug_A.ldlt().solve(aug_b).head(num_vars);
	}
	// Inequality constrained problem
	{
		boost::timer::auto_cpu_timer t;

		VectorXd x(num_vars);
		solve_qp(Q,c,A,b,x);
	}
	return 0;
}<commit_msg>Fixed some issues with matrix inversion.<commit_after>#include "eigen-qp.hpp"

#include <Eigen/Eigenvalues>
#include <boost/timer/timer.hpp>
#include <iostream>

using namespace std;
using namespace Eigen;
/*
 *  min 0.5 x.Q.x + c.x
 *
 *  Ax <= b
 *  Ex = d
 *
 * See: http://etd.dtu.dk/thesis/220437/ep08_19.pdf
 */

void solve_qp(MatrixXd &Q, VectorXd &c, MatrixXd &A, VectorXd &b, VectorXd &x)
{
	int N = c.size();
	int m = b.size();

	// Slack vars
	VectorXd s = VectorXd::Random(m).array().abs().matrix();
	VectorXd z = VectorXd::Random(m).array().abs().matrix();
	x.setRandom();

	// Jacobian
	MatrixXd J(N + 2*m, N + 2*m );

	J.setZero();
	J.block(0,0,N,N) = Q;
	J.block(N,N+m,m,m).setIdentity();
	J.block(N,0,m,N) = -1.0*A;
	J.block(0,N,N,m) = -1.0*A.adjoint();

	// Residual thing?
	bool converged=false;

	VectorXd r(N+2*m);
	VectorXd delt_aff(N+2*m);

	r.head(N) = Q*x + c - A.transpose()*z;
	r.segment(N,m) = s - A*x + b;
	r.tail(m) = (s.array()*z.array()).matrix();

	double mu = s.dot(z)/m;
	double alpha = 1.0;

	cout << "mu = " << mu << endl;
	for (int iter=0; iter < 46; iter++)
	{
		// Build Jacobian
		J.block(N+m,N,m,m).diagonal() = s;
		J.block(N+m,N+m,m,m).diagonal() = z;
		auto Jinv = J.colPivHouseholderQr();

		delt_aff = Jinv.solve(-1.0*r);

		// Compute predictor step length
		alpha = 1.0;
		for (int jj=0; jj < m; jj++)
		{
			double a = -z(jj)/delt_aff(N+jj);
			alpha = (a < alpha) && (a >= 0) ? a : alpha;
			a = -s(jj)/delt_aff(N+m+jj);
			alpha = (a < alpha) && (a >= 0) ? a : alpha;
		}

		double mu_aff = (s + alpha*delt_aff.tail(m)).dot(z+alpha*delt_aff.segment(N,m))/m;
		double sigma  = (mu_aff/mu);
		sigma *= sigma*sigma; // sigma^3

		r.tail(m) +=  (delt_aff.tail(m).array()*delt_aff.segment(N,m).array() - sigma*mu).matrix();

		delt_aff = Jinv.solve(-1.0*r);

		// Compute alpha again
		alpha = 1.0;
		for (int jj=0; jj < m; jj++)
		{
			double a = -z(jj)/delt_aff(N+jj);
			alpha = (a < alpha) && (a > 0) ? a : alpha;
			a = -s(jj)/delt_aff(N+m+jj);
			alpha = (a < alpha) && (a > 0) ? a : alpha;
		}

		// Step
		x += alpha*delt_aff.head(N);
		z += alpha*delt_aff.segment(N,m);
		s += alpha*delt_aff.tail(m);

		// Convergence check
		mu = s.dot(z)/m;
		double step = alpha*delt_aff.norm();

		if (mu < 1E-6 && step < 1E-6)
		{
			cout << "Finished in " << iter << " iterations." << endl;
			break;
		}
		// cout << "iter: " << iter << " step: " << alpha*delt_aff.norm() << " mu: " << mu << endl;

		// Update residuals
		r.head(N) = Q*x + c - A.transpose()*z;
		r.segment(N,m) = s - A*x + b;
		r.tail(m) = (s.array()*z.array()).matrix();
	}

}
int main(int argc, char **argv)
{

	// Make a random problem
	int num_vars = 1000;
	int num_ineq = 30;
	int num_eq   = 1;

	// Random matrices
	MatrixXd Q = MatrixXd::Random(num_vars,num_vars);
	Q *= Q.adjoint()/sqrt(num_vars); // Make it pos def

	VectorXd c = VectorXd::Random(num_vars);

	MatrixXd A = MatrixXd::Random(num_ineq,num_vars);
	VectorXd b = VectorXd::Random(num_ineq);

	MatrixXd E = MatrixXd::Random(num_eq,num_vars);
	VectorXd d = VectorXd::Random(num_eq);

	// Solve unconstrainted system
	{
		boost::timer::auto_cpu_timer t;
		VectorXd x_unconstrained = Q.ldlt().solve(c);
	}
	// Solve equality constrained system: easy
	{
		boost::timer::auto_cpu_timer t;

		MatrixXd aug_A(num_vars+num_eq,num_vars+num_eq);
		VectorXd aug_b(num_vars+num_eq);

		aug_A.block(0,0,num_vars,num_vars) = Q;
		aug_A.block(num_vars,0,num_eq,num_vars) = E;
		aug_A.block(0,num_vars,num_vars,num_eq) = E.transpose();
		aug_A.block(num_vars,num_vars,num_eq,num_eq).setZero();

		aug_b.head(num_vars) = c;
		aug_b.tail(num_eq)   = d;

		VectorXd x_equality = aug_A.ldlt().solve(aug_b).head(num_vars);
	}
	// Inequality constrained problem
	{
		boost::timer::auto_cpu_timer t;

		VectorXd x(num_vars);
		solve_qp(Q,c,A,b,x);
	}
	return 0;
}<|endoftext|>


<commit_before>/*
 * Copyright 2015 - 2021 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "bit.hpp"
#include "new.hpp"
#include "types.hpp"
#include "utility.hpp"

namespace ox {

template<typename T>
class Vector {

	private:
		std::size_t m_size = 0;
		std::size_t m_cap = 0;
		T *m_items = nullptr;

	public:
		Vector() noexcept = default;

		explicit Vector(std::size_t size) noexcept;

		Vector(const Vector &other);

		Vector(Vector &&other) noexcept;

		~Vector();

		bool operator==(const Vector &other) const;

		Vector &operator=(const Vector &other);

		Vector &operator=(Vector &&other);

		[[nodiscard]]
		T &operator[](std::size_t i) noexcept;

		[[nodiscard]]
		const T &operator[](std::size_t i) const noexcept;

		[[nodiscard]]
		Result<T&> front() noexcept;

		[[nodiscard]]
		Result<const T&> front() const noexcept;

		[[nodiscard]]
		Result<T&> back() noexcept;

		[[nodiscard]]
		Result<const T&> back() const noexcept;

		[[nodiscard]]
		std::size_t size() const noexcept;

		[[nodiscard]]
		bool empty() const noexcept;

		void clear();

		void resize(std::size_t size);

		[[nodiscard]]
		constexpr T *data() noexcept {
			return m_items;
		}

		[[nodiscard]]
		constexpr const T *data() const noexcept {
			return m_items;
		}

		[[nodiscard]] bool contains(const T&) const;

		void insert(std::size_t pos, const T &val);

		template<typename... Args>
		void emplace_back(Args&&... args);

		void push_back(const T &item);

		void pop_back();

		/**
		 * Removes an item from the Vector.
		 * @param pos position of item to remove
		 * @return Error if index is out of bounds
		 */
		Error erase(std::size_t pos);

		/**
		 * Moves the last item in the Vector to position pos and decrements the
		 * size by 1.
		 * @param pos position of item to remove
		 * @return Error if index is out of bounds
		 */
		Error unordered_erase(std::size_t pos);

	private:
		void expandCap(std::size_t cap);

};

template<typename T>
Vector<T>::Vector(std::size_t size) noexcept {
	m_size = size;
	m_cap = m_size;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	for (std::size_t i = 0; i < size; i++) {
		m_items[i] = {};
	}
}

template<typename T>
Vector<T>::Vector(const Vector<T> &other) {
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	for (std::size_t i = 0; i < m_size; i++) {
		m_items[i] = ox::move(other.m_items[i]);
	}
}

template<typename T>
Vector<T>::Vector(Vector<T> &&other) noexcept {
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = other.m_items;
	other.m_size = 0;
	other.m_cap = 0;
	other.m_items = nullptr;
}

template<typename T>
Vector<T>::~Vector() {
	if constexpr(ox::is_class<T>()) {
		for (std::size_t i = 0; i < m_size; i++) {
			m_items[i].~T();
		}
	}
	delete[] bit_cast<AllocAlias<T>*>(m_items);
	m_items = nullptr;
}

template<typename T>
bool Vector<T>::operator==(const Vector<T> &other) const {
	for (std::size_t i = 0; i < m_size; i++) {
		if (!(m_items[i] == other.m_items[i])) {
			return false;
		}
	}
	return true;
}

template<typename T>
Vector<T> &Vector<T>::operator=(const Vector<T> &other) {
	this->~Vector<T>();
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	for (std::size_t i = 0; i < m_size; i++) {
		m_items[i] = other.m_items[i];
	}
	return *this;
}

template<typename T>
Vector<T> &Vector<T>::operator=(Vector<T> &&other) {
	this->~Vector<T>();
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = other.m_items;
	other.m_size = 0;
	other.m_cap = 0;
	other.m_items = nullptr;
	return *this;
}

template<typename T>
T &Vector<T>::operator[](std::size_t i) noexcept {
	return m_items[i];
}

template<typename T>
const T &Vector<T>::operator[](std::size_t i) const noexcept {
	return m_items[i];
}

template<typename T>
Result<T&> Vector<T>::front() noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[0];
}

template<typename T>
Result<const T&> Vector<T>::front() const noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[0];
}

template<typename T>
Result<T&> Vector<T>::back() noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[m_size - 1];
}

template<typename T>
Result<const T&> Vector<T>::back() const noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[m_size - 1];
}

template<typename T>
std::size_t Vector<T>::size() const noexcept {
	return m_size;
}

template<typename T>
bool Vector<T>::empty() const noexcept {
	return !m_size;
}

template<typename T>
void Vector<T>::clear() {
	resize(0);
}

template<typename T>
void Vector<T>::resize(std::size_t size) {
	if (m_cap < size) {
		expandCap(size);
	}
	if (m_size < size) {
		for (std::size_t i = m_size; i < size; i++) {
			m_items[i] = {};
		}
	} else {
		for (std::size_t i = size; i < m_size; i++) {
			m_items[i].~T();
		}
	}
	m_size = size;
}

template<typename T>
bool Vector<T>::contains(const T &v) const {
	for (std::size_t i = 0; i < m_size; i++) {
		if (m_items[i] == v) {
			return true;
		}
	}
	return false;
}

template<typename T>
void Vector<T>::insert(std::size_t pos, const T &val) {
	// TODO: insert should ideally have its own expandCap
	if (m_size == m_cap) {
		expandCap(m_cap ? m_cap * 2 : 100);
	}
	for (auto i = m_size; i > pos; --i) {
		m_items[i] = ox::move(m_items[i - 1]);
	}
	m_items[pos] = val;
	++m_size;
}

template<typename T>
template<typename... Args>
void Vector<T>::emplace_back(Args&&... args) {
	if (m_size == m_cap) {
		expandCap(m_cap ? m_cap * 2 : 100);
	}
	new (&m_items[m_size]) T{args...};
	++m_size;
}

template<typename T>
void Vector<T>::push_back(const T &item) {
	if (m_size == m_cap) {
		expandCap(m_cap ? m_cap * 2 : 100);
	}
	new (&m_items[m_size]) T(item);
	++m_size;
}

template<typename T>
void Vector<T>::pop_back() {
	--m_size;
	m_items[m_size].~T();
}

template<typename T>
Error Vector<T>::erase(std::size_t pos) {
	if (pos >= m_size) {
		return OxError(1);
	}
	--m_size;
	for (auto i = pos; i < m_size; ++i) {
		m_items[i] = ox::move(m_items[i + 1]);
	}
	return OxError(0);
}

template<typename T>
Error Vector<T>::unordered_erase(std::size_t pos) {
	if (pos >= m_size) {
		return OxError(1);
	}
	m_size--;
	m_items[pos] = ox::move(m_items[m_size]);
	return OxError(0);
}

template<typename T>
void Vector<T>::expandCap(std::size_t cap) {
	auto oldItems = m_items;
	m_cap = cap;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	if (oldItems) { // move over old items
		const auto itRange = cap > m_size ? m_size : cap;
		for (std::size_t i = 0; i < itRange; i++) {
			m_items[i] = ox::move(oldItems[i]);
		}
		for (std::size_t i = itRange; i < m_cap; i++) {
			new (&m_items[i]) T;
		}
		delete[] bit_cast<AllocAlias<T>*>(oldItems);
	}
}

}
<commit_msg>[ox/std] Cleanup<commit_after>/*
 * Copyright 2015 - 2021 gary@drinkingtea.net
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#pragma once

#include "bit.hpp"
#include "new.hpp"
#include "types.hpp"
#include "utility.hpp"

namespace ox {

template<typename T>
class Vector {

	private:
		std::size_t m_size = 0;
		std::size_t m_cap = 0;
		T *m_items = nullptr;

	public:
		Vector() noexcept = default;

		explicit Vector(std::size_t size) noexcept;

		Vector(const Vector &other);

		Vector(Vector &&other) noexcept;

		~Vector();

		bool operator==(const Vector &other) const;

		Vector &operator=(const Vector &other);

		Vector &operator=(Vector &&other);

		[[nodiscard]]
		T &operator[](std::size_t i) noexcept;

		[[nodiscard]]
		const T &operator[](std::size_t i) const noexcept;

		[[nodiscard]]
		Result<T&> front() noexcept;

		[[nodiscard]]
		Result<const T&> front() const noexcept;

		[[nodiscard]]
		Result<T&> back() noexcept;

		[[nodiscard]]
		Result<const T&> back() const noexcept;

		[[nodiscard]]
		std::size_t size() const noexcept;

		[[nodiscard]]
		bool empty() const noexcept;

		void clear();

		void resize(std::size_t size);

		[[nodiscard]]
		constexpr T *data() noexcept {
			return m_items;
		}

		[[nodiscard]]
		constexpr const T *data() const noexcept {
			return m_items;
		}

		[[nodiscard]]
		bool contains(const T&) const;

		void insert(std::size_t pos, const T &val);

		template<typename... Args>
		void emplace_back(Args&&... args);

		void push_back(const T &item);

		void pop_back();

		/**
		 * Removes an item from the Vector.
		 * @param pos position of item to remove
		 * @return Error if index is out of bounds
		 */
		Error erase(std::size_t pos);

		/**
		 * Moves the last item in the Vector to position pos and decrements the
		 * size by 1.
		 * @param pos position of item to remove
		 * @return Error if index is out of bounds
		 */
		Error unordered_erase(std::size_t pos);

	private:
		void expandCap(std::size_t cap);

};

template<typename T>
Vector<T>::Vector(std::size_t size) noexcept {
	m_size = size;
	m_cap = m_size;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	for (std::size_t i = 0; i < size; i++) {
		m_items[i] = {};
	}
}

template<typename T>
Vector<T>::Vector(const Vector<T> &other) {
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	for (std::size_t i = 0; i < m_size; i++) {
		m_items[i] = ox::move(other.m_items[i]);
	}
}

template<typename T>
Vector<T>::Vector(Vector<T> &&other) noexcept {
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = other.m_items;
	other.m_size = 0;
	other.m_cap = 0;
	other.m_items = nullptr;
}

template<typename T>
Vector<T>::~Vector() {
	if constexpr(ox::is_class<T>()) {
		for (std::size_t i = 0; i < m_size; i++) {
			m_items[i].~T();
		}
	}
	delete[] bit_cast<AllocAlias<T>*>(m_items);
	m_items = nullptr;
}

template<typename T>
bool Vector<T>::operator==(const Vector<T> &other) const {
	for (std::size_t i = 0; i < m_size; i++) {
		if (!(m_items[i] == other.m_items[i])) {
			return false;
		}
	}
	return true;
}

template<typename T>
Vector<T> &Vector<T>::operator=(const Vector<T> &other) {
	this->~Vector<T>();
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	for (std::size_t i = 0; i < m_size; i++) {
		m_items[i] = other.m_items[i];
	}
	return *this;
}

template<typename T>
Vector<T> &Vector<T>::operator=(Vector<T> &&other) {
	this->~Vector<T>();
	m_size = other.m_size;
	m_cap = other.m_cap;
	m_items = other.m_items;
	other.m_size = 0;
	other.m_cap = 0;
	other.m_items = nullptr;
	return *this;
}

template<typename T>
T &Vector<T>::operator[](std::size_t i) noexcept {
	return m_items[i];
}

template<typename T>
const T &Vector<T>::operator[](std::size_t i) const noexcept {
	return m_items[i];
}

template<typename T>
Result<T&> Vector<T>::front() noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[0];
}

template<typename T>
Result<const T&> Vector<T>::front() const noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[0];
}

template<typename T>
Result<T&> Vector<T>::back() noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[m_size - 1];
}

template<typename T>
Result<const T&> Vector<T>::back() const noexcept {
	if (!m_size) {
		AllocAlias<T> v;
		return {*bit_cast<T*>(&v), OxError(1)};
	}
	return m_items[m_size - 1];
}

template<typename T>
std::size_t Vector<T>::size() const noexcept {
	return m_size;
}

template<typename T>
bool Vector<T>::empty() const noexcept {
	return !m_size;
}

template<typename T>
void Vector<T>::clear() {
	resize(0);
}

template<typename T>
void Vector<T>::resize(std::size_t size) {
	if (m_cap < size) {
		expandCap(size);
	}
	if (m_size < size) {
		for (std::size_t i = m_size; i < size; i++) {
			m_items[i] = {};
		}
	} else {
		for (std::size_t i = size; i < m_size; i++) {
			m_items[i].~T();
		}
	}
	m_size = size;
}

template<typename T>
bool Vector<T>::contains(const T &v) const {
	for (std::size_t i = 0; i < m_size; i++) {
		if (m_items[i] == v) {
			return true;
		}
	}
	return false;
}

template<typename T>
void Vector<T>::insert(std::size_t pos, const T &val) {
	// TODO: insert should ideally have its own expandCap
	if (m_size == m_cap) {
		expandCap(m_cap ? m_cap * 2 : 100);
	}
	for (auto i = m_size; i > pos; --i) {
		m_items[i] = ox::move(m_items[i - 1]);
	}
	m_items[pos] = val;
	++m_size;
}

template<typename T>
template<typename... Args>
void Vector<T>::emplace_back(Args&&... args) {
	if (m_size == m_cap) {
		expandCap(m_cap ? m_cap * 2 : 100);
	}
	new (&m_items[m_size]) T{args...};
	++m_size;
}

template<typename T>
void Vector<T>::push_back(const T &item) {
	if (m_size == m_cap) {
		expandCap(m_cap ? m_cap * 2 : 100);
	}
	new (&m_items[m_size]) T(item);
	++m_size;
}

template<typename T>
void Vector<T>::pop_back() {
	--m_size;
	m_items[m_size].~T();
}

template<typename T>
Error Vector<T>::erase(std::size_t pos) {
	if (pos >= m_size) {
		return OxError(1);
	}
	--m_size;
	for (auto i = pos; i < m_size; ++i) {
		m_items[i] = ox::move(m_items[i + 1]);
	}
	return OxError(0);
}

template<typename T>
Error Vector<T>::unordered_erase(std::size_t pos) {
	if (pos >= m_size) {
		return OxError(1);
	}
	m_size--;
	m_items[pos] = ox::move(m_items[m_size]);
	return OxError(0);
}

template<typename T>
void Vector<T>::expandCap(std::size_t cap) {
	auto oldItems = m_items;
	m_cap = cap;
	m_items = bit_cast<T*>(new AllocAlias<T>[m_cap]);
	if (oldItems) { // move over old items
		const auto itRange = cap > m_size ? m_size : cap;
		for (std::size_t i = 0; i < itRange; i++) {
			m_items[i] = ox::move(oldItems[i]);
		}
		for (std::size_t i = itRange; i < m_cap; i++) {
			new (&m_items[i]) T;
		}
		delete[] bit_cast<AllocAlias<T>*>(oldItems);
	}
}

}
<|endoftext|>


<commit_before>/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

 QGROUNDCONTROL 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.

 QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

#include "QGCFileDownload.h"

#include <QFileInfo>
#include <QStandardPaths>

QGCFileDownload::QGCFileDownload(QObject* parent)
    : QNetworkAccessManager(parent)
{

}

bool QGCFileDownload::download(const QString& remoteFile)
{
    if (remoteFile.isEmpty()) {
        qWarning() << "downloadFile empty";
        return false;
    }

    // Split out filename from path
    QString remoteFileName = QFileInfo(remoteFile).fileName();
    if (remoteFileName.isEmpty()) {
        qWarning() << "Unabled to parse filename from downloadFile" << remoteFile;
        return false;
    }

    // Determine location to download file to
    QString localFile = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    if (localFile.isEmpty()) {
        localFile = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
        if (localFile.isEmpty()) {
            qDebug() << "Unabled to find writable download location. Tried downloads and temp directory.";
            return false;
        }
    }
    localFile += "/"  + remoteFileName;

    QUrl remoteUrl;
    if (remoteFile.startsWith("http:")) {
        remoteUrl.setUrl(remoteFile);
    } else {
        remoteUrl = QUrl::fromLocalFile(remoteFile);
    }
    if (!remoteUrl.isValid()) {
        qWarning() << "Remote URL is invalid" << remoteFile;
        return false;
    }

    QNetworkRequest networkRequest(remoteUrl);

    // Store local file location in user attribute so we can retrieve when the download finishes
    networkRequest.setAttribute(QNetworkRequest::User, localFile);

    QNetworkReply* networkReply = get(networkRequest);
    if (!networkReply) {
        qWarning() << "QNetworkAccessManager::get failed";
        return false;
    }

    connect(networkReply, &QNetworkReply::downloadProgress, this, &QGCFileDownload::downloadProgress);
    connect(networkReply, &QNetworkReply::finished, this, &QGCFileDownload::_downloadFinished);
    connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
            this, &QGCFileDownload::_downloadError);

    return true;
}

void QGCFileDownload::_downloadFinished(void)
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender());

    // When an error occurs or the user cancels the download, we still end up here. So bail out in
    // those cases.
    if (reply->error() != QNetworkReply::NoError) {
        return;
    }

    // Download file location is in user attribute
    QString downloadFilename = reply->request().attribute(QNetworkRequest::User).toString();
    Q_ASSERT(!downloadFilename.isEmpty());

    // Store downloaded file in download location
    QFile file(downloadFilename);
    if (!file.open(QIODevice::WriteOnly)) {
        emit error(QString("Could not save downloaded file to %1. Error: %2").arg(downloadFilename).arg(file.errorString()));
        return;
    }

    file.write(reply->readAll());
    file.close();

    emit downloadFinished(reply->url().toString(), downloadFilename);
}

/// @brief Called when an error occurs during download
void QGCFileDownload::_downloadError(QNetworkReply::NetworkError code)
{
    QString errorMsg;

    if (code == QNetworkReply::OperationCanceledError) {
        errorMsg = "Download cancelled";

    } else if (code == QNetworkReply::ContentNotFoundError) {
        errorMsg = "Error: File Not Found";

    } else {
        errorMsg = QString("Error during download. Error: %1").arg(code);
    }

    emit error(errorMsg);
}
<commit_msg>Add https support<commit_after>/*=====================================================================

 QGroundControl Open Source Ground Control Station

 (c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

 This file is part of the QGROUNDCONTROL project

 QGROUNDCONTROL 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.

 QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

 ======================================================================*/

#include "QGCFileDownload.h"

#include <QFileInfo>
#include <QStandardPaths>

QGCFileDownload::QGCFileDownload(QObject* parent)
    : QNetworkAccessManager(parent)
{

}

bool QGCFileDownload::download(const QString& remoteFile)
{
    if (remoteFile.isEmpty()) {
        qWarning() << "downloadFile empty";
        return false;
    }

    // Split out filename from path
    QString remoteFileName = QFileInfo(remoteFile).fileName();
    if (remoteFileName.isEmpty()) {
        qWarning() << "Unabled to parse filename from downloadFile" << remoteFile;
        return false;
    }

    // Determine location to download file to
    QString localFile = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
    if (localFile.isEmpty()) {
        localFile = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
        if (localFile.isEmpty()) {
            qDebug() << "Unabled to find writable download location. Tried downloads and temp directory.";
            return false;
        }
    }
    localFile += "/"  + remoteFileName;

    QUrl remoteUrl;
    if (remoteFile.startsWith("http:") || remoteFile.startsWith("https:")) {
        remoteUrl.setUrl(remoteFile);
    } else {
        remoteUrl = QUrl::fromLocalFile(remoteFile);
    }
    if (!remoteUrl.isValid()) {
        qWarning() << "Remote URL is invalid" << remoteFile;
        return false;
    }

    QNetworkRequest networkRequest(remoteUrl);

    // Store local file location in user attribute so we can retrieve when the download finishes
    networkRequest.setAttribute(QNetworkRequest::User, localFile);

    QNetworkReply* networkReply = get(networkRequest);
    if (!networkReply) {
        qWarning() << "QNetworkAccessManager::get failed";
        return false;
    }

    connect(networkReply, &QNetworkReply::downloadProgress, this, &QGCFileDownload::downloadProgress);
    connect(networkReply, &QNetworkReply::finished, this, &QGCFileDownload::_downloadFinished);
    connect(networkReply, static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error),
            this, &QGCFileDownload::_downloadError);

    return true;
}

void QGCFileDownload::_downloadFinished(void)
{
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender());

    // When an error occurs or the user cancels the download, we still end up here. So bail out in
    // those cases.
    if (reply->error() != QNetworkReply::NoError) {
        return;
    }

    // Download file location is in user attribute
    QString downloadFilename = reply->request().attribute(QNetworkRequest::User).toString();
    Q_ASSERT(!downloadFilename.isEmpty());

    // Store downloaded file in download location
    QFile file(downloadFilename);
    if (!file.open(QIODevice::WriteOnly)) {
        emit error(QString("Could not save downloaded file to %1. Error: %2").arg(downloadFilename).arg(file.errorString()));
        return;
    }

    file.write(reply->readAll());
    file.close();

    emit downloadFinished(reply->url().toString(), downloadFilename);
}

/// @brief Called when an error occurs during download
void QGCFileDownload::_downloadError(QNetworkReply::NetworkError code)
{
    QString errorMsg;

    if (code == QNetworkReply::OperationCanceledError) {
        errorMsg = "Download cancelled";

    } else if (code == QNetworkReply::ContentNotFoundError) {
        errorMsg = "Error: File Not Found";

    } else {
        errorMsg = QString("Error during download. Error: %1").arg(code);
    }

    emit error(errorMsg);
}
<|endoftext|>


<commit_before>#include "Neohuman.h"
#include <iostream>

using namespace BWAPI;
using namespace Filter;

#define MIN(a, b) (((a) < (b) ? (a) : (b)))
#define MAX(a, b) (((a) < (b) ? (b) : (a)))

#define SATRUATION_RADIUS 350
#define WORKERAGGRORADIUS 200

#define SHOWTHINGS

bool Neohuman::doBuild(Unit u, UnitType building, TilePosition at) {
	_buildingQueue.push_back(Triple<int, UnitType, TilePosition>{u->getID(), building, at});
}

void Neohuman::onStart() {
	Broodwar << "The map is totally not " << Broodwar->mapName() << "!" << std::endl;

	//Broodwar->enableFlag(Flag::UserInput);

	// Uncomment the following line and the bot will know about everything through the fog of war (cheat).
	//Broodwar->enableFlag(Flag::CompleteMapInformation);

	// Set the command optimization level so that common commands can be grouped
	// and reduce the bot's APM (Actions Per Minute).
	Broodwar->setCommandOptimizationLevel(2);

	// Check if this is a replay
	if (!Broodwar->isReplay()) {
		if (Broodwar->enemy())
			Broodwar << "The matchup is me (" << Broodwar->self()->getRace() << ") vs " << Broodwar->enemy()->getRace() << std::endl;
		for (auto u: Broodwar->self()->getUnits()) {
			//this->onUnitComplete(u);
		}
	}

}

void Neohuman::onEnd(bool didWin) {
	// Called when the game ends
	if (didWin) {

	} else {

	}
}

int Neohuman::randint(int min, int max) {
	std::uniform_int_distribution<int> dist(min, max);
	return dist(_rand);
}

template <typename T>
T Neohuman::randele(std::vector <T> &v) {
	return v[randint(0, v.size())];
}

void Neohuman::onFrame() {
	// Called once every game frame
	int constructingLine = 0;
	int availableMinerals = Broodwar->self()->minerals();

#ifdef SHOWTHINGS

	// Display the game frame rate as text in the upper left area of the screen
	Broodwar->drawTextScreen(200, 0,  "FPS: %d", Broodwar->getFPS());
	Broodwar->drawTextScreen(200, 12, "Average FPS: %f", Broodwar->getAverageFPS());
	Broodwar->drawTextScreen(200, 24, "I want %d more supply (%d queued, %d in production)", _wantedExtraSupply, _queuedSupply, _supplyBeingMade);
	Broodwar->drawTextScreen(200, 36, "I have %d barracks!", _nBarracks);

#endif

	// Return if the game is a replay or is paused
	if (Broodwar->isReplay() || Broodwar->isPaused() || !Broodwar->self())
		return;

	for (auto &u : Broodwar->self()->getUnits()) {
		if (u->exists() && u->isBeingConstructed()) {
			Broodwar->drawTextScreen(0, constructingLine, "%s", u->getType().c_str());
			constructingLine += 12;
		}
	}

#ifdef SHOWTHINGS

	// Show worker info
	for (auto &u : Broodwar->self()->getUnits()) {
		if (u->getType().isResourceDepot()) {
			Broodwar->drawCircleMap(u->getPosition(), SATRUATION_RADIUS, Colors::Blue);
			auto workers = u->getUnitsInRadius(SATRUATION_RADIUS, (IsGatheringMinerals));
			auto refineries = u->getUnitsInRadius(SATRUATION_RADIUS, (IsRefinery));
			auto gasGeysers = u->getUnitsInRadius(SATRUATION_RADIUS);
			auto mineralFields = u->getUnitsInRadius(SATRUATION_RADIUS, (IsMineralField));
			Broodwar->drawTextMap(u->getPosition() + Position(0, 30), "%cWorkers: %d/%d", Text::White, workers.size(), 2*mineralFields.size());
		}
	}

#endif

	// Prevent spamming by only running our onFrame once every number of latency frames.
	// Latency frames are the number of frames before commands are processed.
	if (Broodwar->getFrameCount() % Broodwar->getLatencyFrames() != 0)
		return;

	_supplyBeingMade = 0;
	for (auto &u : Broodwar->self()->getUnits()) {
		if (u->isConstructing() && u->getType().getRace().getSupplyProvider() == u->getType())
			_supplyBeingMade += 8;
	}

	availableMinerals -= 100*_queuedSupply/8;

	if (Broodwar->elapsedTime() - _timeLastQueuedSupply > 5) {
		_queuedSupply = 0;
		_timeLastQueuedSupply = Broodwar->elapsedTime();
	}

	_nSupplyOverhead = 2 + MAX((Broodwar->self()->supplyUsed() - 10) / 8, 0);
	_wantedExtraSupply = (Broodwar->self()->supplyUsed() - (Broodwar->self()->supplyTotal() + _supplyBeingMade + _queuedSupply)) / 2 + _nSupplyOverhead;

	_nBarracks = 0;
	for (auto &u : Broodwar->self()->getUnits()) {
		// If a cc is under construction
		if (u->isConstructing() && u->getType() == u->getType().getRace().getCenter() && _isExpanding)
			availableMinerals += 400;
		// If a barracks is under construction
		if (u->isConstructing() && u->getType() == UnitTypes::Terran_Barracks && _isBuildingBarracks)
			availableMinerals += 150;

		if (u->getType() == UnitTypes::Terran_Barracks) {
			++_nBarracks;
		}
	}

	if (_isExpanding) {
		availableMinerals -= 400;
	}

	if (_isBuildingBarracks) {
		availableMinerals -= 150;
	}

	// Check if supply should be increased
	if (_wantedExtraSupply > 0 && availableMinerals >= 100 && Broodwar->self()->supplyTotal() < 400) {
		// Find unit to build our supply!
		for (auto &unit : Broodwar->self()->getUnits()) {
			if (unit->exists() && unit->isGatheringMinerals() && unit->isMoving() && !unit->isCarryingMinerals()) {
				// We have found our candidate!
				auto supplyType = unit->getType().getRace().getSupplyProvider();
				auto buildPos = Broodwar->getBuildLocation(supplyType, unit->getTilePosition());

				if (unit->build(supplyType, buildPos)) {
					_queuedSupply += 8;
					_timeLastQueuedSupply = Broodwar->elapsedTime();
					break;
				}
			}
		}
	}

	if (availableMinerals >= 150 && !_isBuildingBarracks && _nBarracks < 20) {
		// Build barracks!
		for (auto &u : Broodwar->self()->getUnits()) {
			if (u->exists() && u->isGatheringMinerals() && u->isMoving() && !u->isCarryingMinerals()) {
				auto buildingType = UnitTypes::Terran_Barracks;
				auto buildingPos = Broodwar->getBuildLocation(buildingType, u->getTilePosition());

				if (u->build(buildingType, buildingPos)) {
					_isBuildingBarracks = true;
					availableMinerals -= 150;
					break;
				}
			}
		}
	}

	/*if (!_isExpanding && availableMinerals >= 400){
		// Expand!
		for (auto &u : Broodwar->self()->getUnits()) {
			if (u->exists() && u->isGatheringMinerals() && u->isMoving() && !u->isCarryingMinerals()) {
				// Builder found!
				auto buildingType = u->getType().getRace().getCenter();
				auto buildPos = Broodwar->getBuildLocation(buildingType, u->getTilePosition());

				if (u->build(buildingType, buildPos)) {
					_isExpanding = true;
					availableMinerals -= 400;
					break;
				}
			}
		}
	}*/

	// Iterate through all the units that we own
	for (auto &u : Broodwar->self()->getUnits()) {
		// Ignore the unit if it no longer exists
		// Make sure to include this block when handling any Unit pointer!
		if (!u->exists())
			continue;

		// Ignore the unit if it has one of the following status ailments
		if (u->isLockedDown() || u->isMaelstrommed() || u->isStasised())
			continue;

		// Ignore the unit if it is in one of the following states
		if (u->isLoaded() || !u->isPowered() || u->isStuck())
			continue;

		// Ignore the unit if it is incomplete or busy constructing
		if (!u->isCompleted() || u->isConstructing())
			continue;

		// If the unit is a worker unit
		if (u->getType().isWorker()) {
			auto enemyUnit = u->getClosestUnit(IsEnemy && IsAttacking, WORKERAGGRORADIUS);
			if (enemyUnit)
				u->attack(enemyUnit);

			// if our worker is idle
			if (u->isIdle()) {
				// Order workers carrying a resource to return them to the center,
				// otherwise find a mineral patch to harvest.
				if (u->isCarryingGas() || u->isCarryingMinerals())
					u->returnCargo();

				else if (!u->getPowerUp()) {
					// Probably need to set up some better logic for this
					auto preferredMiningLocation = u->getClosestUnit(IsMineralField);
					u->gather(preferredMiningLocation);
				}
			}
		} else if (u->getType().isResourceDepot()) {
			auto nearbyGeysers = u->getUnitsInRadius(SATRUATION_RADIUS, (GetType == UnitTypes::Resource_Vespene_Geyser));
			if (u->isIdle()) {
				auto workers = u->getUnitsInRadius(SATRUATION_RADIUS, (IsGatheringMinerals));
				auto mineralFields = u->getUnitsInRadius(SATRUATION_RADIUS, (IsMineralField));
				if (workers.size() < mineralFields.size() * 2 && availableMinerals >= 50) {
					if (u->train(u->getType().getRace().getWorker())) {
						Position pos = u->getPosition();
						Error lastErr = Broodwar->getLastError();
						Broodwar->registerEvent([pos, lastErr](Game*){ Broodwar->drawTextMap(pos + Position(0, -10), "%c%s", Text::Red, lastErr.c_str()); },   // action
							nullptr,    // condition
							Broodwar->getLatencyFrames());  // frames to run
					} else {
						availableMinerals -= 50;
					}
				}
			}
		} else if (u->getType() == UnitTypes::Terran_Barracks) {
			if (u->isIdle() && availableMinerals >= 50)
				if (!u->train(UnitTypes::Terran_Marine))
					availableMinerals -= 50;
		} else if (u->getType() == UnitTypes::Terran_Marine && Broodwar->getFrameCount() % 20 == 0) {
			auto enemyUnit = u->getClosestUnit(IsEnemy && IsAttacking);
			if (enemyUnit) {
				u->attack(enemyUnit);
				continue;
			}
			enemyUnit = u->getClosestUnit(IsEnemy);
			if (enemyUnit) {
				u->attack(enemyUnit);
				continue;
			}
			auto closestMarine = u->getClosestUnit(GetType == UnitTypes::Terran_Marine);
			if (closestMarine) {
				auto walk = u->getPosition() - closestMarine->getPosition();
				u->move(u->getPosition() + walk);
			}
		}
	}
}

void Neohuman::onSendText(std::string text) {
	Broodwar->sendText("%s", text.c_str());
}

void Neohuman::onReceiveText(Player player, std::string text) {
	Broodwar << player->getName() << " said \"" << text << "\"" << std::endl;
}

void Neohuman::onPlayerLeft(Player player) {
	Broodwar->sendText("Goodbye %s!", player->getName().c_str());
}

void Neohuman::onNukeDetect(Position target) {
	if (target) {
		Broodwar << "Nuclear Launch Detected at " << target << std::endl;
	} else {
		Broodwar->sendText("Where's the nuke?");
	}
	// You can also retrieve all the nuclear missile targets using Broodwar->getNukeDots()!
}

void Neohuman::onUnitDiscover(Unit unit) {
}

void Neohuman::onUnitEvade(Unit unit) {
}

void Neohuman::onUnitShow(Unit unit) {
}

void Neohuman::onUnitHide(Unit unit) {
}

void Neohuman::onUnitCreate(Unit unit) {
}

void Neohuman::onUnitDestroy(Unit unit) {
}

void Neohuman::onUnitMorph(Unit unit) {
	this->onUnitComplete(unit);
}

void Neohuman::onUnitRenegade(Unit unit){
}

void Neohuman::onSaveGame(std::string gameName){
}

void Neohuman::onUnitComplete(Unit unit){
	if (unit->getType() == unit->getType().getRace().getCenter())
		_isExpanding = false;
	if (unit->getType() == UnitTypes::Terran_Barracks)
		_isBuildingBarracks = false;
}
<commit_msg>Thinking this may make a very small but important difference against some bots.<commit_after>#include "Neohuman.h"
#include <iostream>

using namespace BWAPI;
using namespace Filter;

#define MIN(a, b) (((a) < (b) ? (a) : (b)))
#define MAX(a, b) (((a) < (b) ? (b) : (a)))

#define SATRUATION_RADIUS 350
#define WORKERAGGRORADIUS 200

#define SHOWTHINGS

bool Neohuman::doBuild(Unit u, UnitType building, TilePosition at) {
	_buildingQueue.push_back(Triple<int, UnitType, TilePosition>{u->getID(), building, at});
}

void Neohuman::onStart() {
	Broodwar << "The map is totally not " << Broodwar->mapName() << "!" << std::endl;

	//Broodwar->enableFlag(Flag::UserInput);

	// Uncomment the following line and the bot will know about everything through the fog of war (cheat).
	//Broodwar->enableFlag(Flag::CompleteMapInformation);

	// Set the command optimization level so that common commands can be grouped
	// and reduce the bot's APM (Actions Per Minute).
	Broodwar->setCommandOptimizationLevel(2);

	// Check if this is a replay
	if (!Broodwar->isReplay()) {
		if (Broodwar->enemy())
			Broodwar << "The matchup is me (" << Broodwar->self()->getRace() << ") vs " << Broodwar->enemy()->getRace() << std::endl;
		for (auto u: Broodwar->self()->getUnits()) {
			//this->onUnitComplete(u);
		}
	}

}

void Neohuman::onEnd(bool didWin) {
	// Called when the game ends
	if (didWin) {

	} else {

	}
}

int Neohuman::randint(int min, int max) {
	std::uniform_int_distribution<int> dist(min, max);
	return dist(_rand);
}

template <typename T>
T Neohuman::randele(std::vector <T> &v) {
	return v[randint(0, v.size())];
}

void Neohuman::onFrame() {
	// Called once every game frame
	int constructingLine = 0;
	int availableMinerals = Broodwar->self()->minerals();

#ifdef SHOWTHINGS

	// Display the game frame rate as text in the upper left area of the screen
	Broodwar->drawTextScreen(200, 0,  "FPS: %d", Broodwar->getFPS());
	Broodwar->drawTextScreen(200, 12, "Average FPS: %f", Broodwar->getAverageFPS());
	Broodwar->drawTextScreen(200, 24, "I want %d more supply (%d queued, %d in production)", _wantedExtraSupply, _queuedSupply, _supplyBeingMade);
	Broodwar->drawTextScreen(200, 36, "I have %d barracks!", _nBarracks);

#endif

	// Return if the game is a replay or is paused
	if (Broodwar->isReplay() || Broodwar->isPaused() || !Broodwar->self())
		return;

	for (auto &u : Broodwar->self()->getUnits()) {
		if (u->exists() && u->isBeingConstructed()) {
			Broodwar->drawTextScreen(0, constructingLine, "%s", u->getType().c_str());
			constructingLine += 12;
		}
	}

#ifdef SHOWTHINGS

	// Show worker info
	for (auto &u : Broodwar->self()->getUnits()) {
		if (u->getType().isResourceDepot()) {
			Broodwar->drawCircleMap(u->getPosition(), SATRUATION_RADIUS, Colors::Blue);
			auto workers = u->getUnitsInRadius(SATRUATION_RADIUS, (IsGatheringMinerals));
			auto refineries = u->getUnitsInRadius(SATRUATION_RADIUS, (IsRefinery));
			auto gasGeysers = u->getUnitsInRadius(SATRUATION_RADIUS);
			auto mineralFields = u->getUnitsInRadius(SATRUATION_RADIUS, (IsMineralField));
			Broodwar->drawTextMap(u->getPosition() + Position(0, 30), "%cWorkers: %d/%d", Text::White, workers.size(), 2*mineralFields.size());
		}
	}

#endif

	// Prevent spamming by only running our onFrame once every number of latency frames.
	// Latency frames are the number of frames before commands are processed.
	if (Broodwar->getFrameCount() % Broodwar->getLatencyFrames() != 0)
		return;

	_supplyBeingMade = 0;
	for (auto &u : Broodwar->self()->getUnits()) {
		if (u->isConstructing() && u->getType().getRace().getSupplyProvider() == u->getType())
			_supplyBeingMade += 8;
	}

	availableMinerals -= 100*_queuedSupply/8;

	if (Broodwar->elapsedTime() - _timeLastQueuedSupply > 5) {
		_queuedSupply = 0;
		_timeLastQueuedSupply = Broodwar->elapsedTime();
	}

	_nSupplyOverhead = 2 + MAX((Broodwar->self()->supplyUsed() - 10) / 8, 0);
	_wantedExtraSupply = (Broodwar->self()->supplyUsed() - (Broodwar->self()->supplyTotal() + _supplyBeingMade + _queuedSupply)) / 2 + _nSupplyOverhead;

	_nBarracks = 0;
	for (auto &u : Broodwar->self()->getUnits()) {
		// If a cc is under construction
		if (u->isConstructing() && u->getType() == u->getType().getRace().getCenter() && _isExpanding)
			availableMinerals += 400;
		// If a barracks is under construction
		if (u->isConstructing() && u->getType() == UnitTypes::Terran_Barracks && _isBuildingBarracks)
			availableMinerals += 150;

		if (u->getType() == UnitTypes::Terran_Barracks) {
			++_nBarracks;
		}
	}

	if (_isExpanding) {
		availableMinerals -= 400;
	}

	if (_isBuildingBarracks) {
		availableMinerals -= 150;
	}

	// Check if supply should be increased
	if (_wantedExtraSupply > 0 && availableMinerals >= 100 && Broodwar->self()->supplyTotal() < 400) {
		// Find unit to build our supply!
		for (auto &unit : Broodwar->self()->getUnits()) {
			if (unit->exists() && unit->isGatheringMinerals() && unit->isMoving() && !unit->isCarryingMinerals()) {
				// We have found our candidate!
				auto supplyType = unit->getType().getRace().getSupplyProvider();
				auto buildPos = Broodwar->getBuildLocation(supplyType, unit->getTilePosition());

				if (unit->build(supplyType, buildPos)) {
					_queuedSupply += 8;
					_timeLastQueuedSupply = Broodwar->elapsedTime();
					break;
				}
			}
		}
	}

	if (availableMinerals >= 150 && !_isBuildingBarracks && _nBarracks < 20) {
		// Build barracks!
		for (auto &u : Broodwar->self()->getUnits()) {
			if (u->exists() && u->isGatheringMinerals() && u->isMoving() && !u->isCarryingMinerals()) {
				auto buildingType = UnitTypes::Terran_Barracks;
				auto buildingPos = Broodwar->getBuildLocation(buildingType, u->getTilePosition());

				if (u->build(buildingType, buildingPos)) {
					_isBuildingBarracks = true;
					availableMinerals -= 150;
					break;
				}
			}
		}
	}

	/*if (!_isExpanding && availableMinerals >= 400){
		// Expand!
		for (auto &u : Broodwar->self()->getUnits()) {
			if (u->exists() && u->isGatheringMinerals() && u->isMoving() && !u->isCarryingMinerals()) {
				// Builder found!
				auto buildingType = u->getType().getRace().getCenter();
				auto buildPos = Broodwar->getBuildLocation(buildingType, u->getTilePosition());

				if (u->build(buildingType, buildPos)) {
					_isExpanding = true;
					availableMinerals -= 400;
					break;
				}
			}
		}
	}*/

	// Iterate through all the units that we own
	for (auto &u : Broodwar->self()->getUnits()) {
		// Ignore the unit if it no longer exists
		// Make sure to include this block when handling any Unit pointer!
		if (!u->exists())
			continue;

		// Ignore the unit if it has one of the following status ailments
		if (u->isLockedDown() || u->isMaelstrommed() || u->isStasised())
			continue;

		// Ignore the unit if it is in one of the following states
		if (u->isLoaded() || !u->isPowered() || u->isStuck())
			continue;

		// Ignore the unit if it is incomplete or busy constructing
		if (!u->isCompleted() || u->isConstructing())
			continue;

		// If the unit is a worker unit
		if (u->getType().isWorker()) {
			auto enemyUnit = u->getClosestUnit(IsEnemy && IsAttacking, WORKERAGGRORADIUS);
			if (enemyUnit)
				u->attack(enemyUnit);

			// if our worker is idle
			if (u->isIdle()) {
				// Order workers carrying a resource to return them to the center,
				// otherwise find a mineral patch to harvest.
				if (u->isCarryingGas() || u->isCarryingMinerals())
					u->returnCargo();

				else if (!u->getPowerUp()) {
					// Probably need to set up some better logic for this
					auto preferredMiningLocation = u->getClosestUnit(IsMineralField);
					u->gather(preferredMiningLocation);
				}
			}
		} else if (u->getType().isResourceDepot()) {
			auto nearbyGeysers = u->getUnitsInRadius(SATRUATION_RADIUS, (GetType == UnitTypes::Resource_Vespene_Geyser));
			if (u->isIdle()) {
				auto workers = u->getUnitsInRadius(SATRUATION_RADIUS, (IsGatheringMinerals));
				auto mineralFields = u->getUnitsInRadius(SATRUATION_RADIUS, (IsMineralField));
				if (workers.size() < mineralFields.size() * 2 && availableMinerals >= 50) {
					if (u->train(u->getType().getRace().getWorker())) {
						Position pos = u->getPosition();
						Error lastErr = Broodwar->getLastError();
						Broodwar->registerEvent([pos, lastErr](Game*){ Broodwar->drawTextMap(pos + Position(0, -10), "%c%s", Text::Red, lastErr.c_str()); },   // action
							nullptr,    // condition
							Broodwar->getLatencyFrames());  // frames to run
					} else {
						availableMinerals -= 50;
					}
				}
			}
		} else if (u->getType() == UnitTypes::Terran_Barracks) {
			if (u->isIdle() && availableMinerals >= 50)
				if (!u->train(UnitTypes::Terran_Marine))
					availableMinerals -= 50;
		} else if (u->getType() == UnitTypes::Terran_Marine && Broodwar->getFrameCount() % 20 == 0) {
			auto enemyUnit = u->getClosestUnit(IsEnemy && IsAttacking);
			if (enemyUnit) {
				u->attack(enemyUnit->getPosition());
				continue;
			}
			enemyUnit = u->getClosestUnit(IsEnemy);
			if (enemyUnit) {
				u->attack(enemyUnit->getPosition());
				continue;
			}
			auto closestMarine = u->getClosestUnit(GetType == UnitTypes::Terran_Marine);
			if (closestMarine) {
				auto walk = u->getPosition() - closestMarine->getPosition();
				u->move(u->getPosition() + walk);
			}
		}
	}
}

void Neohuman::onSendText(std::string text) {
	Broodwar->sendText("%s", text.c_str());
}

void Neohuman::onReceiveText(Player player, std::string text) {
	Broodwar << player->getName() << " said \"" << text << "\"" << std::endl;
}

void Neohuman::onPlayerLeft(Player player) {
	Broodwar->sendText("Goodbye %s!", player->getName().c_str());
}

void Neohuman::onNukeDetect(Position target) {
	if (target) {
		Broodwar << "Nuclear Launch Detected at " << target << std::endl;
	} else {
		Broodwar->sendText("Where's the nuke?");
	}
	// You can also retrieve all the nuclear missile targets using Broodwar->getNukeDots()!
}

void Neohuman::onUnitDiscover(Unit unit) {
}

void Neohuman::onUnitEvade(Unit unit) {
}

void Neohuman::onUnitShow(Unit unit) {
}

void Neohuman::onUnitHide(Unit unit) {
}

void Neohuman::onUnitCreate(Unit unit) {
}

void Neohuman::onUnitDestroy(Unit unit) {
}

void Neohuman::onUnitMorph(Unit unit) {
	this->onUnitComplete(unit);
}

void Neohuman::onUnitRenegade(Unit unit){
}

void Neohuman::onSaveGame(std::string gameName){
}

void Neohuman::onUnitComplete(Unit unit){
	if (unit->getType() == unit->getType().getRace().getCenter())
		_isExpanding = false;
	if (unit->getType() == UnitTypes::Terran_Barracks)
		_isBuildingBarracks = false;
}
<|endoftext|>