<commit_before>#include <iostream>
#include <string>
#include <fstream>

#include "main.h"
#include "bond_angle.cpp"
// #include "bond_length.cpp"

using namespace std;
/**
 * @mainpage The Gaussian Optimization Analytical Tool (GOAT)
 *
 * Welcome to the Gaussian Optimization Analytical Tool (GOAT) documentation site!
 * Users may find relevant info related to this program, a program designed to provide
 * structural analyses of biomolecules successfully optimized using Gaussian software.
 *
 * @short   Main program
 * @file    main.cpp
 * @author  Kate Charbonnet, Hannah Lozano, and Thomas Summers
 * @param   none
 * @return  0 on success
 *
 * The purpose of this program is to provide preliminary structural information on biomolecules
 * optimized using Gaussian computational chemistry software.  Structural and chemical properties
 * identified include: element identification, bond length, bond order, central angles, and torsional
 * angles.  Input of the file to be analyzed will result in an output file listing all the structural
 * information of the biomolecule.
 */

int main(int argc, char* argv[]) {
    ifstream inputfile;
    ofstream logfile;
    ifstream bond_angle;
    unsigned int count_line = 0;
    string line;
    string header1 = "Optimized Parameters";
    string header2 = "Standard orientation:";
    string print(string);

    //Check that input file was directed into the command line
    if (argc < 2) {
        cout << "Error: Inputfile not specified in command line\n";
        return 1;
    }

    //Open the input file and check that it opened
    inputfile.open(argv[1]);
    if (!inputfile.is_open()) {
        cout << "Error: Unable to open the input file.";
        return 2;
    }

    //Generate a log file and check that it opened
    logfile.open("log.txt");
    if (!logfile.is_open()) {
        cout << "Error: Unable to open the logfile.";
        return 3;
    } else {
        logfile << "Logfile for Gaussian Optimization Analytical Tool\n";
    }

    //Search the input file for the first keywords
    while (getline(inputfile, line)) {
        total_lines++;
        count_line++;
        if (line.find(header1, 0) != string::npos) {
            cout << "Found: " << header1 << " at position " << count_line << endl;
            logfile << "Found: " << header1 << " at position " << count_line << endl;
            for (int i = 1912; i; --i) {
                logfile << line << "\n";
                getline (inputfile, line);
            }
        }
    }
    inputfile.close();
    cout << "Search Complete";
    logfile << "Search Complete" << endl;
    logfile.close();
    return 0;

    //Open the file bond_angle.cpp and check that it opened
    bond_angle.open("bond_angle.cpp");
    if (!bond_angle.is_open()) {
        cout << "Error: Unable to open bond_angle file.";
        return 1;
    }
    //Close the file bond_angle.cpp
    bond_angle.close();
    cout << "Bond angle calculation complete.";
    return 0;
}
<commit_msg>main.cpp now compilable<commit_after>#include <iostream>
#include <string>
#include <fstream>

#include "main.h"
#include "bond_angle.cpp"
// #include "bond_length.cpp"

using namespace std;
/**
 * @mainpage The Gaussian Optimization Analytical Tool (GOAT)
 *
 * Welcome to the Gaussian Optimization Analytical Tool (GOAT) documentation site!
 * Users may find relevant info related to this program, a program designed to provide
 * structural analyses of biomolecules successfully optimized using Gaussian software.
 *
 * @short   Main program
 * @file    main.cpp
 * @author  Kate Charbonnet, Hannah Lozano, and Thomas Summers
 * @param   none
 * @return  0 on success
 *
 * The purpose of this program is to provide preliminary structural information on biomolecules
 * optimized using Gaussian computational chemistry software.  Structural and chemical properties
 * identified include: element identification, bond length, bond order, central angles, and torsional
 * angles.  Input of the file to be analyzed will result in an output file listing all the structural
 * information of the biomolecule.
 */

int main(int argc, char* argv[]) {
    ifstream inputfile;
    ofstream logfile;
    ifstream bond_angle;
    unsigned int count_line = 0;
    string line;
    string header1 = "Optimized Parameters";
    string header2 = "Standard orientation:";
    string print(string);

    //Check that input file was directed into the command line
    if (argc < 2) {
        cout << "Error: Inputfile not specified in command line\n";
        return 1;
    }

    //Open the input file and check that it opened
    inputfile.open(argv[1]);
    if (!inputfile.is_open()) {
        cout << "Error: Unable to open the input file.";
        return 2;
    }

    //Generate a log file and check that it opened
    logfile.open("log.txt");
    if (!logfile.is_open()) {
        cout << "Error: Unable to open the logfile.";
        return 3;
    } else {
        logfile << "Logfile for Gaussian Optimization Analytical Tool\n";
    }

    //Search the input file for the first keywords
    while (getline(inputfile, line)) {
        count_line++;
        if (line.find(header1, 0) != string::npos) {
            cout << "Found: " << header1 << " at position " << count_line << endl;
            logfile << "Found: " << header1 << " at position " << count_line << endl;
            for (int i = 1912; i; --i) {
                logfile << line << "\n";
                getline (inputfile, line);
            }
        }
    }
    inputfile.close();
    cout << "Search Complete";
    logfile << "Search Complete" << endl;
    logfile.close();
    return 0;

    //Open the file bond_angle.cpp and check that it opened
    bond_angle.open("bond_angle.cpp");
    if (!bond_angle.is_open()) {
        cout << "Error: Unable to open bond_angle file.";
        return 1;
    }
    //Close the file bond_angle.cpp
    bond_angle.close();
    cout << "Bond angle calculation complete.";
    return 0;
}
<|endoftext|>


<commit_before>#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#define VKCPP_ENHANCED_MODE
#include <vulkan/vk_cpp.h>

#include <iostream>
#include <fstream>

vk::Format format;

vk::Instance create_instance()
{
	vk::ApplicationInfo appInfo("Test app", 1, "Engine", 1, VK_MAKE_VERSION(1, 0, 0));

	vk::InstanceCreateInfo instInfo;

	instInfo.pApplicationInfo(&appInfo);
	instInfo.flags(vk::InstanceCreateFlags());
	instInfo.enabledLayerCount(0);
	instInfo.ppEnabledLayerNames(nullptr);
	instInfo.enabledExtensionCount(1);
	const char* extensionNames[] = { "VK_KHR_xcb_surface" };
	instInfo.ppEnabledExtensionNames(extensionNames);

	return vk::createInstance(instInfo, vk::AllocationCallbacks::null());
}

vk::SurfaceKHR create_surface(const vk::Instance& inst, GLFWwindow* window)
{

	VkSurfaceKHR c_surface;
	auto result = glfwCreateWindowSurface(inst, window, nullptr, &c_surface);

	if(result != VK_SUCCESS)
	{
		std::cerr << "Error creating surface with error: " << vk::to_string(vk::Result(result));
		exit(-1);
	}

	return {c_surface};

}

vk::PhysicalDevice get_physical_device(const vk::Instance& inst)
{
	std::vector<vk::PhysicalDevice> phyDevices;
	inst.enumeratePhysicalDevices(phyDevices);

	// just select the first one
	if(phyDevices.empty()) throw std::runtime_error("No suitable device found");

	return phyDevices[0];

}

vk::Device create_device(const vk::Instance& inst, const vk::PhysicalDevice& physical_device)
{

	auto physDevProps = physical_device.getProperties();
	auto physDevQueueProps = physical_device.getQueueFamilyProperties();

	vk::DeviceQueueCreateInfo queueInfo;
	queueInfo.queueFamilyIndex(0);
	queueInfo.queueCount(physDevQueueProps[0].queueCount());

	float queue_priorities[] = {0.0f};
	queueInfo.pQueuePriorities(queue_priorities);

	vk::DeviceCreateInfo devInfo;
	devInfo.queueCreateInfoCount(1);
	devInfo.pQueueCreateInfos(&queueInfo);
	devInfo.enabledLayerCount(0);
	devInfo.ppEnabledLayerNames(nullptr);
	const char* deviceExtensionNames[1024];
	devInfo.enabledExtensionCount(0);
	devInfo.ppEnabledExtensionNames(deviceExtensionNames);
	devInfo.pEnabledFeatures(nullptr);

	return physical_device.createDevice(devInfo, vk::AllocationCallbacks::null());

}

vk::SwapchainKHR create_swapchain(const vk::Device& device, const vk::SurfaceKHR& surface, const vk::PhysicalDevice& physDev)
{
	vk::SurfaceCapabilitiesKHR capabilities;
	physDev.getSurfaceCapabilitiesKHR(surface, &capabilities);

	std::vector<vk::SurfaceFormatKHR> formats;
	physDev.getSurfaceFormatsKHR(surface, formats);

	format = formats[0].format();

	vk::SwapchainCreateInfoKHR swapchainInfo(vk::SwapchainCreateFlagsKHR(), surface, 2, format,
											 formats[0].colorSpace(), capabilities.currentExtent(), 1,
											 vk::ImageUsageFlags(vk::ImageUsageFlagBits::eColorAttachment), vk::SharingMode::eExclusive, 0, nullptr,
											 vk::SurfaceTransformFlagBitsKHR::eIdentity, vk::CompositeAlphaFlagBitsKHR::eOpaque,
											 vk::PresentModeKHR::eFifoKHR, true, vk::SwapchainKHR());

	vk::SwapchainKHR ret;
	device.createSwapchainKHR(&swapchainInfo, nullptr, &ret);

	return ret;
}

vk::Semaphore create_semaphore(const vk::Device& device)
{
	vk::SemaphoreCreateInfo semaphoreInfo(vk::SemaphoreCreateFlags{});

	return device.createSemaphore(semaphoreInfo, vk::AllocationCallbacks::null());
}

vk::Fence create_fence(const vk::Device& device)
{
	vk::FenceCreateInfo fenceInfo(vk::FenceCreateFlags{});

	return device.createFence(fenceInfo, vk::AllocationCallbacks::null());
}

vk::ImageView create_image_view(const vk::Device& device, const vk::Image& image)
{
	vk::ImageViewCreateInfo imageViewInfo(vk::ImageViewCreateFlags{}, image, vk::ImageViewType::e2D, format,
										  vk::ComponentMapping(), vk::ImageSubresourceRange(vk::ImageAspectFlags(), 0, 1, 0, 1));

	return device.createImageView(imageViewInfo, vk::AllocationCallbacks::null());
}

