<commit_before>/*
 * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
 */

#include "entry_p.h"

#if ENTRY_CONFIG_USE_NATIVE && (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI)

#define XK_MISCELLANY
#define XK_LATIN1
#include <X11/keysymdef.h>
#include <bgfxplatform.h> // will include X11 which #defines None... Don't mess with order of includes.

#undef None
#include <bx/thread.h>
#include <bx/os.h>
#include <string.h> // memset

namespace entry
{
	static uint8_t s_translateKey[512];

	static void initTranslateKey(uint16_t _xk, Key::Enum _key)
	{
		_xk += 256;
		BX_CHECK(_xk < BX_COUNTOF(s_translateKey), "Out of bounds %d.", _xk);
		s_translateKey[_xk&0x1ff] = (uint8_t)_key;
	}

	Key::Enum fromXk(uint16_t _xk)
	{
		_xk += 256;
		return 512 > _xk ? (Key::Enum)s_translateKey[_xk] : Key::None;
	}

	struct MainThreadEntry
	{
		int m_argc;
		char** m_argv;

		static int32_t threadFunc(void* _userData);
	};

	struct Context
	{
		Context()
			: m_modifiers(Modifier::None)
			, m_exit(false)
		{
			memset(s_translateKey, 0, sizeof(s_translateKey) );
			initTranslateKey(XK_Escape,       Key::Esc);
			initTranslateKey(XK_Return,       Key::Return);
			initTranslateKey(XK_Tab,          Key::Tab);
			initTranslateKey(XK_BackSpace,    Key::Backspace);
			initTranslateKey(XK_space,        Key::Space);
			initTranslateKey(XK_Up,           Key::Up);
			initTranslateKey(XK_Down,         Key::Down);
			initTranslateKey(XK_Left,         Key::Left);
			initTranslateKey(XK_Right,        Key::Right);
			initTranslateKey(XK_Page_Up,      Key::PageUp);
			initTranslateKey(XK_Page_Down,    Key::PageUp);
			initTranslateKey(XK_Home,         Key::Home);
			initTranslateKey(XK_KP_End,       Key::End);
			initTranslateKey(XK_Print,        Key::Print);
			initTranslateKey(XK_equal,        Key::Plus);
			initTranslateKey(XK_minus,        Key::Minus);
			initTranslateKey(XK_F1,           Key::F1);
			initTranslateKey(XK_F2,           Key::F2);
			initTranslateKey(XK_F3,           Key::F3);
			initTranslateKey(XK_F4,           Key::F4);
			initTranslateKey(XK_F5,           Key::F5);
			initTranslateKey(XK_F6,           Key::F6);
			initTranslateKey(XK_F7,           Key::F7);
			initTranslateKey(XK_F8,           Key::F8);
			initTranslateKey(XK_F9,           Key::F9);
			initTranslateKey(XK_F10,          Key::F10);
			initTranslateKey(XK_F11,          Key::F11);
			initTranslateKey(XK_F12,          Key::F12);
			initTranslateKey(XK_KP_Insert,    Key::NumPad0);
			initTranslateKey(XK_KP_End,       Key::NumPad1);
			initTranslateKey(XK_KP_Down,      Key::NumPad2);
			initTranslateKey(XK_KP_Page_Down, Key::NumPad3);
			initTranslateKey(XK_KP_Left,      Key::NumPad4);
			initTranslateKey(XK_KP_Begin,     Key::NumPad5);
			initTranslateKey(XK_KP_Right,     Key::NumPad6);
			initTranslateKey(XK_KP_Home,      Key::NumPad7);
			initTranslateKey(XK_KP_Up,        Key::NumPad8);
			initTranslateKey(XK_KP_Page_Up,   Key::NumPad9);
			initTranslateKey('0',             Key::Key0);
			initTranslateKey('1',             Key::Key1);
			initTranslateKey('2',             Key::Key2);
			initTranslateKey('3',             Key::Key3);
			initTranslateKey('4',             Key::Key4);
			initTranslateKey('5',             Key::Key5);
			initTranslateKey('6',             Key::Key6);
			initTranslateKey('7',             Key::Key7);
			initTranslateKey('8',             Key::Key8);
			initTranslateKey('9',             Key::Key9);
			initTranslateKey('a',             Key::KeyA);
			initTranslateKey('b',             Key::KeyB);
			initTranslateKey('c',             Key::KeyC);
			initTranslateKey('d',             Key::KeyD);
			initTranslateKey('e',             Key::KeyE);
			initTranslateKey('f',             Key::KeyF);
			initTranslateKey('g',             Key::KeyG);
			initTranslateKey('h',             Key::KeyH);
			initTranslateKey('i',             Key::KeyI);
			initTranslateKey('j',             Key::KeyJ);
			initTranslateKey('k',             Key::KeyK);
			initTranslateKey('l',             Key::KeyL);
			initTranslateKey('m',             Key::KeyM);
			initTranslateKey('n',             Key::KeyN);
			initTranslateKey('o',             Key::KeyO);
			initTranslateKey('p',             Key::KeyP);
			initTranslateKey('q',             Key::KeyQ);
			initTranslateKey('r',             Key::KeyR);
			initTranslateKey('s',             Key::KeyS);
			initTranslateKey('t',             Key::KeyT);
			initTranslateKey('u',             Key::KeyU);
			initTranslateKey('v',             Key::KeyV);
			initTranslateKey('w',             Key::KeyW);
			initTranslateKey('x',             Key::KeyX);
			initTranslateKey('y',             Key::KeyY);
			initTranslateKey('z',             Key::KeyZ);
		}

		int32_t run(int _argc, char** _argv)
		{
			XInitThreads();
			m_display = XOpenDisplay(0);

			int32_t screen = DefaultScreen(m_display);
			int32_t depth = DefaultDepth(m_display, screen);
			Visual* visual = DefaultVisual(m_display, screen);
			Window root = RootWindow(m_display, screen);

			XSetWindowAttributes windowAttrs;
			memset(&windowAttrs, 0, sizeof(windowAttrs) );
			windowAttrs.background_pixmap = 0;
			windowAttrs.border_pixel = 0;
			windowAttrs.event_mask = 0
					| ButtonPressMask
					| ButtonReleaseMask
					| ExposureMask
					| KeyPressMask
					| KeyReleaseMask
					| PointerMotionMask
					| ResizeRedirectMask
					| StructureNotifyMask
					;

			m_window = XCreateWindow(m_display
									, root
									, 0, 0
									, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, 0, depth
									, InputOutput
									, visual
									, CWBorderPixel|CWEventMask
									, &windowAttrs
									);

			const char *wmDeleteWindowName = "WM_DELETE_WINDOW";
			Atom wmDeleteWindow;
			XInternAtoms(m_display, (char **)&wmDeleteWindowName, 1, False, &wmDeleteWindow);
			XSetWMProtocols(m_display, m_window, &wmDeleteWindow, 1);

			XMapWindow(m_display, m_window);
			XStoreName(m_display, m_window, "BGFX");

			bgfx::x11SetDisplayWindow(m_display, m_window);

			MainThreadEntry mte;
			mte.m_argc = _argc;
			mte.m_argv = _argv;

			bx::Thread thread;
			thread.init(mte.threadFunc, &mte);

			while (!m_exit)
			{
				if (XPending(m_display) )
				{
					XEvent event;
					XNextEvent(m_display, &event);

					switch (event.type)
					{
						case Expose:
							break;

						case ConfigureNotify:
							break;

						case ClientMessage:
							if((Atom)event.xclient.data.l[0] == wmDeleteWindow)
							{
								m_eventQueue.postExitEvent();
							}
							break;

						case ButtonPress:
						case ButtonRelease:
							{
								const XButtonEvent& xbutton = event.xbutton;
								MouseButton::Enum mb;
								switch (xbutton.button)
								{
									case Button1: mb = MouseButton::Left;   break;
									case Button2: mb = MouseButton::Middle; break;
									case Button3: mb = MouseButton::Right;  break;
									default:      mb = MouseButton::None;   break;
								}

								if (MouseButton::None != mb)
								{
									m_eventQueue.postMouseEvent(xbutton.x
										, xbutton.y
										, 0
										, mb
										, event.type == ButtonPress
										);
								}
							}
							break;

						case MotionNotify:
							{
								const XMotionEvent& xmotion = event.xmotion;
								m_eventQueue.postMouseEvent(xmotion.x
										, xmotion.y
										, 0
										);
							}
							break;

						case KeyPress:
						case KeyRelease:
							{
								XKeyEvent& xkey = event.xkey;
								KeySym keysym = XLookupKeysym(&xkey, 0);
								switch (keysym)
								{
								case XK_Meta_L:    setModifier(Modifier::LeftMeta,   KeyPress == event.type); break;
								case XK_Meta_R:    setModifier(Modifier::RightMeta,  KeyPress == event.type); break;
								case XK_Control_L: setModifier(Modifier::LeftCtrl,   KeyPress == event.type); break;
								case XK_Control_R: setModifier(Modifier::RightCtrl,  KeyPress == event.type); break;
								case XK_Shift_L:   setModifier(Modifier::LeftShift,  KeyPress == event.type); break;
								case XK_Shift_R:   setModifier(Modifier::RightShift, KeyPress == event.type); break;
								case XK_Alt_L:     setModifier(Modifier::LeftAlt,    KeyPress == event.type); break;
								case XK_Alt_R:     setModifier(Modifier::RightAlt,   KeyPress == event.type); break;

								default:
									{
										Key::Enum key = fromXk(keysym);
										if (Key::None != key)
										{
											m_eventQueue.postKeyEvent(key, m_modifiers, KeyPress == event.type);
										}
									}
									break;
								}
							}
							break;

						case ResizeRequest:
							{
								const XResizeRequestEvent& xresize = event.xresizerequest;
								XResizeWindow(m_display, m_window, xresize.width, xresize.height);
							}
							break;
					}
				}
			}

			thread.shutdown();

			XUnmapWindow(m_display, m_window);
			XDestroyWindow(m_display, m_window);

			return EXIT_SUCCESS;
		}

		void setModifier(Modifier::Enum _modifier, bool _set)
		{
			m_modifiers &= ~_modifier;
			m_modifiers |= _set ? _modifier : 0;
		}

		uint8_t m_modifiers;
		Display* m_display;
		Window m_window;
		bool m_exit;

		EventQueue m_eventQueue;
	};

	static Context s_ctx;

	int32_t MainThreadEntry::threadFunc(void* _userData)
	{
		MainThreadEntry* self = (MainThreadEntry*)_userData;
		int32_t result = main(self->m_argc, self->m_argv);
		s_ctx.m_exit = true;
		return result;
	}

	const Event* poll()
	{
		return s_ctx.m_eventQueue.poll();
	}

	void release(const Event* _event)
	{
		s_ctx.m_eventQueue.release(_event);
	}

	void setWindowSize(uint32_t _width, uint32_t _height)
	{
		XResizeRequestEvent ev;
		ev.type = ResizeRequest;
		ev.serial = 0;
		ev.send_event = true;
		ev.display = s_ctx.m_display;
		ev.window = s_ctx.m_window;
		ev.width = (int)_width;
		ev.height = (int)_height;
		XSendEvent(s_ctx.m_display, s_ctx.m_window, false, ResizeRedirectMask, (XEvent*)&ev);
	}

	void setWindowTitle(const char* _title)
	{
		BX_UNUSED(_title);
	}

	void toggleWindowFrame()
	{
	}

	void setMouseLock(bool _lock)
	{
		BX_UNUSED(_lock);
	}

} // namespace entry

int main(int _argc, char** _argv)
{
	using namespace entry;
	return s_ctx.run(_argc, _argv);
}

#endif // ENTRY_CONFIG_USE_NATIVE && (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI)
<commit_msg>Fixed x11.<commit_after>/*
 * Copyright 2011-2014 Branimir Karadzic. All rights reserved.
 * License: http://www.opensource.org/licenses/BSD-2-Clause
 */

#include "entry_p.h"

#if ENTRY_CONFIG_USE_NATIVE && (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI)

#define XK_MISCELLANY
#define XK_LATIN1
#include <X11/keysymdef.h>
#include <bgfxplatform.h> // will include X11 which #defines None... Don't mess with order of includes.

