<commit_before>#include "stdafx.h"
#include <d3d11.h>
#include "D3D11Hooker.h"
#include "Console.h"
#include "MinHook.h"
#include "Globals.h"
#include "imgui.h"
#include "Defaults.h"
#include "imgui_impl_dx11.h"
#include "imgui_impl_win32.h"
#include "OverlayControl.h"
#include "OverlayConsole.h"
#include "Input.h"
#include <atomic>
#include <thread>
#include "stb_image_write.h"
#include "stb_image_resize.h"

#pragma comment(lib, "d3d11.lib")

namespace IGCS::D3D11Hooker
{
	#define DXGI_PRESENT_INDEX			8
	#define DXGI_RESIZEBUFFERS_INDEX	13

	//--------------------------------------------------------------------------------------------------------------------------------
	// Forward declarations
	void createRenderTarget(IDXGISwapChain* pSwapChain);
	void cleanupRenderTarget();

	//--------------------------------------------------------------------------------------------------------------------------------
	// Typedefs of functions to hook
	typedef HRESULT(__stdcall *DXGIPresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
	typedef HRESULT(__stdcall *DXGIResizeBuffersHook) (IDXGISwapChain* pSwapChain, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT newFormat, UINT swapChainFlags);

	static ID3D11Device* _device = nullptr;
	static ID3D11DeviceContext* _context = nullptr;
	static ID3D11RenderTargetView* _mainRenderTargetView = nullptr;

	// Looking glass data
	static UINT _width;
	static UINT _height;
// TODO: CHANGE to std:string
	static char _filename[500];
	static atomic_int _framesToGrab;
	static atomic_int _framesToGrabSync;
	static atomic_bool _isDoneSavingImages = true;
	static std::vector<std::vector<uint8_t>> _fb_array;

	//--------------------------------------------------------------------------------------------------------------------------------
	// Pointers to the original hooked functions
	static DXGIPresentHook hookedDXGIPresent = nullptr;
	static DXGIResizeBuffersHook hookedDXGIResizeBuffers = nullptr;

	static bool _tmpSwapChainInitialized = false;
	static atomic_bool _imGuiInitializing = false;
	static atomic_bool _initializeDeviceAndContext = true;
	static atomic_bool _presentInProgress = false;

	HRESULT __stdcall detourDXGIResizeBuffers(IDXGISwapChain* pSwapChain, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT newFormat, UINT swapChainFlags)
	{
		_imGuiInitializing = true;
		ImGui_ImplDX11_InvalidateDeviceObjects();
		cleanupRenderTarget();
		HRESULT toReturn = hookedDXGIResizeBuffers(pSwapChain, bufferCount, width, height, newFormat, swapChainFlags);
		createRenderTarget(pSwapChain);
		ImGui_ImplDX11_CreateDeviceObjects();
		_imGuiInitializing = false;
		return toReturn;
	}

	HRESULT __stdcall detourDXGIPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
	{
		if (_presentInProgress)
		{
			return S_OK;
		}
		_presentInProgress = true;
		if (_tmpSwapChainInitialized)
		{
			if (!(Flags & DXGI_PRESENT_TEST) && !_imGuiInitializing)
			{
				if (_initializeDeviceAndContext)
				{
					if (FAILED(pSwapChain->GetDevice(__uuidof(_device), (void**)&_device)))
					{
						IGCS::Console::WriteError("Failed to get device from hooked swapchain");
					}
					else
					{
						OverlayConsole::instance().logDebug("DX11 Device: %p", (void*)_device);
						_device->GetImmediateContext(&_context);
					}
					if (nullptr == _context)
					{
						IGCS::Console::WriteError("Failed to get device context from hooked swapchain");
					}
					else
					{
						OverlayConsole::instance().logDebug("DX11 Context: %p", (void*)_context);
					}
					createRenderTarget(pSwapChain);
					ImGui_ImplDX11_Init(_device, _context);
					_initializeDeviceAndContext = false;
				}
				if (_framesToGrab > 0)
				{
					/*char buf[100];
					sprintf(buf, "[hook] main: %d hook: %d", framesToGrabSync, framesToGrab);
					OverlayControl::addNotification(buf);*/
					if (_framesToGrab >= _framesToGrabSync) {
						_fb_array.push_back(capture_frame(pSwapChain));
						--_framesToGrab;
						if (_framesToGrab == 0)
						{
							std::thread(saveAllFiles).detach();
						}
					}
				}
				// render our own stuff
				OverlayControl::renderOverlay();
				_context->OMSetRenderTargets(1, &_mainRenderTargetView, NULL);
				ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
				Input::resetKeyStates();
				Input::resetMouseState();
			}

		}
		HRESULT toReturn = hookedDXGIPresent(pSwapChain, SyncInterval, Flags);
		_presentInProgress = false;
		return toReturn;
	}

	void initializeHook()
	{
		_tmpSwapChainInitialized = false;
		D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
		DXGI_SWAP_CHAIN_DESC swapChainDesc;
		ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
		swapChainDesc.BufferCount = 1;
		swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		swapChainDesc.OutputWindow = IGCS::Globals::instance().mainWindowHandle();
		swapChainDesc.SampleDesc.Count = 1;
		swapChainDesc.Windowed = TRUE;
		swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

		ID3D11Device *pTmpDevice = NULL;
		ID3D11DeviceContext *pTmpContext = NULL;
		IDXGISwapChain* pTmpSwapChain;
		if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &pTmpSwapChain, &pTmpDevice, NULL, &pTmpContext)))
		{
			IGCS::Console::WriteError("Failed to create directX device and swapchain!");
			return;
		}

		__int64* pSwapChainVtable = NULL;
		pSwapChainVtable = (__int64*)pTmpSwapChain;
		pSwapChainVtable = (__int64*)pSwapChainVtable[0];

		OverlayConsole::instance().logDebug("Present Address: %p", (void*)(__int64*)pSwapChainVtable[DXGI_PRESENT_INDEX]);

		if (MH_CreateHook((LPBYTE)pSwapChainVtable[DXGI_PRESENT_INDEX], &detourDXGIPresent, reinterpret_cast<LPVOID*>(&hookedDXGIPresent)) != MH_OK)
		{
			IGCS::Console::WriteError("Hooking Present failed!");
		}
		if (MH_EnableHook((LPBYTE)pSwapChainVtable[DXGI_PRESENT_INDEX]) != MH_OK)
		{
			IGCS::Console::WriteError("Enabling of Present hook failed!");
		}

		OverlayConsole::instance().logDebug("ResizeBuffers Address: %p", (__int64*)pSwapChainVtable[DXGI_RESIZEBUFFERS_INDEX]);

		if (MH_CreateHook((LPBYTE)pSwapChainVtable[DXGI_RESIZEBUFFERS_INDEX], &detourDXGIResizeBuffers, reinterpret_cast<LPVOID*>(&hookedDXGIResizeBuffers)) != MH_OK)
		{
			IGCS::Console::WriteError("Hooking ResizeBuffers failed!");
		}
		if (MH_EnableHook((LPBYTE)pSwapChainVtable[DXGI_RESIZEBUFFERS_INDEX]) != MH_OK)
		{
			IGCS::Console::WriteError("Enabling of ResizeBuffers hook failed!");
		}

		pTmpDevice->Release();
		pTmpContext->Release();
		pTmpSwapChain->Release();
		_tmpSwapChainInitialized = true;

		OverlayConsole::instance().logDebug("DX11 hooks set");
	}

	void createRenderTarget(IDXGISwapChain* pSwapChain)
	{
		DXGI_SWAP_CHAIN_DESC sd;
		pSwapChain->GetDesc(&sd);
		ID3D11Texture2D* pBackBuffer;
		D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
		ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
		render_target_view_desc.Format = sd.BufferDesc.Format;
		render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
		pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
		_device->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &_mainRenderTargetView);
		// get the width/height of the back buffer.
		D3D11_TEXTURE2D_DESC StagingDesc;
		pBackBuffer->GetDesc(&StagingDesc);
		_width = StagingDesc.Width;
		_height = StagingDesc.Height;
		pBackBuffer->Release();
	}

	void cleanupRenderTarget()
	{
		if (nullptr != _mainRenderTargetView)
		{
			_mainRenderTargetView->Release();
			_mainRenderTargetView = nullptr;
		}
	}

	void syncFramesToGrab(int ftgs)
	{
		_framesToGrabSync = ftgs;
	}

	std::vector<uint8_t> capture_frame(IDXGISwapChain* pSwapChain)
	{
		OverlayConsole::instance().logLine("capture_frame()");

		std::vector<uint8_t> fbdata(_width * _height * 4);
		uint8_t* buffer = fbdata.data();
		D3D11_TEXTURE2D_DESC StagingDesc;
		ID3D11Texture2D* pBackBuffer = NULL;
		pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)& pBackBuffer);
		pBackBuffer->GetDesc(&StagingDesc);
		StagingDesc.Usage = D3D11_USAGE_STAGING;
		StagingDesc.BindFlags = 0;
		StagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		ID3D11Texture2D* pBackBufferStaging = NULL;
		HRESULT hr = _device->CreateTexture2D(&StagingDesc, NULL, &pBackBufferStaging);
		_context->CopyResource(pBackBufferStaging, pBackBuffer);
		D3D11_MAPPED_SUBRESOURCE mapped;
		hr = _context->Map(pBackBufferStaging, 0, D3D11_MAP_READ, 0, &mapped);
		if (FAILED(hr))
		{
			IGCS::Console::WriteError("Failed to map staging resource with screenshot capture! HRESULT is");
			std::cout << "Failed to map staging resource with screenshot capture! HRESULT is '" << std::hex << hr << std::dec << "'.";
			return fbdata;
		}
		auto mapped_data = static_cast<BYTE*>(mapped.pData);
		const UINT pitch = StagingDesc.Width * 4;
		for (UINT y = 0; y < StagingDesc.Height; y++)
		{
			memcpy(buffer, mapped_data, min(pitch, static_cast<UINT>(mapped.RowPitch)));

			for (UINT x = 0; x < pitch; x += 4)
			{
				buffer[x + 3] = 0xFF;

				if (StagingDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM || StagingDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
				{
					std::swap(buffer[x + 0], buffer[x + 2]);
				}
			}
			buffer += pitch;
			mapped_data += mapped.RowPitch;
		}
		_context->Unmap(pBackBufferStaging, 0);
		return fbdata;
	}

	void takeScreenshot(char* filename, int framesToGrab_ = 1)
	{
		_isDoneSavingImages = false;
		_framesToGrab = framesToGrab_;
		strcpy(_filename, filename);
	}

	int framesRemaining()
	{
		return _framesToGrab;
	}

	bool isDoneSavingImages()
	{
		return _isDoneSavingImages;
	}

	void saveAllFiles()
	{
		int i = 0;
		for (std::vector<uint8_t> d : _fb_array) {
			saveToFile(d, _filename, i);
			++i;
		}
		_fb_array.clear();
		_isDoneSavingImages = true;
		char buf[500];
		sprintf(buf, "All files saved out to %s", _filename);
		OverlayControl::addNotification(buf);
		return;
	}

	void saveToFile(std::vector<uint8_t> data, char* dirname, int framenum = 0)
	{
		char filename[500];
		sprintf(filename, "%s\\%d.jpg", dirname, framenum);
		bool _screenshot_save_success = false; // Default to a save failure unless it is reported to succeed below
		_screenshot_save_success = stbi_write_jpg(filename, _width, _height, 4, data.data(), 80) != 0;
		if (!_screenshot_save_success)
		{
			OverlayConsole::instance().logDebug("Failed to write screenshot of dimensions %dx%d to... %s", _width, _height, filename);
		}
		else {
			OverlayConsole::instance().logDebug("Successfully wrote screenshot of dimensions %dx%d to... %s", _width, _height, filename);
		}
	}

}<commit_msg>Move of screengrab to post-present, with the sync flag enabled so the 0 buffer isn't unbound till the next vbl<commit_after>#include "stdafx.h"
#include <d3d11.h>
#include "D3D11Hooker.h"
#include "Console.h"
#include "MinHook.h"
#include "Globals.h"
#include "imgui.h"
#include "Defaults.h"
#include "imgui_impl_dx11.h"
#include "imgui_impl_win32.h"
#include "OverlayControl.h"
#include "OverlayConsole.h"
#include "Input.h"
#include <atomic>
#include <thread>
#include "stb_image_write.h"
#include "stb_image_resize.h"