int main()
{
	glfwSetErrorCallback([](int error, const char* desc)
	{
		std::cerr << "GLFW error " << error << ": " << desc << std::endl;
	});

	glfwInit();

	if(glfwVulkanSupported() == GLFW_FALSE)
	{
		std::cout << "ERROR";
	}

	glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

	GLFWwindow* window = glfwCreateWindow(1024, 720, "Here", nullptr, nullptr);

	auto inst = create_instance(); assert(inst);
	auto surface = create_surface(inst, window); assert(surface);
	auto physical_device = get_physical_device(inst); assert(physical_device);
	auto device = create_device(inst, physical_device); assert(device);
	auto swapchain = create_swapchain(device, surface, physical_device); assert(swapchain);

	std::vector<vk::Image> images;
	device.getSwapchainImagesKHR(swapchain, images);

	auto semaphore = create_semaphore(device);

	uint32_t currentSwap;
	device.acquireNextImageKHR(swapchain, UINT64_MAX, semaphore, {}, currentSwap);

	auto image_view = create_image_view(device, images[0]);

	auto queue = device.getQueue(0, 0);

	// make render pass
	vk::AttachmentDescription attachDesc(vk::AttachmentDescriptionFlags(), format, vk::SampleCountFlagBits::e1,
										 vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eDontCare,
									  vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eColorAttachmentOptimal);
	vk::AttachmentReference attachRef(0, vk::ImageLayout::eColorAttachmentOptimal);
	vk::SubpassDescription subpassDesc(vk::SubpassDescriptionFlags(), vk::PipelineBindPoint::eGraphics, 0, nullptr, 1, &attachRef, nullptr, nullptr, 0, nullptr);
	vk::RenderPassCreateInfo renderPassInfo(vk::RenderPassCreateFlags(), 1, &attachDesc, 1, &subpassDesc, 0, nullptr);

	auto render_pass = device.createRenderPass(renderPassInfo, vk::AllocationCallbacks::null());

	// make framebuffer
	vk::FramebufferCreateInfo framebufferInfo(vk::FramebufferCreateFlags(), render_pass, 1, &image_view, 1024, 720, 1);
	auto framebuffer = device.createFramebuffer(framebufferInfo, vk::AllocationCallbacks::null());

	// make descriptor set layout
	vk::DescriptorSetLayoutBinding bindings[] = {
		{0, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), nullptr} // vertex position
	};
	vk::DescriptorSetLayoutCreateInfo descSetLayoutCreateInfo({}, 1, bindings);
	auto descriptor_set_layout = device.createDescriptorSetLayout(descSetLayoutCreateInfo, vk::AllocationCallbacks::null());

	// make pipeline layout
	vk::PipelineLayoutCreateInfo pipelineLayoutInfo({}, 1, &descriptor_set_layout, 0, nullptr);
	auto pipeline_layout = device.createPipelineLayout(pipelineLayoutInfo, vk::AllocationCallbacks::null());

	// upload shaders
	std::ifstream fragFile("frag.spv", std::ios::binary | std::ios::ate);
	std::streamsize fragSize = fragFile.tellg();
	fragFile.seekg(0, std::ios::beg);
	std::vector<char> fragSpirVData(fragSize);
	fragFile.read(fragSpirVData.data(), fragSize);

	std::ifstream vertFile("vert.spv", std::ios::binary | std::ios::ate);
	std::streamsize vertSize = vertFile.tellg();
	vertFile.seekg(0, std::ios::beg);
	std::vector<char> vertSpirVData(vertSize);
	vertFile.read(vertSpirVData.data(), vertSize);

	vk::ShaderModuleCreateInfo vertModuleInfo({}, vertSize, reinterpret_cast<uint32_t*>(vertSpirVData.data()));
	vk::ShaderModuleCreateInfo fragModuleInfo({}, fragSize, reinterpret_cast<uint32_t*>(fragSpirVData.data()));

	auto vert_module = device.createShaderModule(vertModuleInfo, vk::AllocationCallbacks::null());
	auto frag_module = device.createShaderModule(fragModuleInfo, vk::AllocationCallbacks::null());

	// viewport
	auto viewport = vk::Viewport(0, 0, 1024, 720, 0, 100);

	// make graphics pipeline: HOLY SHIT THAT'S A LOT OF METADATA
	vk::PipelineShaderStageCreateInfo pipeShaderStageInfo[] = {
		{{}, vk::ShaderStageFlagBits::eVertex, vert_module, "Vert Shader", nullptr},
		{{}, vk::ShaderStageFlagBits::eFragment, frag_module, "Frag Shader", nullptr}
	};
	vk::VertexInputAttributeDescription vertInputAttrDesc(0, 0, vk::Format::eR32G32B32Sfloat, 0);
	vk::PipelineVertexInputStateCreateInfo pipeVertexInputStateInfo({}, 0, nullptr, 1, &vertInputAttrDesc);
	vk::PipelineInputAssemblyStateCreateInfo pipeInputAsmStateInfo({}, vk::PrimitiveTopology::eTriangleList, false); // TODO: not sure
	vk::PipelineTessellationStateCreateInfo pipeTessStateInfo({}, 0);
	vk::Rect2D scissor({}, vk::Extent2D(1024, 720));
	vk::PipelineViewportStateCreateInfo pipeViewportStateInfo({}, 1, &viewport, 1, &scissor);
	vk::PipelineRasterizationStateCreateInfo pipeRasterizationStateInfo({}, false, false, vk::PolygonMode::eFill, vk::CullModeFlags(vk::CullModeFlagBits::eNone), vk::FrontFace::eClockwise, true, 1.f, 100, 1.f, 1.f);
	vk::SampleMask sampleMask = 1; // TODO: ???? this is just an int
	vk::PipelineMultisampleStateCreateInfo pipeMultisampleStateInfo({}, vk::SampleCountFlagBits::e16, false, 1.f/2.f, &sampleMask, false, false); // TODO: not sure
	vk::PipelineDepthStencilStateCreateInfo pipeDepthStencilStateInfo({}, true, true, vk::CompareOp::eLessOrEqual, true, false, vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eEqual, 1, 1, 1), vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eEqual, 1, 1, 1), 0.f, 100.f); // TODO: not sure
	vk::PipelineColorBlendStateCreateInfo pipeColorBlendStateInfo({}, false, vk::LogicOp::eAnd, 0, nullptr, {{0.f, 0.f, 1.f, 1.f}}); // TODO: not sure
	vk::PipelineDynamicStateCreateInfo pipeDynStateInfo({}, 0, nullptr); // TODO: not sure
	vk::GraphicsPipelineCreateInfo graphicsPipeInfo({}, 2, pipeShaderStageInfo, &pipeVertexInputStateInfo, &pipeInputAsmStateInfo, &pipeTessStateInfo, &pipeViewportStateInfo, &pipeRasterizationStateInfo, &pipeMultisampleStateInfo, &pipeDepthStencilStateInfo, &pipeColorBlendStateInfo, &pipeDynStateInfo, pipeline_layout, render_pass, 0, {}, 0);
	auto graphics_pipeline = device.createGraphicsPipelines({}, {graphicsPipeInfo}, vk::AllocationCallbacks::null())[0];

	// make the descriptor pool
	vk::DescriptorPoolSize descPoolSize(vk::DescriptorType::eStorageBuffer, 1);
	vk::DescriptorPoolCreateInfo descPoolInfo({}, 1, 1, &descPoolSize);
	auto descriptor_pool = device.createDescriptorPool(descPoolInfo, vk::AllocationCallbacks::null());

	// make the descriptor set
	vk::DescriptorSetAllocateInfo descSetAllocInfo(descriptor_pool, 1, &descriptor_set_layout);
	auto descriptor_set = device.allocateDescriptorSets(descSetAllocInfo)[0];

	// add buffer
	vk::BufferCreateInfo buffInfo({}, sizeof(float) * 9, vk::BufferUsageFlags(vk::BufferUsageFlagBits::eVertexBuffer), vk::SharingMode::eExclusive, 0, nullptr); // TODO: not sure
	auto vertex_buffer = device.createBuffer(buffInfo, vk::AllocationCallbacks::null());

	// allocate for the buffer
	vk::MemoryAllocateInfo memAllocInfo(sizeof(float) * 9, 0); // TODO: better selection of memory type
	auto device_memory = device.allocateMemory(memAllocInfo, vk::AllocationCallbacks::null());

	// associate the buffer to the allocated space
	device.bindBufferMemory(vertex_buffer, device_memory, 0);

	// write to the buffer
	auto bufferData = device.mapMemory(device_memory, 0, sizeof(float) * 9, {});

	float triData[] = {
		-1.f, -1.f, 0.f,
		 1.f, -1.f, 0.f,
		 0.f,  1.f, 0.f
	};
	bufferData = triData;

	device.unmapMemory(device_memory);

	// update the descriptor sets
	vk::DescriptorBufferInfo descBufferInfo(vertex_buffer, 0, sizeof(float) * 9);
	vk::WriteDescriptorSet writeDescSet(descriptor_set, 0, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &descBufferInfo, nullptr);

	// make a command pool
	vk::CommandPoolCreateInfo poolInfo({}, 0);
	auto commandPool = device.createCommandPool(poolInfo, vk::AllocationCallbacks::null());

	// make the command buffer
	vk::CommandBufferAllocateInfo commandBufferInfo(commandPool, vk::CommandBufferLevel::ePrimary, 1);
	auto commandBuffer = device.allocateCommandBuffers(commandBufferInfo);

	// RENDER!!!!!

	device.destroy(nullptr);
	glfwDestroyWindow(window);
	inst.destroy(nullptr);

}
<commit_msg>Resolve a lot of the issues, but there is still a segfault. I have studided the spec :(<commit_after>#define GLFW_INCLUDE_VULKAN
#include <GLFW/glfw3.h>

#define VKCPP_ENHANCED_MODE
#include <vulkan/vk_cpp.h>

#include <iostream>
#include <fstream>

vk::Format format;

vk::Instance create_instance()
{
	vk::ApplicationInfo appInfo("Test app", 1, "Engine", 1, VK_MAKE_VERSION(1, 0, 0));

	vk::InstanceCreateInfo instInfo;

	instInfo.pApplicationInfo(&appInfo);
	instInfo.flags(vk::InstanceCreateFlags());
	instInfo.enabledLayerCount(0);
	instInfo.ppEnabledLayerNames(nullptr);
	instInfo.enabledExtensionCount(1);
	const char* extensionNames[] = { "VK_KHR_xcb_surface" };
	instInfo.ppEnabledExtensionNames(extensionNames);

	return vk::createInstance(instInfo, vk::AllocationCallbacks::null());
}

vk::SurfaceKHR create_surface(const vk::Instance& inst, GLFWwindow* window)
{

	VkSurfaceKHR c_surface;
	auto result = glfwCreateWindowSurface(inst, window, nullptr, &c_surface);

	if(result != VK_SUCCESS)
	{
		std::cerr << "Error creating surface with error: " << vk::to_string(vk::Result(result));
		exit(-1);
	}

	return {c_surface};

}

vk::PhysicalDevice get_physical_device(const vk::Instance& inst)
{
	std::vector<vk::PhysicalDevice> phyDevices;
	inst.enumeratePhysicalDevices(phyDevices);

	// just select the first one
	if(phyDevices.empty()) throw std::runtime_error("No suitable device found");

	return phyDevices[0];

}

vk::Device create_device(const vk::Instance& inst, const vk::PhysicalDevice& physical_device)
{

	auto physDevProps = physical_device.getProperties();
	auto physDevQueueProps = physical_device.getQueueFamilyProperties();

	vk::DeviceQueueCreateInfo queueInfo;
	queueInfo.queueFamilyIndex(0);
	queueInfo.queueCount(physDevQueueProps[0].queueCount());

	float queue_priorities[] = {0.0f};
	queueInfo.pQueuePriorities(queue_priorities);

	vk::DeviceCreateInfo devInfo;
	devInfo.queueCreateInfoCount(1);
	devInfo.pQueueCreateInfos(&queueInfo);
	devInfo.enabledLayerCount(0);
	devInfo.ppEnabledLayerNames(nullptr);
	const char* deviceExtensionNames[1024];
	devInfo.enabledExtensionCount(0);
	devInfo.ppEnabledExtensionNames(deviceExtensionNames);
	devInfo.pEnabledFeatures(nullptr);

	return physical_device.createDevice(devInfo, vk::AllocationCallbacks::null());

}

vk::SwapchainKHR create_swapchain(const vk::Device& device, const vk::SurfaceKHR& surface, const vk::PhysicalDevice& physDev)
{
	vk::SurfaceCapabilitiesKHR capabilities;
	physDev.getSurfaceCapabilitiesKHR(surface, &capabilities);

	std::vector<vk::SurfaceFormatKHR> formats;
	physDev.getSurfaceFormatsKHR(surface, formats);

	format = formats[0].format();

	vk::SwapchainCreateInfoKHR swapchainInfo(vk::SwapchainCreateFlagsKHR(), surface, 2, format,
											 formats[0].colorSpace(), capabilities.currentExtent(), 1,
											 vk::ImageUsageFlags(vk::ImageUsageFlagBits::eColorAttachment), vk::SharingMode::eExclusive, 0, nullptr,
											 vk::SurfaceTransformFlagBitsKHR::eIdentity, vk::CompositeAlphaFlagBitsKHR::eOpaque,
											 vk::PresentModeKHR::eFifoKHR, true, vk::SwapchainKHR());

	vk::SwapchainKHR ret;
	device.createSwapchainKHR(&swapchainInfo, nullptr, &ret);

	return ret;
}

vk::Semaphore create_semaphore(const vk::Device& device)
{
	vk::SemaphoreCreateInfo semaphoreInfo(vk::SemaphoreCreateFlags{});

	return device.createSemaphore(semaphoreInfo, vk::AllocationCallbacks::null());
}

vk::Fence create_fence(const vk::Device& device)
{
	vk::FenceCreateInfo fenceInfo(vk::FenceCreateFlags{});

	return device.createFence(fenceInfo, vk::AllocationCallbacks::null());
}

vk::ImageView create_image_view(const vk::Device& device, const vk::Image& image)
{
	vk::ImageViewCreateInfo imageViewInfo(vk::ImageViewCreateFlags{}, image, vk::ImageViewType::e2D, format,
										  vk::ComponentMapping(), vk::ImageSubresourceRange(vk::ImageAspectFlags(), 0, 1, 0, 1));

	return device.createImageView(imageViewInfo, vk::AllocationCallbacks::null());
}

int main()
{
	glfwSetErrorCallback([](int error, const char* desc)
	{
		std::cerr << "GLFW error " << error << ": " << desc << std::endl;
	});

	glfwInit();

	if(glfwVulkanSupported() == GLFW_FALSE)
	{
		std::cout << "ERROR";
	}

	glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);

	GLFWwindow* window = glfwCreateWindow(1024, 720, "Here", nullptr, nullptr);

	auto inst = create_instance(); assert(inst);
	auto surface = create_surface(inst, window); assert(surface);
	auto physical_device = get_physical_device(inst); assert(physical_device);
	auto device = create_device(inst, physical_device); assert(device);
	auto swapchain = create_swapchain(device, surface, physical_device); assert(swapchain);

	std::vector<vk::Image> images;
	device.getSwapchainImagesKHR(swapchain, images);

	auto semaphore = create_semaphore(device);

	uint32_t currentSwap;
	device.acquireNextImageKHR(swapchain, UINT64_MAX, semaphore, {}, currentSwap);

	auto image_view = create_image_view(device, images[0]);

	auto queue = device.getQueue(0, 0);

	// make render pass
	vk::AttachmentDescription attachDesc(vk::AttachmentDescriptionFlags(), format, vk::SampleCountFlagBits::e1,
										 vk::AttachmentLoadOp::eClear, vk::AttachmentStoreOp::eStore, vk::AttachmentLoadOp::eDontCare,
									  vk::AttachmentStoreOp::eDontCare, vk::ImageLayout::eColorAttachmentOptimal, vk::ImageLayout::eColorAttachmentOptimal);
	vk::SubpassDescription subpassDesc({}, vk::PipelineBindPoint::eGraphics, 0, nullptr, 0, nullptr, nullptr, nullptr, 0, nullptr);
	vk::RenderPassCreateInfo renderPassInfo(vk::RenderPassCreateFlags(), 1, &attachDesc, 1, &subpassDesc, 0, nullptr);

	auto render_pass = device.createRenderPass(renderPassInfo, vk::AllocationCallbacks::null()); assert(render_pass);

	// make framebuffer
	vk::FramebufferCreateInfo framebufferInfo(vk::FramebufferCreateFlags(), render_pass, 1, &image_view, 1024, 720, 1);
	auto framebuffer = device.createFramebuffer(framebufferInfo, vk::AllocationCallbacks::null()); assert(framebuffer);

	// make descriptor set layout
	vk::DescriptorSetLayoutBinding bindings[] = {
		{0, vk::DescriptorType::eStorageBuffer, 1, vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), nullptr} // vertex position
	};
	vk::DescriptorSetLayoutCreateInfo descSetLayoutCreateInfo({}, 1, bindings);
	auto descriptor_set_layout = device.createDescriptorSetLayout(descSetLayoutCreateInfo, vk::AllocationCallbacks::null()); assert(descriptor_set_layout);

	// make pipeline layout
	vk::PushConstantRange ranges(vk::ShaderStageFlags(vk::ShaderStageFlagBits::eVertex), 0, sizeof(float) * 9);
	vk::PipelineLayoutCreateInfo pipelineLayoutInfo({}, 1, &descriptor_set_layout, 1, &ranges);
	auto pipeline_layout = device.createPipelineLayout(pipelineLayoutInfo, vk::AllocationCallbacks::null()); assert(pipeline_layout);

	// upload shaders
	std::ifstream fragFile("frag.spv", std::ios::binary | std::ios::ate);
	std::streamsize fragSize = fragFile.tellg();
	fragFile.seekg(0, std::ios::beg);
	std::vector<char> fragSpirVData(fragSize);
	fragFile.read(fragSpirVData.data(), fragSize);

	std::ifstream vertFile("vert.spv", std::ios::binary | std::ios::ate);
	std::streamsize vertSize = vertFile.tellg();
	vertFile.seekg(0, std::ios::beg);
	std::vector<char> vertSpirVData(vertSize);
	vertFile.read(vertSpirVData.data(), vertSize);

	vk::ShaderModuleCreateInfo vertModuleInfo({}, vertSize, reinterpret_cast<uint32_t*>(vertSpirVData.data()));
	vk::ShaderModuleCreateInfo fragModuleInfo({}, fragSize, reinterpret_cast<uint32_t*>(fragSpirVData.data()));

	auto vert_module = device.createShaderModule(vertModuleInfo, vk::AllocationCallbacks::null()); assert(vert_module);
	auto frag_module = device.createShaderModule(fragModuleInfo, vk::AllocationCallbacks::null()); assert(frag_module);

	// viewport
	auto viewport = vk::Viewport(0, 0, 1024, 720, 0, 100);

	// make graphics pipeline: HOLY SHIT THAT'S A LOT OF METADATA
	vk::PipelineShaderStageCreateInfo pipeShaderStageInfo[] = {
		{{}, vk::ShaderStageFlagBits::eVertex, vert_module, "Vert Shader", nullptr},
		{{}, vk::ShaderStageFlagBits::eFragment, frag_module, "Frag Shader", nullptr}
	}; // GOOD
	vk::VertexInputAttributeDescription vertInputAttrDesc(0, 0, vk::Format::eR32G32B32Sfloat, 0); // GOOD
	vk::VertexInputBindingDescription vertInputBindingDesc(0, sizeof(float) * 3, vk::VertexInputRate::eVertex); // GOOD
	vk::PipelineVertexInputStateCreateInfo pipeVertexInputStateInfo({}, 1, &vertInputBindingDesc, 1, &vertInputAttrDesc); // GOOD
	vk::PipelineInputAssemblyStateCreateInfo pipeInputAsmStateInfo({}, vk::PrimitiveTopology::eTriangleList, VK_FALSE); // GOOD
	vk::PipelineTessellationStateCreateInfo pipeTessStateInfo({}, 1); // GOOD
	vk::Rect2D scissor({}, vk::Extent2D(1024, 720)); // TODO: not sure
	vk::PipelineViewportStateCreateInfo pipeViewportStateInfo({}, 1, &viewport, 1, &scissor); // GOOD
	vk::PipelineRasterizationStateCreateInfo pipeRasterizationStateInfo({}, VK_FALSE, VK_FALSE, vk::PolygonMode::eFill, vk::CullModeFlags(vk::CullModeFlagBits::eNone), vk::FrontFace::eClockwise, VK_FALSE, 1.f, 100, 1.f, 1.f); // PROBABLY GOOD
	vk::PipelineMultisampleStateCreateInfo pipeMultisampleStateInfo({}, vk::SampleCountFlagBits::e16, VK_FALSE, 1.f/2.f, nullptr, VK_FALSE, VK_FALSE); // GOOD
	vk::PipelineDepthStencilStateCreateInfo pipeDepthStencilStateInfo({}, VK_FALSE, VK_FALSE, vk::CompareOp::eLessOrEqual, VK_FALSE, VK_FALSE, vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eEqual, 1, 1, 1), vk::StencilOpState(vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::StencilOp::eKeep, vk::CompareOp::eEqual, 1, 1, 1), 0.f, 1.f); // GOOD
	vk::GraphicsPipelineCreateInfo graphicsPipeInfo({}, 2, pipeShaderStageInfo, &pipeVertexInputStateInfo, &pipeInputAsmStateInfo, &pipeTessStateInfo, &pipeViewportStateInfo, &pipeRasterizationStateInfo, &pipeMultisampleStateInfo, &pipeDepthStencilStateInfo, nullptr, nullptr, pipeline_layout, render_pass, 0, {}, -1);
	auto graphics_pipeline = device.createGraphicsPipelines({}, {graphicsPipeInfo}, vk::AllocationCallbacks::null())[0]; assert(graphics_pipeline);

	// make the descriptor pool
	vk::DescriptorPoolSize descPoolSize(vk::DescriptorType::eStorageBuffer, 1);
	vk::DescriptorPoolCreateInfo descPoolInfo({}, 1, 1, &descPoolSize);
	auto descriptor_pool = device.createDescriptorPool(descPoolInfo, vk::AllocationCallbacks::null());

	// make the descriptor set
	vk::DescriptorSetAllocateInfo descSetAllocInfo(descriptor_pool, 1, &descriptor_set_layout);
	auto descriptor_set = device.allocateDescriptorSets(descSetAllocInfo)[0];

	// add buffer
	vk::BufferCreateInfo buffInfo({}, sizeof(float) * 9, vk::BufferUsageFlags(vk::BufferUsageFlagBits::eVertexBuffer), vk::SharingMode::eExclusive, 0, nullptr); // TODO: not sure
	auto vertex_buffer = device.createBuffer(buffInfo, vk::AllocationCallbacks::null());

	// allocate for the buffer
	vk::MemoryAllocateInfo memAllocInfo(sizeof(float) * 9, 0); // TODO: better selection of memory type
	auto device_memory = device.allocateMemory(memAllocInfo, vk::AllocationCallbacks::null());

	// associate the buffer to the allocated space
	device.bindBufferMemory(vertex_buffer, device_memory, 0);

	// write to the buffer
	auto bufferData = device.mapMemory(device_memory, 0, sizeof(float) * 9, {});

	float triData[] = {
		-1.f, -1.f, 0.f,
		 1.f, -1.f, 0.f,
		 0.f,  1.f, 0.f
	};
	bufferData = triData;

	device.unmapMemory(device_memory);

	// update the descriptor sets
	vk::DescriptorBufferInfo descBufferInfo(vertex_buffer, 0, sizeof(float) * 9);
	vk::WriteDescriptorSet writeDescSet(descriptor_set, 0, 0, 1, vk::DescriptorType::eStorageBuffer, nullptr, &descBufferInfo, nullptr);

	// make a command pool
	vk::CommandPoolCreateInfo poolInfo({}, 0);
	auto commandPool = device.createCommandPool(poolInfo, vk::AllocationCallbacks::null());

	// make the command buffer
	vk::CommandBufferAllocateInfo commandBufferInfo(commandPool, vk::CommandBufferLevel::ePrimary, 1);
	auto commandBuffer = device.allocateCommandBuffers(commandBufferInfo);

	// RENDER!!!!!

	device.destroy(nullptr);
	glfwDestroyWindow(window);
	inst.destroy(nullptr);

}
<|endoftext|>