#undef None
#include <bx/thread.h>
#include <bx/os.h>
#include <string.h> // memset

namespace entry
{
	static uint8_t s_translateKey[512];

	static void initTranslateKey(uint16_t _xk, Key::Enum _key)
	{
		_xk += 256;
		BX_CHECK(_xk < BX_COUNTOF(s_translateKey), "Out of bounds %d.", _xk);
		s_translateKey[_xk&0x1ff] = (uint8_t)_key;
	}

	Key::Enum fromXk(uint16_t _xk)
	{
		_xk += 256;
		return 512 > _xk ? (Key::Enum)s_translateKey[_xk] : Key::None;
	}

	struct MainThreadEntry
	{
		int m_argc;
		char** m_argv;

		static int32_t threadFunc(void* _userData);
	};

	struct Context
	{
		Context()
			: m_modifiers(Modifier::None)
			, m_exit(false)
		{
			memset(s_translateKey, 0, sizeof(s_translateKey) );
			initTranslateKey(XK_Escape,       Key::Esc);
			initTranslateKey(XK_Return,       Key::Return);
			initTranslateKey(XK_Tab,          Key::Tab);
			initTranslateKey(XK_BackSpace,    Key::Backspace);
			initTranslateKey(XK_space,        Key::Space);
			initTranslateKey(XK_Up,           Key::Up);
			initTranslateKey(XK_Down,         Key::Down);
			initTranslateKey(XK_Left,         Key::Left);
			initTranslateKey(XK_Right,        Key::Right);
			initTranslateKey(XK_Page_Up,      Key::PageUp);
			initTranslateKey(XK_Page_Down,    Key::PageUp);
			initTranslateKey(XK_Home,         Key::Home);
			initTranslateKey(XK_KP_End,       Key::End);
			initTranslateKey(XK_Print,        Key::Print);
			initTranslateKey(XK_equal,        Key::Plus);
			initTranslateKey(XK_minus,        Key::Minus);
			initTranslateKey(XK_F1,           Key::F1);
			initTranslateKey(XK_F2,           Key::F2);
			initTranslateKey(XK_F3,           Key::F3);
			initTranslateKey(XK_F4,           Key::F4);
			initTranslateKey(XK_F5,           Key::F5);
			initTranslateKey(XK_F6,           Key::F6);
			initTranslateKey(XK_F7,           Key::F7);
			initTranslateKey(XK_F8,           Key::F8);
			initTranslateKey(XK_F9,           Key::F9);
			initTranslateKey(XK_F10,          Key::F10);
			initTranslateKey(XK_F11,          Key::F11);
			initTranslateKey(XK_F12,          Key::F12);
			initTranslateKey(XK_KP_Insert,    Key::NumPad0);
			initTranslateKey(XK_KP_End,       Key::NumPad1);
			initTranslateKey(XK_KP_Down,      Key::NumPad2);
			initTranslateKey(XK_KP_Page_Down, Key::NumPad3);
			initTranslateKey(XK_KP_Left,      Key::NumPad4);
			initTranslateKey(XK_KP_Begin,     Key::NumPad5);
			initTranslateKey(XK_KP_Right,     Key::NumPad6);
			initTranslateKey(XK_KP_Home,      Key::NumPad7);
			initTranslateKey(XK_KP_Up,        Key::NumPad8);
			initTranslateKey(XK_KP_Page_Up,   Key::NumPad9);
			initTranslateKey('0',             Key::Key0);
			initTranslateKey('1',             Key::Key1);
			initTranslateKey('2',             Key::Key2);
			initTranslateKey('3',             Key::Key3);
			initTranslateKey('4',             Key::Key4);
			initTranslateKey('5',             Key::Key5);
			initTranslateKey('6',             Key::Key6);
			initTranslateKey('7',             Key::Key7);
			initTranslateKey('8',             Key::Key8);
			initTranslateKey('9',             Key::Key9);
			initTranslateKey('a',             Key::KeyA);
			initTranslateKey('b',             Key::KeyB);
			initTranslateKey('c',             Key::KeyC);
			initTranslateKey('d',             Key::KeyD);
			initTranslateKey('e',             Key::KeyE);
			initTranslateKey('f',             Key::KeyF);
			initTranslateKey('g',             Key::KeyG);
			initTranslateKey('h',             Key::KeyH);
			initTranslateKey('i',             Key::KeyI);
			initTranslateKey('j',             Key::KeyJ);
			initTranslateKey('k',             Key::KeyK);
			initTranslateKey('l',             Key::KeyL);
			initTranslateKey('m',             Key::KeyM);
			initTranslateKey('n',             Key::KeyN);
			initTranslateKey('o',             Key::KeyO);
			initTranslateKey('p',             Key::KeyP);
			initTranslateKey('q',             Key::KeyQ);
			initTranslateKey('r',             Key::KeyR);
			initTranslateKey('s',             Key::KeyS);
			initTranslateKey('t',             Key::KeyT);
			initTranslateKey('u',             Key::KeyU);
			initTranslateKey('v',             Key::KeyV);
			initTranslateKey('w',             Key::KeyW);
			initTranslateKey('x',             Key::KeyX);
			initTranslateKey('y',             Key::KeyY);
			initTranslateKey('z',             Key::KeyZ);
		}

		int32_t run(int _argc, char** _argv)
		{
			XInitThreads();
			m_display = XOpenDisplay(0);

			int32_t screen = DefaultScreen(m_display);
			int32_t depth = DefaultDepth(m_display, screen);
			Visual* visual = DefaultVisual(m_display, screen);
			Window root = RootWindow(m_display, screen);

			XSetWindowAttributes windowAttrs;
			memset(&windowAttrs, 0, sizeof(windowAttrs) );
			windowAttrs.background_pixmap = 0;
			windowAttrs.border_pixel = 0;
			windowAttrs.event_mask = 0
					| ButtonPressMask
					| ButtonReleaseMask
					| ExposureMask
					| KeyPressMask
					| KeyReleaseMask
					| PointerMotionMask
					| ResizeRedirectMask
					| StructureNotifyMask
					;

			m_window = XCreateWindow(m_display
									, root
									, 0, 0
									, ENTRY_DEFAULT_WIDTH, ENTRY_DEFAULT_HEIGHT, 0, depth
									, InputOutput
									, visual
									, CWBorderPixel|CWEventMask
									, &windowAttrs
									);

			const char *wmDeleteWindowName = "WM_DELETE_WINDOW";
			Atom wmDeleteWindow;
			XInternAtoms(m_display, (char **)&wmDeleteWindowName, 1, False, &wmDeleteWindow);
			XSetWMProtocols(m_display, m_window, &wmDeleteWindow, 1);

			XMapWindow(m_display, m_window);
			XStoreName(m_display, m_window, "BGFX");

			bgfx::x11SetDisplayWindow(m_display, m_window);

			MainThreadEntry mte;
			mte.m_argc = _argc;
			mte.m_argv = _argv;

			bx::Thread thread;
			thread.init(mte.threadFunc, &mte);

			WindowHandle defaultWindow = { 0 };

			while (!m_exit)
			{
				if (XPending(m_display) )
				{
					XEvent event;
					XNextEvent(m_display, &event);

					switch (event.type)
					{
						case Expose:
							break;

						case ConfigureNotify:
							break;

						case ClientMessage:
							if((Atom)event.xclient.data.l[0] == wmDeleteWindow)
							{
								m_eventQueue.postExitEvent();
							}
							break;

						case ButtonPress:
						case ButtonRelease:
							{
								const XButtonEvent& xbutton = event.xbutton;
								MouseButton::Enum mb;
								switch (xbutton.button)
								{
									case Button1: mb = MouseButton::Left;   break;
									case Button2: mb = MouseButton::Middle; break;
									case Button3: mb = MouseButton::Right;  break;
									default:      mb = MouseButton::None;   break;
								}

								if (MouseButton::None != mb)
								{
									m_eventQueue.postMouseEvent(defaultWindow
										, xbutton.x
										, xbutton.y
										, 0
										, mb
										, event.type == ButtonPress
										);
								}
							}
							break;

						case MotionNotify:
							{
								const XMotionEvent& xmotion = event.xmotion;
								m_eventQueue.postMouseEvent(defaultWindow
										, xmotion.x
										, xmotion.y
										, 0
										);
							}
							break;

						case KeyPress:
						case KeyRelease:
							{
								XKeyEvent& xkey = event.xkey;
								KeySym keysym = XLookupKeysym(&xkey, 0);
								switch (keysym)
								{
								case XK_Meta_L:    setModifier(Modifier::LeftMeta,   KeyPress == event.type); break;
								case XK_Meta_R:    setModifier(Modifier::RightMeta,  KeyPress == event.type); break;
								case XK_Control_L: setModifier(Modifier::LeftCtrl,   KeyPress == event.type); break;
								case XK_Control_R: setModifier(Modifier::RightCtrl,  KeyPress == event.type); break;
								case XK_Shift_L:   setModifier(Modifier::LeftShift,  KeyPress == event.type); break;
								case XK_Shift_R:   setModifier(Modifier::RightShift, KeyPress == event.type); break;
								case XK_Alt_L:     setModifier(Modifier::LeftAlt,    KeyPress == event.type); break;
								case XK_Alt_R:     setModifier(Modifier::RightAlt,   KeyPress == event.type); break;

								default:
									{
										Key::Enum key = fromXk(keysym);
										if (Key::None != key)
										{
											m_eventQueue.postKeyEvent(defaultWindow, key, m_modifiers, KeyPress == event.type);
										}
									}
									break;
								}
							}
							break;

						case ResizeRequest:
							{
								const XResizeRequestEvent& xresize = event.xresizerequest;
								XResizeWindow(m_display, m_window, xresize.width, xresize.height);
							}
							break;
					}
				}
			}

			thread.shutdown();

			XUnmapWindow(m_display, m_window);
			XDestroyWindow(m_display, m_window);

			return EXIT_SUCCESS;
		}

		void setModifier(Modifier::Enum _modifier, bool _set)
		{
			m_modifiers &= ~_modifier;
			m_modifiers |= _set ? _modifier : 0;
		}

		uint8_t m_modifiers;
		Display* m_display;
		Window m_window;
		bool m_exit;

		EventQueue m_eventQueue;
	};

	static Context s_ctx;

	int32_t MainThreadEntry::threadFunc(void* _userData)
	{
		MainThreadEntry* self = (MainThreadEntry*)_userData;
		int32_t result = main(self->m_argc, self->m_argv);
		s_ctx.m_exit = true;
		return result;
	}

	const Event* poll()
	{
		return s_ctx.m_eventQueue.poll();
	}

	void release(const Event* _event)
	{
		s_ctx.m_eventQueue.release(_event);
	}

	void setWindowSize(WindowHandle _handle, uint32_t _width, uint32_t _height)
	{
		BX_UNUSED(_handle);
		XResizeRequestEvent ev;
		ev.type = ResizeRequest;
		ev.serial = 0;
		ev.send_event = true;
		ev.display = s_ctx.m_display;
		ev.window = s_ctx.m_window;
		ev.width = (int)_width;
		ev.height = (int)_height;
		XSendEvent(s_ctx.m_display, s_ctx.m_window, false, ResizeRedirectMask, (XEvent*)&ev);
	}

	void setWindowTitle(WindowHandle _handle, const char* _title)
	{
		BX_UNUSED(_handle, _title);
	}

	void toggleWindowFrame(WindowHandle _handle)
	{
		BX_UNUSED(_handle);
	}

	void setMouseLock(WindowHandle _handle, bool _lock)
	{
		BX_UNUSED(_handle, _lock);
	}

} // namespace entry

int main(int _argc, char** _argv)
{
	using namespace entry;
	return s_ctx.run(_argc, _argv);
}

#endif // ENTRY_CONFIG_USE_NATIVE && (BX_PLATFORM_FREEBSD || BX_PLATFORM_LINUX || BX_PLATFORM_RPI)
<|endoftext|>


<commit_before>#ifndef APPLICATION_H
#define APPLICATION_H

#include <glbinding/Binding.h>
#include <glbinding/gl/gl.h>
#define GLFW_INCLUDE_NONE