#pragma comment(lib, "d3d11.lib")

namespace IGCS::D3D11Hooker
{
	#define DXGI_PRESENT_INDEX			8
	#define DXGI_RESIZEBUFFERS_INDEX	13

	//--------------------------------------------------------------------------------------------------------------------------------
	// Forward declarations
	void createRenderTarget(IDXGISwapChain* pSwapChain);
	void cleanupRenderTarget();

	//--------------------------------------------------------------------------------------------------------------------------------
	// Typedefs of functions to hook
	typedef HRESULT(__stdcall *DXGIPresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
	typedef HRESULT(__stdcall *DXGIResizeBuffersHook) (IDXGISwapChain* pSwapChain, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT newFormat, UINT swapChainFlags);

	static ID3D11Device* _device = nullptr;
	static ID3D11DeviceContext* _context = nullptr;
	static ID3D11RenderTargetView* _mainRenderTargetView = nullptr;

	// Looking glass data
	static UINT _width;
	static UINT _height;
// TODO: CHANGE to std:string
	static char _filename[500];
	static atomic_int _framesToGrab;
	static atomic_int _framesToGrabSync;
	static atomic_bool _isDoneSavingImages = true;
	static std::vector<std::vector<uint8_t>> _fb_array;

	//--------------------------------------------------------------------------------------------------------------------------------
	// Pointers to the original hooked functions
	static DXGIPresentHook hookedDXGIPresent = nullptr;
	static DXGIResizeBuffersHook hookedDXGIResizeBuffers = nullptr;

	static bool _tmpSwapChainInitialized = false;
	static atomic_bool _imGuiInitializing = false;
	static atomic_bool _initializeDeviceAndContext = true;
	static atomic_bool _presentInProgress = false;

	HRESULT __stdcall detourDXGIResizeBuffers(IDXGISwapChain* pSwapChain, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT newFormat, UINT swapChainFlags)
	{
		_imGuiInitializing = true;
		ImGui_ImplDX11_InvalidateDeviceObjects();
		cleanupRenderTarget();
		HRESULT toReturn = hookedDXGIResizeBuffers(pSwapChain, bufferCount, width, height, newFormat, swapChainFlags);
		createRenderTarget(pSwapChain);
		ImGui_ImplDX11_CreateDeviceObjects();
		_imGuiInitializing = false;
		return toReturn;
	}

	HRESULT __stdcall detourDXGIPresent(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
	{
		if (_presentInProgress)
		{
			return S_OK;
		}
		_presentInProgress = true;
		bool validFrame = false;
		UINT flagsToPass = Flags;
		if (_tmpSwapChainInitialized)
		{
			if (!(Flags & DXGI_PRESENT_TEST) && !_imGuiInitializing)
			{
				if (_initializeDeviceAndContext)
				{
					if (FAILED(pSwapChain->GetDevice(__uuidof(_device), (void**)&_device)))
					{
						IGCS::Console::WriteError("Failed to get device from hooked swapchain");
					}
					else
					{
						OverlayConsole::instance().logDebug("DX11 Device: %p", (void*)_device);
						_device->GetImmediateContext(&_context);
					}
					if (nullptr == _context)
					{
						IGCS::Console::WriteError("Failed to get device context from hooked swapchain");
					}
					else
					{
						OverlayConsole::instance().logDebug("DX11 Context: %p", (void*)_context);
					}
					createRenderTarget(pSwapChain);
					ImGui_ImplDX11_Init(_device, _context);
					_initializeDeviceAndContext = false;
				}
				validFrame = true;
				// render our own stuff
				OverlayControl::renderOverlay();
				_context->OMSetRenderTargets(1, &_mainRenderTargetView, NULL);
				ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
				Input::resetKeyStates();
				Input::resetMouseState();
			}
		}
		bool grabFrame = false;
		if (validFrame && _framesToGrab > 0)
		{
			// make sure the Present call doesn't synchronize, so it's waiting for the VBL and doesn't unbind the backbuffer.
			flagsToPass |= DXGI_PRESENT_DO_NOT_SEQUENCE;
			grabFrame = true;
		}
		HRESULT toReturn = hookedDXGIPresent(pSwapChain, SyncInterval, flagsToPass);
		// if we have to grab the frame, do it now.
		if(grabFrame)
		{
			/*char buf[100];
			sprintf(buf, "[hook] main: %d hook: %d", framesToGrabSync, framesToGrab);
			OverlayControl::addNotification(buf);*/
			if (_framesToGrab >= _framesToGrabSync)
			{
				_fb_array.push_back(capture_frame(pSwapChain));
				--_framesToGrab;
				if (_framesToGrab == 0)
				{
					std::thread(saveAllFiles).detach();
				}
			}
		}
		_presentInProgress = false;
		return toReturn;
	}

	void initializeHook()
	{
		_tmpSwapChainInitialized = false;
		D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0;
		DXGI_SWAP_CHAIN_DESC swapChainDesc;
		ZeroMemory(&swapChainDesc, sizeof(swapChainDesc));
		swapChainDesc.BufferCount = 1;
		swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
		swapChainDesc.OutputWindow = IGCS::Globals::instance().mainWindowHandle();
		swapChainDesc.SampleDesc.Count = 1;
		swapChainDesc.Windowed = TRUE;
		swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;

		ID3D11Device *pTmpDevice = NULL;
		ID3D11DeviceContext *pTmpContext = NULL;
		IDXGISwapChain* pTmpSwapChain;
		if (FAILED(D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, &featureLevel, 1, D3D11_SDK_VERSION, &swapChainDesc, &pTmpSwapChain, &pTmpDevice, NULL, &pTmpContext)))
		{
			IGCS::Console::WriteError("Failed to create directX device and swapchain!");
			return;
		}

		__int64* pSwapChainVtable = NULL;
		pSwapChainVtable = (__int64*)pTmpSwapChain;
		pSwapChainVtable = (__int64*)pSwapChainVtable[0];

		OverlayConsole::instance().logDebug("Present Address: %p", (void*)(__int64*)pSwapChainVtable[DXGI_PRESENT_INDEX]);

		if (MH_CreateHook((LPBYTE)pSwapChainVtable[DXGI_PRESENT_INDEX], &detourDXGIPresent, reinterpret_cast<LPVOID*>(&hookedDXGIPresent)) != MH_OK)
		{
			IGCS::Console::WriteError("Hooking Present failed!");
		}
		if (MH_EnableHook((LPBYTE)pSwapChainVtable[DXGI_PRESENT_INDEX]) != MH_OK)
		{
			IGCS::Console::WriteError("Enabling of Present hook failed!");
		}

		OverlayConsole::instance().logDebug("ResizeBuffers Address: %p", (__int64*)pSwapChainVtable[DXGI_RESIZEBUFFERS_INDEX]);

		if (MH_CreateHook((LPBYTE)pSwapChainVtable[DXGI_RESIZEBUFFERS_INDEX], &detourDXGIResizeBuffers, reinterpret_cast<LPVOID*>(&hookedDXGIResizeBuffers)) != MH_OK)
		{
			IGCS::Console::WriteError("Hooking ResizeBuffers failed!");
		}
		if (MH_EnableHook((LPBYTE)pSwapChainVtable[DXGI_RESIZEBUFFERS_INDEX]) != MH_OK)
		{
			IGCS::Console::WriteError("Enabling of ResizeBuffers hook failed!");
		}

		pTmpDevice->Release();
		pTmpContext->Release();
		pTmpSwapChain->Release();
		_tmpSwapChainInitialized = true;

		OverlayConsole::instance().logDebug("DX11 hooks set");
	}

	void createRenderTarget(IDXGISwapChain* pSwapChain)
	{
		DXGI_SWAP_CHAIN_DESC sd;
		pSwapChain->GetDesc(&sd);
		ID3D11Texture2D* pBackBuffer;
		D3D11_RENDER_TARGET_VIEW_DESC render_target_view_desc;
		ZeroMemory(&render_target_view_desc, sizeof(render_target_view_desc));
		render_target_view_desc.Format = sd.BufferDesc.Format;
		render_target_view_desc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
		pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
		_device->CreateRenderTargetView(pBackBuffer, &render_target_view_desc, &_mainRenderTargetView);
		// get the width/height of the back buffer.
		D3D11_TEXTURE2D_DESC StagingDesc;
		pBackBuffer->GetDesc(&StagingDesc);
		_width = StagingDesc.Width;
		_height = StagingDesc.Height;
		pBackBuffer->Release();
	}

	void cleanupRenderTarget()
	{
		if (nullptr != _mainRenderTargetView)
		{
			_mainRenderTargetView->Release();
			_mainRenderTargetView = nullptr;
		}
	}

	void syncFramesToGrab(int ftgs)
	{
		_framesToGrabSync = ftgs;
	}

	std::vector<uint8_t> capture_frame(IDXGISwapChain* pSwapChain)
	{
		OverlayConsole::instance().logLine("capture_frame()");

		std::vector<uint8_t> fbdata(_width * _height * 4);
		uint8_t* buffer = fbdata.data();
		D3D11_TEXTURE2D_DESC StagingDesc;
		ID3D11Texture2D* pBackBuffer = NULL;
		pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)& pBackBuffer);
		pBackBuffer->GetDesc(&StagingDesc);
		StagingDesc.Usage = D3D11_USAGE_STAGING;
		StagingDesc.BindFlags = 0;
		StagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
		ID3D11Texture2D* pBackBufferStaging = NULL;
		HRESULT hr = _device->CreateTexture2D(&StagingDesc, NULL, &pBackBufferStaging);
		_context->CopyResource(pBackBufferStaging, pBackBuffer);
		D3D11_MAPPED_SUBRESOURCE mapped;
		hr = _context->Map(pBackBufferStaging, 0, D3D11_MAP_READ, 0, &mapped);
		if (FAILED(hr))
		{
			IGCS::Console::WriteError("Failed to map staging resource with screenshot capture! HRESULT is");
			std::cout << "Failed to map staging resource with screenshot capture! HRESULT is '" << std::hex << hr << std::dec << "'.";
			return fbdata;
		}
		auto mapped_data = static_cast<BYTE*>(mapped.pData);
		const UINT pitch = StagingDesc.Width * 4;
		for (UINT y = 0; y < StagingDesc.Height; y++)
		{
			memcpy(buffer, mapped_data, min(pitch, static_cast<UINT>(mapped.RowPitch)));

			for (UINT x = 0; x < pitch; x += 4)
			{
				buffer[x + 3] = 0xFF;

				if (StagingDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM || StagingDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM_SRGB)
				{
					std::swap(buffer[x + 0], buffer[x + 2]);
				}
			}
			buffer += pitch;
			mapped_data += mapped.RowPitch;
		}
		_context->Unmap(pBackBufferStaging, 0);
		return fbdata;
	}

	void takeScreenshot(char* filename, int framesToGrab_ = 1)
	{
		_isDoneSavingImages = false;
		_framesToGrab = framesToGrab_;
		strcpy(_filename, filename);
	}

	int framesRemaining()
	{
		return _framesToGrab;
	}

	bool isDoneSavingImages()
	{
		return _isDoneSavingImages;
	}

	void saveAllFiles()
	{
		int i = 0;
		for (std::vector<uint8_t> d : _fb_array) {
			saveToFile(d, _filename, i);
			++i;
		}
		_fb_array.clear();
		_isDoneSavingImages = true;
		char buf[500];
		sprintf(buf, "All files saved out to %s", _filename);
		OverlayControl::addNotification(buf);
		return;
	}

	void saveToFile(std::vector<uint8_t> data, char* dirname, int framenum = 0)
	{
		char filename[500];
		sprintf(filename, "%s\\%d.jpg", dirname, framenum);
		bool _screenshot_save_success = false; // Default to a save failure unless it is reported to succeed below
		_screenshot_save_success = stbi_write_jpg(filename, _width, _height, 4, data.data(), 80) != 0;
		if (!_screenshot_save_success)
		{
			OverlayConsole::instance().logDebug("Failed to write screenshot of dimensions %dx%d to... %s", _width, _height, filename);
		}
		else {
			OverlayConsole::instance().logDebug("Successfully wrote screenshot of dimensions %dx%d to... %s", _width, _height, filename);
		}
	}

}<|endoftext|>