<commit_before>a1655466-4b02-11e5-9b84-28cfe9171a43<commit_msg>bobby added more bugs<commit_after>a172cede-4b02-11e5-9901-28cfe9171a43<|endoftext|>


<commit_before>#include <Magick++.h>
#include <json.hpp>
#include <boost/filesystem.hpp>
#include <boost/crc.hpp>
#include <vector>
#include <algorithm>
#include <math.h>
#include <fstream>
#include <iostream>
#include <thread>
#include <iterator>
#include <set>
#include <string>

typedef std::vector<boost::filesystem::directory_entry> path_listing;
typedef std::vector<boost::filesystem::path> extension_list;

const size_t max_directory_depth = 10;

struct image_meta{
  std::string checksum;
  std::string exif_date_original;
  std::string type;
};

bool operator<(const image_meta &a,const image_meta &b)
{
  return a.checksum < b.checksum;
}

void to_json(nlohmann::json& j, const image_meta& im) {
   j = nlohmann::json{{"id", im.checksum}, {"date", im.exif_date_original}, {"type", im.type}};
}

void from_json(const nlohmann::json& j, image_meta& im) {

        im.checksum = j.at("id").get<std::string>();
        im.exif_date_original= j.at("date").get<std::string>();
        im.type= j.at("type").get<std::string>();
}

typedef std::set<image_meta> image_set;