#include "EditorScene.hpp"
#include "Logger.hpp"
#include "Renderer.hpp"
#include "Scene.hpp"
#include "Window.hpp"
#include "input.hpp"
#include <GLFW/glfw3.h>
#include <SWI-cpp.h>
#include <functional>
#include <iostream>
#include <physfs.h>
#include <queue>
#include <sstream>
#include <stdexcept>
#include <unordered_set>

class Application final {
	private:
	std::shared_ptr<Window> m_window;
	Renderer                m_renderer;

	struct KeyHash {
		std::size_t operator()(const std::pair<int, int>& key) const {
			// Requires the pair to be ordered as (key, modifiers)
			return key.first << 4 | key.second;
		}
	};
	static std::mutex s_keyQueueMutex;
	static std::unordered_set<std::pair<int, int>, KeyHash> s_keysPressed;
	static std::queue<KeyEvent> s_keyQueue;

	static std::mutex                   s_buttonQueueMutex;
	static std::queue<MouseButtonEvent> s_buttonQueue;

	static std::mutex                     s_movementQueueMutex;
	static std::queue<MouseMovementEvent> s_movementQueue;

	void initFilesystem(int argc, char** argv);

	static void
	key_callback(GLFWwindow*, int key, int, int action, int modifiers);
	static void
	mouse_button_callback(GLFWwindow*, int button, int action, int mods);
	static void
	cursor_position_callback(GLFWwindow* window, double xpos, double ypos);

	void processInput();
	void draw();

	Scene* m_scene; // TODO: Temporary variable for dev. purposes. Remove.

	public:
	Application(int argc, char** argv);
	Application(const Application&) = delete;
	Application& operator=(const Application&) = delete;
	~Application();

	void run();
};

#endif
<commit_msg>Hash/input-type documentation<commit_after>#ifndef APPLICATION_H
#define APPLICATION_H

#include <glbinding/Binding.h>
#include <glbinding/gl/gl.h>
#define GLFW_INCLUDE_NONE

#include "EditorScene.hpp"
#include "Logger.hpp"
#include "Renderer.hpp"
#include "Scene.hpp"
#include "Window.hpp"
#include "input.hpp"
#include <GLFW/glfw3.h>
#include <SWI-cpp.h>
#include <functional>
#include <iostream>
#include <physfs.h>
#include <queue>
#include <sstream>
#include <stdexcept>
#include <unordered_set>

class Application final {
	private:
	std::shared_ptr<Window> m_window;
	Renderer                m_renderer;

	struct KeyHash {
		// Hash function appends 4-bit modifier to 8-bit ASCII key code
		// Requires the pair to be ordered as (key, modifiers)
		std::size_t operator()(const std::pair<int, int>& key) const {
			return key.first << 4 | key.second;
		}
	};
	static std::mutex s_keyQueueMutex;
	static std::unordered_set<std::pair<int, int>, KeyHash> s_keysPressed;
	static std::queue<KeyEvent> s_keyQueue;

	static std::mutex                   s_buttonQueueMutex;
	static std::queue<MouseButtonEvent> s_buttonQueue;

	static std::mutex                     s_movementQueueMutex;
	static std::queue<MouseMovementEvent> s_movementQueue;

	void initFilesystem(int argc, char** argv);

	static void
	key_callback(GLFWwindow*, int key, int, int action, int modifiers);
	static void
	mouse_button_callback(GLFWwindow*, int button, int action, int mods);
	static void
	cursor_position_callback(GLFWwindow* window, double xpos, double ypos);

	void processInput();
	void draw();

	Scene* m_scene; // TODO: Temporary variable for dev. purposes. Remove.

	public:
	Application(int argc, char** argv);
	Application(const Application&) = delete;
	Application& operator=(const Application&) = delete;
	~Application();

	void run();
};

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>

using namespace std;
using namespace boost;

// vector<string> split(string input)       // split strings because of spaces
// {                                        // and semicolons
// 	vector<string> result;               // Other applicable symbols are
// 	                                     // also accounted for.
// 	int j = 0;
// 	int countSpaces = 0;
// 	int countSemicolons = 0;
// 	int countComments = 0;

// 	result.push_back("");

// 	for (int i = 0; i < input.size(); ++i)
// 	{
// 		if (input.at(i) != ' ' && input.at(i) != ';' && input.at(i) != '#')
// 		{
// 			countSpaces = 0;
// 			countSemicolons = 0;
// 			result.at(j) = result.at(j) + input.at(i);
// 		}
// 		else if (input.at(i) == ' ')    // make sure duplicate spaces do not
// 		{                               // count
// 			++countSpaces;
// 			if (countSpaces == 1)
// 			{
// 				++j;
// 				result.push_back("");
// 			}
// 		}

// 		else if (input.at(i) == ';')
// 		{
// 			++countSemicolons;

// 			if (countSemicolons > 1)
// 			{
// 				cout << "Error: Multiple semicolons." << endl;
// 				exit(0);
// 			}
// 			else
// 			{
// 				++j;
// 				result.push_back(";");
// 			}
// 		}

// 		else if (input.at(i) == '#')
// 		{
// 			++countComments;

// 			if (countComments >= 1)
// 			{

// 			}
// 		}
// 	}

// 	return result;
// }

class BaseConnector
{

	public:
		virtual ~BaseConnector() = 0;

};

// Virtual destructor that needs a function body.
BaseConnector::~BaseConnector()
{

}

int main(int argc, char *argv[])
{
	char command_prompt = '$';		// Used to prompt commands
	bool loop = true;               // If it should continue running, then true

	string input;                   // used to read the inputs, including spaces
	vector<string> result;

	cout << command_prompt << ' ';
	while (loop)
	{

		getline(cin, input);

		// Resize the string if there are any # symbols
		for (int i = 0; i < input.size(); ++i)
		{
			if (input.at(i) == '#')
			{
				input.resize(i);
			}
		}

		char_separator<char> separation("; ");
		tokenizer< char_separator<char> > token_text(input, separation);
		BOOST_FOREACH (const string &t, token_text)
		{
			result.push_back(t);
		}

		for (int i = 0; i < result.size(); ++i)   // for debugging split
		{                                         // vector
			cout << result.at(i) << i << endl;
		}

		if (input == "exit")
		{
			loop = false;
		}

		if (loop == true)
		{
			cout << command_prompt << ' ';
		}
	}

	return 0;
}
<commit_msg>Added comments feature<commit_after>// Franklin Yang
// lab 2

// Given specification, design a system
// Use vim

// Submit your code: 1) ilearn
// OR
// email at darvisha@cs.ucr.edu
// Deadline: Friday 5pm
// THursday 1:00 pm

// Compile:
// g++ test.c -o test
// ./test

#include <iostream>
#include <string>
#include <vector>
using namespace std;

class Vehicle {
    private:
        double speed_per_hour;
        string vehicleName;

    public:

        void inputSpeed(double speed)
        {
            speed_per_hour = speed;
        }

        void inputVehicleName(string vName)
        {
            vehicleName = vName;
        }

        double getSpeed()
        {
            return speed_per_hour;
        }

        string getVehicleName()
        {
            return vehicleName;
        }

        // Output name of vehicle
        void go(double timeHours)
        {
            cout << vehicleName << ": " << timeHours * speed_per_hour << endl;
        }
};

class Land: public Vehicle {
    private:
        int number_of_wheels;
        int number_of_seats;

    public:
        void modify_wheels(int numWheels)
        {
            number_of_wheels = numWheels;
        }

        void modify_seats(int numSeats)
        {
            number_of_seats = numSeats;
        }

        int check_wheels()
        {
            return number_of_wheels;
        }

        int check_seats()
        {
            return number_of_seats;
        }
};

class Air: public Vehicle {
    private:

    public:

};

class Water: public Vehicle {
    private:
        int number_of_seats;
        int number_of_doors;
    public:
        void modify_seats(int numSeats)
        {
            number_of_seats = numSeats;
        }
        void modify_doors(int numDoors)
        {
            number_of_doors = numDoors;
        }
        int check_seats()
        {
            return number_of_seats;
        }
        int check_doors()
        {
            return number_of_doors;
        }
};

class Bus: public Land {

    private:
        int number_of_doors;
        double fare;

    public:

        Bus()
        {
            number_of_doors = 2;
            modify_seats(40);
            modify_wheels(6);
            fare = 1.25;
            inputSpeed(50);
            inputVehicleName("Bus");
        }

};

class Coup: public Land {

    private:
        int number_of_doors;

    public:
        Coup()
        {
            number_of_doors = 2;
            modify_seats(4);
            modify_wheels(4);
            inputSpeed(120);
            inputVehicleName("Coup");
        }

};

class Sedan: public Land {
    private:
        int number_of_doors;

    public:
        Sedan()
        {
            number_of_doors = 4;
            modify_seats(4);
            modify_wheels(4);
            inputSpeed(100);
            inputVehicleName("Sedan");
        }
};

class Motorcycle: public Land {
    private:

    public:
        Motorcycle()
        {
            modify_seats(1);
            modify_wheels(2);
            inputSpeed(80);
            inputVehicleName("Motorcycle");
        }
};

class Bicycle: public Land {
    private:

    public:
        Bicycle()
        {
            modify_seats(1);
            modify_wheels(2);
            inputSpeed(25.25);
            inputVehicleName("Bicycle");
        }
};

// The hover board, implied by its name, should be an air vehicle.
// However, it has wheels, so that makes it that the two provided air vehicles
// have only speed in common.
class Hoverboard: public Air {
    private:
        int number_of_wheels;
    public:
        Hoverboard()
        {
            number_of_wheels = 4;
            inputSpeed(30.00);
            inputVehicleName("Hover board");
        }

};

class Paddleboat: public Water {
    private:
        string shape_of_boat;
    public:
        Paddleboat()
        {
            modify_seats(2);
            modify_doors(2);
            inputSpeed(10.00);
            shape_of_boat = "swan";
            inputVehicleName("Paddleboat");
        }
};

class FalconRocket: public Air {
    private:
        int number_of_seats;
        int number_of_doors;
        int tons_of_fuel;
        int tons_of_payload;

    public:
        FalconRocket()
        {
            number_of_seats = 6;
            number_of_doors = 1;
            tons_of_fuel = 9000;
            tons_of_payload = 2000;
            inputSpeed(2112662.054);
            inputVehicleName("Falcon Rocket");
        }

};

class Airplane: public Air {
    private:
        int number_of_seats;
        int number_of_doors;
        int number_of_wheels;
    public:
        Airplane()
        {
            number_of_seats = 500;
            number_of_doors = 6;
            number_of_wheels = 18
            inputSpeed(550);
            inputVehicleName("Passenger Plane");
        }
};

class Forklift: public Land {
    private:
        int max_weight_kg;
    public:
        Forklift()
        {
            modify_seats(1);
            modify_wheels(4);
            max_weight_kg = 10000;
            inputSpeed(25);
            inputVehicleName("Forklift");
        }
};

class Jet: public Air {
    private:
        int number_of_seats;
    public:
        Jet()
        {
            number_of_seats = 2;
            inputSpeed(7200);
            inputVehicleName("Jet");
        }
};

int main()
{
    vector<Vehicle> vehicleVector;
    Bus bus1;
    Coup coup1;
    Sedan sedan1;
    Motorcycle motorcycle1;
    Bicycle bicycle1;
    Hoverboard hoverboard1;
    Paddleboat paddleboat1;
    FalconRocket falconrocket1;

    Airplane airplane1;
    Forklift forklift1;
    Jet jet1;

    vehicleVector.push_back(bus1);
    vehicleVector.push_back(coup1);
    vehicleVector.push_back(sedan1);
    vehicleVector.push_back(motorcycle1);
    vehicleVector.push_back(bicycle1);
    vehicleVector.push_back(hoverboard1);
    vehicleVector.push_back(paddleboat1);
    vehicleVector.push_back(falconrocket1);

    vehicleVector.push_back(airplane1);
    vehicleVector.push_back(forklift1);
    vehicleVector.push_back(jet1);

    int inputTime;

    cout << "Please input the time: ";
    cin >> inputTime;

    for (int i = 0; i < vehicleVector.size(); ++i)
    {
        vehicleVector.at(i).go(inputTime);
    }

    return 0;
}

// Part A: Why did you design the system like this?

// SI units?

// Part B: What decisions that you made in part A made it difficult to extend?

// Part C: What did you add, and how is that different from A and B?