<commit_before>// fluxbox.hh for Fluxbox Window Manager
// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// blackbox.hh for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: fluxbox.hh,v 1.88 2004/05/02 20:48:16 fluxgen Exp $

#ifndef	 FLUXBOX_HH
#define	 FLUXBOX_HH

#include "FbTk/App.hh"
#include "FbTk/Resource.hh"
#include "FbTk/Timer.hh"
#include "FbTk/Observer.hh"
#include "FbTk/SignalHandler.hh"

#include <X11/Xlib.h>
#include <X11/Xresource.h>

#include <cstdio>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else // !TIME_WITH_SYS_TIME
#ifdef	HAVE_SYS_TIME_H
#include <sys/time.h>
#else // !HAVE_SYS_TIME_H
#include <time.h>
#endif // HAVE_SYS_TIME_H
#endif // TIME_WITH_SYS_TIME

#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>

class AtomHandler;
class FluxboxWindow;
class WinClient;
class Keys;
class BScreen;
class FbAtoms;
class Toolbar;

///	main class for the window manager.
/**
	singleton type
*/
class Fluxbox : public FbTk::App,
                public FbTk::SignalEventHandler,
                public FbTk::Observer {
public:
    Fluxbox(int argc, char **argv, const char * dpy_name= 0,
            const char *rcfilename = 0);
    virtual ~Fluxbox();

    static Fluxbox *instance() { return s_singleton; }
    /// main event loop
    void eventLoop();
    bool validateWindow(Window win) const;
    void grab();
    void ungrab();
    Keys *keys() { return m_key.get(); }
    inline Atom getFluxboxPidAtom() const { return m_fluxbox_pid; }

    // Not currently implemented until we decide how it'll be used
    //WinClient *searchGroup(Window);
    WinClient *searchWindow(Window);
    inline WinClient *getFocusedWindow() { return m_focused_window; }

    BScreen *searchScreen(Window w);

    inline unsigned int getDoubleClickInterval() const { return *m_rc_double_click_interval; }
    inline unsigned int getUpdateDelayTime() const { return *m_rc_update_delay_time; }
    inline Time getLastTime() const { return m_last_time; }

    AtomHandler *getAtomHandler(const std::string &name);
    void addAtomHandler(AtomHandler *atomh, const std::string &name);
    void removeAtomHandler(AtomHandler *atomh);

    /// obsolete
    enum Titlebar{SHADE=0, MINIMIZE, MAXIMIZE, CLOSE, STICK, MENU, EMPTY};
    enum TabsAttachArea{ATTACH_AREA_WINDOW= 0, ATTACH_AREA_TITLEBAR};

    inline bool getIgnoreBorder() const { return *m_rc_ignoreborder; }

    inline const std::vector<Fluxbox::Titlebar>& getTitlebarRight() const { return *m_rc_titlebar_right; }
    inline const std::vector<Fluxbox::Titlebar>& getTitlebarLeft() const { return *m_rc_titlebar_left; }
    inline const Fluxbox::TabsAttachArea getTabsAttachArea() const { return *m_rc_tabs_attach_area; }
    inline const std::string &getStyleFilename() const { return *m_rc_stylefile; }

    inline const std::string &getMenuFilename() const { return *m_rc_menufile; }
    inline const std::string &getSlitlistFilename() const { return *m_rc_slitlistfile; }
    inline int colorsPerChannel() const { return *m_rc_colors_per_channel; }
    inline int getNumberOfLayers() const { return *m_rc_numlayers; }

    // class to store layer numbers (special Resource type)
    // we have a special resource type because we need to be able to name certain layers
    // a Resource<int> wouldn't allow this
    class Layer {
    public:
        explicit Layer(int i) : m_num(i) {};
        inline int getNum() const { return m_num; }

        Layer &operator=(int num) { m_num = num; return *this; }

    private:
        int m_num;
    };

    // TODO these probably should be configurable
    inline int getMenuLayer()      const { return 0; }
    inline int getAboveDockLayer() const { return 2; }
    inline int getDockLayer()      const { return 4; }
    inline int getTopLayer()       const { return 6; }
    inline int getNormalLayer()    const { return 8; }
    inline int getBottomLayer()    const { return 10; }
    inline int getDesktopLayer()   const { return 12; }

    inline time_t getAutoRaiseDelay() const { return *m_rc_auto_raise_delay; }

    inline unsigned int getCacheLife() const { return *m_rc_cache_life * 60000; }
    inline unsigned int getCacheMax() const { return *m_rc_cache_max; }
    inline bool useMod1() const { return *m_rc_use_mod1; }

    inline void maskWindowEvents(Window w, FluxboxWindow *bw)
        { m_masked = w; m_masked_window = bw; }

    void watchKeyRelease(BScreen &screen, unsigned int mods);

    void setFocusedWindow(WinClient *w);
    void revertFocus(BScreen &screen);
    // like revertFocus, but specifically related to this window (transients etc)
    void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false);
    void shutdown();
    void load_rc(BScreen &scr);
    void loadRootCommand(BScreen &scr);
    void loadTitlebar();
    void saveStyleFilename(const char *val) { m_rc_stylefile = (val == 0 ? "" : val); }
    void saveMenuFilename(const char *);
    void clearMenuFilenames();
    void saveTitlebarFilename(const char *);
    void saveSlitlistFilename(const char *val) { m_rc_slitlistfile = (val == 0 ? "" : val); }
    void saveWindowSearch(Window win, WinClient *winclient);
    // some windows relate to the group, not the client, so we record separately
    // searchWindow on these windows will give the active client in the group
    void saveWindowSearchGroup(Window win, FluxboxWindow *fbwin);
    void saveGroupSearch(Window win, WinClient *winclient);
    void save_rc();
    void removeWindowSearch(Window win);
    void removeWindowSearchGroup(Window win);
    void removeGroupSearch(Window win);
    void restart(const char *command = 0);
    void reconfigure();
    void rereadMenu();
    /// reloads the menus if the timestamps changed
    void checkMenu();

    void hideExtraMenus(BScreen &screen);

    /// handle any system signal sent to the application
    void handleSignal(int signum);
    void update(FbTk::Subject *changed);

    void attachSignals(FluxboxWindow &win);
    void attachSignals(WinClient &winclient);

    void timed_reconfigure();

    bool isStartup() const { return m_starting; }

    /// get screen from number
    BScreen *findScreen(int num);

    typedef std::vector<Fluxbox::Titlebar> TitlebarList;
    /// @return whether the timestamps on the menu changed
    bool menuTimestampsChanged() const;
    bool haveShape() const { return m_have_shape; }
    int shapeEventbase() const { return m_shape_eventbase; }
    void getDefaultDataFilename(char *, std::string &);
    // screen mouse was in at last key event
    BScreen *mouseScreen() { return m_mousescreen; }
    // screen of window that last key event (i.e. focused window) went to
    BScreen *keyScreen() { return m_keyscreen; }
    // screen we are watching for modifier changes
    BScreen *watchingScreen() { return m_watching_screen; }
    const XEvent &lastEvent() const { return m_last_event; }
private:

    typedef struct MenuTimestamp {
        std::string filename;
        time_t timestamp;
    } MenuTimestamp;

    std::string getRcFilename();
    void load_rc();

    void reload_rc();
    void real_rereadMenu();
    void real_reconfigure();

    void handleEvent(XEvent *xe);

    void setupConfigFiles();
    void handleButtonEvent(XButtonEvent &be);
    void handleUnmapNotify(XUnmapEvent &ue);
    void handleClientMessage(XClientMessageEvent &ce);
    void handleKeyEvent(XKeyEvent &ke);
    void setTitlebar(std::vector<Fluxbox::Titlebar>& dir, const char *arg);

    std::auto_ptr<FbAtoms> m_fbatoms;

    FbTk::ResourceManager m_resourcemanager, &m_screen_rm;

    //--- Resources

    FbTk::Resource<bool> m_rc_tabs, m_rc_ignoreborder;
    FbTk::Resource<int> m_rc_colors_per_channel, m_rc_numlayers,
        m_rc_double_click_interval, m_rc_update_delay_time;
    FbTk::Resource<std::string> m_rc_stylefile,
        m_rc_menufile, m_rc_keyfile, m_rc_slitlistfile,
        m_rc_groupfile;

    FbTk::Resource<TitlebarList> m_rc_titlebar_left, m_rc_titlebar_right;
    FbTk::Resource<TabsAttachArea> m_rc_tabs_attach_area;
    FbTk::Resource<unsigned int> m_rc_cache_life, m_rc_cache_max;
    FbTk::Resource<time_t> m_rc_auto_raise_delay;
    FbTk::Resource<bool> m_rc_use_mod1; /// temporary!, to disable mod1 for resize/move

    std::map<Window, WinClient *> m_window_search;
    std::map<Window, FluxboxWindow *> m_window_search_group;
    // A window is the group leader, which can map to several
    // WinClients in the group, it is *not* fluxbox's concept of groups
    // See ICCCM section 4.1.11
    // The group leader (which may not be mapped, so may not have a WinClient)
    // will have it's window being the group index
    std::multimap<Window, WinClient *> m_group_search;

    std::list<MenuTimestamp *> m_menu_timestamps;
    typedef std::list<BScreen *> ScreenList;
    ScreenList m_screen_list;

    WinClient *m_focused_window;
    FluxboxWindow *m_masked_window;

    BScreen *m_mousescreen, *m_keyscreen;
    BScreen *m_watching_screen;
    unsigned int m_watch_keyrelease;

    Atom m_fluxbox_pid;

    bool m_reconfigure_wait, m_reread_menu_wait;
    Time m_last_time;
    Window m_masked;
    std::string m_rc_file; ///< resource filename
    char **m_argv;
    int m_argc;
    XEvent m_last_event;

    FbTk::Timer m_reconfig_timer; ///< when we execute reconfig command we must wait at least to next event round

    std::auto_ptr<Keys> m_key;

    //default arguments for titlebar left and right
    static Fluxbox::Titlebar s_titlebar_left[], s_titlebar_right[];
    static Fluxbox *s_singleton;

    typedef std::map<AtomHandler *, std::string> AtomHandlerContainer;
    typedef AtomHandlerContainer::iterator AtomHandlerContainerIt;

    AtomHandlerContainer m_atomhandler;
    std::vector<Toolbar *> m_toolbars;

    bool m_starting;
    bool m_shutdown;
    int m_server_grabs;
    int m_randr_event_type; ///< the type number of randr event
    int m_shape_eventbase; ///< event base for shape events
    bool m_have_shape; ///< if shape is supported by server
    const char *m_RC_PATH;
    const char *m_RC_INIT_FILE;
    Atom m_kwm1_dockwindow, m_kwm2_dockwindow;
};

#endif // FLUXBOX_HH
<commit_msg>typedef Toolbars<commit_after>// fluxbox.hh for Fluxbox Window Manager
// Copyright (c) 2001 - 2003 Henrik Kinnunen (fluxgen at users.sourceforge.net)
//
// blackbox.hh for Blackbox - an X11 Window manager
// Copyright (c) 1997 - 2000 Brad Hughes (bhughes at tcac.net)
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
// and/or sell copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.

// $Id: fluxbox.hh,v 1.89 2004/07/15 09:52:14 fluxgen Exp $

#ifndef	 FLUXBOX_HH
#define	 FLUXBOX_HH

#include "FbTk/App.hh"
#include "FbTk/Resource.hh"
#include "FbTk/Timer.hh"
#include "FbTk/Observer.hh"
#include "FbTk/SignalHandler.hh"

#include <X11/Xlib.h>
#include <X11/Xresource.h>

#include <cstdio>

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif // HAVE_CONFIG_H

#ifdef TIME_WITH_SYS_TIME
#include <sys/time.h>
#include <time.h>
#else // !TIME_WITH_SYS_TIME
#ifdef	HAVE_SYS_TIME_H
#include <sys/time.h>
#else // !HAVE_SYS_TIME_H
#include <time.h>
#endif // HAVE_SYS_TIME_H
#endif // TIME_WITH_SYS_TIME

#include <list>
#include <map>
#include <memory>
#include <string>
#include <vector>

class AtomHandler;
class FluxboxWindow;
class WinClient;
class Keys;
class BScreen;
class FbAtoms;
class Toolbar;