bool calculate_checksum(boost::filesystem::path filep, std::string &checksum)
{
  std::ifstream file(filep.string(),std::ios::in | std::ios::binary);
  std::vector<uint8_t> raw((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>());

  boost::crc_32_type result;
  result.process_bytes(&raw[0],raw.size());

  std::stringstream s;
  s << std::hex << result.checksum();
  s >> checksum;

  return true;
}

bool list_directory(const boost::filesystem::path root_directory,path_listing &files, extension_list extensions, size_t recursions = 0)
{
  recursions++;
  bool is_directory = true;

  if(boost::filesystem::exists(root_directory) && boost::filesystem::is_directory(root_directory))   {
    for(auto &entry: boost::filesystem::directory_iterator(root_directory))
      {
        if(boost::filesystem::is_directory(entry))
        {
          if(recursions <= max_directory_depth)
          {
            list_directory(entry.path(),files,extensions, recursions);
          }
        }

        if(boost::filesystem::is_regular_file(entry) && std::find(extensions.begin(),extensions.end(),entry.path().extension()) != extensions.end())
        {
          files.push_back(entry);
        }
      }

  }else
  {
    is_directory = false;
  }

  return is_directory;

}

bool resize_single_picture(boost::filesystem::directory_entry entry, boost::filesystem::path output_directory, int new_width, std::string checksum, image_set &pictures_added)
{
   if(!boost::filesystem::is_directory(output_directory))
  {
    return false;
  }

   std::string filepath = entry.path().string();

   Magick::Image image;

   image.read(filepath);
   auto size = image.size();

   double w = size.width();
   double h = size.height();

   double ratio = h/w;
   int new_height = floor(new_width * ratio);

   std::string file_with_extension = checksum + entry.path().extension().string();
   auto output_filepath = output_directory / std::to_string(new_width) / file_with_extension;
   std::string output_name(output_filepath.string());

   std::cout << "Resizing..." << output_name << std::endl;

   //image.filterType(Magick::FilterType::LanczosFilter); // already default + not supported in earlier lib versions
   image.resize(Magick::Geometry(new_width, new_height));

   image.write(output_name);

   image_meta imgi;
   imgi.checksum = checksum;
   imgi.exif_date_original = image.attribute("EXIF:DateTimeOriginal");
   if(entry.path().extension().string().find('.') != std::string::npos)
   {
     imgi.type = entry.path().extension().string().substr(1,entry.path().extension().string().length());
   }else
   {
     imgi.type = "none";
   }
   pictures_added.insert(imgi);
   return true;
}

bool create_direectories()
{
  return true;
}

bool resize_pictures_in_directory(path_listing files, boost::filesystem::path output_directory, int new_width, image_set &pictures_added)
{
  std::string checksum = "";

  for(auto &entry : files)
  {
    calculate_checksum(entry.path(), checksum);
    resize_single_picture(entry, output_directory, new_width, checksum, pictures_added);
  }

  return true;
}

bool parallel_resize(path_listing files, boost::filesystem::path output_directory, int new_width, image_set &pictures_added)
{

  size_t cores = std::thread::hardware_concurrency()/2;

  int batch_size = files.size()/cores;
  int start = 0;
  int stop = batch_size;

  std::vector<std::thread> thread_pool;

  for(int p=0;p<cores;p++)
  {
    path_listing partitioned_files(files.begin()+start, files.begin()+stop);
    start += batch_size;
    stop += batch_size;

    thread_pool.push_back(std::thread(resize_pictures_in_directory,partitioned_files,output_directory,new_width, std::ref(pictures_added)));
  }

  for(auto &t : thread_pool)
  {
    t.join();
  }
  return true;

}

bool load_json(boost::filesystem::path path,nlohmann::json &json)
{
  path = path / "digest.json";
  std::ifstream j(path.string());
  if(j)
  {
    j >> json;
    return true;
  }

  return false;
}

bool save_json(boost::filesystem::path path, nlohmann::json json)
{
  path = path / "digest.json";
  std::ofstream j(path.string());
  if(j)
  {
  std::cout << "SAVING" << path.string() << std::endl;
    j << json.dump(4);
    return true;
  }

    return false;
}

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

nlohmann::json json;

bool existing_json = load_json(boost::filesystem::path(argv[2]),json);
path_listing files;

extension_list allowed_extensions({".jpg",".jpeg",".JPG",".png",".PNG"});

image_set pictures_added;
std::set<int> resolutions;

try
{
image_set pa = json[argv[3]]["pictures"];
std::set<int> res = json[argv[3]]["widths"];

pictures_added = pa;
resolutions = res;
}catch(std::exception &e)
{
}

list_directory(boost::filesystem::path(argv[1]),files, allowed_extensions);
if(argc > 4)
{
  for(int p=4; p< argc;p++)
  {
    boost::filesystem::path sub = boost::filesystem::path(argv[2]) / std::to_string(std::stoi(argv[p]));

    boost::filesystem::create_directory(sub);
    resolutions.insert(std::stoi(argv[p]));
    resize_pictures_in_directory(files,boost::filesystem::path(argv[2]),std::stoi(argv[p]), pictures_added);
   // parallel_resize(files,boost::filesystem::path(argv[2]),std::stoi(argv[p]), pictures_added);;
  }
}

json[argv[3]]["pictures"] = nlohmann::json(pictures_added);
json[argv[3]]["widths"] = resolutions;

save_json(boost::filesystem::path(argv[2]), json);

return 0;
}
<commit_msg>📅 Supporting file creation date when not in exif<commit_after>#include <Magick++.h>
#include <json.hpp>
#include <boost/filesystem.hpp>
#include <boost/crc.hpp>
#include <vector>
#include <algorithm>
#include <math.h>
#include <fstream>
#include <iostream>
#include <thread>
#include <iterator>
#include <set>
#include <string>

typedef std::vector<boost::filesystem::directory_entry> path_listing;
typedef std::vector<boost::filesystem::path> extension_list;

const size_t max_directory_depth = 10;

struct image_meta{
  std::string checksum;
  std::string exif_date_original;
  std::string type;
};

bool operator<(const image_meta &a,const image_meta &b)
{
  return a.checksum < b.checksum;
}

void to_json(nlohmann::json& j, const image_meta& im) {
   j = nlohmann::json{{"id", im.checksum}, {"date", im.exif_date_original}, {"type", im.type}};
}

void from_json(const nlohmann::json& j, image_meta& im) {

        im.checksum = j.at("id").get<std::string>();
        im.exif_date_original= j.at("date").get<std::string>();
        im.type= j.at("type").get<std::string>();
}

typedef std::set<image_meta> image_set;

bool calculate_checksum(boost::filesystem::path filep, std::string &checksum)
{
  std::ifstream file(filep.string(),std::ios::in | std::ios::binary);
  std::vector<uint8_t> raw((std::istreambuf_iterator<char>(file)),std::istreambuf_iterator<char>());

  boost::crc_32_type result;
  result.process_bytes(&raw[0],raw.size());

  std::stringstream s;
  s << std::hex << result.checksum();
  s >> checksum;

  return true;
}

bool list_directory(const boost::filesystem::path root_directory,path_listing &files, extension_list extensions, size_t recursions = 0)
{
  recursions++;
  bool is_directory = true;

  if(boost::filesystem::exists(root_directory) && boost::filesystem::is_directory(root_directory))   {
    for(auto &entry: boost::filesystem::directory_iterator(root_directory))
      {
        if(boost::filesystem::is_directory(entry))
        {
          if(recursions <= max_directory_depth)
          {
            list_directory(entry.path(),files,extensions, recursions);
          }
        }

        if(boost::filesystem::is_regular_file(entry) && std::find(extensions.begin(),extensions.end(),entry.path().extension()) != extensions.end())
        {
          files.push_back(entry);
        }
      }

  }else
  {
    is_directory = false;
  }

  return is_directory;

}

bool resize_single_picture(boost::filesystem::directory_entry entry, boost::filesystem::path output_directory, int new_width, std::string checksum, image_set &pictures_added)
{
   if(!boost::filesystem::is_directory(output_directory))
  {
    return false;
  }

   std::string filepath = entry.path().string();

   Magick::Image image;

   image.read(filepath);
   auto size = image.size();

   double w = size.width();
   double h = size.height();

   double ratio = h/w;
   int new_height = floor(new_width * ratio);

   std::string file_with_extension = checksum + entry.path().extension().string();
   auto output_filepath = output_directory / std::to_string(new_width) / file_with_extension;
   std::string output_name(output_filepath.string());

   std::cout << "Resizing..." << output_name << std::endl;

   //image.filterType(Magick::FilterType::LanczosFilter); // already default + not supported in earlier lib versions
   image.resize(Magick::Geometry(new_width, new_height));

   image.write(output_name);

   image_meta imgi;
   imgi.checksum = checksum;
   imgi.exif_date_original = image.attribute("EXIF:DateTimeOriginal");

   if(imgi.exif_date_original == "")
   {
   auto t = boost::filesystem::last_write_time(entry.path());
   std::ostringstream  write_time;
   write_time  << std::put_time(std::localtime(&t),"%Y:%m:%d %H:%M:%S");
   imgi.exif_date_original = write_time.str();
   }

   if(entry.path().extension().string().find('.') != std::string::npos)
   {
     imgi.type = entry.path().extension().string().substr(1,entry.path().extension().string().length());
   }else
   {
     imgi.type = "none";
   }
   pictures_added.insert(imgi);
   return true;
}

bool create_direectories()
{
  return true;
}

bool resize_pictures_in_directory(path_listing files, boost::filesystem::path output_directory, int new_width, image_set &pictures_added)
{
  std::string checksum = "";

  for(auto &entry : files)
  {
    calculate_checksum(entry.path(), checksum);
    resize_single_picture(entry, output_directory, new_width, checksum, pictures_added);
  }

  return true;
}

bool parallel_resize(path_listing files, boost::filesystem::path output_directory, int new_width, image_set &pictures_added)
{

  size_t cores = std::thread::hardware_concurrency()/2;

  int batch_size = files.size()/cores;
  int start = 0;
  int stop = batch_size;

  std::vector<std::thread> thread_pool;

  for(int p=0;p<cores;p++)
  {
    path_listing partitioned_files(files.begin()+start, files.begin()+stop);
    start += batch_size;
    stop += batch_size;

    thread_pool.push_back(std::thread(resize_pictures_in_directory,partitioned_files,output_directory,new_width, std::ref(pictures_added)));
  }

  for(auto &t : thread_pool)
  {
    t.join();
  }
  return true;

}

bool load_json(boost::filesystem::path path,nlohmann::json &json)
{
  path = path / "digest.json";
  std::ifstream j(path.string());
  if(j)
  {
    j >> json;
    return true;
  }

  return false;
}

bool save_json(boost::filesystem::path path, nlohmann::json json)
{
  path = path / "digest.json";
  std::ofstream j(path.string());
  if(j)
  {
  std::cout << "SAVING" << path.string() << std::endl;
    j << json.dump(4);
    return true;
  }

    return false;
}

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

nlohmann::json json;

bool existing_json = load_json(boost::filesystem::path(argv[2]),json);
path_listing files;

extension_list allowed_extensions({".jpg",".jpeg",".JPG",".png",".PNG"});

image_set pictures_added;
std::set<int> resolutions;

try
{
image_set pa = json[argv[3]]["pictures"];
std::set<int> res = json[argv[3]]["widths"];

pictures_added = pa;
resolutions = res;
}catch(std::exception &e)
{
}

list_directory(boost::filesystem::path(argv[1]),files, allowed_extensions);
if(argc > 4)
{
  for(int p=4; p< argc;p++)
  {
    boost::filesystem::path sub = boost::filesystem::path(argv[2]) / std::to_string(std::stoi(argv[p]));

    boost::filesystem::create_directory(sub);
    resolutions.insert(std::stoi(argv[p]));
    resize_pictures_in_directory(files,boost::filesystem::path(argv[2]),std::stoi(argv[p]), pictures_added);
   // parallel_resize(files,boost::filesystem::path(argv[2]),std::stoi(argv[p]), pictures_added);;
  }
}

json[argv[3]]["pictures"] = nlohmann::json(pictures_added);
json[argv[3]]["widths"] = resolutions;

save_json(boost::filesystem::path(argv[2]), json);

return 0;
}
<|endoftext|>


<commit_before>#include "sgct.h"
#include "ParticleSystem.h"
#include "Snow.h"
#include "World.h"
#include "HelperFunctions.h"
#include "Field.h"
#include "DebugField.h"
#include "Gravity.h"
#include "Wind.h"
#include "ObjSystem.h"
#include "SoapBubble.h"
#include "Vortex.h"
#include <iostream>
#include "SimplexNoise.h"

//our beautiful global variables
sgct::Engine* gEngine;
Snow* gParticles;
World* gWorld;
Object* gObject;
Object* tree;
SoapBubble* gBubble;
Wind* gWind;
Gravity* gGrav;
Vortex* gTurbine;

bool gDisplayInfo;
bool gStatsGraph;
bool gWireframe;

sgct::SharedDouble curr_time(0.0);
sgct::SharedDouble sizeFactorX(0.0);
sgct::SharedDouble sizeFactorY(0.0);
sgct::SharedDouble sizeFactorZ(0.0);
sgct::SharedDouble vortFactorX(0.0);
sgct::SharedDouble vortFactorY(0.0);
sgct::SharedDouble vortFactorZ(0.0);
sgct::SharedDouble positionX(0.0);
sgct::SharedDouble positionZ(0.0);
sgct::SharedDouble radius(0.0);

void initialize();
void draw();
void myPreSyncFun();
void statsDrawFun();
void myEncodeFun();
void myDecodeFun();
void externalControlCallback(const char * receivedChars, int size, int clientId);
void sendMessageToExternalControl(void * data, int length);

int main(int argc, char *argv[])
{
	initRandom();

	gEngine = new sgct::Engine(argc, argv);

	gEngine->setInitOGLFunction(initialize);
	gEngine->setDrawFunction(draw);
	gEngine->setPreSyncFunction(myPreSyncFun);
	gEngine->setPostSyncPreDrawFunction(statsDrawFun);
	gEngine->setExternalControlCallback(externalControlCallback);
	sgct::SharedData::instance()->setEncodeFunction(myEncodeFun);
	sgct::SharedData::instance()->setDecodeFunction(myDecodeFun);

	gParticles = new Snow(gEngine);
	gWorld = new World(gEngine);

	gBubble = new SoapBubble(gEngine);

	gObject = new Object(gEngine);
	tree = new Object(gEngine);

	gGrav = new Gravity();
	gGrav->init(-9.81f);
	gParticles->addField(gGrav);

	gWind = new Wind();
	//wind->init(getRandom(-0.2, 0.2), 0.0f, getRandom(-0.2, 0.2));
	gWind->setAcceleration(0.0f, 0.0f, 0.0f);
	gParticles->addField(gWind);

	gTurbine = new Vortex();
	gTurbine->init(0.0f, 0.0f, 0.0f);
	gParticles->addField(gTurbine);

	//Not working yet... :(
	SimplexNoise* noise = new SimplexNoise();
	noise->init(glm::vec3(0), glm::vec3(0));

	gParticles->addField(noise);

	if(!gEngine->init(sgct::Engine::OpenGL_3_3_Core_Profile))
	{
		delete gEngine;
		return EXIT_FAILURE;
	}

	cout << "---- Fields active on gParticles ----" << endl;
	gParticles->printFields();
	cout << "---------------" << endl << endl;

	gEngine->render();

	gParticles->destroy();
	gObject->deleteObject();
	delete gObject;
	delete gEngine;
	delete gParticles;
	delete gWorld;
	delete gBubble;
	delete gWind;
	delete gTurbine;

	exit(EXIT_SUCCESS);
}