// http://www.cplusplus.com/doc/tutorial/inheritance/<|endoftext|>


<commit_before>/**
 * (c) 2016 David "Danilaw" Soria Parra
 * vim: set ts=2 sts=2 sw=2 expandtab:
 */
#ifdef HAVE_COLLECTD
extern "C" {
#define HAVE_ENDIAN_H 1
#include <endian.h>
#include <stdint.h>
#include <stdbool.h>
#include <collectd/liboconfig/oconfig.h>
#include <collectd/core/daemon/collectd.h>
#include <collectd/core/daemon/common.h> /* auxiliary functions */
#include <collectd/core/daemon/plugin.h> /* plugin_register_*, plugin_dispatch_values */
}
#endif

#include <cstdlib>
#include <memory>
#include <string>

#include "collector.h"

// static const char * PLUGIN_NAME = "mumble";
#define PLUGIN_NAME "mumble"

static const char *config_keys[] = {"IceHost", "IcePort", "IceSecret"};
static std::string ice_host = "";
static std::string ice_secret = "";
static uint32_t ice_port = 6502;
static int config_keys_num = sizeof(config_keys);

MumbleCollector *collector = nullptr;

#ifdef HAVE_COLLECTD
static int my_config(const char *key, const char *value) {
  if (strcmp(key, "IcePort") == 0) {
    auto mport = strtol(key, nullptr, 10);
    assert(mport > 0 && mport < 65536);
    ice_port = static_cast<uint32_t>(mport);
    return 0;
  }

  if (strcmp(key, "IceHost") == 0) {
    ice_host = std::string(value);
    return 0;
  }

  if (strcmp(key, "IceSecret") == 0) {
    ice_secret = std::string(value);
    return 0;
  }
  return 1;
}

static int my_init(void) {
  collector = new MumbleCollector(ice_host, ice_port, ice_secret);
  return 0;
}

static int my_shutdown(void) {
  if (collector) {
    delete collector;
  }
  return 0;
}

static int my_read(void) {
  value_t values[1];
  value_list_t vl = VALUE_LIST_INIT;

  values[0].gauge = collector->getUserCount();

  vl.values = values;
  vl.values_len = STATIC_ARRAY_SIZE(values);
  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
  sstrncpy(vl.plugin, PLUGIN_NAME, sizeof(vl.plugin));
  sstrncpy(vl.type, "count", sizeof(vl.type));
  plugin_dispatch_values(&vl);
  return 0;
}

/**
 * Definition for the datatype to be used by collectd
 */
static data_source_t mumble_dsrc[] = {{"count", DS_TYPE_GAUGE, 0, NAN}};
static data_set_t mumble_ds = {PLUGIN_NAME, STATIC_ARRAY_SIZE(mumble_dsrc),
                               mumble_dsrc};

extern "C" {
void module_register() {
  plugin_register_data_set(&mumble_ds);
  plugin_register_config(PLUGIN_NAME, my_config, config_keys, config_keys_num);
  plugin_register_init(PLUGIN_NAME, my_init);
  plugin_register_shutdown(PLUGIN_NAME, my_shutdown);
  plugin_register_read(PLUGIN_NAME, my_read);
}
}

#else

int main(int argc, char **argv) {
  MumbleCollector collector;
  std::cout << collector.getUserCount() << std::endl;
  return 0;
}
#endif
<commit_msg>default host is 127.0.0.1<commit_after>/**
 * (c) 2016 David "Danilaw" Soria Parra
 * vim: set ts=2 sts=2 sw=2 expandtab:
 */
#ifdef HAVE_COLLECTD
extern "C" {
#define HAVE_ENDIAN_H 1
#include <endian.h>
#include <stdint.h>
#include <stdbool.h>
#include <collectd/liboconfig/oconfig.h>
#include <collectd/core/daemon/collectd.h>
#include <collectd/core/daemon/common.h> /* auxiliary functions */
#include <collectd/core/daemon/plugin.h> /* plugin_register_*, plugin_dispatch_values */
}
#endif

#include <cstdlib>
#include <memory>
#include <string>

#include "collector.h"

// static const char * PLUGIN_NAME = "mumble";
#define PLUGIN_NAME "mumble"

static const char *config_keys[] = {"IceHost", "IcePort", "IceSecret"};
static std::string ice_host = "127.0.0.1";
static std::string ice_secret = "";
static uint32_t ice_port = 6502;
static int config_keys_num = sizeof(config_keys);

MumbleCollector *collector = nullptr;

#ifdef HAVE_COLLECTD
static int my_config(const char *key, const char *value) {
  if (strcmp(key, "IcePort") == 0) {
    auto mport = strtol(key, nullptr, 10);
    assert(mport > 0 && mport < 65536);
    ice_port = static_cast<uint32_t>(mport);
    return 0;
  }

  if (strcmp(key, "IceHost") == 0) {
    ice_host = std::string(value);
    return 0;
  }

  if (strcmp(key, "IceSecret") == 0) {
    ice_secret = std::string(value);
    return 0;
  }
  return 1;
}

static int my_init(void) {
  collector = new MumbleCollector(ice_host, ice_port, ice_secret);
  return 0;
}

static int my_shutdown(void) {
  if (collector) {
    delete collector;
  }
  return 0;
}

static int my_read(void) {
  value_t values[1];
  value_list_t vl = VALUE_LIST_INIT;

  values[0].gauge = collector->getUserCount();

  vl.values = values;
  vl.values_len = STATIC_ARRAY_SIZE(values);
  sstrncpy(vl.host, hostname_g, sizeof(vl.host));
  sstrncpy(vl.plugin, PLUGIN_NAME, sizeof(vl.plugin));
  sstrncpy(vl.type, "count", sizeof(vl.type));
  plugin_dispatch_values(&vl);
  return 0;
}

/**
 * Definition for the datatype to be used by collectd
 */
static data_source_t mumble_dsrc[] = {{"count", DS_TYPE_GAUGE, 0, NAN}};
static data_set_t mumble_ds = {PLUGIN_NAME, STATIC_ARRAY_SIZE(mumble_dsrc),
                               mumble_dsrc};

extern "C" {
void module_register() {
  plugin_register_data_set(&mumble_ds);
  plugin_register_config(PLUGIN_NAME, my_config, config_keys, config_keys_num);
  plugin_register_init(PLUGIN_NAME, my_init);
  plugin_register_shutdown(PLUGIN_NAME, my_shutdown);
  plugin_register_read(PLUGIN_NAME, my_read);
}
}

#else

int main(int argc, char **argv) {
  MumbleCollector collector;
  std::cout << collector.getUserCount() << std::endl;
  return 0;
}
#endif
<|endoftext|>


<commit_before>/*
 * Author: doe300
 *
 * See the file "LICENSE" for the full license governing this code.
 */

#include "./optimization/Optimizer.h"
#include "Compiler.h"
#include "Precompiler.h"
#include "Profiler.h"
#include "concepts.h"
#include "config.h"
#include "git_commit.h"
#include "log.h"
#include "precompilation/FrontendCompiler.h"
#include "tool_paths.h"
#include "tools.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <unistd.h>
#include <unordered_map>

using namespace std;
using namespace vc4c;

extern void disassemble(const std::string& input, const std::string& output, OutputMode outputMode);

static void printHelp()
{
    vc4c::Configuration defaultConfig;
    std::cout << "Usage: vc4c [flags] [options] -o <destination> <sources>" << std::endl;
    std::cout << "flags:" << std::endl;
    std::cout << "\t-h, --help\t\tPrints this help message and exits" << std::endl;
    std::cout << "\t-v, --version\t\tPrints version and build info and exists" << std::endl;
    std::cout << "\t--verbose\t\tEnables verbose debug logging" << std::endl;
    std::cout << "\t--quiet\t\t\tQuiet verbose debug logging" << std::endl;
    std::cout << "\t-l, --log <file>\tWrite log output to the given file, defaults to stdout ('-')" << std::endl;
    std::cout << "\t--hex\t\t\tGenerate hex output (e.g. included in source-code)" << std::endl;
    std::cout << "\t--bin\t\t\tGenerate binary output (as used by VC4CL run-time)" << std::endl;
    std::cout << "\t--asm\t\t\tGenerate assembler output (for analysis only)" << std::endl;

    std::cout << "optimizations:" << std::endl;
    std::cout << "\t-O0,-O1,-O2,-O3\t\t\tSwitches to the specific optimization level, defaults to -O2" << std::endl;
    std::map<std::string, std::string> sortedPasses;
    for(const auto& pass : vc4c::optimizations::Optimizer::ALL_PASSES)
        sortedPasses.emplace(pass.parameterName, pass.description);
    for(const auto& pass : sortedPasses)
    {
        std::cout << "\t--f" << std::left << std::setw(28) << pass.first << pass.second << std::endl;
        // TODO print which optimization level includes optimization
        std::cout << "\t--fno-" << std::left << std::setw(25) << pass.first << "Disables the above optimization"
                  << std::endl;
    }

    std::cout << "optimization parameters:" << std::endl;
    std::cout << "\t--fcombine-load-threshold=" << defaultConfig.additionalOptions.combineLoadThreshold
              << "\tThe maximum distance between two literal loads to combine" << std::endl;
    std::cout << "\t--faccumulator-threshold=" << defaultConfig.additionalOptions.accumulatorThreshold
              << "\tThe maximum live-range of a local still considered to be mapped to an accumulator" << std::endl;
    std::cout << "\t--freplace-nop-threshold=" << defaultConfig.additionalOptions.replaceNopThreshold
              << "\tThe number of instructions to search for a replacement for NOPs" << std::endl;
    std::cout << "\t--foptimization-iterations=" << defaultConfig.additionalOptions.maxOptimizationIterations
              << "\tThe maximum number of iterations to repeat the optimizations in" << std::endl;
    std::cout << "\t--fcommon-subexpression-threshold=" << defaultConfig.additionalOptions.maxCommonExpressionDinstance
              << "\tThe maximum distance for two common subexpressions to be combined" << std::endl;

    std::cout << "options:" << std::endl;
    std::cout << "\t--kernel-info\t\tWrite the kernel-info meta-data (as required by VC4CL run-time, default)"
              << std::endl;
    std::cout << "\t--no-kernel-info\tDont write the kernel-info meta-data" << std::endl;
    std::cout << "\t--spirv\t\t\tExplicitely use the SPIR-V front-end" << std::endl;
    std::cout << "\t--llvm\t\t\tExplicitely use the LLVM-IR front-end" << std::endl;
    std::cout << "\t--verification-error\tAbort if instruction verification failed" << std::endl;
    std::cout << "\t--no-verification-error\tContinue if instruction verification failed" << std::endl;
    std::cout << "\tany other option is passed to the pre-compiler" << std::endl;

    std::cout << "modes:" << std::endl;
    std::cout << "(modes completely change the behavior of the program and therefore only support a limited number of "
                 "options)"
              << std::endl;
    std::cout << "\t--disassemble\t\tDisassembles the binary input to either hex or assembler output. Only supports "
                 "the input-, output- and logging-flags listed above."
              << std::endl;
    std::cout << "\t--precompile-stdlib\tPre-compiles the the VC4CLStdLib.h header file given as input "
                 "into the folder specified as output. Ignores all other options except for the logging flags"
              << std::endl;
}

static std::string toVersionString(unsigned version)
{
    std::stringstream s;
    s << (static_cast<float>(version) / 10.0f);
    return s.str();
}