///	main class for the window manager.
/**
	singleton type
*/
class Fluxbox : public FbTk::App,
                public FbTk::SignalEventHandler,
                public FbTk::Observer {
public:
    Fluxbox(int argc, char **argv, const char * dpy_name= 0,
            const char *rcfilename = 0);
    virtual ~Fluxbox();

    static Fluxbox *instance() { return s_singleton; }
    /// main event loop
    void eventLoop();
    bool validateWindow(Window win) const;
    void grab();
    void ungrab();
    Keys *keys() { return m_key.get(); }
    inline Atom getFluxboxPidAtom() const { return m_fluxbox_pid; }

    // Not currently implemented until we decide how it'll be used
    //WinClient *searchGroup(Window);
    WinClient *searchWindow(Window);
    inline WinClient *getFocusedWindow() { return m_focused_window; }

    BScreen *searchScreen(Window w);

    inline unsigned int getDoubleClickInterval() const { return *m_rc_double_click_interval; }
    inline unsigned int getUpdateDelayTime() const { return *m_rc_update_delay_time; }
    inline Time getLastTime() const { return m_last_time; }

    AtomHandler *getAtomHandler(const std::string &name);
    void addAtomHandler(AtomHandler *atomh, const std::string &name);
    void removeAtomHandler(AtomHandler *atomh);

    /// obsolete
    enum Titlebar{SHADE=0, MINIMIZE, MAXIMIZE, CLOSE, STICK, MENU, EMPTY};
    enum TabsAttachArea{ATTACH_AREA_WINDOW= 0, ATTACH_AREA_TITLEBAR};

    inline bool getIgnoreBorder() const { return *m_rc_ignoreborder; }

    inline const std::vector<Fluxbox::Titlebar>& getTitlebarRight() const { return *m_rc_titlebar_right; }
    inline const std::vector<Fluxbox::Titlebar>& getTitlebarLeft() const { return *m_rc_titlebar_left; }
    inline const Fluxbox::TabsAttachArea getTabsAttachArea() const { return *m_rc_tabs_attach_area; }
    inline const std::string &getStyleFilename() const { return *m_rc_stylefile; }

    inline const std::string &getMenuFilename() const { return *m_rc_menufile; }
    inline const std::string &getSlitlistFilename() const { return *m_rc_slitlistfile; }
    inline int colorsPerChannel() const { return *m_rc_colors_per_channel; }
    inline int getNumberOfLayers() const { return *m_rc_numlayers; }

    // class to store layer numbers (special Resource type)
    // we have a special resource type because we need to be able to name certain layers
    // a Resource<int> wouldn't allow this
    class Layer {
    public:
        explicit Layer(int i) : m_num(i) {};
        inline int getNum() const { return m_num; }

        Layer &operator=(int num) { m_num = num; return *this; }

    private:
        int m_num;
    };

    // TODO these probably should be configurable
    inline int getMenuLayer()      const { return 0; }
    inline int getAboveDockLayer() const { return 2; }
    inline int getDockLayer()      const { return 4; }
    inline int getTopLayer()       const { return 6; }
    inline int getNormalLayer()    const { return 8; }
    inline int getBottomLayer()    const { return 10; }
    inline int getDesktopLayer()   const { return 12; }

    inline time_t getAutoRaiseDelay() const { return *m_rc_auto_raise_delay; }

    inline unsigned int getCacheLife() const { return *m_rc_cache_life * 60000; }
    inline unsigned int getCacheMax() const { return *m_rc_cache_max; }
    inline bool useMod1() const { return *m_rc_use_mod1; }

    inline void maskWindowEvents(Window w, FluxboxWindow *bw)
        { m_masked = w; m_masked_window = bw; }

    void watchKeyRelease(BScreen &screen, unsigned int mods);

    void setFocusedWindow(WinClient *w);
    void revertFocus(BScreen &screen);
    // like revertFocus, but specifically related to this window (transients etc)
    void unfocusWindow(WinClient &client, bool full_revert = true, bool unfocus_frame = false);
    void shutdown();
    void load_rc(BScreen &scr);
    void loadRootCommand(BScreen &scr);
    void loadTitlebar();
    void saveStyleFilename(const char *val) { m_rc_stylefile = (val == 0 ? "" : val); }
    void saveMenuFilename(const char *);
    void clearMenuFilenames();
    void saveTitlebarFilename(const char *);
    void saveSlitlistFilename(const char *val) { m_rc_slitlistfile = (val == 0 ? "" : val); }
    void saveWindowSearch(Window win, WinClient *winclient);
    // some windows relate to the group, not the client, so we record separately
    // searchWindow on these windows will give the active client in the group
    void saveWindowSearchGroup(Window win, FluxboxWindow *fbwin);
    void saveGroupSearch(Window win, WinClient *winclient);
    void save_rc();
    void removeWindowSearch(Window win);
    void removeWindowSearchGroup(Window win);
    void removeGroupSearch(Window win);
    void restart(const char *command = 0);
    void reconfigure();
    void rereadMenu();
    /// reloads the menus if the timestamps changed
    void checkMenu();

    void hideExtraMenus(BScreen &screen);

    /// handle any system signal sent to the application
    void handleSignal(int signum);
    void update(FbTk::Subject *changed);

    void attachSignals(FluxboxWindow &win);
    void attachSignals(WinClient &winclient);

    void timed_reconfigure();

    bool isStartup() const { return m_starting; }

    /// get screen from number
    BScreen *findScreen(int num);

    typedef std::vector<Fluxbox::Titlebar> TitlebarList;
    /// @return whether the timestamps on the menu changed
    bool menuTimestampsChanged() const;
    bool haveShape() const { return m_have_shape; }
    int shapeEventbase() const { return m_shape_eventbase; }
    void getDefaultDataFilename(char *, std::string &);
    // screen mouse was in at last key event
    BScreen *mouseScreen() { return m_mousescreen; }
    // screen of window that last key event (i.e. focused window) went to
    BScreen *keyScreen() { return m_keyscreen; }
    // screen we are watching for modifier changes
    BScreen *watchingScreen() { return m_watching_screen; }
    const XEvent &lastEvent() const { return m_last_event; }
private:

    typedef struct MenuTimestamp {
        std::string filename;
        time_t timestamp;
    } MenuTimestamp;

    std::string getRcFilename();
    void load_rc();

    void reload_rc();
    void real_rereadMenu();
    void real_reconfigure();

    void handleEvent(XEvent *xe);

    void setupConfigFiles();
    void handleButtonEvent(XButtonEvent &be);
    void handleUnmapNotify(XUnmapEvent &ue);
    void handleClientMessage(XClientMessageEvent &ce);
    void handleKeyEvent(XKeyEvent &ke);
    void setTitlebar(std::vector<Fluxbox::Titlebar>& dir, const char *arg);

    std::auto_ptr<FbAtoms> m_fbatoms;

    FbTk::ResourceManager m_resourcemanager, &m_screen_rm;

    //--- Resources

    FbTk::Resource<bool> m_rc_tabs, m_rc_ignoreborder;
    FbTk::Resource<int> m_rc_colors_per_channel, m_rc_numlayers,
        m_rc_double_click_interval, m_rc_update_delay_time;
    FbTk::Resource<std::string> m_rc_stylefile,
        m_rc_menufile, m_rc_keyfile, m_rc_slitlistfile,
        m_rc_groupfile;

    FbTk::Resource<TitlebarList> m_rc_titlebar_left, m_rc_titlebar_right;
    FbTk::Resource<TabsAttachArea> m_rc_tabs_attach_area;
    FbTk::Resource<unsigned int> m_rc_cache_life, m_rc_cache_max;
    FbTk::Resource<time_t> m_rc_auto_raise_delay;
    FbTk::Resource<bool> m_rc_use_mod1; /// temporary!, to disable mod1 for resize/move

    std::map<Window, WinClient *> m_window_search;
    std::map<Window, FluxboxWindow *> m_window_search_group;
    // A window is the group leader, which can map to several
    // WinClients in the group, it is *not* fluxbox's concept of groups
    // See ICCCM section 4.1.11
    // The group leader (which may not be mapped, so may not have a WinClient)
    // will have it's window being the group index
    std::multimap<Window, WinClient *> m_group_search;

    std::list<MenuTimestamp *> m_menu_timestamps;
    typedef std::list<BScreen *> ScreenList;
    ScreenList m_screen_list;

    WinClient *m_focused_window;
    FluxboxWindow *m_masked_window;

    BScreen *m_mousescreen, *m_keyscreen;
    BScreen *m_watching_screen;
    unsigned int m_watch_keyrelease;

    Atom m_fluxbox_pid;

    bool m_reconfigure_wait, m_reread_menu_wait;
    Time m_last_time;
    Window m_masked;
    std::string m_rc_file; ///< resource filename
    char **m_argv;
    int m_argc;
    XEvent m_last_event;

    FbTk::Timer m_reconfig_timer; ///< when we execute reconfig command we must wait at least to next event round

    std::auto_ptr<Keys> m_key;

    //default arguments for titlebar left and right
    static Fluxbox::Titlebar s_titlebar_left[], s_titlebar_right[];
    static Fluxbox *s_singleton;

    typedef std::map<AtomHandler *, std::string> AtomHandlerContainer;
    typedef AtomHandlerContainer::iterator AtomHandlerContainerIt;

    AtomHandlerContainer m_atomhandler;
    typedef std::vector<Toolbar *> Toolbars;
    Toolbars m_toolbars;

    bool m_starting;
    bool m_shutdown;
    int m_server_grabs;
    int m_randr_event_type; ///< the type number of randr event
    int m_shape_eventbase; ///< event base for shape events
    bool m_have_shape; ///< if shape is supported by server
    const char *m_RC_PATH;
    const char *m_RC_INIT_FILE;
    Atom m_kwm1_dockwindow, m_kwm2_dockwindow;
};

#endif // FLUXBOX_HH
<|endoftext|>


<commit_before>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#ifndef SYSLOGD_HPP
#define SYSLOGD_HPP

#include <cstdio>
#include <type_traits>
#include <string>
#include <map>
#include <regex>

#include <sys/syslog.h>

const int BUFLEN = 2048;
const int TIMELEN = 32;

const std::map<int, std::string> pri_colors = {
  { LOG_EMERG,   "\033[38;5;1m" },    // RED
  { LOG_ALERT,   "\033[38;5;160m" },  // RED (lighter)
  { LOG_CRIT,    "\033[38;5;196m" },  // RED (even lighter)
  { LOG_ERR,     "\033[38;5;208m" },  // DARK YELLOW
  { LOG_WARNING, "\033[93m" },        // YELLOW
  { LOG_NOTICE,  "\033[92m" },        // GREEN
  { LOG_INFO,    "\033[96m" },        // TURQUOISE
  { LOG_DEBUG,   "\033[94m" }         // BLUE
};
const std::string COLOR_END = "\033[0m";

struct Syslog_facility {
  virtual void syslog(const std::string& log_message) = 0;
  virtual std::string name() = 0;

  Syslog_facility() {}
  Syslog_facility(const char* ident) : ident_{ident} {}

  bool ident_is_set();
  const char* ident() { return ident_; }

  void set_priority(int priority) { priority_ = priority; }
  int priority() { return priority_; }
  std::string priority_string();

  void set_logopt(int logopt) { logopt_ = logopt; }
  int logopt() { return logopt_; }

private:
  const char* ident_ = nullptr;
  int priority_;
  int logopt_;
};

struct Syslog_kern : public Syslog_facility {
  void syslog(const std::string& log_message) override;
  std::string name() override;

  Syslog_kern() : Syslog_facility() {}
  Syslog_kern(const char* ident) : Syslog_facility(ident) {}
};

struct Syslog_user : public Syslog_facility {
  void syslog(const std::string& log_message) override;
  std::string name() override;

  Syslog_user() : Syslog_facility() {}
  Syslog_user(const char* ident) : Syslog_facility(ident) {}
};

struct Syslog_mail : public Syslog_facility {
  void syslog(const std::string& log_message) override;
  std::string name() override;

  Syslog_mail() : Syslog_facility() {}
  Syslog_mail(const char* ident) : Syslog_facility(ident) {}
};

struct Syslog {

  // Parameter pack arguments
  template <typename... Args>
  static void syslog(int priority, const char* message, Args&&... args) {
    // snprintf removes % if calling syslog with %m in addition to arguments
    // Find %m here first and escape % if found
    std::regex m_regex{"\\%m"};
    std::string msg = std::regex_replace(message, m_regex, "%%m");

    char buf[BUFLEN];
    snprintf(buf, BUFLEN, msg.c_str(), args...);
    syslog(priority, buf);
  };