void initialize()
{
	if(!gParticles->initialize())
	{
		std::cout << "Error Initialzing Particle System:" << std::endl;
		exit(EXIT_FAILURE);
	}
	gWorld->initializeWorld();

	gObject->loadObj("road/road.obj", "road/road.png");
	gObject->scale(0.2f,0.2f,0.2f);
	gObject->translate(0.0f, -2.0f, 5.0f);

	tree->loadObj("road/tree.obj","road/tree.png");
	tree->scale(0.05f,0.05f,0.05f);
	tree->translate(0.0f, -1.0f, -6.0f);

	gBubble->createSphere(1.5f, 100);

	gDisplayInfo = false;
	gStatsGraph = false;
	gWireframe = false;
}

void draw()
{
	double delta = gEngine->getDt();
	gWorld->drawWorld();
	gBubble->drawBubble();
	//gObject->draw();
	//tree->draw();
	gParticles->move(delta);
	gParticles->draw(delta);
}

//Checking the time since the program started, not sure if we need this either.
void myPreSyncFun()
{
	//Checks so the gEnginenode is actually the master.
	if( gEngine->isMaster() )
	{
		//Sets the current time since the program started
		curr_time.setVal(sgct::Engine::getTime());
	}
}

void myEncodeFun()
{
	sgct::SharedData::instance()->writeDouble(&curr_time);
 	sgct::SharedData::instance()->writeDouble(&sizeFactorX);
 	sgct::SharedData::instance()->writeDouble(&sizeFactorY);
 	sgct::SharedData::instance()->writeDouble(&sizeFactorZ);
 	sgct::SharedData::instance()->writeDouble(&vortFactorX);
 	sgct::SharedData::instance()->writeDouble(&vortFactorY);
 	sgct::SharedData::instance()->writeDouble(&vortFactorZ);
 	sgct::SharedData::instance()->writeDouble(&positionX);
 	sgct::SharedData::instance()->writeDouble(&positionZ);
 	sgct::SharedData::instance()->writeDouble(&radius);
}

void myDecodeFun()
{
	sgct::SharedData::instance()->readDouble(&curr_time);
	sgct::SharedData::instance()->readDouble(&sizeFactorX);
	sgct::SharedData::instance()->readDouble(&sizeFactorY);
	sgct::SharedData::instance()->readDouble(&sizeFactorZ);
	sgct::SharedData::instance()->readDouble(&vortFactorX);
	sgct::SharedData::instance()->readDouble(&vortFactorY);
	sgct::SharedData::instance()->readDouble(&vortFactorZ);
	sgct::SharedData::instance()->readDouble(&positionX);
	sgct::SharedData::instance()->readDouble(&positionZ);
	sgct::SharedData::instance()->readDouble(&radius);
}

//Shows stats and graph depending on if the variables are true or not. Dont know if we need this? Currently set to false.
void statsDrawFun()
{
	gEngine->setDisplayInfoVisibility(gDisplayInfo);
	gEngine->setStatsGraphVisibility(gStatsGraph);
	gEngine->setWireframe(gWireframe);
}