static void printInfo()
{
    std::cout << "Running VC4C in version: " << VC4C_VERSION << " (" << GIT_COMMIT << ')' << std::endl;
    std::cout << "Build configuration: ";
    static const std::vector<std::string> infoString = {
#ifndef NDEBUG
        "debug mode",
#endif
#ifdef SPIRV_TOOLS_FRONTEND
        "SPIR-V Tools front-end",
#else
        "builtin SPIR-V front-end",
#endif
#ifdef USE_LLVM_LIBRARY
        std::string("LLVM library front-end with libLLVM ") + toVersionString(LLVM_LIBRARY_VERSION),
#endif
#ifdef SPIRV_TOOLS_FRONTEND
        "SPIR-V linker",
#endif
#ifdef VERIFIER_HEADER
        "vc4asm verification",
#endif
#ifdef USE_CLANG_LIBRARY
        "compilation with clang library"
#endif
    };
    std::cout << vc4c::to_string<std::string>(infoString, std::string{"; "}) << '\n' << std::endl;

    std::cout << "Standard library location:" << std::endl;
    try
    {
        auto stdlib = precompilation::findStandardLibraryFiles();
        std::cout << "\theader in " << stdlib.configurationHeader << std::endl;
        std::cout << "\tPCH in " << stdlib.precompiledHeader << std::endl;
        std::cout << "\tLLVM module in " << stdlib.llvmModule << std::endl;
        std::cout << "\tSPIR-V module in " << stdlib.spirvModule << std::endl;
    }
    catch(const std::exception& err)
    {
        std::cout << "Failed to find standard library files!" << std::endl;
        std::cout << err.what() << std::endl;
    }

    std::cout << "Tool locations:" << std::endl;
    for(const auto& tool : std::vector<FrontendTool>{
            CLANG_TOOL, SPIRV_LLVM_SPIRV_TOOL, LLVM_LINK_TOOL, LLVM_DIS_TOOL, LLVM_AS_TOOL, SPIRV_LINK_TOOL})
    {
        if(auto tool_found = precompilation::findToolLocation(tool))
        {
            std::cout << "\t" << tool.name << " in " << *tool_found << " (default"
                      << (tool_found == std::string{tool.defaultPath} ? ")" :
                                                                        (" '" + std::string{tool.defaultPath} + "')"))
                      << std::endl;
        }
        else
            std::cout << "\t" << tool.name << " not in "
                      << (tool.hasDefaultPath() ? (std::string{tool.defaultPath} + ", neither in ") : "") << "$PATH"
                      << std::endl;
    }
}

static auto availableOptimizations = vc4c::optimizations::Optimizer::getPasses(OptimizationLevel::FULL);

/*
 *
 */