  // va_list arguments (POSIX)
  static void syslog(int priority, const char* message, va_list args) {
    // vsnprintf removes % if calling syslog with %m in addition to arguments
    // Find %m here first and escape % if found
    std::regex m_regex{"\\%m"};
    std::string msg = std::regex_replace(message, m_regex, "%%m");

    char buf[BUFLEN];
    vsnprintf(buf, BUFLEN, msg.c_str(), args);
    syslog(priority, buf);
  };

  static void syslog(int priority, const char* buf);

  template <typename Facility>
  static void openlog(const char* ident, int logopt) {
    static_assert(std::is_base_of<Syslog_facility, Facility>::value, "Facility is not base of Syslog_facility");
    last_open = std::make_unique<Facility>(ident);

    if (valid_logopt(logopt))
      last_open->set_logopt(logopt);

    // TODO:

    if (logopt & LOG_CONS and last_open->priority() == LOG_ERR) {
      // Log to system console

    }

    if (logopt & LOG_NDELAY) {
      // Connect to syslog daemon immediately

    } else if (logopt & LOG_ODELAY) {
      // Delay open until syslog() is called

    }

    if (logopt & LOG_NOWAIT) {
      // Do not wait for child processes - deprecated?

    }

    if (logopt & LOG_PERROR) {
      // Log to stderr

    }
  }

  static void closelog() {
    // Back to default values:
    // ident_ = nullptr; (Will then be service-name)
    // log_opt = 0;
    // facility = LOG_USER;
    openlog<Syslog_user>(nullptr, 0);
  }

  static bool valid_priority(int priority) {
    if (priority < LOG_EMERG or priority > LOG_DEBUG)
      return false;

    return true;
  }

  static bool valid_logopt(int logopt) {
    if (logopt & LOG_PID or logopt & LOG_CONS or logopt & LOG_NDELAY or
      logopt & LOG_ODELAY or logopt & LOG_NOWAIT or logopt & LOG_PERROR)
      return true;

    return false;
  }

private:
  static std::unique_ptr<Syslog_facility> last_open;
};

#endif<commit_msg>Syslog: Should be possible to clear logopt<commit_after>// This file is a part of the IncludeOS unikernel - www.includeos.org
//
// Copyright 2015 Oslo and Akershus University College of Applied Sciences
// and Alfred Bratterud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once
#ifndef SYSLOGD_HPP
#define SYSLOGD_HPP

#include <cstdio>
#include <type_traits>
#include <string>
#include <map>
#include <regex>

#include <sys/syslog.h>

const int BUFLEN = 2048;
const int TIMELEN = 32;

const std::map<int, std::string> pri_colors = {
  { LOG_EMERG,   "\033[38;5;1m" },    // RED
  { LOG_ALERT,   "\033[38;5;160m" },  // RED (lighter)
  { LOG_CRIT,    "\033[38;5;196m" },  // RED (even lighter)
  { LOG_ERR,     "\033[38;5;208m" },  // DARK YELLOW
  { LOG_WARNING, "\033[93m" },        // YELLOW
  { LOG_NOTICE,  "\033[92m" },        // GREEN
  { LOG_INFO,    "\033[96m" },        // TURQUOISE
  { LOG_DEBUG,   "\033[94m" }         // BLUE
};
const std::string COLOR_END = "\033[0m";

struct Syslog_facility {
  virtual void syslog(const std::string& log_message) = 0;
  virtual std::string name() = 0;

  Syslog_facility() {}
  Syslog_facility(const char* ident) : ident_{ident} {}

  bool ident_is_set();
  const char* ident() { return ident_; }

  void set_priority(int priority) { priority_ = priority; }
  int priority() { return priority_; }
  std::string priority_string();

  void set_logopt(int logopt) { logopt_ = logopt; }
  int logopt() { return logopt_; }

private:
  const char* ident_ = nullptr;
  int priority_;
  int logopt_;
};

struct Syslog_kern : public Syslog_facility {
  void syslog(const std::string& log_message) override;
  std::string name() override;

  Syslog_kern() : Syslog_facility() {}
  Syslog_kern(const char* ident) : Syslog_facility(ident) {}
};

struct Syslog_user : public Syslog_facility {
  void syslog(const std::string& log_message) override;
  std::string name() override;

  Syslog_user() : Syslog_facility() {}
  Syslog_user(const char* ident) : Syslog_facility(ident) {}
};

struct Syslog_mail : public Syslog_facility {
  void syslog(const std::string& log_message) override;
  std::string name() override;

  Syslog_mail() : Syslog_facility() {}
  Syslog_mail(const char* ident) : Syslog_facility(ident) {}
};

struct Syslog {

  // Parameter pack arguments
  template <typename... Args>
  static void syslog(int priority, const char* message, Args&&... args) {
    // snprintf removes % if calling syslog with %m in addition to arguments
    // Find %m here first and escape % if found
    std::regex m_regex{"\\%m"};
    std::string msg = std::regex_replace(message, m_regex, "%%m");

    char buf[BUFLEN];
    snprintf(buf, BUFLEN, msg.c_str(), args...);
    syslog(priority, buf);
  };

  // va_list arguments (POSIX)
  static void syslog(int priority, const char* message, va_list args) {
    // vsnprintf removes % if calling syslog with %m in addition to arguments
    // Find %m here first and escape % if found
    std::regex m_regex{"\\%m"};
    std::string msg = std::regex_replace(message, m_regex, "%%m");

    char buf[BUFLEN];
    vsnprintf(buf, BUFLEN, msg.c_str(), args);
    syslog(priority, buf);
  };

  static void syslog(int priority, const char* buf);

  template <typename Facility>
  static void openlog(const char* ident, int logopt) {
    static_assert(std::is_base_of<Syslog_facility, Facility>::value, "Facility is not base of Syslog_facility");
    last_open = std::make_unique<Facility>(ident);

    if (valid_logopt(logopt) or logopt == 0)  // Should be possible to clear the logopt
      last_open->set_logopt(logopt);

    // TODO:

    if (logopt & LOG_CONS and last_open->priority() == LOG_ERR) {
      // Log to system console

    }

    if (logopt & LOG_NDELAY) {
      // Connect to syslog daemon immediately

    } else if (logopt & LOG_ODELAY) {
      // Delay open until syslog() is called

    }

    if (logopt & LOG_NOWAIT) {
      // Do not wait for child processes - deprecated?

    }

    if (logopt & LOG_PERROR) {
      // Log to stderr

    }
  }

  static void closelog() {
    // Back to default values:
    // ident_ = nullptr; (Will then be service-name)
    // log_opt = 0;
    // facility = LOG_USER;
    openlog<Syslog_user>(nullptr, 0);
  }

  static bool valid_priority(int priority) {
    if (priority < LOG_EMERG or priority > LOG_DEBUG)
      return false;

    return true;
  }

  static bool valid_logopt(int logopt) {
    if (logopt & LOG_PID or logopt & LOG_CONS or logopt & LOG_NDELAY or
      logopt & LOG_ODELAY or logopt & LOG_NOWAIT or logopt & LOG_PERROR)
      return true;

    return false;
  }

private:
  static std::unique_ptr<Syslog_facility> last_open;
};

#endif<|endoftext|>


<commit_before>// -------------------------------------------------------------------------
//    @FileName         :    NFPluginLoader.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :
//    @Module           :    NFPluginLoader
//
// -------------------------------------------------------------------------

//#include <crtdbg.h>
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
#include "NFCActorManager.h"
#include "NFComm/Config/NFConfig.h"
#include "NFComm/NFPluginModule/NFPlatform.h"

#if NF_PLATFORM == NF_PLATFORM_LINUX
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <signal.h>
#endif

#if NF_PLATFORM == NF_PLATFORM_WIN

#pragma comment( lib, "DbgHelp" )
// Dumpļ
void CreateDumpFile(const std::string& strDumpFilePathName, EXCEPTION_POINTERS* pException)
{
    // Dumpļ
    HANDLE hDumpFile = CreateFile(strDumpFilePathName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    // DumpϢ
    MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
    dumpInfo.ExceptionPointers = pException;
    dumpInfo.ThreadId = GetCurrentThreadId();
    dumpInfo.ClientPointers = TRUE;

    // дDumpļ
    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);

    CloseHandle(hDumpFile);
}

// Unhandled ExceptionĻص
long ApplicationCrashHandler(EXCEPTION_POINTERS* pException)
{
    time_t t = time(0);
    char szDmupName[MAX_PATH];
    tm* ptm = localtime(&t);

    sprintf_s(szDmupName, "%04d_%02d_%02d_%02d_%02d_%02d.dmp",  ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    CreateDumpFile(szDmupName, pException);

    FatalAppExit(-1,  szDmupName);

    return EXCEPTION_EXECUTE_HANDLER;
}
#endif

void CloseXButton()
{
#if defined(NF_DEBUG_MODE)
#if NF_PLATFORM == NF_PLATFORM_WIN
	HWND hWnd = GetConsoleWindow();
	if (hWnd)
	{
		HMENU hMenu = GetSystemMenu(hWnd, FALSE);
		EnableMenuItem(hMenu, SC_CLOSE, MF_DISABLED | MF_BYCOMMAND);
	}
#endif
#endif
}

bool bExitApp = false;
std::thread gThread;

void ThreadFunc()
{
    while (!bExitApp)
    {
        //std::this_thread::sleep_for(std::chrono::milliseconds(1000));

        //         std::string s;
        //         std::cin >> s;
        //         if ( 0 == stricmp( s.c_str(), "exit" ) )
        //         {
        //             bExitApp = true;
        //         }
    }
}

void CreateBackThread()
{
    //gThread = std::thread(std::bind(&ThreadFunc));
    //auto f = std::async (std::launch::async, std::bind(ThreadFunc));
    //std::cout << "CreateBackThread, thread ID = " << gThread.get_id() << std::endl;
}

void InitDaemon()
{
#if NF_PLATFORM == NF_PLATFORM_LINUX
    daemon(1, 0);

    // ignore signals
    signal(SIGINT,  SIG_IGN);
    signal(SIGHUP,  SIG_IGN);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
#endif
}

void PrintfLogo()
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif

    std::cout << "\n" << std::endl;
    std::cout << "" << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "                 NoahFrame                  " << std::endl;
    std::cout << "   Copyright (c) 2011-2016  NFrame Studio   " << std::endl;
    std::cout << "             All rights reserved.           " << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "" << std::endl;
    std::cout << "\n" << std::endl;

#if NF_PLATFORM == NF_PLATFORM_WIN
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif // NF_PLATFORM
}

#if NF_PLATFORM == NF_PLATFORM_WIN || NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_APPLE
int main(int argc, char* argv[])
#elif  NF_PLATFORM == NF_PLATFORM_ANDROID || NF_PLATFORM == NF_PLATFORM_APPLE_IOS

#endif
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
#elif NF_PLATFORM == NF_PLATFORM_LINUX
    bool bDaemon = false;

    if (argc > 1)
    {
        if (0 == NFSTRICMP((const char*)argv[1], "-d"))
        {
            bDaemon = true;
        }
    }

    if (bDaemon)
    {
        InitDaemon();
    }

    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);

#endif
    NFCActorManager::GetSingletonPtr()->Init();
    NFCActorManager::GetSingletonPtr()->AfterInit();
    NFCActorManager::GetSingletonPtr()->CheckConfig();

    PrintfLogo();

    CloseXButton();
    CreateBackThread();

    while (!bExitApp)    //DEBUG汾RELEASE
    {
        while (true)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(1));

            if (bExitApp)
            {
                break;
            }

#if NF_PLATFORM == NF_PLATFORM_WIN
            __try
            {
#endif
                NFCActorManager::GetSingletonPtr()->Execute();
#if NF_PLATFORM == NF_PLATFORM_WIN
            }
            __except (ApplicationCrashHandler(GetExceptionInformation()))
            {
            }
#endif
        }
    }

    NFCActorManager::GetSingletonPtr()->BeforeShut();
    NFCActorManager::GetSingletonPtr()->Shut();

    NFCActorManager::GetSingletonPtr()->ReleaseInstance();

    return 0;
}
<commit_msg>opened the "close windows" button when it run in debug mode<commit_after>// -------------------------------------------------------------------------
//    @FileName         :    NFPluginLoader.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :
//    @Module           :    NFPluginLoader
//
// -------------------------------------------------------------------------