//Used to alter certain values when sent from GUI. This way we can alter the fields or change gravity in realtime!
void externalControlCallback(const char * receivedChars, int size, int clientId)
{
	//Checks so the gEnginenode is actually the master.
	if(gEngine->isMaster())
	{
		if(size >= 6 && strncmp(receivedChars, "winX", 4) == 0)
		{
			//We need an int.
 			int tmpVal = atoi(receivedChars + 5);
 			sizeFactorX.setVal(tmpVal);
			gWind->setAcceleration((sizeFactorX.getVal()*0.01f), (sizeFactorY.getVal()*0.01f), (sizeFactorZ.getVal()*0.01f));

		}

		else if(size >= 6 && strncmp(receivedChars, "winY", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
 			sizeFactorY.setVal(tmpVal);
			gWind->setAcceleration((sizeFactorX.getVal()*0.01f), (sizeFactorY.getVal()*0.01f), (sizeFactorZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "winZ", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
 			sizeFactorZ.setVal(tmpVal);
			gWind->setAcceleration((sizeFactorX.getVal()*0.01f), (sizeFactorY.getVal()*0.01f), (sizeFactorZ.getVal()*0.01f));
		}
		else if(size >= 6 && strncmp(receivedChars, "vorX", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			gTurbine->setForce((tmpVal*0.01f), (tmpVal*0.01f), (tmpVal*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "vorY", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			vortFactorY.setVal(tmpVal);
			gTurbine->setForce((vortFactorX.getVal()*0.01f), (vortFactorY.getVal()*0.01f), (vortFactorZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "vorZ", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			vortFactorZ.setVal(tmpVal);
			gTurbine->setForce((vortFactorX.getVal()*0.01f), (vortFactorY.getVal()*0.01f), (vortFactorZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "posX", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			positionX.setVal(tmpVal);
			gTurbine->setPosition((positionX.getVal()*0.01f),(positionZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "posZ", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			positionZ.setVal(tmpVal);
			gTurbine->setPosition((positionX.getVal()*0.01f),(positionZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "r", 1) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			radius.setVal(tmpVal);
			gTurbine->setRadius(radius.getVal());
		}

		else if(size >= 6 && strcmp(receivedChars, "pause") != 0)
		{
			gParticles->togglePause();
		}

		else if(size >= 6 && strncmp(receivedChars, "grav", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			gGrav->init(-tmpVal);
		}
	}
}
<commit_msg>Fixed radius for vortex and informationbuttons in cpp file<commit_after>#include "sgct.h"
#include "ParticleSystem.h"
#include "Snow.h"
#include "World.h"
#include "HelperFunctions.h"
#include "Field.h"
#include "DebugField.h"
#include "Gravity.h"
#include "Wind.h"
#include "ObjSystem.h"
#include "SoapBubble.h"
#include "Vortex.h"
#include <iostream>
#include "SimplexNoise.h"

//our beautiful global variables
sgct::Engine* gEngine;
Snow* gParticles;
World* gWorld;
Object* gObject;
Object* tree;
SoapBubble* gBubble;
Wind* gWind;
Gravity* gGrav;
Vortex* gTurbine;

bool gDisplayInfo;
bool gStatsGraph;
bool gWireframe;

sgct::SharedDouble curr_time(0.0);
sgct::SharedDouble sizeFactorX(0.0);
sgct::SharedDouble sizeFactorY(0.0);
sgct::SharedDouble sizeFactorZ(0.0);
sgct::SharedDouble vortFactorX(0.0);
sgct::SharedDouble vortFactorY(0.0);
sgct::SharedDouble vortFactorZ(0.0);
sgct::SharedDouble positionX(0.0);
sgct::SharedDouble positionZ(0.0);
sgct::SharedDouble radius(0.0);

void initialize();
void draw();
void myPreSyncFun();
void statsDrawFun();
void myEncodeFun();
void myDecodeFun();
void externalControlCallback(const char * receivedChars, int size, int clientId);
void sendMessageToExternalControl(void * data, int length);

int main(int argc, char *argv[])
{
	initRandom();

	gEngine = new sgct::Engine(argc, argv);

	gEngine->setInitOGLFunction(initialize);
	gEngine->setDrawFunction(draw);
	gEngine->setPreSyncFunction(myPreSyncFun);
	gEngine->setPostSyncPreDrawFunction(statsDrawFun);
	gEngine->setExternalControlCallback(externalControlCallback);
	sgct::SharedData::instance()->setEncodeFunction(myEncodeFun);
	sgct::SharedData::instance()->setDecodeFunction(myDecodeFun);

	gParticles = new Snow(gEngine);
	gWorld = new World(gEngine);

	gBubble = new SoapBubble(gEngine);

	gObject = new Object(gEngine);
	tree = new Object(gEngine);

	gGrav = new Gravity();
	gGrav->init(-9.81f);
	gParticles->addField(gGrav);

	gWind = new Wind();
	//wind->init(getRandom(-0.2, 0.2), 0.0f, getRandom(-0.2, 0.2));
	gWind->setAcceleration(0.0f, 0.0f, 0.0f);
	gParticles->addField(gWind);

	gTurbine = new Vortex();
	gTurbine->init(0.0f, 0.0f, 0.0f);
	gParticles->addField(gTurbine);

	//Not working yet... :(
	SimplexNoise* noise = new SimplexNoise();
	noise->init(glm::vec3(0), glm::vec3(0));

	gParticles->addField(noise);

	if(!gEngine->init(sgct::Engine::OpenGL_3_3_Core_Profile))
	{
		delete gEngine;
		return EXIT_FAILURE;
	}

	cout << "---- Fields active on gParticles ----" << endl;
	gParticles->printFields();
	cout << "---------------" << endl << endl;

	gEngine->render();

	gParticles->destroy();
	gObject->deleteObject();
	delete gObject;
	delete gEngine;
	delete gParticles;
	delete gWorld;
	delete gBubble;
	delete gWind;
	delete gTurbine;

	exit(EXIT_SUCCESS);
}

void initialize()
{
	if(!gParticles->initialize())
	{
		std::cout << "Error Initialzing Particle System:" << std::endl;
		exit(EXIT_FAILURE);
	}
	gWorld->initializeWorld();

	gObject->loadObj("road/road.obj", "road/road.png");
	gObject->scale(0.2f,0.2f,0.2f);
	gObject->translate(0.0f, -2.0f, 5.0f);

	tree->loadObj("road/tree.obj","road/tree.png");
	tree->scale(0.05f,0.05f,0.05f);
	tree->translate(0.0f, -1.0f, -6.0f);

	gBubble->createSphere(1.5f, 100);

	gDisplayInfo = false;
	gStatsGraph = false;
	gWireframe = false;
}

void draw()
{
	double delta = gEngine->getDt();
	gWorld->drawWorld();
	gBubble->drawBubble();
	//gObject->draw();
	//tree->draw();
	gParticles->move(delta);
	gParticles->draw(delta);
}

//Checking the time since the program started, not sure if we need this either.
void myPreSyncFun()
{
	//Checks so the gEnginenode is actually the master.
	if( gEngine->isMaster() )
	{
		//Sets the current time since the program started
		curr_time.setVal(sgct::Engine::getTime());
	}
}

void myEncodeFun()
{
	sgct::SharedData::instance()->writeDouble(&curr_time);
 	sgct::SharedData::instance()->writeDouble(&sizeFactorX);
 	sgct::SharedData::instance()->writeDouble(&sizeFactorY);
 	sgct::SharedData::instance()->writeDouble(&sizeFactorZ);
 	sgct::SharedData::instance()->writeDouble(&vortFactorX);
 	sgct::SharedData::instance()->writeDouble(&vortFactorY);
 	sgct::SharedData::instance()->writeDouble(&vortFactorZ);
 	sgct::SharedData::instance()->writeDouble(&positionX);
 	sgct::SharedData::instance()->writeDouble(&positionZ);
 	sgct::SharedData::instance()->writeDouble(&radius);
}

void myDecodeFun()
{
	sgct::SharedData::instance()->readDouble(&curr_time);
	sgct::SharedData::instance()->readDouble(&sizeFactorX);
	sgct::SharedData::instance()->readDouble(&sizeFactorY);
	sgct::SharedData::instance()->readDouble(&sizeFactorZ);
	sgct::SharedData::instance()->readDouble(&vortFactorX);
	sgct::SharedData::instance()->readDouble(&vortFactorY);
	sgct::SharedData::instance()->readDouble(&vortFactorZ);
	sgct::SharedData::instance()->readDouble(&positionX);
	sgct::SharedData::instance()->readDouble(&positionZ);
	sgct::SharedData::instance()->readDouble(&radius);
}

//Shows stats and graph depending on if the variables are true or not. Dont know if we need this? Currently set to false.
void statsDrawFun()
{
	gEngine->setDisplayInfoVisibility(gDisplayInfo);
	gEngine->setStatsGraphVisibility(gStatsGraph);
	gEngine->setWireframe(gWireframe);
}

//Used to alter certain values when sent from GUI. This way we can alter the fields or change gravity in realtime!
void externalControlCallback(const char * receivedChars, int size, int clientId)
{
	//Checks so the gEnginenode is actually the master.
	if(gEngine->isMaster())
	{
		if(size >= 6 && strncmp(receivedChars, "winX", 4) == 0)
		{
			//We need an int.
 			int tmpVal = atoi(receivedChars + 5);
 			sizeFactorX.setVal(tmpVal);
			gWind->setAcceleration((sizeFactorX.getVal()*0.01f), (sizeFactorY.getVal()*0.01f), (sizeFactorZ.getVal()*0.01f));

		}

		else if(size >= 6 && strncmp(receivedChars, "winY", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
 			sizeFactorY.setVal(tmpVal);
			gWind->setAcceleration((sizeFactorX.getVal()*0.01f), (sizeFactorY.getVal()*0.01f), (sizeFactorZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "winZ", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
 			sizeFactorZ.setVal(tmpVal);
			gWind->setAcceleration((sizeFactorX.getVal()*0.01f), (sizeFactorY.getVal()*0.01f), (sizeFactorZ.getVal()*0.01f));
		}
		else if(size >= 6 && strncmp(receivedChars, "vorX", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			gTurbine->setForce((tmpVal*0.01f), (tmpVal*0.01f), (tmpVal*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "vorY", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			vortFactorY.setVal(tmpVal);
			gTurbine->setForce((vortFactorX.getVal()*0.01f), (vortFactorY.getVal()*0.01f), (vortFactorZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "vorZ", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			vortFactorZ.setVal(tmpVal);
			gTurbine->setForce((vortFactorX.getVal()*0.01f), (vortFactorY.getVal()*0.01f), (vortFactorZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "posX", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			positionX.setVal(tmpVal);
			gTurbine->setPosition((positionX.getVal()*0.01f),(positionZ.getVal()*0.01f));
		}

		else if(size >= 6 && strncmp(receivedChars, "posZ", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			positionZ.setVal(tmpVal);
			gTurbine->setPosition((positionX.getVal()*0.01f),(positionZ.getVal()*0.01f));
		}

		else if(size >= 6 && strcmp(receivedChars, "radius") != 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			radius.setVal(tmpVal);
			gTurbine->setRadius(radius.getVal());
		}

		else if(size >= 6 && strcmp(receivedChars, "pause") != 0)
		{
			gParticles->togglePause();
		}

		else if(size >= 6 && strncmp(receivedChars, "grav", 4) == 0)
		{
			//We need an int.
			int tmpVal = atoi(receivedChars + 5);
			gGrav->init(-tmpVal);
		}

		else if(size >= 6 && strcmp(receivedChars, "display") != 0)
		{
			gDisplayInfo = !gDisplayInfo;
		}

		else if(size >= 6 && strcmp(receivedChars, "stats") != 0)
		{
			gStatsGraph = !gStatsGraph;
		}

		else if(size >= 6 && strcmp(receivedChars, "wire") != 0)
		{
			gWireframe = !gWireframe;
		}
	}
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <utility>
#include <cstdio>
#include <cstdint>
#include <cstdlib>
extern "C" {
#include <lightning.h>
}

enum Opcode {
    OP_NOP,
    OP_PUSH,
    OP_ADD,
    OP_SUB,
    OP_MUL,
    OP_DIV,
    OP_CALL,
};
const char *trans_opcode(int op) {
    switch (op) {
    case OP_NOP:
        return "NOP";
    case OP_PUSH:
        return "PUSH";
    case OP_ADD:
        return "ADD";
    case OP_SUB:
        return "SUB";
    case OP_MUL:
        return "MUL";
    case OP_DIV:
        return "DIV";
    case OP_CALL:
        return "CALL";
    default:
        return "unknown";
    }

}

struct Instruction {
    uint8_t op;
    union {
        int    ival;
        double dval;
        struct {
            uint32_t fidx;
            uint32_t nargs;
        } callop;
    };

    Instruction(Opcode op) : op(op) {}
    Instruction(Opcode op, int ival) : op(op), ival(ival) {}
    Instruction(Opcode op, double dval) : op(op), dval(dval) {}
    Instruction(Opcode op, uint32_t function_idx, uint32_t nargs)
        : op(op) { callop.fidx = function_idx; callop.nargs = nargs; }
};

void _JIT_stack_push(jit_state_t *_jit, int reg, int *sp) {
    jit_stxi_d(*sp, JIT_FP, reg);
    *sp += sizeof(double);
}

void _JIT_stack_pop(jit_state_t *_jit, int reg, int *sp) {
    *sp -= sizeof(double);
    jit_ldxi_d(reg, JIT_FP, *sp);
}

typedef std::pair<int, double> Result;

// TODO: implement
struct MyEnv {
    // static Result myFunc(void *self, uint32_t nargs, const double *stack) {
    //     return static_cast<MyEnv*>(self)->myFuncImpl(nargs, stack);
    // }

    Result myFunc(/*void *self,*/ uint32_t nargs, const double *stack) {
        printf("inside MyEnv::myFunc: %p\n", this);
        return std::make_pair(0, stack[0] + stack[1]);
    }

// private:
    // Result myFuncImpl(uint32_t nargs, const double *stack) {
    //     return std::make_pair(0, stack[0] + stack[1]);
    // }
};

Result fixme_function(void*, uint32_t nargs, const double *stack) {
    return std::make_pair(0, stack[0] + stack[1]);
}

Result second_function(void*, uint32_t nargs, const double *stack) {
    int retcode;
    double result;
    if (nargs < 3) {
        retcode = 1;
        result = 0.0;
    } else {
        retcode = 0;
        result = stack[0] != 0.0 ? stack[1] : stack[2];
    }
    return std::make_pair(retcode, result);
}

//typedef Result (*Callback)(void *, uint32_t, const double*);
typedef void* Callback;

struct Translator {
    virtual ~Translator() {}
    virtual Callback lookup(uint32_t function_idx)=0;
};

struct DummyTranslator : public Translator {
    virtual ~DummyTranslator() {}
    Callback lookup(uint32_t function_idx) override {
        switch (function_idx) {
        case 1:
            //return (void*)fixme_function;
            return (void*)&MyEnv::myFunc;
        case 2:
            return (void*)second_function;
        default:
            throw std::runtime_error("Unknown function index!");
        }
    }
};

typedef std::vector<Instruction> Program;

class JIT {
public:
    JIT() : _jit(jit_new_state()), func_(nullptr) {}

    ~JIT() {
        jit_destroy_state();
    }

    bool compile(const Program &program, Translator &trans, void *userdata) {
        jit_node_t *fn = jit_note(NULL, 0);
        jit_prolog();
        const int stack_base_offset = jit_allocai(32 * sizeof(double));
        int stack_top_idx = 0;

        auto &&stackPush = [&](int reg) {
            jit_stxi_d(stack_base_offset + stack_top_idx * sizeof(double), JIT_FP, reg);
            ++stack_top_idx;
        };

        auto &&stackPop = [&](int reg) {
            --stack_top_idx;
            jit_ldxi_d(reg, JIT_FP, stack_base_offset + stack_top_idx * sizeof(double));
            return reg;
        };

        size_t pc = 0;
        const size_t progsz = program.size();
        while (pc < progsz) {
            const Instruction &instr = program[pc];
            switch (instr.op) {
            case OP_NOP:
                break;
            case OP_PUSH:
                stackPush(JIT_F0);
                jit_movi_d(JIT_F0, instr.dval);
                break;
            case OP_ADD: {
                const int reg = stackPop(JIT_F1);
                jit_addr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_SUB: {
                const int reg = stackPop(JIT_F1);
                jit_subr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_MUL: {
                const int reg = stackPop(JIT_F1);
                jit_mulr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_DIV: {
                const int reg = stackPop(JIT_F1);
                jit_divr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_CALL: {
                stackPush(JIT_F0);
                const int sp = stack_top_idx - (instr.callop.nargs);
                jit_addi(JIT_R0, JIT_FP, stack_base_offset + sp * sizeof(double));

                jit_prepare();
                jit_pushargi((jit_word_t)userdata); // 1st arg: userdata
                jit_pushargi(instr.callop.nargs);   // 2nd arg: # of arguments
                jit_pushargr(JIT_R0);               // 3rd arg: pointer to args on stack

                auto &&cb = trans.lookup(instr.callop.fidx);
                jit_finishi(reinterpret_cast<jit_pointer_t>(cb));

                stack_top_idx -= instr.callop.nargs; // consume arguments on stack
                jit_retval_d(JIT_F0);
            }
                break;
            }

            ++pc;
        }

        jit_retr_d(JIT_F0);
        jit_epilog();

        (void)jit_emit();
        func_ = reinterpret_cast<JitFunction>(jit_address(fn));

        return true;
    }

    bool run() {
        result_ = func_();
        return true;
    }

    double result() const noexcept {
        return result_;
    }

    void disassemble() {
        jit_disassemble();
    }

    const char *error() const {
        return "TODO: implement";
    }

private:
    typedef double (*JitFunction)();

    jit_state_t *_jit; // DO NOT CHANGE NAME.  Satisfies req.s for GNU lightning macros
    JitFunction func_;
    double result_;
};

int main(int argc, char **argv) {
    Program program = {
        { OP_PUSH, 1234. },
        { OP_PUSH, 6666. },
        //{ OP_ADD         },
        { OP_CALL, 1, 2  }, // fixme_function
        { OP_PUSH, 4444. },
        { OP_SUB         },
        { OP_PUSH, 5555. },
        { OP_MUL         },
    };

    init_jit(argv[0]); // TODO: move to static function
    JIT jit;
    DummyTranslator trans;
    MyEnv env, env2, env3;

    if (!jit.compile(program, trans, &env)) {
        std::cerr << "Failed to compile program!" << std::endl;
        return 1;
    }

    if (!jit.run()) {
        std::cerr << "Error running program: " << jit.error() << std::endl;
        return 1;
    }

    std::cout << "\n\nProgram: \n";
    jit.disassemble();

    std::cout << "Result: " << jit.result() << std::endl;
    std::cout << "Expected: " << (((1234. + 6666.) - 4444.) * 5555.) << std::endl;

    for (int i = 0; i < 10; ++i) {
        std::cout << jit.result() << std::endl;
    }

    finish_jit();

    double stk[] = { 1., 2. };
    auto v1 = env2.myFunc(2, &stk[0]);
    auto v2 = env3.myFunc(2, &stk[0]);
    std::cout << (v1.second + v2.second) << std::endl;

    return 0;
}
<commit_msg>Evil cast to allow converting member function to void*<commit_after>#include <iostream>
#include <vector>
#include <utility>
#include <cstdio>
#include <cstdint>
#include <cstdlib>
extern "C" {
#include <lightning.h>
}

enum Opcode {
    OP_NOP,
    OP_PUSH,
    OP_ADD,
    OP_SUB,
    OP_MUL,
    OP_DIV,
    OP_CALL,
};
const char *trans_opcode(int op) {
    switch (op) {
    case OP_NOP:
        return "NOP";
    case OP_PUSH:
        return "PUSH";
    case OP_ADD:
        return "ADD";
    case OP_SUB:
        return "SUB";
    case OP_MUL:
        return "MUL";
    case OP_DIV:
        return "DIV";
    case OP_CALL:
        return "CALL";
    default:
        return "unknown";
    }

}

struct Instruction {
    uint8_t op;
    union {
        int    ival;
        double dval;
        struct {
            uint32_t fidx;
            uint32_t nargs;
        } callop;
    };

    Instruction(Opcode op) : op(op) {}
    Instruction(Opcode op, int ival) : op(op), ival(ival) {}
    Instruction(Opcode op, double dval) : op(op), dval(dval) {}
    Instruction(Opcode op, uint32_t function_idx, uint32_t nargs)
        : op(op) { callop.fidx = function_idx; callop.nargs = nargs; }
};

void _JIT_stack_push(jit_state_t *_jit, int reg, int *sp) {
    jit_stxi_d(*sp, JIT_FP, reg);
    *sp += sizeof(double);
}

void _JIT_stack_pop(jit_state_t *_jit, int reg, int *sp) {
    *sp -= sizeof(double);
    jit_ldxi_d(reg, JIT_FP, *sp);
}

typedef std::pair<int, double> Result;

template<typename T, typename R>
void* evil_cast(R(T::*f)(uint32_t, const double*))
{
    union
    {
        R(T::*pf)(uint32_t, const double*);
        void* p;
    };
    pf = f;
    return p;
}

// TODO: implement
struct MyEnv {
    // static Result myFunc(void *self, uint32_t nargs, const double *stack) {
    //     return static_cast<MyEnv*>(self)->myFuncImpl(nargs, stack);
    // }

    Result myFunc(/*void *self,*/ uint32_t nargs, const double *stack) {
        printf("inside MyEnv::myFunc: %p\n", this);
        return std::make_pair(0, stack[0] + stack[1]);
    }

// private:
    // Result myFuncImpl(uint32_t nargs, const double *stack) {
    //     return std::make_pair(0, stack[0] + stack[1]);
    // }
};

Result fixme_function(void*, uint32_t nargs, const double *stack) {
    return std::make_pair(0, stack[0] + stack[1]);
}

Result second_function(void*, uint32_t nargs, const double *stack) {
    int retcode;
    double result;
    if (nargs < 3) {
        retcode = 1;
        result = 0.0;
    } else {
        retcode = 0;
        result = stack[0] != 0.0 ? stack[1] : stack[2];
    }
    return std::make_pair(retcode, result);
}

//typedef Result (*Callback)(void *, uint32_t, const double*);
typedef void* Callback;

struct Translator {
    virtual ~Translator() {}
    virtual Callback lookup(uint32_t function_idx)=0;
};

struct DummyTranslator : public Translator {

    virtual ~DummyTranslator() {}
    Callback lookup(uint32_t function_idx) override {
        //#pragma GCC diagnostic ignored "-Wpmf-conversions"
        switch (function_idx) {
        case 1:
            //return (void*)fixme_function;
            //return (void*)&MyEnv::myFunc;
            return evil_cast(&MyEnv::myFunc);
        case 2:
            return (void*)second_function;
        default:
            throw std::runtime_error("Unknown function index!");
        }
        //#pragma GCC diagnostic pop
    }
};

typedef std::vector<Instruction> Program;

class JIT {
public:
    JIT() : _jit(jit_new_state()), func_(nullptr) {}

    ~JIT() {
        jit_destroy_state();
    }

    bool compile(const Program &program, Translator &trans, void *userdata) {
        jit_node_t *fn = jit_note(NULL, 0);
        jit_prolog();
        const int stack_base_offset = jit_allocai(32 * sizeof(double));
        int stack_top_idx = 0;

        auto &&stackPush = [&](int reg) {
            jit_stxi_d(stack_base_offset + stack_top_idx * sizeof(double), JIT_FP, reg);
            ++stack_top_idx;
        };

        auto &&stackPop = [&](int reg) {
            --stack_top_idx;
            jit_ldxi_d(reg, JIT_FP, stack_base_offset + stack_top_idx * sizeof(double));
            return reg;
        };

        size_t pc = 0;
        const size_t progsz = program.size();
        while (pc < progsz) {
            const Instruction &instr = program[pc];
            switch (instr.op) {
            case OP_NOP:
                break;
            case OP_PUSH:
                stackPush(JIT_F0);
                jit_movi_d(JIT_F0, instr.dval);
                break;
            case OP_ADD: {
                const int reg = stackPop(JIT_F1);
                jit_addr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_SUB: {
                const int reg = stackPop(JIT_F1);
                jit_subr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_MUL: {
                const int reg = stackPop(JIT_F1);
                jit_mulr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_DIV: {
                const int reg = stackPop(JIT_F1);
                jit_divr_d(JIT_F0, reg, JIT_F0);
            }
                break;
            case OP_CALL: {
                stackPush(JIT_F0);
                const int sp = stack_top_idx - (instr.callop.nargs);
                jit_addi(JIT_R0, JIT_FP, stack_base_offset + sp * sizeof(double));

                jit_prepare();
                jit_pushargi((jit_word_t)userdata); // 1st arg: userdata
                jit_pushargi(instr.callop.nargs);   // 2nd arg: # of arguments
                jit_pushargr(JIT_R0);               // 3rd arg: pointer to args on stack

                auto &&cb = trans.lookup(instr.callop.fidx);
                jit_finishi(reinterpret_cast<jit_pointer_t>(cb));

                stack_top_idx -= instr.callop.nargs; // consume arguments on stack
                jit_retval_d(JIT_F0);
            }
                break;
            }

            ++pc;
        }

        jit_retr_d(JIT_F0);
        jit_epilog();

        (void)jit_emit();
        func_ = reinterpret_cast<JitFunction>(jit_address(fn));

        return true;
    }

    bool run() {
        result_ = func_();
        return true;
    }

    double result() const noexcept {
        return result_;
    }

    void disassemble() {
        jit_disassemble();
    }

    const char *error() const {
        return "TODO: implement";
    }

private:
    typedef double (*JitFunction)();

    jit_state_t *_jit; // DO NOT CHANGE NAME.  Satisfies req.s for GNU lightning macros
    JitFunction func_;
    double result_;
};

int main(int argc, char **argv) {
    Program program = {
        { OP_PUSH, 1234. },
        { OP_PUSH, 6666. },
        //{ OP_ADD         },
        { OP_CALL, 1, 2  }, // fixme_function
        { OP_PUSH, 4444. },
        { OP_SUB         },
        { OP_PUSH, 5555. },
        { OP_MUL         },
    };

    init_jit(argv[0]); // TODO: move to static function
    JIT jit;
    DummyTranslator trans;
    MyEnv env, env2, env3;

    if (!jit.compile(program, trans, &env)) {
        std::cerr << "Failed to compile program!" << std::endl;
        return 1;
    }

    if (!jit.run()) {
        std::cerr << "Error running program: " << jit.error() << std::endl;
        return 1;
    }

    std::cout << "\n\nProgram: \n";
    jit.disassemble();

    std::cout << "Result: " << jit.result() << std::endl;
    std::cout << "Expected: " << (((1234. + 6666.) - 4444.) * 5555.) << std::endl;

    for (int i = 0; i < 10; ++i) {
        std::cout << jit.result() << std::endl;
    }

    finish_jit();

    double stk[] = { 1., 2. };
    auto v1 = env2.myFunc(2, &stk[0]);
    auto v2 = env3.myFunc(2, &stk[0]);
    std::cout << (v1.second + v2.second) << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2004-2008  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "znc.h"
#include <getopt.h>

static struct option g_LongOpts[] = {
	{ "help",			no_argument,	0,	'h' },
	{ "version",			no_argument,	0,	'v' },
	{ "no-color",			no_argument,	0,	'n' },
	{ "allow-root",			no_argument,	0,	'r' },
	{ "makeconf",			no_argument,	0,	'c' },
	{ "makepass",			no_argument,	0,	's' },
#ifdef HAVE_LIBSSL
	{ "makepem",			no_argument,	0,	'p' },
	{ "encrypt-pem",		no_argument,	0, 	'e' },
#endif /* HAVE_LIBSSL */
	{ "datadir",                    required_argument,	0,   'd' },
	{ 0, 0, 0, 0 }
};

static void GenerateHelp(const char *appname) {
	CUtils::PrintMessage("USAGE: " + CString(appname) + " [options] [config]");
	CUtils::PrintMessage("Options are:");
	CUtils::PrintMessage("\t-h, --help         List available command line options (this page)");
	CUtils::PrintMessage("\t-v, --version      Output version information and exit");
	CUtils::PrintMessage("\t-n, --no-color     Don't use escape sequences in the output");
	CUtils::PrintMessage("\t-r, --allow-root   Don't complain if ZNC is run as root");
	CUtils::PrintMessage("\t-c, --makeconf     Interactively create a new config");
	CUtils::PrintMessage("\t-s, --makepass     Generates a password for use in config");
#ifdef HAVE_LIBSSL
	CUtils::PrintMessage("\t-p, --makepem      Generates a pemfile for use with SSL");
	CUtils::PrintMessage("\t-e, --encrypt-pem  when used along with --makepem, encrypts the private key in the pemfile");
#endif /* HAVE_LIBSSL */
	CUtils::PrintMessage("\t-d, --datadir      Set a different znc repository (default is ~/.znc)");
}

static void die(int sig) {
	signal(SIGPIPE, SIG_DFL);

#ifdef _DEBUG
	CUtils::PrintMessage("Exiting on SIG [" + CString(sig) + "]");
	if ((sig == SIGABRT) || (sig == SIGSEGV)) {
		abort();
	}
#endif /* _DEBUG */

	delete &CZNC::Get();
	exit(sig);
}

static void rehash(int sig) {
	CZNC::Get().SetNeedRehash(true);
}

static bool isRoot() {
	// User root? If one of these were root, we could switch the others to root, too
	if (geteuid() == 0 || getuid() == 0)
		return true;

	return false;
}

int main(int argc, char** argv) {
	CString sConfig;
	CString sDataDir = "";

	srand(time(NULL));
	CUtils::SetStdoutIsTTY(isatty(1));

#ifdef HAVE_LIBSSL
	InitSSL();
#endif /* HAVE_LIBSSL */

	int iArg, iOptIndex = -1;
	bool bMakeConf = false;
	bool bMakePass = false;
	bool bAllowRoot = false;
#ifdef HAVE_LIBSSL
	bool bMakePem = false;
	bool bEncPem = false;

	while ((iArg = getopt_long(argc, argv, "hvnrcsped:", g_LongOpts, &iOptIndex)) != -1) {
#else
	while ((iArg = getopt_long(argc, argv, "hvnrcsd:", g_LongOpts, &iOptIndex)) != -1) {
#endif /* HAVE_LIBSSL */
	    switch (iArg) {
		case 'h':
			GenerateHelp(argv[0]);
			return 0;
		case 'v':
			cout << CZNC::GetTag() << endl;
			return 0;
		case 'n':
			CUtils::SetStdoutIsTTY(false);
			break;
		case 'r':
			bAllowRoot = true;
			break;
		case 'c':
			bMakeConf = true;
			break;
		case 's':
			bMakePass = true;
			break;
#ifdef HAVE_LIBSSL
		case 'p':
			bMakePem = true;
			break;
		case 'e':
			bEncPem = true;
			break;
#endif /* HAVE_LIBSSL */
		case 'd':
			sDataDir = CString(optarg);
			break;
		case '?':
		default:
			GenerateHelp(argv[0]);
			return 1;
	    }
	}

	if (optind < argc) {
		sConfig = argv[optind];
	} else {
		sConfig = "znc.conf";
	}

	CZNC* pZNC = &CZNC::Get();
	pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir);

	if (bMakeConf) {
		if (pZNC->WriteNewConfig(sConfig)) {
			char const* args[5];

			if (argc > 2) {
				args[0] = argv[0];
				if (!sDataDir.empty()) {
					args[1] = "--datadir";
					args[2] = strdup(sDataDir.c_str());
					args[3] = argv[optind];
					args[4] = NULL;
				} else {
					args[1] = argv[optind];
					args[2] = NULL;
				}
			} else if (argc > 1) {
				args[0] = argv[0];
				if (!sDataDir.empty()) {
					args[1] = "--datadir";
					args[2] = strdup(sDataDir.c_str());
					args[3] = NULL;
				} else {
					args[1] = NULL;
				}
			} else {
				CUtils::PrintError("Unable to launch znc [Try manually restarting]");
				return 1;
			}

			if ((chdir(pZNC->GetCurPath().c_str()) == -1)
					|| (execv(*argv, (char *const*)args) == -1)) {
				CUtils::PrintError("Unable to launch znc [" + CString(strerror(errno)) + "]");
				return 1;
			}
		}

		return 0;
	}

#ifdef HAVE_LIBSSL
	if (bMakePem) {
		pZNC->WritePemFile(bEncPem);

		delete pZNC;
		return 0;
	}
	if (bEncPem && !bMakePem) {
		CUtils::PrintError("--encrypt-pem should be used along with --makepem.");
		return 1;
	}

#endif /* HAVE_LIBSSL */
	if (bMakePass) {
		CString sSalt;
		CString sHash = CUtils::GetSaltedHashPass(sSalt);
		CUtils::PrintMessage("Use this in the <User> section of your config:");
		CUtils::PrintMessage("Pass = md5#" + sHash + "#" + sSalt + "#");

		return 0;
	}

	if (!pZNC->ParseConfig(sConfig)) {
		CUtils::PrintError("Unrecoverable config error.");
		delete pZNC;
		return 1;
	}

	if (!pZNC->OnBoot()) {
		CUtils::PrintError("Exiting due to module boot errors.");
		delete pZNC;
		return 1;
	}

	if (isRoot()) {
		CUtils::PrintError("You are running ZNC as root! Don't do that! There are not many valid");
		CUtils::PrintError("reasons for this and it can, in theory, cause great damage!");
		if (!bAllowRoot) {
			exit(1);
		}
		CUtils::PrintError("You have been warned.");
		CUtils::PrintError("Hit CTRL+C now if you don't want to run ZNC as root.");
		CUtils::PrintError("ZNC will start in 30 seconds.");
		sleep(30);
	}

#ifdef _DEBUG
	int iPid = getpid();
	CUtils::PrintMessage("Staying open for debugging [pid: " + CString(iPid) + "]");

	pZNC->WritePidFile(iPid);
	CUtils::PrintMessage(CZNC::GetTag());
#else
	CUtils::PrintAction("Forking into the background");

	int iPid = fork();

	if (iPid == -1) {
		CUtils::PrintStatus(false, strerror(errno));
		delete pZNC;
		exit(1);
	}

	if (iPid > 0) {
		// We are the parent. We are done and will go to bed.
		CUtils::PrintStatus(true, "[pid: " + CString(iPid) + "]");

		pZNC->WritePidFile(iPid);
		CUtils::PrintMessage(CZNC::GetTag());
		exit(0);
	}

	// Redirect std in/out/err to /dev/null
	close(0); open("/dev/null", O_RDONLY);
	close(1); open("/dev/null", O_WRONLY);
	close(2); open("/dev/null", O_WRONLY);

	CUtils::SetStdoutIsTTY(false);

	// We are the child. There is no way we can be a process group
	// leader, thus setsid() must succeed.
	setsid();
	// Now we are in our own process group and session (no controlling
	// terminal). We are independent!
#endif

	struct sigaction sa;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, (struct sigaction*) NULL);

	sa.sa_handler = rehash;
	sigaction(SIGHUP,  &sa, (struct sigaction*) NULL);

	// Once this signal is caught, the signal handler is reset
	// to SIG_DFL. This avoids endless loop with signals.
	sa.sa_flags = SA_RESETHAND;
	sa.sa_handler = die;
	sigaction(SIGINT,  &sa, (struct sigaction*) NULL);
	sigaction(SIGILL,  &sa, (struct sigaction*) NULL);
	sigaction(SIGQUIT, &sa, (struct sigaction*) NULL);
	sigaction(SIGBUS,  &sa, (struct sigaction*) NULL);
	sigaction(SIGSEGV, &sa, (struct sigaction*) NULL);
	sigaction(SIGTERM, &sa, (struct sigaction*) NULL);

	int iRet = 0;

	try {
		iRet = pZNC->Loop();
	} catch (CException e) {
		// EX_Shutdown is thrown to exit
		switch (e.GetType()) {
			case CException::EX_Shutdown:
				iRet = 0;
			default:
				iRet = 1;
		}
	}

	delete pZNC;

	return iRet;
}
<commit_msg>Move some code around<commit_after>/*
 * Copyright (C) 2004-2008  See the AUTHORS file for details.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 */

#include "znc.h"
#include <getopt.h>

static struct option g_LongOpts[] = {
	{ "help",			no_argument,	0,	'h' },
	{ "version",			no_argument,	0,	'v' },
	{ "no-color",			no_argument,	0,	'n' },
	{ "allow-root",			no_argument,	0,	'r' },
	{ "makeconf",			no_argument,	0,	'c' },
	{ "makepass",			no_argument,	0,	's' },
#ifdef HAVE_LIBSSL
	{ "makepem",			no_argument,	0,	'p' },
	{ "encrypt-pem",		no_argument,	0, 	'e' },
#endif /* HAVE_LIBSSL */
	{ "datadir",                    required_argument,	0,   'd' },
	{ 0, 0, 0, 0 }
};

static void GenerateHelp(const char *appname) {
	CUtils::PrintMessage("USAGE: " + CString(appname) + " [options] [config]");
	CUtils::PrintMessage("Options are:");
	CUtils::PrintMessage("\t-h, --help         List available command line options (this page)");
	CUtils::PrintMessage("\t-v, --version      Output version information and exit");
	CUtils::PrintMessage("\t-n, --no-color     Don't use escape sequences in the output");
	CUtils::PrintMessage("\t-r, --allow-root   Don't complain if ZNC is run as root");
	CUtils::PrintMessage("\t-c, --makeconf     Interactively create a new config");
	CUtils::PrintMessage("\t-s, --makepass     Generates a password for use in config");
#ifdef HAVE_LIBSSL
	CUtils::PrintMessage("\t-p, --makepem      Generates a pemfile for use with SSL");
	CUtils::PrintMessage("\t-e, --encrypt-pem  when used along with --makepem, encrypts the private key in the pemfile");
#endif /* HAVE_LIBSSL */
	CUtils::PrintMessage("\t-d, --datadir      Set a different znc repository (default is ~/.znc)");
}

static void die(int sig) {
	signal(SIGPIPE, SIG_DFL);

#ifdef _DEBUG
	CUtils::PrintMessage("Exiting on SIG [" + CString(sig) + "]");
	if ((sig == SIGABRT) || (sig == SIGSEGV)) {
		abort();
	}
#endif /* _DEBUG */

	delete &CZNC::Get();
	exit(sig);
}

static void rehash(int sig) {
	CZNC::Get().SetNeedRehash(true);
}

static bool isRoot() {
	// User root? If one of these were root, we could switch the others to root, too
	if (geteuid() == 0 || getuid() == 0)
		return true;

	return false;
}

int main(int argc, char** argv) {
	CString sConfig;
	CString sDataDir = "";

	srand(time(NULL));
	CUtils::SetStdoutIsTTY(isatty(1));

#ifdef HAVE_LIBSSL
	InitSSL();
#endif /* HAVE_LIBSSL */

	int iArg, iOptIndex = -1;
	bool bMakeConf = false;
	bool bMakePass = false;
	bool bAllowRoot = false;
#ifdef HAVE_LIBSSL
	bool bMakePem = false;
	bool bEncPem = false;

	while ((iArg = getopt_long(argc, argv, "hvnrcsped:", g_LongOpts, &iOptIndex)) != -1) {
#else
	while ((iArg = getopt_long(argc, argv, "hvnrcsd:", g_LongOpts, &iOptIndex)) != -1) {
#endif /* HAVE_LIBSSL */
	    switch (iArg) {
		case 'h':
			GenerateHelp(argv[0]);
			return 0;
		case 'v':
			cout << CZNC::GetTag() << endl;
			return 0;
		case 'n':
			CUtils::SetStdoutIsTTY(false);
			break;
		case 'r':
			bAllowRoot = true;
			break;
		case 'c':
			bMakeConf = true;
			break;
		case 's':
			bMakePass = true;
			break;
#ifdef HAVE_LIBSSL
		case 'p':
			bMakePem = true;
			break;
		case 'e':
			bEncPem = true;
			break;
#endif /* HAVE_LIBSSL */
		case 'd':
			sDataDir = CString(optarg);
			break;
		case '?':
		default:
			GenerateHelp(argv[0]);
			return 1;
	    }
	}

	if (optind < argc) {
		sConfig = argv[optind];
	} else {
		sConfig = "znc.conf";
	}

	CZNC* pZNC = &CZNC::Get();
	pZNC->InitDirs(((argc) ? argv[0] : ""), sDataDir);

#ifdef HAVE_LIBSSL
	if (bMakePem) {
		pZNC->WritePemFile(bEncPem);

		delete pZNC;
		return 0;
	}
	if (bEncPem && !bMakePem) {
		CUtils::PrintError("--encrypt-pem should be used along with --makepem.");
		return 1;
	}

#endif /* HAVE_LIBSSL */
	if (bMakePass) {
		CString sSalt;
		CString sHash = CUtils::GetSaltedHashPass(sSalt);
		CUtils::PrintMessage("Use this in the <User> section of your config:");
		CUtils::PrintMessage("Pass = md5#" + sHash + "#" + sSalt + "#");

		return 0;
	}

	if (bMakeConf) {
		if (pZNC->WriteNewConfig(sConfig)) {
			char const* args[5];

			if (argc > 2) {
				args[0] = argv[0];
				if (!sDataDir.empty()) {
					args[1] = "--datadir";
					args[2] = strdup(sDataDir.c_str());
					args[3] = argv[optind];
					args[4] = NULL;
				} else {
					args[1] = argv[optind];
					args[2] = NULL;
				}
			} else if (argc > 1) {
				args[0] = argv[0];
				if (!sDataDir.empty()) {
					args[1] = "--datadir";
					args[2] = strdup(sDataDir.c_str());
					args[3] = NULL;
				} else {
					args[1] = NULL;
				}
			} else {
				CUtils::PrintError("Unable to launch znc [Try manually restarting]");
				return 1;
			}

			if ((chdir(pZNC->GetCurPath().c_str()) == -1)
					|| (execv(*argv, (char *const*)args) == -1)) {
				CUtils::PrintError("Unable to launch znc [" + CString(strerror(errno)) + "]");
				return 1;
			}
		}

		return 0;
	}

	if (!pZNC->ParseConfig(sConfig)) {
		CUtils::PrintError("Unrecoverable config error.");
		delete pZNC;
		return 1;
	}

	if (!pZNC->OnBoot()) {
		CUtils::PrintError("Exiting due to module boot errors.");
		delete pZNC;
		return 1;
	}

	if (isRoot()) {
		CUtils::PrintError("You are running ZNC as root! Don't do that! There are not many valid");
		CUtils::PrintError("reasons for this and it can, in theory, cause great damage!");
		if (!bAllowRoot) {
			exit(1);
		}
		CUtils::PrintError("You have been warned.");
		CUtils::PrintError("Hit CTRL+C now if you don't want to run ZNC as root.");
		CUtils::PrintError("ZNC will start in 30 seconds.");
		sleep(30);
	}

#ifdef _DEBUG
	int iPid = getpid();
	CUtils::PrintMessage("Staying open for debugging [pid: " + CString(iPid) + "]");

	pZNC->WritePidFile(iPid);
	CUtils::PrintMessage(CZNC::GetTag());
#else
	CUtils::PrintAction("Forking into the background");

	int iPid = fork();

	if (iPid == -1) {
		CUtils::PrintStatus(false, strerror(errno));
		delete pZNC;
		exit(1);
	}

	if (iPid > 0) {
		// We are the parent. We are done and will go to bed.
		CUtils::PrintStatus(true, "[pid: " + CString(iPid) + "]");

		pZNC->WritePidFile(iPid);
		CUtils::PrintMessage(CZNC::GetTag());
		exit(0);
	}

	// Redirect std in/out/err to /dev/null
	close(0); open("/dev/null", O_RDONLY);
	close(1); open("/dev/null", O_WRONLY);
	close(2); open("/dev/null", O_WRONLY);

	CUtils::SetStdoutIsTTY(false);

	// We are the child. There is no way we can be a process group
	// leader, thus setsid() must succeed.
	setsid();
	// Now we are in our own process group and session (no controlling
	// terminal). We are independent!
#endif

	struct sigaction sa;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	sa.sa_handler = SIG_IGN;
	sigaction(SIGPIPE, &sa, (struct sigaction*) NULL);

	sa.sa_handler = rehash;
	sigaction(SIGHUP,  &sa, (struct sigaction*) NULL);

	// Once this signal is caught, the signal handler is reset
	// to SIG_DFL. This avoids endless loop with signals.
	sa.sa_flags = SA_RESETHAND;
	sa.sa_handler = die;
	sigaction(SIGINT,  &sa, (struct sigaction*) NULL);
	sigaction(SIGILL,  &sa, (struct sigaction*) NULL);
	sigaction(SIGQUIT, &sa, (struct sigaction*) NULL);
	sigaction(SIGBUS,  &sa, (struct sigaction*) NULL);
	sigaction(SIGSEGV, &sa, (struct sigaction*) NULL);
	sigaction(SIGTERM, &sa, (struct sigaction*) NULL);

	int iRet = 0;

	try {
		iRet = pZNC->Loop();
	} catch (CException e) {
		// EX_Shutdown is thrown to exit
		switch (e.GetType()) {
			case CException::EX_Shutdown:
				iRet = 0;
			default:
				iRet = 1;
		}
	}

	delete pZNC;

	return iRet;
}
<|endoftext|>


<commit_before>//Game is now divided into modules

#include "Game.h"
#include <iostream>

int main(int argc, char* argv[])
{
	std::cout << "game init attempt...\n";
	if (TheGame::Instance()->init("Chapter 1", 100, 100, 640, 480, false))
	{
		std::cout << "game init success!\n";
		while (TheGame::Instance()->running())
		{
			TheGame::Instance()->handleEvents();
			TheGame::Instance()->update();
			TheGame::Instance()->render();

			SDL_Delay(10);
		}
	}
	else
	{
		std::cout << "game init failure - " << SDL_GetError() << "\n";
		return -1;
	}

	return 0;
}<commit_msg>added "game closing..." output in main()<commit_after>//Game is now divided into modules

#include "Game.h"
#include <iostream>

int main(int argc, char* argv[])
{
	std::cout << "game init attempt...\n";
	if (TheGame::Instance()->init("Chapter 1", 100, 100, 640, 480, false))
	{
		std::cout << "game init success!\n";
		while (TheGame::Instance()->running())
		{
			TheGame::Instance()->handleEvents();
			TheGame::Instance()->update();
			TheGame::Instance()->render();

			SDL_Delay(10);
		}
	}
	else
	{
		std::cout << "game init failure - " << SDL_GetError() << "\n";
		return -1;
	}

	std::cout << "game closing...\n";
	TheGame::Instance()->clean();

	return 0;
}<|endoftext|>


<commit_before>efda7654-2747-11e6-b2a4-e0f84713e7b8<commit_msg>Long commit messages are not required<commit_after>eff10740-2747-11e6-88dc-e0f84713e7b8<|endoftext|>


<commit_before>64c4bfd1-2749-11e6-823b-e0f84713e7b8<commit_msg>GOD DAMNED IT!<commit_after>64d27f26-2749-11e6-b1d1-e0f84713e7b8<|endoftext|>