int main(int argc, char** argv)
{
    std::unique_ptr<std::wofstream> fileLog;
    std::reference_wrapper<std::wostream> logStream = std::wcout;
    bool colorLog = true;
#ifndef NDEBUG
    LogLevel minLevel = LogLevel::DEBUG;
#else
    LogLevel minLevel = LogLevel::WARNING;
#endif

    Configuration config;
    std::vector<std::string> inputFiles;
    std::string outputFile;
    std::string options;
    bool runDisassembler = false;
    bool precompileStdlib = false;
    std::wstringstream dummyLogOutput;

    if(argc == 1)
    {
        printHelp();
        return 0;
    }

    for(int i = 1; i < argc; ++i)
    {
        // treat an argument, which first character isnt "-", as an input file
        if(strcmp(argv[i - 1], "-D") == 0 || strcmp(argv[i - 1], "-U") == 0 || strcmp(argv[i - 1], "-I") == 0)
        {
            // ... with exception if they are preceded by an '-D', '-U' or '-I', then forward them to the front-end
            options.append(argv[i]).append(" ");
        }
        else if(argv[i][0] != '-')
        {
            inputFiles.emplace_back(argv[i]);
        }

        // flags
        else if(strcmp("--help", argv[i]) == 0 || strcmp("-h", argv[i]) == 0)
        {
            printHelp();
            return 0;
        }
        else if(strcmp("--version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0)
        {
            // disable all logging to not break our version output
            setLogger(dummyLogOutput, false, LogLevel::SEVERE);
            printInfo();
            return 0;
        }
        else if(strcmp("--quiet", argv[i]) == 0)
            minLevel = LogLevel::WARNING;
        else if(strcmp("--verbose", argv[i]) == 0)
            minLevel = LogLevel::DEBUG;
        else if(strcmp("--log", argv[i]) == 0 || strcmp("-l", argv[i]) == 0)
        {
            if(strcmp("-", argv[i + 1]) == 0)
            {
                colorLog = true;
                logStream = std::wcout;
            }
            else
            {
                colorLog = false;
                fileLog = std::make_unique<std::wofstream>(argv[i + 1]);
                logStream = *fileLog;
            }
            ++i;
        }
        else if(strcmp("--disassemble", argv[i]) == 0)
            runDisassembler = true;
        else if(strcmp("--precompile-stdlib", argv[i]) == 0)
            precompileStdlib = true;
        else if(strcmp("-o", argv[i]) == 0)
        {
            if(i + 1 == argc)
            {
                std::cerr << "No output file specified after -o, aborting!" << std::endl;
                return 7;
            }

            outputFile = argv[i + 1];

            // increment `i` more than usual, because argv[i + 1] is already consumed
            i += 1;
        }
        else if(!vc4c::tools::parseConfigurationParameter(config, argv[i]) || strstr(argv[i], "-cl") == argv[i])
            // pass every not understood option to the pre-compiler, as well as every OpenCL compiler option
            options.append(argv[i]).append(" ");
    }

    if(&logStream.get() == &std::wcout && outputFile == "-")
    {
        std::cerr << "Cannot write both log and data to stdout, aborting" << std::endl;
        return 6;
    }
    setLogger(logStream, colorLog, minLevel);

    if(inputFiles.empty())
    {
        std::cerr << "No input file(s) specified, aborting!" << std::endl;
        return 2;
    }
    if(outputFile.empty())
    {
        // special case: if input files is just one, we specify the implicit output file.
        std::string postfix;
        if(inputFiles.size() == 1)
        {
            switch(config.outputMode)
            {
            case OutputMode::BINARY:
                postfix = ".bin";
                break;
            case OutputMode::HEX:
                postfix = ".hex";
                break;
            case OutputMode::ASSEMBLER:
                postfix = ".s";
                break;
            }
            outputFile = inputFiles[0] + postfix;
        }
        else
        {
            std::cerr << "No output file specified, aborting!" << std::endl;
            std::cerr << "NOTE: If multiple files are inputed, specifying output file is MUST." << std::endl;
            return 3;
        }
    }

    if(runDisassembler)
    {
        if(inputFiles.size() != 1)
        {
            std::cerr << "For disassembling, a single input file must be specified, aborting!" << std::endl;
            return 4;
        }
        CPPLOG_LAZY(logging::Level::DEBUG,
            log << "Disassembling '" << inputFiles[0] << "' into '" << outputFile << "'..." << logging::endl);
        disassemble(inputFiles[0], outputFile, config.outputMode);
        return 0;
    }
    if(precompileStdlib)
    {
        if(inputFiles.size() != 1)
        {
            std::cerr
                << "For pre-compiling the VC4CL standard library, a single input file must be specified, aborting!"
                << std::endl;
            return 5;
        }
        CPPLOG_LAZY(logging::Level::DEBUG,
            log << "Pre-compiling '" << inputFiles[0] << "' into '" << outputFile << "'..." << logging::endl);
        precompilation::precompileStandardLibraryFiles(inputFiles[0], outputFile);
        return 0;
    }

    CPPLOG_LAZY(logging::Level::DEBUG,
        log << "Compiling '" << to_string<std::string>(inputFiles, std::string{"', '"}) << "' into '" << outputFile
            << "' with optimization level " << static_cast<unsigned>(config.optimizationLevel) << " and options '"
            << options << "' ..." << logging::endl);

    CompilationData input{};
    // link if necessary
    if(inputFiles.size() > 1)
    {
        std::vector<CompilationData> inputs;
        for(const std::string& file : inputFiles)
        {
            inputs.emplace_back(CompilationData{file});
        }
        input = Precompiler::linkSourceCode(inputs);
        if(!isSupportedByFrontend(input.getType(), config.frontend))
        {
            std::cerr << "Selected front-end does not support the input-format generated by the linker, aborting! "
                      << std::endl;
            return 5;
        }
    }
    else
    {
        input = CompilationData{inputFiles[0]};
    }

    PROFILE_START(Compiler);
    std::ignore = Compiler::compile(input, config, options, outputFile == "-" ? "/dev/stdout" : outputFile);
    PROFILE_END(Compiler);

    PROFILE_RESULTS();
    return 0;
}
<commit_msg>Fix error for tools without default paths<commit_after>/*
 * Author: doe300
 *
 * See the file "LICENSE" for the full license governing this code.
 */

#include "./optimization/Optimizer.h"
#include "Compiler.h"
#include "Precompiler.h"
#include "Profiler.h"
#include "concepts.h"
#include "config.h"
#include "git_commit.h"
#include "log.h"
#include "precompilation/FrontendCompiler.h"
#include "tool_paths.h"
#include "tools.h"

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iomanip>
#include <sstream>
#include <string>
#include <unistd.h>
#include <unordered_map>

using namespace std;
using namespace vc4c;

extern void disassemble(const std::string& input, const std::string& output, OutputMode outputMode);

static void printHelp()
{
    vc4c::Configuration defaultConfig;
    std::cout << "Usage: vc4c [flags] [options] -o <destination> <sources>" << std::endl;
    std::cout << "flags:" << std::endl;
    std::cout << "\t-h, --help\t\tPrints this help message and exits" << std::endl;
    std::cout << "\t-v, --version\t\tPrints version and build info and exists" << std::endl;
    std::cout << "\t--verbose\t\tEnables verbose debug logging" << std::endl;
    std::cout << "\t--quiet\t\t\tQuiet verbose debug logging" << std::endl;
    std::cout << "\t-l, --log <file>\tWrite log output to the given file, defaults to stdout ('-')" << std::endl;
    std::cout << "\t--hex\t\t\tGenerate hex output (e.g. included in source-code)" << std::endl;
    std::cout << "\t--bin\t\t\tGenerate binary output (as used by VC4CL run-time)" << std::endl;
    std::cout << "\t--asm\t\t\tGenerate assembler output (for analysis only)" << std::endl;

    std::cout << "optimizations:" << std::endl;
    std::cout << "\t-O0,-O1,-O2,-O3\t\t\tSwitches to the specific optimization level, defaults to -O2" << std::endl;
    std::map<std::string, std::string> sortedPasses;
    for(const auto& pass : vc4c::optimizations::Optimizer::ALL_PASSES)
        sortedPasses.emplace(pass.parameterName, pass.description);
    for(const auto& pass : sortedPasses)
    {
        std::cout << "\t--f" << std::left << std::setw(28) << pass.first << pass.second << std::endl;
        // TODO print which optimization level includes optimization
        std::cout << "\t--fno-" << std::left << std::setw(25) << pass.first << "Disables the above optimization"
                  << std::endl;
    }

    std::cout << "optimization parameters:" << std::endl;
    std::cout << "\t--fcombine-load-threshold=" << defaultConfig.additionalOptions.combineLoadThreshold
              << "\tThe maximum distance between two literal loads to combine" << std::endl;
    std::cout << "\t--faccumulator-threshold=" << defaultConfig.additionalOptions.accumulatorThreshold
              << "\tThe maximum live-range of a local still considered to be mapped to an accumulator" << std::endl;
    std::cout << "\t--freplace-nop-threshold=" << defaultConfig.additionalOptions.replaceNopThreshold
              << "\tThe number of instructions to search for a replacement for NOPs" << std::endl;
    std::cout << "\t--foptimization-iterations=" << defaultConfig.additionalOptions.maxOptimizationIterations
              << "\tThe maximum number of iterations to repeat the optimizations in" << std::endl;
    std::cout << "\t--fcommon-subexpression-threshold=" << defaultConfig.additionalOptions.maxCommonExpressionDinstance
              << "\tThe maximum distance for two common subexpressions to be combined" << std::endl;

    std::cout << "options:" << std::endl;
    std::cout << "\t--kernel-info\t\tWrite the kernel-info meta-data (as required by VC4CL run-time, default)"
              << std::endl;
    std::cout << "\t--no-kernel-info\tDont write the kernel-info meta-data" << std::endl;
    std::cout << "\t--spirv\t\t\tExplicitely use the SPIR-V front-end" << std::endl;
    std::cout << "\t--llvm\t\t\tExplicitely use the LLVM-IR front-end" << std::endl;
    std::cout << "\t--verification-error\tAbort if instruction verification failed" << std::endl;
    std::cout << "\t--no-verification-error\tContinue if instruction verification failed" << std::endl;
    std::cout << "\tany other option is passed to the pre-compiler" << std::endl;

    std::cout << "modes:" << std::endl;
    std::cout << "(modes completely change the behavior of the program and therefore only support a limited number of "
                 "options)"
              << std::endl;
    std::cout << "\t--disassemble\t\tDisassembles the binary input to either hex or assembler output. Only supports "
                 "the input-, output- and logging-flags listed above."
              << std::endl;
    std::cout << "\t--precompile-stdlib\tPre-compiles the the VC4CLStdLib.h header file given as input "
                 "into the folder specified as output. Ignores all other options except for the logging flags"
              << std::endl;
}

static std::string toVersionString(unsigned version)
{
    std::stringstream s;
    s << (static_cast<float>(version) / 10.0f);
    return s.str();
}

static void printInfo()
{
    std::cout << "Running VC4C in version: " << VC4C_VERSION << " (" << GIT_COMMIT << ')' << std::endl;
    std::cout << "Build configuration: ";
    static const std::vector<std::string> infoString = {
#ifndef NDEBUG
        "debug mode",
#endif
#ifdef SPIRV_TOOLS_FRONTEND
        "SPIR-V Tools front-end",
#else
        "builtin SPIR-V front-end",
#endif
#ifdef USE_LLVM_LIBRARY
        std::string("LLVM library front-end with libLLVM ") + toVersionString(LLVM_LIBRARY_VERSION),
#endif
#ifdef SPIRV_TOOLS_FRONTEND
        "SPIR-V linker",
#endif
#ifdef VERIFIER_HEADER
        "vc4asm verification",
#endif
#ifdef USE_CLANG_LIBRARY
        "compilation with clang library"
#endif
    };
    std::cout << vc4c::to_string<std::string>(infoString, std::string{"; "}) << '\n' << std::endl;

    std::cout << "Standard library location:" << std::endl;
    try
    {
        auto stdlib = precompilation::findStandardLibraryFiles();
        std::cout << "\theader in " << stdlib.configurationHeader << std::endl;
        std::cout << "\tPCH in " << stdlib.precompiledHeader << std::endl;
        std::cout << "\tLLVM module in " << stdlib.llvmModule << std::endl;
        std::cout << "\tSPIR-V module in " << stdlib.spirvModule << std::endl;
    }
    catch(const std::exception& err)
    {
        std::cout << "Failed to find standard library files!" << std::endl;
        std::cout << err.what() << std::endl;
    }

    std::cout << "Tool locations:" << std::endl;
    for(const auto& tool : std::vector<FrontendTool>{
            CLANG_TOOL, SPIRV_LLVM_SPIRV_TOOL, LLVM_LINK_TOOL, LLVM_DIS_TOOL, LLVM_AS_TOOL, SPIRV_LINK_TOOL})
    {
        if(auto tool_found = precompilation::findToolLocation(tool))
        {
            std::string defaultPath = tool.defaultPath ? tool.defaultPath : "";
            std::cout << "\t" << tool.name << " in " << *tool_found << " (default"
                      << (!defaultPath.empty() && tool_found == defaultPath ? ")" : (" '" + defaultPath + "')"))
                      << std::endl;
        }
        else
            std::cout << "\t" << tool.name << " not in "
                      << (tool.hasDefaultPath() ? (std::string{tool.defaultPath} + ", neither in ") : "") << "$PATH"
                      << std::endl;
    }
}

static auto availableOptimizations = vc4c::optimizations::Optimizer::getPasses(OptimizationLevel::FULL);

/*
 *
 */
int main(int argc, char** argv)
{
    std::unique_ptr<std::wofstream> fileLog;
    std::reference_wrapper<std::wostream> logStream = std::wcout;
    bool colorLog = true;
#ifndef NDEBUG
    LogLevel minLevel = LogLevel::DEBUG;
#else
    LogLevel minLevel = LogLevel::WARNING;
#endif

    Configuration config;
    std::vector<std::string> inputFiles;
    std::string outputFile;
    std::string options;
    bool runDisassembler = false;
    bool precompileStdlib = false;
    std::wstringstream dummyLogOutput;

    if(argc == 1)
    {
        printHelp();
        return 0;
    }

    for(int i = 1; i < argc; ++i)
    {
        // treat an argument, which first character isnt "-", as an input file
        if(strcmp(argv[i - 1], "-D") == 0 || strcmp(argv[i - 1], "-U") == 0 || strcmp(argv[i - 1], "-I") == 0)
        {
            // ... with exception if they are preceded by an '-D', '-U' or '-I', then forward them to the front-end
            options.append(argv[i]).append(" ");
        }
        else if(argv[i][0] != '-')
        {
            inputFiles.emplace_back(argv[i]);
        }

        // flags
        else if(strcmp("--help", argv[i]) == 0 || strcmp("-h", argv[i]) == 0)
        {
            printHelp();
            return 0;
        }
        else if(strcmp("--version", argv[i]) == 0 || strcmp("-v", argv[i]) == 0)
        {
            // disable all logging to not break our version output
            setLogger(dummyLogOutput, false, LogLevel::SEVERE);
            printInfo();
            return 0;
        }
        else if(strcmp("--quiet", argv[i]) == 0)
            minLevel = LogLevel::WARNING;
        else if(strcmp("--verbose", argv[i]) == 0)
            minLevel = LogLevel::DEBUG;
        else if(strcmp("--log", argv[i]) == 0 || strcmp("-l", argv[i]) == 0)
        {
            if(strcmp("-", argv[i + 1]) == 0)
            {
                colorLog = true;
                logStream = std::wcout;
            }
            else
            {
                colorLog = false;
                fileLog = std::make_unique<std::wofstream>(argv[i + 1]);
                logStream = *fileLog;
            }
            ++i;
        }
        else if(strcmp("--disassemble", argv[i]) == 0)
            runDisassembler = true;
        else if(strcmp("--precompile-stdlib", argv[i]) == 0)
            precompileStdlib = true;
        else if(strcmp("-o", argv[i]) == 0)
        {
            if(i + 1 == argc)
            {
                std::cerr << "No output file specified after -o, aborting!" << std::endl;
                return 7;
            }

            outputFile = argv[i + 1];

            // increment `i` more than usual, because argv[i + 1] is already consumed
            i += 1;
        }
        else if(!vc4c::tools::parseConfigurationParameter(config, argv[i]) || strstr(argv[i], "-cl") == argv[i])
            // pass every not understood option to the pre-compiler, as well as every OpenCL compiler option
            options.append(argv[i]).append(" ");
    }

    if(&logStream.get() == &std::wcout && outputFile == "-")
    {
        std::cerr << "Cannot write both log and data to stdout, aborting" << std::endl;
        return 6;
    }
    setLogger(logStream, colorLog, minLevel);

    if(inputFiles.empty())
    {
        std::cerr << "No input file(s) specified, aborting!" << std::endl;
        return 2;
    }
    if(outputFile.empty())
    {
        // special case: if input files is just one, we specify the implicit output file.
        std::string postfix;
        if(inputFiles.size() == 1)
        {
            switch(config.outputMode)
            {
            case OutputMode::BINARY:
                postfix = ".bin";
                break;
            case OutputMode::HEX:
                postfix = ".hex";
                break;
            case OutputMode::ASSEMBLER:
                postfix = ".s";
                break;
            }
            outputFile = inputFiles[0] + postfix;
        }
        else
        {
            std::cerr << "No output file specified, aborting!" << std::endl;
            std::cerr << "NOTE: If multiple files are inputed, specifying output file is MUST." << std::endl;
            return 3;
        }
    }

    if(runDisassembler)
    {
        if(inputFiles.size() != 1)
        {
            std::cerr << "For disassembling, a single input file must be specified, aborting!" << std::endl;
            return 4;
        }
        CPPLOG_LAZY(logging::Level::DEBUG,
            log << "Disassembling '" << inputFiles[0] << "' into '" << outputFile << "'..." << logging::endl);
        disassemble(inputFiles[0], outputFile, config.outputMode);
        return 0;
    }
    if(precompileStdlib)
    {
        if(inputFiles.size() != 1)
        {
            std::cerr
                << "For pre-compiling the VC4CL standard library, a single input file must be specified, aborting!"
                << std::endl;
            return 5;
        }
        CPPLOG_LAZY(logging::Level::DEBUG,
            log << "Pre-compiling '" << inputFiles[0] << "' into '" << outputFile << "'..." << logging::endl);
        precompilation::precompileStandardLibraryFiles(inputFiles[0], outputFile);
        return 0;
    }

    CPPLOG_LAZY(logging::Level::DEBUG,
        log << "Compiling '" << to_string<std::string>(inputFiles, std::string{"', '"}) << "' into '" << outputFile
            << "' with optimization level " << static_cast<unsigned>(config.optimizationLevel) << " and options '"
            << options << "' ..." << logging::endl);

    CompilationData input{};
    // link if necessary
    if(inputFiles.size() > 1)
    {
        std::vector<CompilationData> inputs;
        for(const std::string& file : inputFiles)
        {
            inputs.emplace_back(CompilationData{file});
        }
        input = Precompiler::linkSourceCode(inputs);
        if(!isSupportedByFrontend(input.getType(), config.frontend))
        {
            std::cerr << "Selected front-end does not support the input-format generated by the linker, aborting! "
                      << std::endl;
            return 5;
        }
    }
    else
    {
        input = CompilationData{inputFiles[0]};
    }

    PROFILE_START(Compiler);
    std::ignore = Compiler::compile(input, config, options, outputFile == "-" ? "/dev/stdout" : outputFile);
    PROFILE_END(Compiler);

    PROFILE_RESULTS();
    return 0;
}
<|endoftext|>


<commit_before>#include "block.h"
#include "board.h"
#include "game.h"
#include "parser.h"
#include "directoryLoader.h"
#include "featureFile.h"
#include "rprop.h"

#include <stdio.h>

#define HIDDEN_LAYER_SIZE 5

const char usage[] = "Usage: gobot -train modelOutputFile iterations gameDirectory "
                     "[featureDirectory]\n"
                     "             -test modelFile gameDirectory [featureDirectory]\n"
                     "             -predict modelFile gameFile [featureFile]\n"
                     "             -generateFeatures gameDirectory featureDirectory";

int main(int argc, char *argv[])
{
    if(argc < 4)
    {
        printf("%s\n", usage);

        return 1;
    }
    else if(!strcmp(argv[1], "-train"))
    {
        if(argc < 5)
        {
            printf("%s\n", usage);

            return 1;
        }

        int iterations = atoi(argv[3]);

        DirectoryIterator games(argv[4], iterations);

        RProp model(NUMBER_OF_FEATURES, HIDDEN_LAYER_SIZE);

        if(argc > 5)
        {
            model.trainWithFeatures(games, argv[5]);
        }
        else
        {
            model.train(games);
        }

        model.outputToFile(argv[2]);
    }
    else if(!strcmp(argv[1], "-test"))
    {
        DirectoryIterator games(argv[3]);

        RProp model;

        if(!model.readFromFile(argv[2]))
        {
            printf("Couldn't read model from: %s\n", argv[2]);

            return 1;
        }

        if(argc > 4)
        {
            printf("Accuracy: %f%%\n", model.testWithFeatures(games, argv[4]));
        }
        else
        {
            printf("Accuracy: %f%%\n", model.test(games));
        }
    }
    else if(!strcmp(argv[1], "-predict"))
    {
        Game game;

        if(!parseFile(&game, argv[3]))
        {
            printf("Couldn't read game file: %s\n", argv[3]);

            return 1;
        }

        RProp model;

        if(!model.readFromFile(argv[2]))
        {
            printf("Couldn't read model from: %s\n", argv[2]);

            return 1;
        }

        if(argc > 4)
        {
            std::map<BoardLocation, BlockFinalFeatures> featureMap;

            if(!readFeaturesFromFile(featureMap, argv[4]))
            {
                printf("Couldn't read feature file: %s\n", argv[4]);

                return 1;
            }

            printf("Estimate: %f\n", model.predictWithFeatures(game, featureMap));
        }
        else
        {
            printf("Estimate: %f\n", model.predict(game));
        }
    }
    else if(!strcmp(argv[1], "-generateFeatures"))
    {
        char buffer[100];
        int i = 0;
        DirectoryIterator games(argv[2]);

        for( ; games != games.end(); ++games)
        {
            Game game;

            sprintf(buffer, "%s/%s", argv[2], *games);

            if(!parseFile(&game, buffer))
            {
                printf("Couldn't read game file: %s\n", buffer);

                return 1;
            }

            Board board = game.playGame();

            sprintf(buffer, "%s/%sf", argv[3], *games);

            if(!writeFeaturesToFile(board, buffer))
            {
                printf("Could not write the features to: %s\n", buffer);

                return 1;
            }

            if(i % 100 == 0)
            {
                printf(".");
                fflush(stdout);
            }

            ++i;
        }

        printf("\n");
    }
    else
    {
        printf("%s\n", usage);

        return 1;
    }

    return 0;
}
<commit_msg>Update hidden layer size<commit_after>#include "block.h"
#include "board.h"
#include "game.h"
#include "parser.h"
#include "directoryLoader.h"
#include "featureFile.h"
#include "rprop.h"

#include <stdio.h>

#define HIDDEN_LAYER_SIZE 20

const char usage[] = "Usage: gobot -train modelOutputFile iterations gameDirectory "
                     "[featureDirectory]\n"
                     "             -test modelFile gameDirectory [featureDirectory]\n"
                     "             -predict modelFile gameFile [featureFile]\n"
                     "             -generateFeatures gameDirectory featureDirectory";

int main(int argc, char *argv[])
{
    if(argc < 4)
    {
        printf("%s\n", usage);

        return 1;
    }
    else if(!strcmp(argv[1], "-train"))
    {
        if(argc < 5)
        {
            printf("%s\n", usage);

            return 1;
        }

        int iterations = atoi(argv[3]);

        DirectoryIterator games(argv[4], iterations);

        RProp model(NUMBER_OF_FEATURES, HIDDEN_LAYER_SIZE);

        if(argc > 5)
        {
            model.trainWithFeatures(games, argv[5]);
        }
        else
        {
            model.train(games);
        }

        model.outputToFile(argv[2]);
    }
    else if(!strcmp(argv[1], "-test"))
    {
        DirectoryIterator games(argv[3]);

        RProp model;

        if(!model.readFromFile(argv[2]))
        {
            printf("Couldn't read model from: %s\n", argv[2]);

            return 1;
        }

        if(argc > 4)
        {
            printf("Accuracy: %f%%\n", model.testWithFeatures(games, argv[4]));
        }
        else
        {
            printf("Accuracy: %f%%\n", model.test(games));
        }
    }
    else if(!strcmp(argv[1], "-predict"))
    {
        Game game;

        if(!parseFile(&game, argv[3]))
        {
            printf("Couldn't read game file: %s\n", argv[3]);

            return 1;
        }

        RProp model;

        if(!model.readFromFile(argv[2]))
        {
            printf("Couldn't read model from: %s\n", argv[2]);

            return 1;
        }

        if(argc > 4)
        {
            std::map<BoardLocation, BlockFinalFeatures> featureMap;

            if(!readFeaturesFromFile(featureMap, argv[4]))
            {
                printf("Couldn't read feature file: %s\n", argv[4]);

                return 1;
            }

            printf("Estimate: %f\n", model.predictWithFeatures(game, featureMap));
        }
        else
        {
            printf("Estimate: %f\n", model.predict(game));
        }
    }
    else if(!strcmp(argv[1], "-generateFeatures"))
    {
        char buffer[100];
        int i = 0;
        DirectoryIterator games(argv[2]);

        for( ; games != games.end(); ++games)
        {
            Game game;

            sprintf(buffer, "%s/%s", argv[2], *games);

            if(!parseFile(&game, buffer))
            {
                printf("Couldn't read game file: %s\n", buffer);

                return 1;
            }

            Board board = game.playGame();

            sprintf(buffer, "%s/%sf", argv[3], *games);

            if(!writeFeaturesToFile(board, buffer))
            {
                printf("Could not write the features to: %s\n", buffer);

                return 1;
            }

            if(i % 100 == 0)
            {
                printf(".");
                fflush(stdout);
            }

            ++i;
        }

        printf("\n");
    }
    else
    {
        printf("%s\n", usage);

        return 1;
    }

    return 0;
}
<|endoftext|>


<commit_before>// -*- C++ -*-

#pragma once

#include <cstdint>
#include <utility>

namespace OTI
{
    class lcg_PLE63
    {
#pragma region Typedefs/Constants
        public: typedef uint_fast64_t result_type;
        public: typedef result_type   seed_type;

        public: static constexpr result_type  nbits = 63ULL;
        public: static constexpr result_type  mod   = 1ULL << nbits;
        public: static constexpr result_type  mask  = mod - 1ULL;

        // those values are from P.L'Ecuyer "Efficient and Portable Combined RNGs", Comm.ACM 31(6): 742-749, 774 (1988)
        public: static constexpr result_type  mult  = 2806196910506780709ULL;
        public: static constexpr result_type  add   = 1ULL;

        public: static constexpr result_type  default_seed   = 1ULL;

        public: static constexpr float        norm  = float{1.0842021724855044340074528008699e-19};
#pragma endregion

#pragma region Data
        private: mutable seed_type _seed;
#pragma endregion

#pragma region Ctor/Dtor/op=
        public: lcg_PLE63(result_type seed = default_seed):
            _seed{seed}
        {
        }

        public: lcg_PLE63(lcg_PLE63 const& r):
            _seed{r._seed}
        {
        }

        public: lcg_PLE63(lcg_PLE63&& r):
            _seed{std::move(r._seed)}
        {
        }

        public: lcg_PLE63& operator=(lcg_PLE63 const& r)
        {
            _seed = r._seed;
            return *this;
        }

        public: lcg_PLE63& operator=(lcg_PLE63& r)
        {
            _seed = std::move(r._seed);
            return *this;
        }

        public: ~lcg_PLE63()
        {
        }
#pragma endregion

#pragma region Observers
        public: seed_type seed() const
        {
            return _seed;
        }
#pragma endregion

#pragma region Helpers

        // compute and return positive skip
        public: static int64_t compute_nskip(int64_t ns);

        // could skip forward as well as backward
        public: static result_type skip(int64_t ns, seed_type seed);

        public: static result_type sample(seed_type seed)
        {
            return (mult * seed + add) & mask;
        }
#pragma endregion

#pragma region Mutators
        public: void sample() const
        {
            _seed = sample(_seed);
        }

        public: float number() const
        {
            sample();
            return float(_seed) * norm;
        }

        public: void skip(int64_t ns) const
        {
            _seed = skip(ns, _seed);
        }
#pragma endregion
    };
}
<commit_msg>Fixed move op=, some type clean-up<commit_after>// -*- C++ -*-

#pragma once

#include <cstdint>
#include <utility>

namespace OTI
{
    class lcg_PLE63
    {
#pragma region Typedefs/Constants
        public: typedef uint_fast64_t result_type;
        public: typedef result_type   seed_type;

        public: static constexpr result_type  nbits = 63ULL;
        public: static constexpr result_type  mod   = 1ULL << nbits;
        public: static constexpr result_type  mask  = mod - 1ULL;

        // those values are from P.L'Ecuyer "Efficient and Portable Combined RNGs", Comm.ACM 31(6): 742-749, 774 (1988)
        public: static constexpr result_type  mult  = 2806196910506780709ULL;
        public: static constexpr result_type  add   = 1ULL;

        public: static constexpr seed_type  default_seed   = 1ULL;

        public: static constexpr float        norm  = float{1.0842021724855044340074528008699e-19};
#pragma endregion

#pragma region Data
        private: mutable seed_type _seed;
#pragma endregion

#pragma region Ctor/Dtor/op=
        public: lcg_PLE63(seed_type seed = default_seed):
            _seed{seed}
        {
        }

        public: lcg_PLE63(lcg_PLE63 const& r):
            _seed{r._seed}
        {
        }

        public: lcg_PLE63(lcg_PLE63&& r):
            _seed{std::move(r._seed)}
        {
        }

        public: lcg_PLE63& operator=(lcg_PLE63 const& r)
        {
            _seed = r._seed;
            return *this;
        }

        public: lcg_PLE63& operator=(lcg_PLE63&& r)
        {
            _seed = std::move(r._seed);
            return *this;
        }

        public: ~lcg_PLE63()
        {
        }
#pragma endregion

#pragma region Observers
        public: seed_type seed() const
        {
            return _seed;
        }
#pragma endregion

#pragma region Helpers

        // compute and return positive skip
        public: static int64_t compute_nskip(int64_t ns);

        // could skip forward as well as backward
        public: static result_type skip(int64_t ns, seed_type seed);

        public: static result_type sample(seed_type seed)
        {
            return (mult * seed + add) & mask;
        }
#pragma endregion

#pragma region Mutators
        public: void sample() const
        {
            _seed = sample(_seed);
        }

        public: float number() const
        {
            sample();
            return float(_seed) * norm;
        }

        public: void skip(int64_t ns) const
        {
            _seed = skip(ns, _seed);
        }
#pragma endregion
    };
}
<|endoftext|>


<commit_before>// This file was developed by Thomas Müller <thomas94@gmx.net>.
// It is published under the BSD 3-Clause License within the LICENSE file.

#include <tev/ImageViewer.h>
#include <tev/Ipc.h>
#include <tev/SharedQueue.h>
#include <tev/ThreadPool.h>

#include <args.hxx>
#include <ImfThreading.h>

#include <utf8.h>

#include <iostream>
#include <thread>

using namespace args;
using namespace filesystem;
using namespace std;

TEV_NAMESPACE_BEGIN

int mainFunc(const vector<string>& arguments) {
    ArgumentParser parser{
        "Inspection tool for images with a high dynamic range.",
        "tev was developed by Thomas Müller <thomas94@gmx.net>. "
        "Its source code is available under the BSD 3-Clause License at https://tom94.net",
    };

    HelpFlag helpFlag{
        parser,
        "HELP",
        "Display this help menu",
        {'h', "help"},
    };

    Flag versionFlag{
        parser,
        "VERSION",
        "Display the version of tev",
        {'v', "version"},
    };

    Flag newWindowFlag{
        parser,
        "NEW WINDOW",
        "Open a new window of tev, even if one exists already",
        {'n', "new"},
    };

    ValueFlag<float> exposureFlag{
        parser,
        "EXPOSURE",
        "Scales the brightness of an image prior to tonemapping by 2^EXPOSURE. "
        "It can be controlled via the GUI, or by pressing E/Shift+E.",
        {'e', "exposure"},
    };

    ValueFlag<string> filterFlag{
        parser,
        "FILTER",
        "Filter visible images and layers according to a supplied string. "
        "The string must have the format 'image:layer'. "
        "Only images whose name contains 'image' and layers whose name contains 'layer' will be visible.",
        {'f', "filter"},
    };

    ValueFlag<bool> maximizeFlag{
        parser,
        "MAXIMIZE",
        "Maximize the window on startup. "
        "If no images were supplied via the command line, then the default is FALSE. "
        "Otherwise, the default is TRUE.",
        {"max", "maximize"},
    };

    ValueFlag<string> metricFlag{
        parser,
        "METRIC",
        "The metric to use when comparing two images. "
        "The available metrics are:\n"
        "E   - Error\n"
        "AE  - Absolute Error\n"
        "SE  - Squared Error\n"
        "RAE - Relative Absolute Error\n"
        "RSE - Relative Squared Error\n"
        "Default is E.",
        {'m', "metric"},
    };

    ValueFlag<float> offsetFlag{
        parser,
        "OFFSET",
        "Add an absolute offset to the image after EXPOSURE has been applied. "
        "It can be controlled via the GUI, or by pressing O/Shift+O.",
        {'o', "offset"},
    };

    ValueFlag<string> tonemapFlag{
        parser,
        "TONEMAP",
        "The tonemapping algorithm to use. "
        "The available tonemaps are:\n"
        "sRGB   - sRGB\n"
        "Gamma  - Gamma curve (2.2)\n"
        "FC     - False Color\n"
        "PN     - Positive=Green, Negative=Red\n"
        "Default is sRGB.",
        {'t', "tonemap"},
    };

    PositionalList<string> imageFiles{
        parser,
        "images",
        "The image files to be opened by tev. "
        "If an argument starting with a ':' is encountered, "
        "then this argument is not treated as an image file "
        "but as a comma-separated channel selector. Until the next channel "
        "selector is encountered only channels containing "
        "elements from the current selector will be loaded. This is "
        "especially useful for selectively loading a specific "
        "part of a multi-part EXR file.",
    };

    // Parse command line arguments and react to parsing
    // errors using exceptions.
    try {
        TEV_ASSERT(arguments.size() > 0, "Number of arguments must be bigger than 0.");

        parser.Prog(arguments.front());
        parser.ParseArgs(begin(arguments) + 1, end(arguments));
    } catch (Help) {
        std::cout << parser;
        return 0;
    } catch (ParseError e) {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return -1;
    } catch (ValidationError e) {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return -2;
    }

    if (versionFlag) {
        cout
            << "tev — The EXR Viewer" << endl
            << "version " TEV_VERSION << endl;
        return 0;
    }

    auto ipc = make_shared<Ipc>();

    // If we're not the primary instance and did not request to open a new window,
    // simply send the to-be-opened images to the primary instance.
    if (!ipc->isPrimaryInstance() && !newWindowFlag) {
        string channelSelector;
        for (auto imageFile : get(imageFiles)) {
            if (!imageFile.empty() && imageFile[0] == ':') {
                channelSelector = imageFile.substr(1);
                continue;
            }

            try {
                ipc->sendToPrimaryInstance(tfm::format("%s:%s", path{imageFile}.make_absolute(), channelSelector));
            } catch (runtime_error e) {
                cerr << tfm::format("Invalid file '%s': %s", imageFile, e.what()) << endl;
            }
        }

        return 0;
    }

    Imf::setGlobalThreadCount(thread::hardware_concurrency());

    cout << "Loading window..." << endl;

    // Load images passed via command line in the background prior to
    // creating our main application such that they are not stalled
    // by the potentially slow initialization of opengl / glfw.
    shared_ptr<SharedQueue<ImageAddition>> imagesToAdd = make_shared<SharedQueue<ImageAddition>>();
    string channelSelector;
    for (auto imageFile : get(imageFiles)) {
        if (!imageFile.empty() && imageFile[0] == ':') {
            channelSelector = imageFile.substr(1);
            continue;
        }

        ThreadPool::singleWorker().enqueueTask([imageFile, channelSelector, &imagesToAdd] {
            auto image = tryLoadImage(imageFile, channelSelector);
            if (image) {
                imagesToAdd->push({false, image});
            }
        });
    }

    // Init nanogui application
    nanogui::init();

    {
        auto app = unique_ptr<ImageViewer>{new ImageViewer{ipc, imagesToAdd, !imageFiles}};
        app->drawAll();
        app->setVisible(true);

        // Do what the maximize flag tells us---if it exists---and
        // maximize if we have images otherwise.
        if (maximizeFlag ? get(maximizeFlag) : imageFiles) {
            app->maximize();
        }

        // Apply parameter flags
        if (exposureFlag) { app->setExposure(get(exposureFlag)); }
        if (filterFlag)   { app->setFilter(get(filterFlag)); }
        if (metricFlag)   { app->setMetric(toMetric(get(metricFlag))); }
        if (offsetFlag)   { app->setOffset(get(offsetFlag)); }
        if (tonemapFlag)  { app->setTonemap(toTonemap(get(tonemapFlag))); }

        // Refresh only every 250ms if there are no user interactions.
        // This makes an idling tev surprisingly energy-efficient. :)
        nanogui::mainloop(250);
    }

    // On some linux distributions glfwTerminate() (which is called by
    // nanogui::shutdown()) causes segfaults. Since we are done with our
    // program here anyways, let's let the OS clean up after us.
    //nanogui::shutdown();

    // Let all threads gracefully terminate.
    ThreadPool::shutdown();

    return 0;
}

TEV_NAMESPACE_END

#ifdef _WIN32
int wmain(int argc, wchar_t* argv[]) {
#else
int main(int argc, char* argv[]) {
#endif
    try {
        vector<string> arguments;
        for (int i = 0; i < argc; ++i) {
#ifdef _WIN32
            arguments.emplace_back(tev::utf16to8(argv[i]));
#else
            string arg = argv[i];
            // OSX sometimes (seemingly sporadically) passes the
            // process serial number via a command line parameter.
            // We would like to ignore this.
            if (arg.find("-psn") != 0) {
                arguments.emplace_back(tev::ensureUtf8(argv[i]));
            }
#endif
        }

        tev::mainFunc(arguments);
    } catch (const exception& e) {
        cerr << tfm::format("Uncaught exception: %s", e.what()) << endl;
        return 1;
    }
}
<commit_msg>Sort CLI help alphabetically<commit_after>// This file was developed by Thomas Müller <thomas94@gmx.net>.
// It is published under the BSD 3-Clause License within the LICENSE file.

#include <tev/ImageViewer.h>
#include <tev/Ipc.h>
#include <tev/SharedQueue.h>
#include <tev/ThreadPool.h>

#include <args.hxx>
#include <ImfThreading.h>

#include <utf8.h>

#include <iostream>
#include <thread>

using namespace args;
using namespace filesystem;
using namespace std;

TEV_NAMESPACE_BEGIN

int mainFunc(const vector<string>& arguments) {
    ArgumentParser parser{
        "Inspection tool for images with a high dynamic range.",
        "tev was developed by Thomas Müller <thomas94@gmx.net>. "
        "Its source code is available under the BSD 3-Clause License at https://tom94.net",
    };

    ValueFlag<float> exposureFlag{
        parser,
        "EXPOSURE",
        "Scales the brightness of an image prior to tonemapping by 2^EXPOSURE. "
        "It can be controlled via the GUI, or by pressing E/Shift+E.",
        {'e', "exposure"},
    };

    ValueFlag<string> filterFlag{
        parser,
        "FILTER",
        "Filter visible images and layers according to a supplied string. "
        "The string must have the format 'image:layer'. "
        "Only images whose name contains 'image' and layers whose name contains 'layer' will be visible.",
        {'f', "filter"},
    };

    HelpFlag helpFlag{
        parser,
        "HELP",
        "Display this help menu",
        {'h', "help"},
    };

    ValueFlag<bool> maximizeFlag{
        parser,
        "MAXIMIZE",
        "Maximize the window on startup. "
        "If no images were supplied via the command line, then the default is FALSE. "
        "Otherwise, the default is TRUE.",
        {"max", "maximize"},
    };

    ValueFlag<string> metricFlag{
        parser,
        "METRIC",
        "The metric to use when comparing two images. "
        "The available metrics are:\n"
        "E   - Error\n"
        "AE  - Absolute Error\n"
        "SE  - Squared Error\n"
        "RAE - Relative Absolute Error\n"
        "RSE - Relative Squared Error\n"
        "Default is E.",
        {'m', "metric"},
    };

    Flag newWindowFlag{
        parser,
        "NEW WINDOW",
        "Open a new window of tev, even if one exists already",
        {'n', "new"},
    };

    ValueFlag<float> offsetFlag{
        parser,
        "OFFSET",
        "Add an absolute offset to the image after EXPOSURE has been applied. "
        "It can be controlled via the GUI, or by pressing O/Shift+O.",
        {'o', "offset"},
    };

    ValueFlag<string> tonemapFlag{
        parser,
        "TONEMAP",
        "The tonemapping algorithm to use. "
        "The available tonemaps are:\n"
        "sRGB   - sRGB\n"
        "Gamma  - Gamma curve (2.2)\n"
        "FC     - False Color\n"
        "PN     - Positive=Green, Negative=Red\n"
        "Default is sRGB.",
        {'t', "tonemap"},
    };

    Flag versionFlag{
        parser,
        "VERSION",
        "Display the version of tev",
        {'v', "version"},
    };

    PositionalList<string> imageFiles{
        parser,
        "images",
        "The image files to be opened by tev. "
        "If an argument starting with a ':' is encountered, "
        "then this argument is not treated as an image file "
        "but as a comma-separated channel selector. Until the next channel "
        "selector is encountered only channels containing "
        "elements from the current selector will be loaded. This is "
        "especially useful for selectively loading a specific "
        "part of a multi-part EXR file.",
    };

    // Parse command line arguments and react to parsing
    // errors using exceptions.
    try {
        TEV_ASSERT(arguments.size() > 0, "Number of arguments must be bigger than 0.");

        parser.Prog(arguments.front());
        parser.ParseArgs(begin(arguments) + 1, end(arguments));
    } catch (Help) {
        std::cout << parser;
        return 0;
    } catch (ParseError e) {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return -1;
    } catch (ValidationError e) {
        std::cerr << e.what() << std::endl;
        std::cerr << parser;
        return -2;
    }

    if (versionFlag) {
        cout
            << "tev — The EXR Viewer" << endl
            << "version " TEV_VERSION << endl;
        return 0;
    }

    auto ipc = make_shared<Ipc>();

    // If we're not the primary instance and did not request to open a new window,
    // simply send the to-be-opened images to the primary instance.
    if (!ipc->isPrimaryInstance() && !newWindowFlag) {
        string channelSelector;
        for (auto imageFile : get(imageFiles)) {
            if (!imageFile.empty() && imageFile[0] == ':') {
                channelSelector = imageFile.substr(1);
                continue;
            }

            try {
                ipc->sendToPrimaryInstance(tfm::format("%s:%s", path{imageFile}.make_absolute(), channelSelector));
            } catch (runtime_error e) {
                cerr << tfm::format("Invalid file '%s': %s", imageFile, e.what()) << endl;
            }
        }

        return 0;
    }

    Imf::setGlobalThreadCount(thread::hardware_concurrency());

    cout << "Loading window..." << endl;

    // Load images passed via command line in the background prior to
    // creating our main application such that they are not stalled
    // by the potentially slow initialization of opengl / glfw.
    shared_ptr<SharedQueue<ImageAddition>> imagesToAdd = make_shared<SharedQueue<ImageAddition>>();
    string channelSelector;
    for (auto imageFile : get(imageFiles)) {
        if (!imageFile.empty() && imageFile[0] == ':') {
            channelSelector = imageFile.substr(1);
            continue;
        }

        ThreadPool::singleWorker().enqueueTask([imageFile, channelSelector, &imagesToAdd] {
            auto image = tryLoadImage(imageFile, channelSelector);
            if (image) {
                imagesToAdd->push({false, image});
            }
        });
    }

    // Init nanogui application
    nanogui::init();

    {
        auto app = unique_ptr<ImageViewer>{new ImageViewer{ipc, imagesToAdd, !imageFiles}};
        app->drawAll();
        app->setVisible(true);

        // Do what the maximize flag tells us---if it exists---and
        // maximize if we have images otherwise.
        if (maximizeFlag ? get(maximizeFlag) : imageFiles) {
            app->maximize();
        }

        // Apply parameter flags
        if (exposureFlag) { app->setExposure(get(exposureFlag)); }
        if (filterFlag)   { app->setFilter(get(filterFlag)); }
        if (metricFlag)   { app->setMetric(toMetric(get(metricFlag))); }
        if (offsetFlag)   { app->setOffset(get(offsetFlag)); }
        if (tonemapFlag)  { app->setTonemap(toTonemap(get(tonemapFlag))); }

        // Refresh only every 250ms if there are no user interactions.
        // This makes an idling tev surprisingly energy-efficient. :)
        nanogui::mainloop(250);
    }

    // On some linux distributions glfwTerminate() (which is called by
    // nanogui::shutdown()) causes segfaults. Since we are done with our
    // program here anyways, let's let the OS clean up after us.
    //nanogui::shutdown();

    // Let all threads gracefully terminate.
    ThreadPool::shutdown();

    return 0;
}

TEV_NAMESPACE_END

#ifdef _WIN32
int wmain(int argc, wchar_t* argv[]) {
#else
int main(int argc, char* argv[]) {
#endif
    try {
        vector<string> arguments;
        for (int i = 0; i < argc; ++i) {
#ifdef _WIN32
            arguments.emplace_back(tev::utf16to8(argv[i]));
#else
            string arg = argv[i];
            // OSX sometimes (seemingly sporadically) passes the
            // process serial number via a command line parameter.
            // We would like to ignore this.
            if (arg.find("-psn") != 0) {
                arguments.emplace_back(tev::ensureUtf8(argv[i]));
            }
#endif
        }

        tev::mainFunc(arguments);
    } catch (const exception& e) {
        cerr << tfm::format("Uncaught exception: %s", e.what()) << endl;
        return 1;
    }
}
<|endoftext|>