//#include <crtdbg.h>
#include <time.h>
#include <stdio.h>
#include <iostream>
#include <utility>
#include <thread>
#include <chrono>
#include <functional>
#include <atomic>
#include "NFCActorManager.h"
#include "NFComm/Config/NFConfig.h"
#include "NFComm/NFPluginModule/NFPlatform.h"

#if NF_PLATFORM == NF_PLATFORM_LINUX
#include <unistd.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <signal.h>
#endif

#if NF_PLATFORM == NF_PLATFORM_WIN

#pragma comment( lib, "DbgHelp" )
// Dumpļ
void CreateDumpFile(const std::string& strDumpFilePathName, EXCEPTION_POINTERS* pException)
{
    // Dumpļ
    HANDLE hDumpFile = CreateFile(strDumpFilePathName.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    // DumpϢ
    MINIDUMP_EXCEPTION_INFORMATION dumpInfo;
    dumpInfo.ExceptionPointers = pException;
    dumpInfo.ThreadId = GetCurrentThreadId();
    dumpInfo.ClientPointers = TRUE;

    // дDumpļ
    MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hDumpFile, MiniDumpNormal, &dumpInfo, NULL, NULL);

    CloseHandle(hDumpFile);
}

// Unhandled ExceptionĻص
long ApplicationCrashHandler(EXCEPTION_POINTERS* pException)
{
    time_t t = time(0);
    char szDmupName[MAX_PATH];
    tm* ptm = localtime(&t);

    sprintf_s(szDmupName, "%04d_%02d_%02d_%02d_%02d_%02d.dmp",  ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
    CreateDumpFile(szDmupName, pException);

    FatalAppExit(-1,  szDmupName);

    return EXCEPTION_EXECUTE_HANDLER;
}
#endif

void CloseXButton()
{
#ifndef NF_DEBUG_MODE
#if NF_PLATFORM == NF_PLATFORM_WIN
	HWND hWnd = GetConsoleWindow();
	if (hWnd)
	{
		HMENU hMenu = GetSystemMenu(hWnd, FALSE);
		EnableMenuItem(hMenu, SC_CLOSE, MF_DISABLED | MF_BYCOMMAND);
	}
#endif
#endif
}

bool bExitApp = false;
std::thread gThread;

void ThreadFunc()
{
    while (!bExitApp)
    {
        //std::this_thread::sleep_for(std::chrono::milliseconds(1000));

        //         std::string s;
        //         std::cin >> s;
        //         if ( 0 == stricmp( s.c_str(), "exit" ) )
        //         {
        //             bExitApp = true;
        //         }
    }
}

void CreateBackThread()
{
    //gThread = std::thread(std::bind(&ThreadFunc));
    //auto f = std::async (std::launch::async, std::bind(ThreadFunc));
    //std::cout << "CreateBackThread, thread ID = " << gThread.get_id() << std::endl;
}

void InitDaemon()
{
#if NF_PLATFORM == NF_PLATFORM_LINUX
    daemon(1, 0);

    // ignore signals
    signal(SIGINT,  SIG_IGN);
    signal(SIGHUP,  SIG_IGN);
    signal(SIGQUIT, SIG_IGN);
    signal(SIGPIPE, SIG_IGN);
    signal(SIGTTOU, SIG_IGN);
    signal(SIGTTIN, SIG_IGN);
    signal(SIGTERM, SIG_IGN);
#endif
}

void PrintfLogo()
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif

    std::cout << "\n" << std::endl;
    std::cout << "" << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "                 NoahFrame                  " << std::endl;
    std::cout << "   Copyright (c) 2011-2016  NFrame Studio   " << std::endl;
    std::cout << "             All rights reserved.           " << std::endl;
    std::cout << "                                            " << std::endl;
    std::cout << "" << std::endl;
    std::cout << "\n" << std::endl;

#if NF_PLATFORM == NF_PLATFORM_WIN
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
#endif // NF_PLATFORM
}

#if NF_PLATFORM == NF_PLATFORM_WIN || NF_PLATFORM == NF_PLATFORM_LINUX || NF_PLATFORM == NF_PLATFORM_APPLE
int main(int argc, char* argv[])
#elif  NF_PLATFORM == NF_PLATFORM_ANDROID || NF_PLATFORM == NF_PLATFORM_APPLE_IOS

#endif
{
#if NF_PLATFORM == NF_PLATFORM_WIN
    SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)ApplicationCrashHandler);
#elif NF_PLATFORM == NF_PLATFORM_LINUX
    bool bDaemon = false;

    if (argc > 1)
    {
        if (0 == NFSTRICMP((const char*)argv[1], "-d"))
        {
            bDaemon = true;
        }
    }

    if (bDaemon)
    {
        InitDaemon();
    }

    signal(SIGPIPE, SIG_IGN);
    signal(SIGCHLD, SIG_IGN);

#endif
    NFCActorManager::GetSingletonPtr()->Init();
    NFCActorManager::GetSingletonPtr()->AfterInit();
    NFCActorManager::GetSingletonPtr()->CheckConfig();

    PrintfLogo();

    CloseXButton();
    CreateBackThread();

    while (!bExitApp)    //DEBUG汾RELEASE
    {
        while (true)
        {
            std::this_thread::sleep_for(std::chrono::milliseconds(1));

            if (bExitApp)
            {
                break;
            }

#if NF_PLATFORM == NF_PLATFORM_WIN
            __try
            {
#endif
                NFCActorManager::GetSingletonPtr()->Execute();
#if NF_PLATFORM == NF_PLATFORM_WIN
            }
            __except (ApplicationCrashHandler(GetExceptionInformation()))
            {
            }
#endif
        }
    }

    NFCActorManager::GetSingletonPtr()->BeforeShut();
    NFCActorManager::GetSingletonPtr()->Shut();

    NFCActorManager::GetSingletonPtr()->ReleaseInstance();

    return 0;
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

//-----------------------------------------------------------------
//         AliAnalysisTaskSpectraAllChAOD class
//-----------------------------------------------------------------

#include "TChain.h"
#include "TTree.h"
#include "TLegend.h"
#include "TH1F.h"
#include "TH2F.h"
#include "THnSparse.h"
#include "TCanvas.h"
#include "AliAnalysisTask.h"
#include "AliAODTrack.h"
#include "AliAODMCParticle.h"
#include "AliVParticle.h"
#include "AliAODEvent.h"
#include "AliAODInputHandler.h"
#include "AliAnalysisTaskSpectraAllChAOD.h"
#include "AliAnalysisTaskESDfilter.h"
#include "AliAnalysisDataContainer.h"
#include "AliSpectraAODTrackCuts.h"
#include "AliSpectraAODEventCuts.h"
#include "AliHelperPID.h"
#include "AliPIDCombined.h"
#include "AliCentrality.h"
#include "TProof.h"
#include "AliVEvent.h"
#include "AliStack.h"
#include <TMCProcess.h>

#include <iostream>

using namespace AliHelperPIDNameSpace;
using namespace std;

ClassImp(AliAnalysisTaskSpectraAllChAOD)

//________________________________________________________________________
AliAnalysisTaskSpectraAllChAOD::AliAnalysisTaskSpectraAllChAOD(const char *name) : AliAnalysisTaskSE(name),
  fAOD(0x0),
  fTrackCuts(0x0),
  fEventCuts(0x0),
  fHelperPID(0x0),
  fIsMC(0),
  fCharge(0),
  fVZEROside(0),
  fOutput(0x0),
  fnCentBins(20),
  fnQvecBins(40)
{
  // Default constructor
  DefineInput(0, TChain::Class());
  DefineOutput(1, TList::Class());
  DefineOutput(2, AliSpectraAODEventCuts::Class());
  DefineOutput(3, AliSpectraAODTrackCuts::Class());
  DefineOutput(4, AliHelperPID::Class());
}

//________________________________________________________________________
void AliAnalysisTaskSpectraAllChAOD::UserCreateOutputObjects()
{
  // create output objects
  fOutput=new TList();
  fOutput->SetOwner();
  fOutput->SetName("fOutput");

  if (!fTrackCuts) AliFatal("Track Cuts should be set in the steering macro");
  if (!fEventCuts) AliFatal("Event Cuts should be set in the steering macro");
  if (!fHelperPID)  AliFatal("HelperPID should be set in the steering macro");

  // binning common to all the THn
  const Double_t ptBins[] = {0.20,0.30,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.2,1.4,1.6,1.8,2.0,2.4,2.8,3.2,3.6,4.0,5.0,6.0,7.0,8.0,9.0,10.,12.,15.};
  const Int_t nptBins=26;

  //dimensions of THnSparse for tracks
  const Int_t nvartrk=8;
  //                                             pt          cent        Q vec     IDrec     IDgen       isph           iswd      y
  Int_t    binsHistRealTrk[nvartrk] = {      nptBins, fnCentBins,   fnQvecBins,        4,        3,         2,          2,       2};
  Double_t xminHistRealTrk[nvartrk] = {         0.,          0.,            0.,     -1.5,      -0.5,      -0.5,        -0.5,   -0.5};
  Double_t xmaxHistRealTrk[nvartrk] = {       10.,       100.,            8.,      2.5,      2.5,       1.5,         1.5,     0.5};
  THnSparseF* NSparseHistTrk = new THnSparseF("NSparseHistTrk","NSparseHistTrk",nvartrk,binsHistRealTrk,xminHistRealTrk,xmaxHistRealTrk);
  NSparseHistTrk->GetAxis(0)->SetTitle("#it{p}_{T,rec}");
  NSparseHistTrk->GetAxis(0)->SetName("pT_rec");
  NSparseHistTrk->SetBinEdges(0,ptBins);
  NSparseHistTrk->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(2)->SetTitle("Q vec");
  NSparseHistTrk->GetAxis(2)->SetName("Q_vec");
  NSparseHistTrk->GetAxis(3)->SetTitle("ID rec");
  NSparseHistTrk->GetAxis(3)->SetName("ID_rec");
  NSparseHistTrk->GetAxis(4)->SetTitle("ID gen");
  NSparseHistTrk->GetAxis(4)->SetName("ID_gen");
  NSparseHistTrk->GetAxis(5)->SetTitle("isph");
  NSparseHistTrk->GetAxis(5)->SetName("isph");
  NSparseHistTrk->GetAxis(6)->SetTitle("iswd");
  NSparseHistTrk->GetAxis(6)->SetName("iswd");
  NSparseHistTrk->GetAxis(7)->SetTitle("y");
  NSparseHistTrk->GetAxis(7)->SetName("y");
  fOutput->Add(NSparseHistTrk);

  //dimensions of THnSparse for stack
  const Int_t nvarst=5;
  //                                             pt          cent    IDgen        isph        y
  Int_t    binsHistRealSt[nvarst] = {      nptBins,  fnCentBins,        3,         2,        2};
  Double_t xminHistRealSt[nvarst] = {         0.,           0.,      -0.5,      -0.5,    -0.5};
  Double_t xmaxHistRealSt[nvarst] = {       10.,        100.,      2.5,       1.5,      0.5};
  THnSparseF* NSparseHistSt = new THnSparseF("NSparseHistSt","NSparseHistSt",nvarst,binsHistRealSt,xminHistRealSt,xmaxHistRealSt);
  NSparseHistSt->GetAxis(0)->SetTitle("#it{p}_{T,gen}");
  NSparseHistSt->SetBinEdges(0,ptBins);
  NSparseHistSt->GetAxis(0)->SetName("pT_rec");
  NSparseHistSt->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(2)->SetTitle("ID gen");
  NSparseHistSt->GetAxis(2)->SetName("ID_gen");
  NSparseHistSt->GetAxis(3)->SetTitle("isph");
  NSparseHistSt->GetAxis(3)->SetName("isph");
  NSparseHistSt->GetAxis(4)->SetTitle("y");
  NSparseHistSt->GetAxis(4)->SetName("y");
  fOutput->Add(NSparseHistSt);

  //dimensions of THnSparse for the normalization
  const Int_t nvarev=2;
  //                                             cent             Q vec
  Int_t    binsHistRealEv[nvarev] = {    fnCentBins,      fnQvecBins};
  Double_t xminHistRealEv[nvarev] = {           0.,               0.};
  Double_t xmaxHistRealEv[nvarev] = {       100.,              10.};
  THnSparseF* NSparseHistEv = new THnSparseF("NSparseHistEv","NSparseHistEv",nvarev,binsHistRealEv,xminHistRealEv,xmaxHistRealEv);
  NSparseHistEv->GetAxis(0)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(0)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(1)->SetTitle("Q vec");
  NSparseHistEv->GetAxis(1)->SetName("Q_vec");
  fOutput->Add(NSparseHistEv);

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//________________________________________________________________________

void AliAnalysisTaskSpectraAllChAOD::UserExec(Option_t *)
{
  //Printf("An event");
  // main event loop
  fAOD = dynamic_cast<AliAODEvent*>(fInputEvent);
  if (!fAOD) {
    AliWarning("ERROR: AliAODEvent not available \n");
    return;
  }

  if (strcmp(fAOD->ClassName(), "AliAODEvent"))
    {
      AliFatal("Not processing AODs");
    }

  if(!fEventCuts->IsSelected(fAOD,fTrackCuts))return;//event selection

  //Default TPC priors
  if(fHelperPID->GetPIDType()==kBayes)fHelperPID->GetPIDCombined()->SetDefaultTPCPriors();//FIXME maybe this can go in the UserCreateOutputObject?

  Double_t Qvec=0.;//in case of MC we save space in the memory
  if(!fIsMC){
    if(fVZEROside==0)Qvec=fEventCuts->GetqV0A();
    else if (fVZEROside==1)Qvec=fEventCuts->GetqV0C();
  }

  Double_t Cent=fEventCuts->GetCent();

  // First do MC to fill up the MC particle array
  TClonesArray *arrayMC = 0;
  if (fIsMC)
    {
      arrayMC = (TClonesArray*) fAOD->GetList()->FindObject(AliAODMCParticle::StdBranchName());
      if (!arrayMC) {
	AliFatal("Error: MC particles branch not found!\n");
      }
      Int_t nMC = arrayMC->GetEntries();
      for (Int_t iMC = 0; iMC < nMC; iMC++)
	{
	  AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(iMC);
	  if(!partMC->Charge()) continue;//Skip neutrals
	  if(fCharge != 0 && partMC->Charge() != fCharge) continue;//if fCharge != 0 only select fCharge

	  if(partMC->Eta() < fTrackCuts->GetEtaMin() || partMC->Eta() > fTrackCuts->GetEtaMax())continue;//ETA CUT ON GENERATED!!!!!!!!!!!!!!!!!!!!!!!!!!

	  //pt     cent    IDgen        isph        y
 	  Double_t varSt[5];
	  varSt[0]=partMC->Pt();
	  varSt[1]=Cent;
	  varSt[2]=(Double_t)fHelperPID->GetParticleSpecies(partMC);
	  varSt[3]=(Double_t)partMC->IsPhysicalPrimary();
	  varSt[4]=partMC->Y();
	  ((THnSparseF*)fOutput->FindObject("NSparseHistSt"))->Fill(varSt);//stack loop

	  //Printf("a particle");

	}
    }

  //main loop on tracks
  for (Int_t iTracks = 0; iTracks < fAOD->GetNumberOfTracks(); iTracks++) {
    AliAODTrack* track = fAOD->GetTrack(iTracks);
    if(fCharge != 0 && track->Charge() != fCharge) continue;//if fCharge != 0 only select fCharge
    if (!fTrackCuts->IsSelected(track,kTRUE)) continue; //track selection (rapidity selection NOT in the standard cuts)
    Int_t IDrec=fHelperPID->GetParticleSpecies(track,kTRUE);//id from detector
    Double_t y= track->Y(fHelperPID->GetMass((AliHelperParticleSpecies_t)IDrec));
    Int_t IDgen=kSpUndefined;//set if MC
    Int_t isph=-999;
    Int_t iswd=-999;

    if (arrayMC) {
      AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(TMath::Abs(track->GetLabel()));
      if (!partMC) {
	AliError("Cannot get MC particle");
	continue;
      }
      IDgen=fHelperPID->GetParticleSpecies(partMC);
      isph=partMC->IsPhysicalPrimary();
      iswd=partMC->IsSecondaryFromWeakDecay();//FIXME not working on old productions
    }

    //pt     cent    Q vec     IDrec     IDgen       isph           iswd      y
    Double_t varTrk[8];
    varTrk[0]=track->Pt();
    varTrk[1]=Cent;
    varTrk[2]=Qvec;
    varTrk[3]=(Double_t)IDrec;
    varTrk[4]=(Double_t)IDgen;
    varTrk[5]=(Double_t)isph;
    varTrk[6]=(Double_t)iswd;
    varTrk[7]=y;
    ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop

    //for nsigma PID fill double counting of ID
    if(fHelperPID->GetPIDType()<kBayes){//only nsigma
      Bool_t *HasDC;
      HasDC=fHelperPID->GetDoubleCounting(track,kTRUE);//get the array with double counting
      for(Int_t ipart=0;ipart<kNSpecies;ipart++){
	if(HasDC[ipart]==kTRUE){
	  varTrk[3]=(Double_t)ipart;
	  ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop
	}
      }
    }

    //fill all charged (-1)
    varTrk[3]=-1.;
    ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop

    //Printf("a track");

  } // end loop on tracks

  Double_t varEv[2];
  varEv[0]=Cent;
  varEv[1]=Qvec;
  ((THnSparseF*)fOutput->FindObject("NSparseHistEv"))->Fill(varEv);//event loop

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//_________________________________________________________________
void   AliAnalysisTaskSpectraAllChAOD::Terminate(Option_t *)
{
  // Terminate
}
<commit_msg>All Charged at position 4 instead of -1<commit_after>/**************************************************************************
 * Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

//-----------------------------------------------------------------
//         AliAnalysisTaskSpectraAllChAOD class
//-----------------------------------------------------------------

#include "TChain.h"
#include "TTree.h"
#include "TLegend.h"
#include "TH1F.h"
#include "TH2F.h"
#include "THnSparse.h"
#include "TCanvas.h"
#include "AliAnalysisTask.h"
#include "AliAODTrack.h"
#include "AliAODMCParticle.h"
#include "AliVParticle.h"
#include "AliAODEvent.h"
#include "AliAODInputHandler.h"
#include "AliAnalysisTaskSpectraAllChAOD.h"
#include "AliAnalysisTaskESDfilter.h"
#include "AliAnalysisDataContainer.h"
#include "AliSpectraAODTrackCuts.h"
#include "AliSpectraAODEventCuts.h"
#include "AliHelperPID.h"
#include "AliPIDCombined.h"
#include "AliCentrality.h"
#include "TProof.h"
#include "AliVEvent.h"
#include "AliStack.h"
#include <TMCProcess.h>

#include <iostream>

using namespace AliHelperPIDNameSpace;
using namespace std;

ClassImp(AliAnalysisTaskSpectraAllChAOD)

//________________________________________________________________________
AliAnalysisTaskSpectraAllChAOD::AliAnalysisTaskSpectraAllChAOD(const char *name) : AliAnalysisTaskSE(name),
  fAOD(0x0),
  fTrackCuts(0x0),
  fEventCuts(0x0),
  fHelperPID(0x0),
  fIsMC(0),
  fCharge(0),
  fVZEROside(0),
  fOutput(0x0),
  fnCentBins(20),
  fnQvecBins(40)
{
  // Default constructor
  DefineInput(0, TChain::Class());
  DefineOutput(1, TList::Class());
  DefineOutput(2, AliSpectraAODEventCuts::Class());
  DefineOutput(3, AliSpectraAODTrackCuts::Class());
  DefineOutput(4, AliHelperPID::Class());
}

//________________________________________________________________________
void AliAnalysisTaskSpectraAllChAOD::UserCreateOutputObjects()
{
  // create output objects
  fOutput=new TList();
  fOutput->SetOwner();
  fOutput->SetName("fOutput");

  if (!fTrackCuts) AliFatal("Track Cuts should be set in the steering macro");
  if (!fEventCuts) AliFatal("Event Cuts should be set in the steering macro");
  if (!fHelperPID)  AliFatal("HelperPID should be set in the steering macro");

  // binning common to all the THn
  const Double_t ptBins[] = {0.20,0.30,0.4,0.5,0.6,0.7,0.8,0.9,1.0,1.2,1.4,1.6,1.8,2.0,2.4,2.8,3.2,3.6,4.0,5.0,6.0,7.0,8.0,9.0,10.,12.,15.};
  const Int_t nptBins=26;

  //dimensions of THnSparse for tracks
  const Int_t nvartrk=8;
  //                                             pt          cent        Q vec     IDrec     IDgen       isph           iswd      y
  Int_t    binsHistRealTrk[nvartrk] = {      nptBins, fnCentBins,   fnQvecBins,        4,        3,         2,          2,       2};
  Double_t xminHistRealTrk[nvartrk] = {         0.,          0.,            0.,      -.5,      -0.5,      -0.5,        -0.5,   -0.5};
  Double_t xmaxHistRealTrk[nvartrk] = {       10.,       100.,            8.,      3.5,      2.5,       1.5,         1.5,     0.5};
  THnSparseF* NSparseHistTrk = new THnSparseF("NSparseHistTrk","NSparseHistTrk",nvartrk,binsHistRealTrk,xminHistRealTrk,xmaxHistRealTrk);
  NSparseHistTrk->GetAxis(0)->SetTitle("#it{p}_{T,rec}");
  NSparseHistTrk->GetAxis(0)->SetName("pT_rec");
  NSparseHistTrk->SetBinEdges(0,ptBins);
  NSparseHistTrk->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistTrk->GetAxis(2)->SetTitle("Q vec");
  NSparseHistTrk->GetAxis(2)->SetName("Q_vec");
  NSparseHistTrk->GetAxis(3)->SetTitle("ID rec");
  NSparseHistTrk->GetAxis(3)->SetName("ID_rec");
  NSparseHistTrk->GetAxis(4)->SetTitle("ID gen");
  NSparseHistTrk->GetAxis(4)->SetName("ID_gen");
  NSparseHistTrk->GetAxis(5)->SetTitle("isph");
  NSparseHistTrk->GetAxis(5)->SetName("isph");
  NSparseHistTrk->GetAxis(6)->SetTitle("iswd");
  NSparseHistTrk->GetAxis(6)->SetName("iswd");
  NSparseHistTrk->GetAxis(7)->SetTitle("y");
  NSparseHistTrk->GetAxis(7)->SetName("y");
  fOutput->Add(NSparseHistTrk);

  //dimensions of THnSparse for stack
  const Int_t nvarst=5;
  //                                             pt          cent    IDgen        isph        y
  Int_t    binsHistRealSt[nvarst] = {      nptBins,  fnCentBins,        3,         2,        2};
  Double_t xminHistRealSt[nvarst] = {         0.,           0.,      -0.5,      -0.5,    -0.5};
  Double_t xmaxHistRealSt[nvarst] = {       10.,        100.,      2.5,       1.5,      0.5};
  THnSparseF* NSparseHistSt = new THnSparseF("NSparseHistSt","NSparseHistSt",nvarst,binsHistRealSt,xminHistRealSt,xmaxHistRealSt);
  NSparseHistSt->GetAxis(0)->SetTitle("#it{p}_{T,gen}");
  NSparseHistSt->SetBinEdges(0,ptBins);
  NSparseHistSt->GetAxis(0)->SetName("pT_rec");
  NSparseHistSt->GetAxis(1)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(1)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistSt->GetAxis(2)->SetTitle("ID gen");
  NSparseHistSt->GetAxis(2)->SetName("ID_gen");
  NSparseHistSt->GetAxis(3)->SetTitle("isph");
  NSparseHistSt->GetAxis(3)->SetName("isph");
  NSparseHistSt->GetAxis(4)->SetTitle("y");
  NSparseHistSt->GetAxis(4)->SetName("y");
  fOutput->Add(NSparseHistSt);

  //dimensions of THnSparse for the normalization
  const Int_t nvarev=2;
  //                                             cent             Q vec
  Int_t    binsHistRealEv[nvarev] = {    fnCentBins,      fnQvecBins};
  Double_t xminHistRealEv[nvarev] = {           0.,               0.};
  Double_t xmaxHistRealEv[nvarev] = {       100.,              10.};
  THnSparseF* NSparseHistEv = new THnSparseF("NSparseHistEv","NSparseHistEv",nvarev,binsHistRealEv,xminHistRealEv,xmaxHistRealEv);
  NSparseHistEv->GetAxis(0)->SetTitle(Form("%s cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(0)->SetName(Form("%s_cent",fEventCuts->GetCentralityMethod().Data()));
  NSparseHistEv->GetAxis(1)->SetTitle("Q vec");
  NSparseHistEv->GetAxis(1)->SetName("Q_vec");
  fOutput->Add(NSparseHistEv);

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//________________________________________________________________________

void AliAnalysisTaskSpectraAllChAOD::UserExec(Option_t *)
{
  //Printf("An event");
  // main event loop
  fAOD = dynamic_cast<AliAODEvent*>(fInputEvent);
  if (!fAOD) {
    AliWarning("ERROR: AliAODEvent not available \n");
    return;
  }

  if (strcmp(fAOD->ClassName(), "AliAODEvent"))
    {
      AliFatal("Not processing AODs");
    }

  if(!fEventCuts->IsSelected(fAOD,fTrackCuts))return;//event selection

  //Default TPC priors
  if(fHelperPID->GetPIDType()==kBayes)fHelperPID->GetPIDCombined()->SetDefaultTPCPriors();//FIXME maybe this can go in the UserCreateOutputObject?

  Double_t Qvec=0.;//in case of MC we save space in the memory
  if(!fIsMC){
    if(fVZEROside==0)Qvec=fEventCuts->GetqV0A();
    else if (fVZEROside==1)Qvec=fEventCuts->GetqV0C();
  }

  Double_t Cent=fEventCuts->GetCent();

  // First do MC to fill up the MC particle array
  TClonesArray *arrayMC = 0;
  if (fIsMC)
    {
      arrayMC = (TClonesArray*) fAOD->GetList()->FindObject(AliAODMCParticle::StdBranchName());
      if (!arrayMC) {
	AliFatal("Error: MC particles branch not found!\n");
      }
      Int_t nMC = arrayMC->GetEntries();
      for (Int_t iMC = 0; iMC < nMC; iMC++)
	{
	  AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(iMC);
	  if(!partMC->Charge()) continue;//Skip neutrals
	  if(fCharge != 0 && partMC->Charge() != fCharge) continue;//if fCharge != 0 only select fCharge

	  if(partMC->Eta() < fTrackCuts->GetEtaMin() || partMC->Eta() > fTrackCuts->GetEtaMax())continue;//ETA CUT ON GENERATED!!!!!!!!!!!!!!!!!!!!!!!!!!

	  //pt     cent    IDgen        isph        y
 	  Double_t varSt[5];
	  varSt[0]=partMC->Pt();
	  varSt[1]=Cent;
	  varSt[2]=(Double_t)fHelperPID->GetParticleSpecies(partMC);
	  varSt[3]=(Double_t)partMC->IsPhysicalPrimary();
	  varSt[4]=partMC->Y();
	  ((THnSparseF*)fOutput->FindObject("NSparseHistSt"))->Fill(varSt);//stack loop

	  //Printf("a particle");

	}
    }

  //main loop on tracks
  for (Int_t iTracks = 0; iTracks < fAOD->GetNumberOfTracks(); iTracks++) {
    AliAODTrack* track = fAOD->GetTrack(iTracks);
    if(fCharge != 0 && track->Charge() != fCharge) continue;//if fCharge != 0 only select fCharge
    if (!fTrackCuts->IsSelected(track,kTRUE)) continue; //track selection (rapidity selection NOT in the standard cuts)
    Int_t IDrec=fHelperPID->GetParticleSpecies(track,kTRUE);//id from detector
    Double_t y= track->Y(fHelperPID->GetMass((AliHelperParticleSpecies_t)IDrec));
    Int_t IDgen=kSpUndefined;//set if MC
    Int_t isph=-999;
    Int_t iswd=-999;

    if (arrayMC) {
      AliAODMCParticle *partMC = (AliAODMCParticle*) arrayMC->At(TMath::Abs(track->GetLabel()));
      if (!partMC) {
	AliError("Cannot get MC particle");
	continue;
      }
      IDgen=fHelperPID->GetParticleSpecies(partMC);
      isph=partMC->IsPhysicalPrimary();
      iswd=partMC->IsSecondaryFromWeakDecay();//FIXME not working on old productions
    }

    //pt     cent    Q vec     IDrec     IDgen       isph           iswd      y
    Double_t varTrk[8];
    varTrk[0]=track->Pt();
    varTrk[1]=Cent;
    varTrk[2]=Qvec;
    varTrk[3]=(Double_t)IDrec;
    varTrk[4]=(Double_t)IDgen;
    varTrk[5]=(Double_t)isph;
    varTrk[6]=(Double_t)iswd;
    varTrk[7]=y;
    ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop

    //for nsigma PID fill double counting of ID
    if(fHelperPID->GetPIDType()<kBayes){//only nsigma
      Bool_t *HasDC;
      HasDC=fHelperPID->GetDoubleCounting(track,kTRUE);//get the array with double counting
      for(Int_t ipart=0;ipart<kNSpecies;ipart++){
	if(HasDC[ipart]==kTRUE){
	  varTrk[3]=(Double_t)ipart;
	  ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop
	}
      }
    }

    //fill all charged (4)
    varTrk[3]=4.;
    ((THnSparseF*)fOutput->FindObject("NSparseHistTrk"))->Fill(varTrk);//track loop

    //Printf("a track");

  } // end loop on tracks

  Double_t varEv[2];
  varEv[0]=Cent;
  varEv[1]=Qvec;
  ((THnSparseF*)fOutput->FindObject("NSparseHistEv"))->Fill(varEv);//event loop

  PostData(1, fOutput  );
  PostData(2, fEventCuts);
  PostData(3, fTrackCuts);
  PostData(4, fHelperPID);
}

//_________________________________________________________________
void   AliAnalysisTaskSpectraAllChAOD::Terminate(Option_t *)
{
  // Terminate
}
<|endoftext|>


<commit_before>#include <Probulator/Experiments.h>

namespace Probulator
{

template <typename T>
inline T& addExperiment(ExperimentList& list, const char* name, const char* suffix)
{
    T* e = new T;
    list.push_back(std::unique_ptr<Experiment>(e));
    e->m_name = name;
    e->m_suffix = suffix;
    return *e;
}

void addAllExperiments(ExperimentList& experiments)
{
    const u32 lobeCount = 12; // <-- tweak this
    const float lambda = 0.5f * lobeCount; // <-- tweak this;

    Experiment* experimentMCIS = &addExperiment<ExperimentMCIS>(experiments, "Monte Carlo [Importance Sampling]", "MCIS")
        .setSampleCount(5000)
        .setJitterEnabled(false) // prefer errors due to correlation instead of noise due to jittering
        .setUseAsReference(true); // other experiments will be compared against this

    addExperiment<ExperimentMCIS>(experiments, "Monte Carlo [Importance Sampling, Scrambled]", "MCISS")
        .setSampleCount(5000)
        .setJitterEnabled(true)
        .setEnabled(false); // disabled by default, since MCIS mode is superior

    addExperiment<ExperimentMC>(experiments, "Monte Carlo", "MC")
        .setHemisphereSampleCount(5000)
        .setEnabled(false); // disabled by default, since MCIS mode is superior

    addExperiment<ExperimentSHL1Geomerics>(experiments, "Spherical Harmonics L1 [Geomerics]", "SHL1G");

    addExperiment<ExperimentSH<1>>(experiments, "Spherical Harmonics L1", "SHL1");
    addExperiment<ExperimentSH<2>>(experiments, "Spherical Harmonics L2", "SHL2");
    addExperiment<ExperimentSH<3>>(experiments, "Spherical Harmonics L3", "SHL3");
    addExperiment<ExperimentSH<4>>(experiments, "Spherical Harmonics L4", "SHL4");

    addExperiment<ExperimentHBasis<4>>(experiments, "HBasis-4", "H4")
        .setInput(experimentMCIS);
    addExperiment<ExperimentHBasis<6>>(experiments, "HBasis-6", "H6")
        .setInput(experimentMCIS);

    addExperiment<ExperimentSGNaive>(experiments, "Spherical Gaussians [Naive]", "SG")
        .setBrdfLambda(8.5f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGLS>(experiments, "Spherical Gaussians [Least Squares]", "SGLS")
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGLS>(experiments, "Spherical Gaussians [Least Squares + Ambient]", "SGLSA")
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setAmbientLobeEnabled(true)
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGNNLS>(experiments, "Spherical Gaussians [Non-Negative Least Squares]", "SGNNLS")
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGGA>(experiments, "Spherical Gaussians [Genetic Algorithm]", "SGGA")
        .setPopulationAndGenerationCount(50, 2000)
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda)
        .setEnabled(false); // disabled by default, as it requires *very* long time to converge
}

void resetAllExperiments(ExperimentList& experiments)
{
	for (auto& e : experiments)
	{
		e->reset();
	}
}

} // namespace Probulator<commit_msg>Updated experiment name (Scrambled -> Jittered)<commit_after>#include <Probulator/Experiments.h>

namespace Probulator
{

template <typename T>
inline T& addExperiment(ExperimentList& list, const char* name, const char* suffix)
{
    T* e = new T;
    list.push_back(std::unique_ptr<Experiment>(e));
    e->m_name = name;
    e->m_suffix = suffix;
    return *e;
}

void addAllExperiments(ExperimentList& experiments)
{
    const u32 lobeCount = 12; // <-- tweak this
    const float lambda = 0.5f * lobeCount; // <-- tweak this;

    Experiment* experimentMCIS = &addExperiment<ExperimentMCIS>(experiments, "Monte Carlo [Importance Sampling]", "MCIS")
        .setSampleCount(5000)
        .setJitterEnabled(false) // prefer errors due to correlation instead of noise due to jittering
        .setUseAsReference(true); // other experiments will be compared against this

    addExperiment<ExperimentMCIS>(experiments, "Monte Carlo [Importance Sampling, Jittered]", "MCISS")
        .setSampleCount(5000)
        .setJitterEnabled(true)
        .setEnabled(false); // disabled by default, since MCIS mode is superior

    addExperiment<ExperimentMC>(experiments, "Monte Carlo", "MC")
        .setHemisphereSampleCount(5000)
        .setEnabled(false); // disabled by default, since MCIS mode is superior

    addExperiment<ExperimentSHL1Geomerics>(experiments, "Spherical Harmonics L1 [Geomerics]", "SHL1G");

    addExperiment<ExperimentSH<1>>(experiments, "Spherical Harmonics L1", "SHL1");
    addExperiment<ExperimentSH<2>>(experiments, "Spherical Harmonics L2", "SHL2");
    addExperiment<ExperimentSH<3>>(experiments, "Spherical Harmonics L3", "SHL3");
    addExperiment<ExperimentSH<4>>(experiments, "Spherical Harmonics L4", "SHL4");

    addExperiment<ExperimentHBasis<4>>(experiments, "HBasis-4", "H4")
        .setInput(experimentMCIS);
    addExperiment<ExperimentHBasis<6>>(experiments, "HBasis-6", "H6")
        .setInput(experimentMCIS);

    addExperiment<ExperimentSGNaive>(experiments, "Spherical Gaussians [Naive]", "SG")
        .setBrdfLambda(8.5f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGLS>(experiments, "Spherical Gaussians [Least Squares]", "SGLS")
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGLS>(experiments, "Spherical Gaussians [Least Squares + Ambient]", "SGLSA")
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setAmbientLobeEnabled(true)
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGNNLS>(experiments, "Spherical Gaussians [Non-Negative Least Squares]", "SGNNLS")
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda);

    addExperiment<ExperimentSGGA>(experiments, "Spherical Gaussians [Genetic Algorithm]", "SGGA")
        .setPopulationAndGenerationCount(50, 2000)
        .setBrdfLambda(3.0f) // Chosen arbitrarily through experimentation
        .setLobeCountAndLambda(lobeCount, lambda)
        .setEnabled(false); // disabled by default, as it requires *very* long time to converge
}

void resetAllExperiments(ExperimentList& experiments)
{
	for (auto& e : experiments)
	{
		e->reset();
	}
}

} // namespace Probulator<|endoftext|>