<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI Widget ターミナル
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/glfw_app/blob/master/LICENSE
*/
//=====================================================================//
#include "widgets/widget_director.hpp"
#include "widgets/widget_frame.hpp"
#include "utils/terminal.hpp"
#include "core/glcore.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	GUI terminal クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct widget_terminal : public widget {

		typedef widget_terminal value_type;

		typedef std::function< void(uint32_t ch) > input_func_type;
		typedef std::function< void(const utils::lstring& line) > enter_func_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_terminal パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {
			std::string		font_;			///< ターミナル描画フォント
			uint32_t		font_width_;	///< フォント幅（初期化で設定される）
			uint32_t		font_height_;	///< フォント高
			uint32_t		height_;		///< 行の高さ

			bool			echo_;			///< キー入力とエコー
			bool			auto_fit_;	   	///< 等幅フォントに対するフレームの最適化

			input_func_type input_func_;	///< １文字入力毎に呼ぶ関数
			enter_func_type enter_func_;	///< 「Enter」時に呼ぶ関数

			param() : font_("Inconsolata"), font_width_(0), font_height_(18), height_(20),
				echo_(true), auto_fit_(true) { }
		};

		widget_director&	wd_;

		param				param_;

		utils::terminal		terminal_;
		uint32_t			interval_;

		bool				focus_;

		vtx::ipos			scroll_ofs_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_terminal(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p), terminal_(), interval_(0),
			focus_(false), scroll_ofs_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~widget_terminal() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	型を取得
		*/
		//-----------------------------------------------------------------//
		type_id type() const override { return get_type_id<value_type>(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	widget 型の基本名称を取得
			@return widget 型の基本名称
		*/
		//-----------------------------------------------------------------//
		const char* type_name() const override { return "terminal"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ハイブリッド・ウィジェットのサイン
			@return ハイブリッド・ウィジェットの場合「true」を返す。
		*/
		//-----------------------------------------------------------------//
		bool hybrid() const override { return false; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得(ro)
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		const param& get_local_param() const { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		param& at_local_param() { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ターミナル・インスタンスへの参照
			@return ターミナル・インスタンス
		*/
		//-----------------------------------------------------------------//
		utils::terminal& at_terminal() { return terminal_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	１文字出力
			@param[in]	wch	文字
		*/
		//-----------------------------------------------------------------//
		void output(uint32_t wch) {
			terminal_.output(wch);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	テキストの出力
			@param[in]	text	テキスト
		*/
		//-----------------------------------------------------------------//
		void output(const std::string& text) {
			if(text.empty()) return;

			auto ls = utils::utf8_to_utf32(text);
			for(auto ch : ls) {
				output(ch);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::RESIZE_H_ENABLE, false);
			at_param().state_.set(widget::state::RESIZE_V_ENABLE, false);
			at_param().state_.set(widget::state::SERVICE);
			at_param().state_.set(widget::state::MOVE_ROOT, false);
			at_param().state_.set(widget::state::RESIZE_ROOT);
			at_param().state_.set(widget::state::CLIP_PARENTS);
			at_param().state_.set(widget::state::AREA_ROOT);

			using namespace gl;
			core& core = core::get_instance();
			fonts& fonts = core.at_fonts();

			fonts.push_font_face();
			fonts.set_font_type(param_.font_);
			fonts.set_font_size(param_.font_height_);
			fonts.enable_proportional(false);
			fonts.set_spaceing(0);
			param_.font_width_ = fonts.get_width(' ');
			fonts.pop_font_face();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(wd_.get_focus_widget() == this || wd_.get_focus_widget() == wd_.root_widget(this)) {
				focus_ = true;
			} else {
				focus_ = false;
			}

			// スクロール処理、マウスホイール
			if(get_focus()) {
				const vtx::spos& scr = wd_.get_scroll();
				scroll_ofs_ += scr;
				if(scroll_ofs_.y < 0) scroll_ofs_.y = 0;
			}

			if(get_param().parents_ && get_state(widget::state::AREA_ROOT)) {
				if(get_param().parents_->type() == get_type_id<widget_frame>()) {
					// 親になってるフレームを取得
					widget_frame* w = static_cast<widget_frame*>(at_param().parents_);
					if(w) {
						bool resize = false;
						vtx::irect sr = w->get_draw_area();
						if(param_.auto_fit_) {
							vtx::ipos ss(sr.size.x / param_.font_width_,
										 sr.size.y / param_.height_);
							ss.x *= param_.font_width_;
//							if(ss.x < w->get_param().resize_min_.x) {
//								ss.x = w->get_param().resize_min_.x / param_.font_width_;
//								ss.x *= param_.font_width_;
//							}
							ss.y *= param_.height_;
//							if(ss.y < w->get_param().resize_min_.y) {
//								ss.y = w->get_param().resize_min_.y / param_.height_;
//								ss.y *= param_.height_;
//							}
							w->set_draw_area(ss);
							sr = w->get_draw_area();
						}
						if(sr.size != get_rect().size) resize = true;
						at_rect() = sr;
						if(resize) {
						}
					}
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-----------------------------------------------------------------//
		void service() override
		{
			if(!get_state(state::ENABLE)) {
				focus_ = false;
				return;
			}

			if(focus_) {
				if(param_.echo_) {
					auto s = wd_.at_keyboard().input();
					terminal_.output(s);
					if(!s.empty()) {
						if(param_.input_func_ != nullptr) {
							for(auto ch : s) {
								param_.input_func_(ch);
							}
						}
						if(param_.enter_func_ != nullptr && terminal_.get_last_char() == 0x0D) {
							param_.enter_func_(terminal_.get_last_text32());
						}
					}
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			using namespace gl;
			core& core = core::get_instance();
			const vtx::spos& vsz = core.get_size();
//			const vtx::spos& siz = core.get_rect().size;
			gl::fonts& fonts = core.at_fonts();

			const widget::param& wp = get_param();

			if(wp.clip_.size.x > 0 && wp.clip_.size.y > 0) {

				glPushMatrix();

				vtx::irect rect;
				if(wp.state_[widget::state::CLIP_PARENTS]) {
					rect.org  = wp.rpos_;
					rect.size = wp.rect_.size;
				} else {
					rect.org.set(0);
					rect.size = wp.rect_.size;
				}

				fonts.push_font_face();
				fonts.set_font_type(param_.font_);
				fonts.set_font_size(param_.font_height_);

				vtx::irect clip_ = wp.clip_;

//				float sx = vsz.x / siz.x;
				float sx = core.get_dpi_scale();
//				float sy = vsz.y / siz.y;
				float sy = core.get_dpi_scale();
				glViewport(clip_.org.x * sx, vsz.y - clip_.org.y * sy - clip_.size.y * sy,
					clip_.size.x * sx, clip_.size.y * sy);
				fonts.setup_matrix(clip_.size.x, clip_.size.y);

				fonts.enable_center(false);
				fonts.enable_proportional(false);

				const img::rgbaf& cf = wd_.get_color();
				vtx::ipos limit(clip_.size.x / param_.font_width_, clip_.size.y / param_.height_);
				vtx::ipos chs(rect.org);
				auto ln = terminal_.get_line_num();
				vtx::ipos ofs(0);
				if(ln > limit.y) ofs.y = ln - limit.y;
				auto npy = ofs.y - scroll_ofs_.y;
				if(npy < 0) {
					npy = 0;
					scroll_ofs_.y = ofs.y;
				} else if(npy > ofs.y) {
					npy = ofs.y;
				}
				ofs.y = npy;
				vtx::ipos pos;
				for(pos.y = 0; pos.y < limit.y; ++pos.y) {
					for(pos.x = 0; pos.x < limit.x; ++pos.x) {
						const auto& t = terminal_.get_char(pos + ofs);
						img::rgba8 fc = t.fc_;
						fc *= cf.r;
						fc.alpha_scale(cf.a);
						fonts.set_fore_color(fc);
						img::rgba8 bc = t.bc_;
						bc *= cf.r;
						bc.alpha_scale(cf.a);
						fonts.set_back_color(bc);
						if(focus_ && (pos + ofs) == terminal_.get_cursor()) {
							if((interval_ % 40) < 20) {
								fonts.swap_color();
							}
						}
						auto cha = t.cha_;
						if(cha < 0x20) cha = 0x3F;  // 制御コードは DEL-char として扱う
						if(cha > 0x7f) {
							fonts.pop_font_face();
						}
						int fw = fonts.get_width(cha);
						vtx::irect br(chs, vtx::ipos(fw, param_.height_));
						fonts.draw_back(br);
						chs.x += fonts.draw(chs, cha);
						fonts.swap_color(false);
						if(cha > 0x7f) {
							fonts.push_font_face();
							fonts.set_font_type(param_.font_);
						}
					}
					chs.y += param_.height_;
					chs.x = rect.org.x;
				}
				++interval_;

				fonts.restore_matrix();
				fonts.pop_font_face();
				glPopMatrix();
				glViewport(0, 0, vsz.x, vsz.y);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のセーブ
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool save(sys::preference& pre) override {
			return false;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override {
			return false;
		}
	};
}
<commit_msg>Update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI Widget ターミナル
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2017 Kunihito Hiramatsu @n
				Released under the MIT license @n
				https://github.com/hirakuni45/glfw_app/blob/master/LICENSE
*/
//=====================================================================//
#include "widgets/widget_director.hpp"
#include "widgets/widget_frame.hpp"
#include "utils/terminal.hpp"
#include "core/glcore.hpp"

namespace gui {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief	GUI terminal クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	struct widget_terminal : public widget {

		typedef widget_terminal value_type;

		typedef std::function< void(uint32_t ch) > input_func_type;
		typedef std::function< void(const utils::lstring& line) > enter_func_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_terminal パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {
			std::string		font_;			///< ターミナル描画フォント
			uint32_t		font_width_;	///< フォント幅（初期化で設定される）
			uint32_t		font_height_;	///< フォント高
			uint32_t		height_;		///< 行の高さ

			bool			echo_;			///< キー入力とエコー
			bool			auto_fit_;	   	///< 等幅フォントに対するフレームの最適化

			input_func_type input_func_;	///< １文字入力毎に呼ぶ関数
			enter_func_type enter_func_;	///< 「Enter」時に呼ぶ関数

			param() : font_("Inconsolata"), font_width_(0), font_height_(18), height_(20),
				echo_(true), auto_fit_(true) { }
		};

	private:

		widget_director&	wd_;

		param				param_;

		utils::terminal		terminal_;
		uint32_t			interval_;

		bool				focus_;

		vtx::ipos			scroll_ofs_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_terminal(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p), terminal_(), interval_(0),
			focus_(false), scroll_ofs_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	デストラクター
		*/
		//-----------------------------------------------------------------//
		virtual ~widget_terminal() { }

		//-----------------------------------------------------------------//
		/*!
			@brief	型を取得
		*/
		//-----------------------------------------------------------------//
		type_id type() const override { return get_type_id<value_type>(); }

		//-----------------------------------------------------------------//
		/*!
			@brief	widget 型の基本名称を取得
			@return widget 型の基本名称
		*/
		//-----------------------------------------------------------------//
		const char* type_name() const override { return "terminal"; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ハイブリッド・ウィジェットのサイン
			@return ハイブリッド・ウィジェットの場合「true」を返す。
		*/
		//-----------------------------------------------------------------//
		bool hybrid() const override { return false; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得(ro)
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		const param& get_local_param() const { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	個別パラメーターへの取得
			@return 個別パラメーター
		*/
		//-----------------------------------------------------------------//
		param& at_local_param() { return param_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	ターミナル・インスタンスへの参照
			@return ターミナル・インスタンス
		*/
		//-----------------------------------------------------------------//
		utils::terminal& at_terminal() { return terminal_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	１文字出力
			@param[in]	wch	文字
		*/
		//-----------------------------------------------------------------//
		void output(uint32_t wch) {
			terminal_.output(wch);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	テキストの出力
			@param[in]	text	テキスト
		*/
		//-----------------------------------------------------------------//
		void output(const std::string& text) {
			if(text.empty()) return;

			auto ls = utils::utf8_to_utf32(text);
			for(auto ch : ls) {
				output(ch);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::RESIZE_H_ENABLE, false);
			at_param().state_.set(widget::state::RESIZE_V_ENABLE, false);
			at_param().state_.set(widget::state::SERVICE);
			at_param().state_.set(widget::state::MOVE_ROOT, false);
			at_param().state_.set(widget::state::RESIZE_ROOT);
			at_param().state_.set(widget::state::CLIP_PARENTS);
			at_param().state_.set(widget::state::AREA_ROOT);

			using namespace gl;
			core& core = core::get_instance();
			fonts& fonts = core.at_fonts();

			fonts.push_font_face();
			fonts.set_font_type(param_.font_);
			fonts.set_font_size(param_.font_height_);
			fonts.enable_proportional(false);
			fonts.set_spaceing(0);
			param_.font_width_ = fonts.get_width(' ');
			fonts.pop_font_face();
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(wd_.get_focus_widget() == this || wd_.get_focus_widget() == wd_.root_widget(this)) {
				focus_ = true;
			} else {
				focus_ = false;
			}

			// スクロール処理、マウスホイール
			if(get_focus()) {
				const vtx::spos& scr = wd_.get_scroll();
				scroll_ofs_ += scr;
				if(scroll_ofs_.y < 0) scroll_ofs_.y = 0;
			}

			if(get_param().parents_ && get_state(widget::state::AREA_ROOT)) {
				if(get_param().parents_->type() == get_type_id<widget_frame>()) {
					// 親になってるフレームを取得
					widget_frame* w = static_cast<widget_frame*>(at_param().parents_);
					if(w) {
						bool resize = false;
						vtx::irect sr = w->get_draw_area();
						if(param_.auto_fit_) {
							vtx::ipos ss(sr.size.x / param_.font_width_,
										 sr.size.y / param_.height_);
							ss.x *= param_.font_width_;
//							if(ss.x < w->get_param().resize_min_.x) {
//								ss.x = w->get_param().resize_min_.x / param_.font_width_;
//								ss.x *= param_.font_width_;
//							}
							ss.y *= param_.height_;
//							if(ss.y < w->get_param().resize_min_.y) {
//								ss.y = w->get_param().resize_min_.y / param_.height_;
//								ss.y *= param_.height_;
//							}
							w->set_draw_area(ss);
							sr = w->get_draw_area();
						}
						if(sr.size != get_rect().size) resize = true;
						at_rect() = sr;
						if(resize) {
						}
					}
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	サービス
		*/
		//-----------------------------------------------------------------//
		void service() override
		{
			if(!get_state(state::ENABLE)) {
				focus_ = false;
				return;
			}

			if(focus_) {
				if(param_.echo_) {
					auto s = wd_.at_keyboard().input();
					terminal_.output(s);
					if(!s.empty()) {
						if(param_.input_func_ != nullptr) {
							for(auto ch : s) {
								param_.input_func_(ch);
							}
						}
						if(param_.enter_func_ != nullptr && terminal_.get_last_char() == 0x0D) {
							param_.enter_func_(terminal_.get_last_text32());
						}
					}
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			using namespace gl;
			core& core = core::get_instance();
			const vtx::spos& vsz = core.get_size();
//			const vtx::spos& siz = core.get_rect().size;
			gl::fonts& fonts = core.at_fonts();

			const widget::param& wp = get_param();

			if(wp.clip_.size.x > 0 && wp.clip_.size.y > 0) {

				glPushMatrix();

				vtx::irect rect;
				if(wp.state_[widget::state::CLIP_PARENTS]) {
					rect.org  = wp.rpos_;
					rect.size = wp.rect_.size;
				} else {
					rect.org.set(0);
					rect.size = wp.rect_.size;
				}

				fonts.push_font_face();
				fonts.set_font_type(param_.font_);
				fonts.set_font_size(param_.font_height_);

				vtx::irect clip_ = wp.clip_;

//				float sx = vsz.x / siz.x;
				float sx = core.get_dpi_scale();
//				float sy = vsz.y / siz.y;
				float sy = core.get_dpi_scale();
				glViewport(clip_.org.x * sx, vsz.y - clip_.org.y * sy - clip_.size.y * sy,
					clip_.size.x * sx, clip_.size.y * sy);
				fonts.setup_matrix(clip_.size.x, clip_.size.y);

				fonts.enable_center(false);
				fonts.enable_proportional(false);

				const img::rgbaf& cf = wd_.get_color();
				vtx::ipos limit(clip_.size.x / param_.font_width_, clip_.size.y / param_.height_);
				vtx::ipos chs(rect.org);
				auto ln = terminal_.get_line_num();
				vtx::ipos ofs(0);
				if(ln > limit.y) ofs.y = ln - limit.y;
				auto npy = ofs.y - scroll_ofs_.y;
				if(npy < 0) {
					npy = 0;
					scroll_ofs_.y = ofs.y;
				} else if(npy > ofs.y) {
					npy = ofs.y;
				}
				ofs.y = npy;
				vtx::ipos pos;
				for(pos.y = 0; pos.y < limit.y; ++pos.y) {
					for(pos.x = 0; pos.x < limit.x; ++pos.x) {
						const auto& t = terminal_.get_char(pos + ofs);
						img::rgba8 fc = t.fc_;
						fc *= cf.r;
						fc.alpha_scale(cf.a);
						fonts.set_fore_color(fc);
						img::rgba8 bc = t.bc_;
						bc *= cf.r;
						bc.alpha_scale(cf.a);
						fonts.set_back_color(bc);
						if(focus_ && (pos + ofs) == terminal_.get_cursor()) {
							if((interval_ % 40) < 20) {
								fonts.swap_color();
							}
						}
						auto cha = t.cha_;
						if(cha < 0x20) cha = 0x3F;  // 制御コードは DEL-char として扱う
						if(cha > 0x7f) {
							fonts.pop_font_face();
						}
						int fw = fonts.get_width(cha);
						vtx::irect br(chs, vtx::ipos(fw, param_.height_));
						fonts.draw_back(br);
						chs.x += fonts.draw(chs, cha);
						fonts.swap_color(false);
						if(cha > 0x7f) {
							fonts.push_font_face();
							fonts.set_font_type(param_.font_);
						}
					}
					chs.y += param_.height_;
					chs.x = rect.org.x;
				}
				++interval_;

				fonts.restore_matrix();
				fonts.pop_font_face();
				glPopMatrix();
				glViewport(0, 0, vsz.x, vsz.y);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のセーブ
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool save(sys::preference& pre) override {
			return false;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override {
			return false;
		}
	};
}
<|endoftext|>


<commit_before>#include "../common/util.h"
#include "font.h"
#include "text.h"

/* NOTE:
 * This example uses font rendering to demonstrate how instancing
 * works. Instancing is mostly useful when you want to render a
 * very large quantity of objects. This example only renders
 * "HELLOWORLD" to the screen, which is hardly an appropriate
 * use case for instancing. In your own applications, you should
 * always consider if instancing is the correct way to go, or if
 * you should consider a dynamic buffer (which we will cover
 * in a later example).
 *
 * The text rendering in this example is very basic. It only renders
 * uppercase characters of fixed-width fonts. It is a contrived example
 * that allows to show how instancing works. I will add a better example
 * later, which can render TrueType fonts with any color and transformation.
 */

int main(void)
{
    GLFWwindow* window;

    window = init("Instancing", 640, 480);
    if(!window)
    {
        return -1;
    }

    Font font;
    if(!font.load("font.png", 26))
    {
        return -1;
    }
    Text text;
    if(!text.load(&font))
    {
        return -1;
    }
    text.setPosition(0.0f, 0.0f);
    text.setString("HELLOWORLD");

    glClearColor(0.75f, 0.75f, 0.75f, 1.0f);

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        text.render();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glfwTerminate();
    return 0;
}
<commit_msg>glBlend<commit_after>#include "../common/util.h"
#include "font.h"
#include "text.h"

/* NOTE:
 * This example uses font rendering to demonstrate how instancing
 * works. Instancing is mostly useful when you want to render a
 * very large quantity of objects. This example only renders
 * "HELLOWORLD" to the screen, which is hardly an appropriate
 * use case for instancing. In your own applications, you should
 * always consider if instancing is the correct way to go, or if
 * you should consider a dynamic buffer (which we will cover
 * in a later example).
 *
 * The text rendering in this example is very basic. It only renders
 * uppercase characters of fixed-width fonts. It is a contrived example
 * that allows to show how instancing works. I will add a better example
 * later, which can render TrueType fonts with any color and transformation.
 */

int main(void)
{
    GLFWwindow* window;

    window = init("Instancing", 640, 480);
    if(!window)
    {
        return -1;
    }

    // Enable transparency for font rendering!
    // If you render transparent objects, you should always think
    // about the drawing order
    glEnable(GL_BLEND);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);

    Font font;
    if(!font.load("font.png", 26))
    {
        return -1;
    }
    Text text;
    if(!text.load(&font))
    {
        return -1;
    }
    text.setPosition(0.0f, 0.0f);
    text.setString("HELLOWORLD");

    glClearColor(0.75f, 0.75f, 0.75f, 1.0f);

    while(!glfwWindowShouldClose(window))
    {
        glClear(GL_COLOR_BUFFER_BIT);

        text.render();

        glfwSwapBuffers(window);
        glfwPollEvents();
    }

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


<commit_before>// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)

#include "bal_problem.h"

#include <cstdio>
#include <cstdlib>
#include <string>
#include <glog/logging.h>
#include "ceres/rotation.h"

namespace ceres {
namespace examples {

template<typename T>
void FscanfOrDie(FILE *fptr, const char *format, T *value) {
  int num_scanned = fscanf(fptr, format, value);
  if (num_scanned != 1) {
    LOG(FATAL) << "Invalid UW data file.";
  }
}

BALProblem::BALProblem(const std::string filename, bool use_quaternions) {
  FILE* fptr = fopen(filename.c_str(), "r");

  if (!fptr) {
    LOG(FATAL) << "Error: unable to open file " << filename;
    return;
  };

  // This wil die horribly on invalid files. Them's the breaks.
  FscanfOrDie(fptr, "%d", &num_cameras_);
  FscanfOrDie(fptr, "%d", &num_points_);
  FscanfOrDie(fptr, "%d", &num_observations_);

  VLOG(1) << "Header: " << num_cameras_
          << " " << num_points_
          << " " << num_observations_;

  point_index_ = new int[num_observations_];
  camera_index_ = new int[num_observations_];
  observations_ = new double[2 * num_observations_];

  num_parameters_ = 9 * num_cameras_ + 3 * num_points_;
  parameters_ = new double[num_parameters_];

  for (int i = 0; i < num_observations_; ++i) {
    FscanfOrDie(fptr, "%d", camera_index_ + i);
    FscanfOrDie(fptr, "%d", point_index_ + i);
    for (int j = 0; j < 2; ++j) {
      FscanfOrDie(fptr, "%lf", observations_ + 2*i + j);
    }
  }

  for (int i = 0; i < num_parameters_; ++i) {
    FscanfOrDie(fptr, "%lf", parameters_ + i);
  }

  use_quaternions_ = use_quaternions;
  if (use_quaternions) {
    // Switch the angle-axis rotations to quaternions.
    num_parameters_ = 10 * num_cameras_ + 3 * num_points_;
    double* quaternion_parameters = new double[num_parameters_];
    double* original_cursor = parameters_;
    double* quaternion_cursor = quaternion_parameters;
    for (int i = 0; i < num_cameras_; ++i) {
      AngleAxisToQuaternion(original_cursor, quaternion_cursor);
      quaternion_cursor += 4;
      original_cursor += 3;
      for (int j = 4; j < 10; ++j) {
       *quaternion_cursor++ = *original_cursor++;
      }
    }
    // Copy the rest of the points.
    for (int i = 0; i < 3 * num_points_; ++i) {
      *quaternion_cursor++ = *original_cursor++;
    }
    // Swap in the quaternion parameters.
    delete []parameters_;
    parameters_ = quaternion_parameters;
  }
}

BALProblem::~BALProblem() {
  delete []point_index_;
  delete []camera_index_;
  delete []observations_;
  delete []parameters_;
}

}  // namespace examples
}  // namespace ceres
<commit_msg>Close the bal_problem file when done reading it.<commit_after>// Ceres Solver - A fast non-linear least squares minimizer
// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
//   this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
// * Neither the name of Google Inc. nor the names of its contributors may be
//   used to endorse or promote products derived from this software without
//   specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Author: sameeragarwal@google.com (Sameer Agarwal)

#include "bal_problem.h"

#include <cstdio>
#include <cstdlib>
#include <string>
#include <glog/logging.h>
#include "ceres/rotation.h"

namespace ceres {
namespace examples {

template<typename T>
void FscanfOrDie(FILE *fptr, const char *format, T *value) {
  int num_scanned = fscanf(fptr, format, value);
  if (num_scanned != 1) {
    LOG(FATAL) << "Invalid UW data file.";
  }
}

BALProblem::BALProblem(const std::string filename, bool use_quaternions) {
  FILE* fptr = fopen(filename.c_str(), "r");

  if (!fptr) {
    LOG(FATAL) << "Error: unable to open file " << filename;
    return;
  };

  // This wil die horribly on invalid files. Them's the breaks.
  FscanfOrDie(fptr, "%d", &num_cameras_);
  FscanfOrDie(fptr, "%d", &num_points_);
  FscanfOrDie(fptr, "%d", &num_observations_);

  VLOG(1) << "Header: " << num_cameras_
          << " " << num_points_
          << " " << num_observations_;

  point_index_ = new int[num_observations_];
  camera_index_ = new int[num_observations_];
  observations_ = new double[2 * num_observations_];

  num_parameters_ = 9 * num_cameras_ + 3 * num_points_;
  parameters_ = new double[num_parameters_];

  for (int i = 0; i < num_observations_; ++i) {
    FscanfOrDie(fptr, "%d", camera_index_ + i);
    FscanfOrDie(fptr, "%d", point_index_ + i);
    for (int j = 0; j < 2; ++j) {
      FscanfOrDie(fptr, "%lf", observations_ + 2*i + j);
    }
  }

  for (int i = 0; i < num_parameters_; ++i) {
    FscanfOrDie(fptr, "%lf", parameters_ + i);
  }

  fclose(fptr);

  use_quaternions_ = use_quaternions;
  if (use_quaternions) {
    // Switch the angle-axis rotations to quaternions.
    num_parameters_ = 10 * num_cameras_ + 3 * num_points_;
    double* quaternion_parameters = new double[num_parameters_];
    double* original_cursor = parameters_;
    double* quaternion_cursor = quaternion_parameters;
    for (int i = 0; i < num_cameras_; ++i) {
      AngleAxisToQuaternion(original_cursor, quaternion_cursor);
      quaternion_cursor += 4;
      original_cursor += 3;
      for (int j = 4; j < 10; ++j) {
       *quaternion_cursor++ = *original_cursor++;
      }
    }
    // Copy the rest of the points.
    for (int i = 0; i < 3 * num_points_; ++i) {
      *quaternion_cursor++ = *original_cursor++;
    }
    // Swap in the quaternion parameters.
    delete []parameters_;
    parameters_ = quaternion_parameters;
  }
}

BALProblem::~BALProblem() {
  delete []point_index_;
  delete []camera_index_;
  delete []observations_;
  delete []parameters_;
}

}  // namespace examples
}  // namespace ceres
<|endoftext|>


<commit_before>#include "classui.h"
#include "listworker.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <time.h>
#include <stdlib.h>

using namespace std;

ClassUI::ClassUI()
{

}
void ClassUI::mainMenu()
{
    if (firstRun == true)
    {
        cout << "\t" << "Welcome to the Amazing Database! " << endl;
        cout << "--------------------------------------------------------------" << endl;
        cout << "\t" << "   *** Quote of the day ***" << endl;
        cout << getQuotes() << endl;
        firstRun = false;
    }
    string choice;
    do
    {
        cout << "--------------------------------------------------------------" << endl;
        cout << " (1) - "  << "Add a scientist to the database." << endl;
        cout << " (2) - "  << "Remove a scientist from the database." << endl;
        cout << " (3) - "  << "View the entire database." << endl;
        cout << " (4) - "  << "Save the database." << endl;
        cout << " (5) - "  << "Search the database." << endl;
        cout << " (6) - "  << "Sort the database." << endl;
        cout << " (7) - "  << "Edit a scientist." << endl;
        cout << " (8) - "  << "Exit." << endl;
        cout << "Enter your command (1 - 8): ";
        cin >> choice;
        if (choice != "8")
        {
           select(choice);
        }
        else
        {
            list.saveFile();
            runOn = false;
        }
    }while(runOn == true);

    cout << endl;

}
void ClassUI::select(string ch)
{
    if(ch == "1")
    {
        cin.ignore();           // When using editPerson it will ignore the first letter unless this ignore is here rather then in addPerson
        addPerson();
    }
    else if(ch == "2")
    {
        remove();
    }
    else if(ch == "3")
    {
        viewAll();
    }
    else if(ch == "4")
    {
        save();
    }
    else if(ch == "5")
    {
        searching();
    }
    else if(ch == "6")
    {
        sorting();
    }
    else if(ch == "7")
    {
        editPerson();
    }
    else if(ch == "yo")
    {
        yo();
    }
    else
    {
        cout << "Invalid input. Please enter a number between 1 - 7." << endl;
    }
}
void ClassUI::view(int i)
{
    cout << "--------------------------------------------------------------" << endl;
    int nameSize  = list.getNameSize(i);

    cout << list.getName(i);

    if(nameSize > 0 && nameSize <= 7)
    {
        cout << "\t" << "\t" << "\t" << "\t";
    }
    else if(nameSize > 7 && nameSize <= 15)
    {
        cout << "\t" << "\t" << "\t";
    }
    else if(nameSize > 15 && nameSize <= 23)
    {
        cout << "\t" << "\t";
    }
    else if(nameSize > 23 && nameSize <= 31)
    {
        cout << "\t";
    }

    if(list.getGender(i) == 'M' || list.getGender(i) == 'm')
    {
        cout << "|Male" << "\t";
    }
    else
    {
        cout << "|Female" << "\t";
    }

    cout  << "|" << list.getBirth(i);

    if(list.getDeath(i) == 0)
    {
        cout << "\t" << "| n/a"  << "\t" << "|" << list.getAge(i) << endl;
    }
    else
    {
        cout << "\t" << "|" << list.getDeath(i) << "\t" << "|" << list.getAge(i) <<  endl;
    }

    cout << list.getComment(i) << endl;
}
void ClassUI::viewAll()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << "Name" << "\t" << "\t" << "\t" << "\t" << "|Gender " << "|Born " << "\t" << "|Death"  << "\t" << "|Age" << endl;
    for(int i = 0; i < list.personsSize(); i++)
    {
        view(i);
    }
}
void ClassUI::addPerson()
{
    string name;
    string comment;
    char gender;
    char yesOrNo;
    int yearOfBirth = 0;
    int yearOfDeath = 0;

    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter name of the scientist: ";
    std::getline(std::cin,name);
    cout << "Enter a gender (M/F): ";
    cin >> gender;

    if (gender == 'm')
    {
        gender = 'M';
    }
    else if (gender == 'f')
    {
        gender = 'F';
    }

    if (gender == 'm' || gender == 'M' || gender == 'f' || gender == 'F')
    {
       cout << "Enter a year of birth: ";
       cin >> yearOfBirth;
       if (yearOfBirth < 0 || yearOfBirth > 2016)
       {
           cout << "not a valid year of birth" << endl;
           return mainMenu();
       }
       cout << "Is the individual deceased? (y/n) ";
       cin >> yesOrNo;

       if (yesOrNo == 'Y' || yesOrNo == 'y')
       {
            cout << "Enter a year of death: ";
            cin >> yearOfDeath;
            if(yearOfBirth > yearOfDeath)
            {
                cout << "Not a valid year of death" << endl;
                return mainMenu();
            }
       }

       cout << "Enter a comment about the scientist: ";
       cin.ignore();
       std::getline(std::cin,comment);
    }
    else
    {
        cout << "Invalid gender! Try again." << endl;
        return mainMenu();
    }

    cout << "Are you sure that you want to add this scientist? (y/n) ";
    string validatePerson;
    cin >> validatePerson;

    if(validatePerson == "y")
    {
        cout << "New scientist added!" << endl;
        list.addNewPerson(name, gender, yearOfBirth, yearOfDeath, comment);
    }
    else
    {
        cout << "scientist not added!" << endl;
    }
}
void ClassUI::searching()
{
    cout << "-------------Select any of the following commands-------------" << endl;
    cout << "What do you want to search for?" << endl;
    cout << " (1) - Search by name." << endl;
    cout << " (2) - Search by gender." << endl;
    cout << " (3) - Search by year of birth." << endl;
    cout << " (4) - Search by age." << endl;
    cout << " (5) - Return to main menu." << endl;

    search();
}
void ClassUI::search()
{
    string searchChoice;
    cout << "Enter your command (1 - 4): ";
    cin >> searchChoice;
    cout << endl;

    if (searchChoice == "1")
    {
        string namesearch;
        cout << "--------------------------------------------------------------" << endl;
        cout << "Enter a name you want to search for: ";
        cin.ignore();
        std::getline(std::cin,namesearch);
        cout << "--------------------------------------------------------------" << endl;
        for(int i = 0; i < list.personsSize();++i)
        {
            std::size_t found = list.getName(i).find(namesearch);
            if (found!=std::string::npos)
            {
                view(i);
            }
        }

        if(list.nameSearcher(namesearch) == false)
        {
            cout << "Sorry that name is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "2")
    {
        char gendersearch;

        cout << "Enter a gender you want to search for: (M/F)";
        cin >> gendersearch;

        if(gendersearch == 'm')
            {
                 gendersearch = 'M';
            }
        else if (gendersearch == 'f')
            {
                 gendersearch = 'F';
            }

        for(int i = 0; i < list.personsSize();++i)
        {
            if(gendersearch == list.getGender(i))
            {
                gendersearch = list.getGender(i);
                view(i);
            }
        }

        if(list.genderSearcher(gendersearch) == false)
        {
            cout << "Sorry that gender is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "3")
    {
            int yearsearch;
            cout << "Enter a year you want to search for: ";
            cin >> yearsearch;

            for(int i = 0; i < list.personsSize();++i)
            {
                if(yearsearch == list.getBirth(i))
                {
                    yearsearch = list.getBirth(i);
                    view(i);
                }
            }

            if(list.yearSearcher(yearsearch) == false)
            {
                cout << "Sorry that year is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
                searching();
            }
    }
    else if (searchChoice == "4")
    {
        int agesearch;
        cout << "Enter a age you want to search for: ";
        cin >> agesearch;

        for(int i = 0; i < list.personsSize();++i)
        {
            if(agesearch == list.getAge(i))
            {
                agesearch = list.getAge(i);
                view(i);
            }
        }

        if(list.ageSearcher(agesearch) == false)
        {
            cout << "Sorry that age is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "Error reading input. Please enter a number between 1- 3." << endl;
        search();
    }
}
void ClassUI::remove()
{
    string name;
    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter the full name of the scientist that you want to remove: ";
    cin.ignore();
    std::getline(std::cin,name);

    if (list.removePersonFound(name) == true)
    {
        char validateRemove;
        cout << "scientist found!" << endl;
        cout << "Are you sure you want to remove this scientist? (y/n): ";
        cin >> validateRemove;

        if(validateRemove == 'y' || validateRemove == 'Y')
        {
            if(list.removePerson(name) == true)
            {
                cout << "Scientist removed!" << endl;
            }
            else
            {
                cout << "Scientist not removed!" << endl;
            }
        }
        else
        {
            cout << "Scientist not removed!" << endl;
        }
    }
    else
    {
        cout << "Serson not found!" << endl;
    }

}
void ClassUI::save()
{
    list.saveFile();
    cout << "Database saved." << endl;
}
void ClassUI::yo()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << endl;
    cout << "`8.`8888.      ,8'     ,o888888o.     " << endl;
    cout << " `8.`8888.    ,8'   . 8888     `88.   " << endl;
    cout << "  `8.`8888.  ,8'   ,8 8888       `8b  " << endl;
    cout << "   `8.`8888.,8'    88 8888        `8b " << endl;
    cout << "    `8.`88888'     88 8888         88 " << endl;
    cout << "     `8. 8888      88 8888         88 " << endl;
    cout << "      `8 8888      88 8888        ,8P " << endl;
    cout << "       8 8888      `8 8888       ,8P  " << endl;
    cout << "       8 8888       ` 8888     ,88'   " << endl;
    cout << "       8 8888          `8888888P'     " << endl;
    cout << endl;
}
string ClassUI::getQuotes()
{
    string quotes[5] = {"\"A good programmer is someone who always looks both ways before crossing a one-way street.\" (Doug Linder)",
                        "\"Programming is like sex. One mistake and you have to support it for the rest of your life.\" (Michael Sinz)",
                        "\"Walking on water and developing software from a specification are easy if both are frozen.\" (Edward V Berard)",
                        "\"One man's crappy software is another man's full time job.\" (Jessica Gaston)",
                        "\"A C program is like a fast dance on a newly waxed dance floor by people carrying razors.\" (Waldi Ravens)"
                       };
    int v1 = 0;
    srand (time(NULL));
    v1 = rand() % 5;
    return quotes[v1];
}
void ClassUI::sorting()
{
    string sortcho;
    cout << "Enter a sort command:" << endl;
    cout << "--------------------------------------------------------------" << endl;
    cout << " (1) - Sort by alphabetical order." << endl;
    cout << " (2) - Sort by chronological order." << endl;
    cout << " (3) - Sort by gender." << endl;
    cout << " (4) - Sort by age." << endl;
    cout << " (5) - Return to main menu." << endl;
    cout << "Enter your command (1 - 5): ";
    cin >> sortcho;
    cout << endl;

    if(sortcho == "1")
    {
        list.sortNames();
         viewAll();
    }
    else if(sortcho == "2")
    {
        list.sortBirth();
         viewAll();
    }
    else if(sortcho == "3")
    {
        list.sortGender();
        viewAll();
    }
    else if(sortcho == "4")
    {
        list.sortAge();
        viewAll();
    }
    else if(sortcho == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "That is not a valid command! Try again." << endl;
        sorting();
    }
}
void ClassUI::editPerson()
{
    string name;
    cout << "Enter the full name of the Scientist that you want to edit: ";
    cin.ignore();
    std::getline(std::cin,name);
    if(list.removePersonFound(name))
    {
        list.removePerson(name);
        addPerson();
    }
    else
    {
        cout << "Scientist not found!" << endl;
        cout << "Press any key to continue...";
        cin.get();
    }
}
/*
void ClassUI::clearTheScreen() //
{
    #if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
        system("clear");
    #endif

    #if defined(_WIN32) || defined(_WIN64)
        system("cls");
    #endif
}
*/
<commit_msg>lagadi einn staf.<commit_after>#include "classui.h"
#include "listworker.h"
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <time.h>
#include <stdlib.h>

using namespace std;

ClassUI::ClassUI()
{

}
void ClassUI::mainMenu()
{
    if (firstRun == true)
    {
        cout << "\t" << "Welcome to the Amazing Database! " << endl;
        cout << "--------------------------------------------------------------" << endl;
        cout << "\t" << "   *** Quote of the day ***" << endl;
        cout << getQuotes() << endl;
        firstRun = false;
    }
    string choice;
    do
    {
        cout << "--------------------------------------------------------------" << endl;
        cout << " (1) - "  << "Add a scientist to the database." << endl;
        cout << " (2) - "  << "Remove a scientist from the database." << endl;
        cout << " (3) - "  << "View the entire database." << endl;
        cout << " (4) - "  << "Save the database." << endl;
        cout << " (5) - "  << "Search the database." << endl;
        cout << " (6) - "  << "Sort the database." << endl;
        cout << " (7) - "  << "Edit a scientist." << endl;
        cout << " (8) - "  << "Exit." << endl;
        cout << "Enter your command (1 - 8): ";
        cin >> choice;
        if (choice != "8")
        {
           select(choice);
        }
        else
        {
            list.saveFile();
            runOn = false;
        }
    }while(runOn == true);

    cout << endl;

}
void ClassUI::select(string ch)
{
    if(ch == "1")
    {
        cin.ignore();           // When using editPerson it will ignore the first letter unless this ignore is here rather then in addPerson
        addPerson();
    }
    else if(ch == "2")
    {
        remove();
    }
    else if(ch == "3")
    {
        viewAll();
    }
    else if(ch == "4")
    {
        save();
    }
    else if(ch == "5")
    {
        searching();
    }
    else if(ch == "6")
    {
        sorting();
    }
    else if(ch == "7")
    {
        editPerson();
    }
    else if(ch == "yo")
    {
        yo();
    }
    else
    {
        cout << "Invalid input. Please enter a number between 1 - 7." << endl;
    }
}
void ClassUI::view(int i)
{
    cout << "--------------------------------------------------------------" << endl;
    int nameSize  = list.getNameSize(i);

    cout << list.getName(i);

    if(nameSize > 0 && nameSize <= 7)
    {
        cout << "\t" << "\t" << "\t" << "\t";
    }
    else if(nameSize > 7 && nameSize <= 15)
    {
        cout << "\t" << "\t" << "\t";
    }
    else if(nameSize > 15 && nameSize <= 23)
    {
        cout << "\t" << "\t";
    }
    else if(nameSize > 23 && nameSize <= 31)
    {
        cout << "\t";
    }

    if(list.getGender(i) == 'M' || list.getGender(i) == 'm')
    {
        cout << "|Male" << "\t";
    }
    else
    {
        cout << "|Female" << "\t";
    }

    cout  << "|" << list.getBirth(i);

    if(list.getDeath(i) == 0)
    {
        cout << "\t" << "| n/a"  << "\t" << "|" << list.getAge(i) << endl;
    }
    else
    {
        cout << "\t" << "|" << list.getDeath(i) << "\t" << "|" << list.getAge(i) <<  endl;
    }

    cout << list.getComment(i) << endl;
}
void ClassUI::viewAll()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << "Name" << "\t" << "\t" << "\t" << "\t" << "|Gender " << "|Born " << "\t" << "|Death"  << "\t" << "|Age" << endl;
    for(int i = 0; i < list.personsSize(); i++)
    {
        view(i);
    }
}
void ClassUI::addPerson()
{
    string name;
    string comment;
    char gender;
    char yesOrNo;
    int yearOfBirth = 0;
    int yearOfDeath = 0;

    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter name of the scientist: ";
    std::getline(std::cin,name);
    cout << "Enter a gender (M/F): ";
    cin >> gender;

    if (gender == 'm')
    {
        gender = 'M';
    }
    else if (gender == 'f')
    {
        gender = 'F';
    }

    if (gender == 'm' || gender == 'M' || gender == 'f' || gender == 'F')
    {
       cout << "Enter a year of birth: ";
       cin >> yearOfBirth;
       if (yearOfBirth < 0 || yearOfBirth > 2016)
       {
           cout << "not a valid year of birth" << endl;
           return mainMenu();
       }
       cout << "Is the individual deceased? (y/n) ";
       cin >> yesOrNo;

       if (yesOrNo == 'Y' || yesOrNo == 'y')
       {
            cout << "Enter a year of death: ";
            cin >> yearOfDeath;
            if(yearOfBirth > yearOfDeath)
            {
                cout << "Not a valid year of death" << endl;
                return mainMenu();
            }
       }

       cout << "Enter a comment about the scientist: ";
       cin.ignore();
       std::getline(std::cin,comment);
    }
    else
    {
        cout << "Invalid gender! Try again." << endl;
        return mainMenu();
    }

    cout << "Are you sure that you want to add this scientist? (y/n) ";
    string validatePerson;
    cin >> validatePerson;

    if(validatePerson == "y")
    {
        cout << "New scientist added!" << endl;
        list.addNewPerson(name, gender, yearOfBirth, yearOfDeath, comment);
    }
    else
    {
        cout << "scientist not added!" << endl;
    }
}
void ClassUI::searching()
{
    cout << "-------------Select any of the following commands-------------" << endl;
    cout << "What do you want to search for?" << endl;
    cout << " (1) - Search by name." << endl;
    cout << " (2) - Search by gender." << endl;
    cout << " (3) - Search by year of birth." << endl;
    cout << " (4) - Search by age." << endl;
    cout << " (5) - Return to main menu." << endl;

    search();
}
void ClassUI::search()
{
    string searchChoice;
    cout << "Enter your command (1 - 4): ";
    cin >> searchChoice;
    cout << endl;

    if (searchChoice == "1")
    {
        string namesearch;
        cout << "--------------------------------------------------------------" << endl;
        cout << "Enter a name you want to search for: ";
        cin.ignore();
        std::getline(std::cin,namesearch);
        cout << "--------------------------------------------------------------" << endl;
        for(int i = 0; i < list.personsSize();++i)
        {
            std::size_t found = list.getName(i).find(namesearch);
            if (found!=std::string::npos)
            {
                view(i);
            }
        }

        if(list.nameSearcher(namesearch) == false)
        {
            cout << "Sorry that name is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "2")
    {
        char gendersearch;

        cout << "Enter a gender you want to search for: (M/F)";
        cin >> gendersearch;

        if(gendersearch == 'm')
            {
                 gendersearch = 'M';
            }
        else if (gendersearch == 'f')
            {
                 gendersearch = 'F';
            }

        for(int i = 0; i < list.personsSize();++i)
        {
            if(gendersearch == list.getGender(i))
            {
                gendersearch = list.getGender(i);
                view(i);
            }
        }

        if(list.genderSearcher(gendersearch) == false)
        {
            cout << "Sorry that gender is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "3")
    {
            int yearsearch;
            cout << "Enter a year you want to search for: ";
            cin >> yearsearch;

            for(int i = 0; i < list.personsSize();++i)
            {
                if(yearsearch == list.getBirth(i))
                {
                    yearsearch = list.getBirth(i);
                    view(i);
                }
            }

            if(list.yearSearcher(yearsearch) == false)
            {
                cout << "Sorry that year is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
                searching();
            }
    }
    else if (searchChoice == "4")
    {
        int agesearch;
        cout << "Enter a age you want to search for: ";
        cin >> agesearch;

        for(int i = 0; i < list.personsSize();++i)
        {
            if(agesearch == list.getAge(i))
            {
                agesearch = list.getAge(i);
                view(i);
            }
        }

        if(list.ageSearcher(agesearch) == false)
        {
            cout << "Sorry that age is not in our database, but you can add a new scientist in the 'Add section' in the main menu." << endl;
            searching();
        }
    }
    else if (searchChoice == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "Error reading input. Please enter a number between 1- 3." << endl;
        search();
    }
}
void ClassUI::remove()
{
    string name;
    cout << "--------------------------------------------------------------" << endl;
    cout << "Enter the full name of the scientist that you want to remove: ";
    cin.ignore();
    std::getline(std::cin,name);

    if (list.removePersonFound(name) == true)
    {
        char validateRemove;
        cout << "Scientist found!" << endl;
        cout << "Are you sure you want to remove this scientist? (y/n): ";
        cin >> validateRemove;

        if(validateRemove == 'y' || validateRemove == 'Y')
        {
            if(list.removePerson(name) == true)
            {
                cout << "Scientist removed!" << endl;
            }
            else
            {
                cout << "Scientist not removed!" << endl;
            }
        }
        else
        {
            cout << "Scientist not removed!" << endl;
        }
    }
    else
    {
        cout << "Serson not found!" << endl;
    }

}
void ClassUI::save()
{
    list.saveFile();
    cout << "Database saved." << endl;
}
void ClassUI::yo()
{
    cout << "--------------------------------------------------------------" << endl;
    cout << endl;
    cout << "`8.`8888.      ,8'     ,o888888o.     " << endl;
    cout << " `8.`8888.    ,8'   . 8888     `88.   " << endl;
    cout << "  `8.`8888.  ,8'   ,8 8888       `8b  " << endl;
    cout << "   `8.`8888.,8'    88 8888        `8b " << endl;
    cout << "    `8.`88888'     88 8888         88 " << endl;
    cout << "     `8. 8888      88 8888         88 " << endl;
    cout << "      `8 8888      88 8888        ,8P " << endl;
    cout << "       8 8888      `8 8888       ,8P  " << endl;
    cout << "       8 8888       ` 8888     ,88'   " << endl;
    cout << "       8 8888          `8888888P'     " << endl;
    cout << endl;
}
string ClassUI::getQuotes()
{
    string quotes[5] = {"\"A good programmer is someone who always looks both ways before crossing a one-way street.\" (Doug Linder)",
                        "\"Programming is like sex. One mistake and you have to support it for the rest of your life.\" (Michael Sinz)",
                        "\"Walking on water and developing software from a specification are easy if both are frozen.\" (Edward V Berard)",
                        "\"One man's crappy software is another man's full time job.\" (Jessica Gaston)",
                        "\"A C program is like a fast dance on a newly waxed dance floor by people carrying razors.\" (Waldi Ravens)"
                       };
    int v1 = 0;
    srand (time(NULL));
    v1 = rand() % 5;
    return quotes[v1];
}
void ClassUI::sorting()
{
    string sortcho;
    cout << "Enter a sort command:" << endl;
    cout << "--------------------------------------------------------------" << endl;
    cout << " (1) - Sort by alphabetical order." << endl;
    cout << " (2) - Sort by chronological order." << endl;
    cout << " (3) - Sort by gender." << endl;
    cout << " (4) - Sort by age." << endl;
    cout << " (5) - Return to main menu." << endl;
    cout << "Enter your command (1 - 5): ";
    cin >> sortcho;
    cout << endl;

    if(sortcho == "1")
    {
        list.sortNames();
         viewAll();
    }
    else if(sortcho == "2")
    {
        list.sortBirth();
         viewAll();
    }
    else if(sortcho == "3")
    {
        list.sortGender();
        viewAll();
    }
    else if(sortcho == "4")
    {
        list.sortAge();
        viewAll();
    }
    else if(sortcho == "5")
    {
        mainMenu();
    }
    else
    {
        cout << "That is not a valid command! Try again." << endl;
        sorting();
    }
}
void ClassUI::editPerson()
{
    string name;
    cout << "Enter the full name of the Scientist that you want to edit: ";
    cin.ignore();
    std::getline(std::cin,name);
    if(list.removePersonFound(name))
    {
        list.removePerson(name);
        addPerson();
    }
    else
    {
        cout << "Scientist not found!" << endl;
        cout << "Press any key to continue...";
        cin.get();
    }
}
/*
void ClassUI::clearTheScreen() //
{
    #if defined(__linux__) || defined(__unix__) || defined(__APPLE__)
        system("clear");
    #endif

    #if defined(_WIN32) || defined(_WIN64)
        system("cls");
    #endif
}
*/
<|endoftext|>


<commit_before>/*
  EEPROM.cpp - EEPROM library
  Copyright (c) 2006 David A. Mellis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/******************************************************************************
 * Includes
 ******************************************************************************/

#include "Energia.h"
#include "driverlib/eeprom.h"
#include "EEPROM.h"

/******************************************************************************
 * Definitions
 ******************************************************************************/

/******************************************************************************
 * Constructors
 ******************************************************************************/

/******************************************************************************
 * User API
 ******************************************************************************/
#define BYTES_PER_WORD 	4
#define WORDS_PER_BLOCK 16
#define NUM_BLOCKS		32

uint8_t EEPROMClass::read(int address)
{
	unsigned long byteAddr = address - (address % BYTES_PER_WORD);
	//int block = address / (BYTES_PER_WORD * WORDS_PER_BLOCK);
	//int word = (address / BYTES_PER_WORD) % WORDS_PER_BLOCK;
	unsigned long wordVal = 0;

	ROM_EEPROMRead(&wordVal, byteAddr, 4);
	wordVal = wordVal >> (8*(address % BYTES_PER_WORD));

	return (uint8_t) wordVal;
}

void EEPROMClass::write(int address, uint8_t value)
{
	unsigned long byteAddr = address - (address % BYTES_PER_WORD);

	unsigned long wordVal = 0;
	ROM_EEPROMRead(&wordVal, byteAddr, 4);
	wordVal &= ~(0xFF << (8*(address % BYTES_PER_WORD)));
	wordVal += value << (8*(address % BYTES_PER_WORD));

	ROM_EEPROMProgram(&wordVal, byteAddr, 4);
}

EEPROMClass EEPROM;
<commit_msg>Update EEPROM.cpp<commit_after>/*
  EEPROM.cpp - EEPROM library
  Copyright (c) 2006 David A. Mellis.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

/******************************************************************************
 * Includes
 ******************************************************************************/

#include "Energia.h"
#include "driverlib/eeprom.h"
#include "EEPROM.h"

/******************************************************************************
 * Definitions
 ******************************************************************************/

/******************************************************************************
 * Constructors
 ******************************************************************************/

/******************************************************************************
 * User API
 ******************************************************************************/
#define BYTES_PER_WORD 	4
#define WORDS_PER_BLOCK 16
#define NUM_BLOCKS		32

uint8_t EEPROMClass::read(int address)
{
	uint32_t byteAddr = address - (address % BYTES_PER_WORD);
	//int block = address / (BYTES_PER_WORD * WORDS_PER_BLOCK);
	//int word = (address / BYTES_PER_WORD) % WORDS_PER_BLOCK;
	uint32_t wordVal = 0;

	ROM_EEPROMRead(&wordVal, byteAddr, 4);
	wordVal = wordVal >> (8*(address % BYTES_PER_WORD));

	return (uint8_t) wordVal;
}

void EEPROMClass::write(int address, uint8_t value)
{
	uint32_t byteAddr = address - (address % BYTES_PER_WORD);

	uint32_t wordVal = 0;
	ROM_EEPROMRead(&wordVal, byteAddr, 4);
	wordVal &= ~(0xFF << (8*(address % BYTES_PER_WORD)));
	wordVal += value << (8*(address % BYTES_PER_WORD));

	ROM_EEPROMProgram(&wordVal, byteAddr, 4);
}

EEPROMClass EEPROM;
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "BackendPasses.h"

#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/Inliner.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Scalar.h"

//#include "clang/Basic/LangOptions.h"
//#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Basic/CharInfo.h"

using namespace cling;
using namespace clang;
using namespace llvm;
using namespace llvm::legacy;

namespace {
  class KeepLocalGVPass: public ModulePass {
    static char ID;

    bool runOnGlobal(GlobalValue& GV) {
      if (GV.isDeclaration())
        return false; // no change.

      // GV is a definition.

      llvm::GlobalValue::LinkageTypes LT = GV.getLinkage();
      if (!GV.isDiscardableIfUnused(LT))
        return false;

      if (LT == llvm::GlobalValue::InternalLinkage
          || LT == llvm::GlobalValue::PrivateLinkage) {
        GV.setLinkage(llvm::GlobalValue::ExternalLinkage);
        return true; // a change!
      }
      return false;
    }

  public:
    KeepLocalGVPass() : ModulePass(ID) {}

    bool runOnModule(Module &M) override {
      bool ret = false;
      for (auto &&F: M)
        ret |= runOnGlobal(F);
      for (auto &&G: M.globals())
        ret |= runOnGlobal(G);
      return ret;
    }
  };
}

char KeepLocalGVPass::ID = 0;

namespace {

  // Add a suffix to the CUDA module ctor/dtor to generate a unique name.
  // This is necessary for lazy compilation. Without suffix, cling cannot
  // distinguish ctor/dtor of subsequent modules.
  class UniqueCUDAStructorName : public ModulePass {
    static char ID;

    bool runOnFunction(Function& F, const StringRef ModuleName){
      if(F.hasName() && (F.getName() == "__cuda_module_ctor"
          || F.getName() == "__cuda_module_dtor") ){
        llvm::SmallString<128> NewFunctionName;
        NewFunctionName.append(F.getName());
        NewFunctionName.append("_");
        NewFunctionName.append(ModuleName);

        for (size_t i = 0; i < NewFunctionName.size(); ++i) {
          // Replace everything that is not [a-zA-Z0-9._] with a _. This set
          // happens to be the set of C preprocessing numbers.
          if (!isPreprocessingNumberBody(NewFunctionName[i]))
            NewFunctionName[i] = '_';
        }

        F.setName(NewFunctionName);

        return true;
      }

      return false;
    }

  public:
    UniqueCUDAStructorName() : ModulePass(ID) {}

    bool runOnModule(Module &M) override {
      bool ret = false;
      const StringRef ModuleName = M.getName();
      for (auto &&F: M)
        ret |= runOnFunction(F, ModuleName);
      return ret;
    }
  };
}

char UniqueCUDAStructorName::ID = 0;

BackendPasses::~BackendPasses() {
  //delete m_PMBuilder->Inliner;
}

void BackendPasses::CreatePasses(llvm::Module& M, int OptLevel)
{
  // From BackEndUtil's clang::EmitAssemblyHelper::CreatePasses().

#if 0
  CodeGenOptions::InliningMethod Inlining = m_CGOpts.getInlining();
  CodeGenOptions& CGOpts_ = const_cast<CodeGenOptions&>(m_CGOpts);
  // DON'T: we will not find our symbols...
  //CGOpts_.CXXCtorDtorAliases = 1;

  // Default clang -O2 on Linux 64bit also has the following, but see
  // CIFactory.cpp.
  CGOpts_.DisableFPElim = 0;
  CGOpts_.DiscardValueNames = 1;
  CGOpts_.OmitLeafFramePointer = 1;
  CGOpts_.OptimizationLevel = 2;
  CGOpts_.RelaxAll = 0;
  CGOpts_.UnrollLoops = 1;
  CGOpts_.VectorizeLoop = 1;
  CGOpts_.VectorizeSLP = 1;
#endif

#if 0 // def __GNUC__
  // Better inlining is pending https://bugs.llvm.org//show_bug.cgi?id=19668
  // and its consequence https://sft.its.cern.ch/jira/browse/ROOT-7111
  // shown e.g. by roottest/cling/stl/map/badstringMap
  if (Inlining > CodeGenOptions::NormalInlining)
    Inlining = CodeGenOptions::NormalInlining;
#endif

  // Handle disabling of LLVM optimization, where we want to preserve the
  // internal module before any optimization.
  if (m_CGOpts.DisableLLVMPasses) {
    OptLevel = 0;
    // Always keep at least ForceInline - NoInlining is deadly for libc++.
    // Inlining = CGOpts.NoInlining;
  }

  llvm::PassManagerBuilder PMBuilder;
  PMBuilder.OptLevel = OptLevel;
  PMBuilder.SizeLevel = m_CGOpts.OptimizeSize;
  PMBuilder.SLPVectorize = OptLevel > 1 ? 1 : 0; // m_CGOpts.VectorizeSLP
  PMBuilder.LoopVectorize = OptLevel > 1 ? 1 : 0; // m_CGOpts.VectorizeLoop

  PMBuilder.DisableTailCalls = m_CGOpts.DisableTailCalls;
  PMBuilder.DisableUnrollLoops = !m_CGOpts.UnrollLoops;
  PMBuilder.MergeFunctions = m_CGOpts.MergeFunctions;
  PMBuilder.RerollLoops = m_CGOpts.RerollLoops;

  PMBuilder.LibraryInfo = new TargetLibraryInfoImpl(m_TM.getTargetTriple());

  // At O0 and O1 we only run the always inliner which is more efficient. At
  // higher optimization levels we run the normal inliner.
  // See also call to `CGOpts.setInlining()` in CIFactory!
  if (m_CGOpts.OptimizationLevel <= 1) {
    bool InsertLifetimeIntrinsics = m_CGOpts.OptimizationLevel != 0;
    PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
  } else {
    PMBuilder.Inliner = createFunctionInliningPass(m_CGOpts.OptimizationLevel,
                                                   m_CGOpts.OptimizeSize,
            (!m_CGOpts.SampleProfileFile.empty() && m_CGOpts.EmitSummaryIndex));
  }

  // Set up the per-module pass manager.
  m_MPM[OptLevel].reset(new legacy::PassManager());

  m_MPM[OptLevel]->add(new KeepLocalGVPass());
  // The function __cuda_module_ctor and __cuda_module_dtor will just generated,
  // if a CUDA fatbinary file exist. Without file path there is no need for the
  // function pass.
  if(!m_CGOpts.CudaGpuBinaryFileNames.empty())
    m_MPM[OptLevel]->add(new UniqueCUDAStructorName());
  m_MPM[OptLevel]->add(createTargetTransformInfoWrapperPass(
                                                   m_TM.getTargetIRAnalysis()));

  m_TM.adjustPassManager(PMBuilder);

  PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                         [&](const PassManagerBuilder &,
                             legacy::PassManagerBase &PM) {
                              PM.add(createAddDiscriminatorsPass());
                            });

  //if (!CGOpts.RewriteMapFiles.empty())
  //  addSymbolRewriterPass(CGOpts, m_MPM);

  PMBuilder.populateModulePassManager(*m_MPM[OptLevel]);

  m_FPM[OptLevel].reset(new legacy::FunctionPassManager(&M));
  m_FPM[OptLevel]->add(createTargetTransformInfoWrapperPass(
                                                   m_TM.getTargetIRAnalysis()));
  if (m_CGOpts.VerifyModule)
      m_FPM[OptLevel]->add(createVerifierPass());
  PMBuilder.populateFunctionPassManager(*m_FPM[OptLevel]);
}

void BackendPasses::runOnModule(Module& M, int OptLevel) {

  if (OptLevel < 0)
    OptLevel = 0;
  if (OptLevel > 3)
    OptLevel = 3;

  if (!m_MPM[OptLevel])
    CreatePasses(M, OptLevel);

  static constexpr std::array<llvm::CodeGenOpt::Level, 4> CGOptLevel {{
    llvm::CodeGenOpt::None,
    llvm::CodeGenOpt::Less,
    llvm::CodeGenOpt::Default,
    llvm::CodeGenOpt::Aggressive
  }};
  // TM's OptLevel is used to build orc::SimpleCompiler passes for every Module.
  m_TM.setOptLevel(CGOptLevel[OptLevel]);

  // Run the per-function passes on the module.
  m_FPM[OptLevel]->doInitialization();
  for (auto&& I: M.functions())
    if (!I.isDeclaration())
      m_FPM[OptLevel]->run(I);
  m_FPM[OptLevel]->doFinalization();

  m_MPM[OptLevel]->run(M);
}
<commit_msg>[cling] Enable inline passes for higher (cling-runtime) opt levels.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "BackendPasses.h"

#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/AlwaysInliner.h"
#include "llvm/Transforms/IPO/Inliner.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Scalar.h"

//#include "clang/Basic/LangOptions.h"
//#include "clang/Basic/TargetOptions.h"
#include "clang/Frontend/CodeGenOptions.h"
#include "clang/Basic/CharInfo.h"

using namespace cling;
using namespace clang;
using namespace llvm;
using namespace llvm::legacy;

namespace {
  class KeepLocalGVPass: public ModulePass {
    static char ID;

    bool runOnGlobal(GlobalValue& GV) {
      if (GV.isDeclaration())
        return false; // no change.

      // GV is a definition.

      llvm::GlobalValue::LinkageTypes LT = GV.getLinkage();
      if (!GV.isDiscardableIfUnused(LT))
        return false;

      if (LT == llvm::GlobalValue::InternalLinkage
          || LT == llvm::GlobalValue::PrivateLinkage) {
        GV.setLinkage(llvm::GlobalValue::ExternalLinkage);
        return true; // a change!
      }
      return false;
    }

  public:
    KeepLocalGVPass() : ModulePass(ID) {}

    bool runOnModule(Module &M) override {
      bool ret = false;
      for (auto &&F: M)
        ret |= runOnGlobal(F);
      for (auto &&G: M.globals())
        ret |= runOnGlobal(G);
      return ret;
    }
  };
}

char KeepLocalGVPass::ID = 0;

namespace {

  // Add a suffix to the CUDA module ctor/dtor to generate a unique name.
  // This is necessary for lazy compilation. Without suffix, cling cannot
  // distinguish ctor/dtor of subsequent modules.
  class UniqueCUDAStructorName : public ModulePass {
    static char ID;

    bool runOnFunction(Function& F, const StringRef ModuleName){
      if(F.hasName() && (F.getName() == "__cuda_module_ctor"
          || F.getName() == "__cuda_module_dtor") ){
        llvm::SmallString<128> NewFunctionName;
        NewFunctionName.append(F.getName());
        NewFunctionName.append("_");
        NewFunctionName.append(ModuleName);

        for (size_t i = 0; i < NewFunctionName.size(); ++i) {
          // Replace everything that is not [a-zA-Z0-9._] with a _. This set
          // happens to be the set of C preprocessing numbers.
          if (!isPreprocessingNumberBody(NewFunctionName[i]))
            NewFunctionName[i] = '_';
        }

        F.setName(NewFunctionName);

        return true;
      }

      return false;
    }

  public:
    UniqueCUDAStructorName() : ModulePass(ID) {}

    bool runOnModule(Module &M) override {
      bool ret = false;
      const StringRef ModuleName = M.getName();
      for (auto &&F: M)
        ret |= runOnFunction(F, ModuleName);
      return ret;
    }
  };
}

char UniqueCUDAStructorName::ID = 0;

BackendPasses::~BackendPasses() {
  //delete m_PMBuilder->Inliner;
}

void BackendPasses::CreatePasses(llvm::Module& M, int OptLevel)
{
  // From BackEndUtil's clang::EmitAssemblyHelper::CreatePasses().

#if 0
  CodeGenOptions::InliningMethod Inlining = m_CGOpts.getInlining();
  CodeGenOptions& CGOpts_ = const_cast<CodeGenOptions&>(m_CGOpts);
  // DON'T: we will not find our symbols...
  //CGOpts_.CXXCtorDtorAliases = 1;

  // Default clang -O2 on Linux 64bit also has the following, but see
  // CIFactory.cpp.
  CGOpts_.DisableFPElim = 0;
  CGOpts_.DiscardValueNames = 1;
  CGOpts_.OmitLeafFramePointer = 1;
  CGOpts_.OptimizationLevel = 2;
  CGOpts_.RelaxAll = 0;
  CGOpts_.UnrollLoops = 1;
  CGOpts_.VectorizeLoop = 1;
  CGOpts_.VectorizeSLP = 1;
#endif

#if 0 // def __GNUC__
  // Better inlining is pending https://bugs.llvm.org//show_bug.cgi?id=19668
  // and its consequence https://sft.its.cern.ch/jira/browse/ROOT-7111
  // shown e.g. by roottest/cling/stl/map/badstringMap
  if (Inlining > CodeGenOptions::NormalInlining)
    Inlining = CodeGenOptions::NormalInlining;
#endif

  // Handle disabling of LLVM optimization, where we want to preserve the
  // internal module before any optimization.
  if (m_CGOpts.DisableLLVMPasses) {
    OptLevel = 0;
    // Always keep at least ForceInline - NoInlining is deadly for libc++.
    // Inlining = CGOpts.NoInlining;
  }

  llvm::PassManagerBuilder PMBuilder;
  PMBuilder.OptLevel = OptLevel;
  PMBuilder.SizeLevel = m_CGOpts.OptimizeSize;
  PMBuilder.SLPVectorize = OptLevel > 1 ? 1 : 0; // m_CGOpts.VectorizeSLP
  PMBuilder.LoopVectorize = OptLevel > 1 ? 1 : 0; // m_CGOpts.VectorizeLoop

  PMBuilder.DisableTailCalls = m_CGOpts.DisableTailCalls;
  PMBuilder.DisableUnrollLoops = !m_CGOpts.UnrollLoops;
  PMBuilder.MergeFunctions = m_CGOpts.MergeFunctions;
  PMBuilder.RerollLoops = m_CGOpts.RerollLoops;

  PMBuilder.LibraryInfo = new TargetLibraryInfoImpl(m_TM.getTargetTriple());

  // At O0 and O1 we only run the always inliner which is more efficient. At
  // higher optimization levels we run the normal inliner.
  // See also call to `CGOpts.setInlining()` in CIFactory!
  if (PMBuilder.OptLevel <= 1) {
    bool InsertLifetimeIntrinsics = PMBuilder.OptLevel != 0;
    PMBuilder.Inliner = createAlwaysInlinerLegacyPass(InsertLifetimeIntrinsics);
  } else {
    PMBuilder.Inliner = createFunctionInliningPass(OptLevel,
                                                   PMBuilder.SizeLevel,
            (!m_CGOpts.SampleProfileFile.empty() && m_CGOpts.EmitSummaryIndex));
  }

  // Set up the per-module pass manager.
  m_MPM[OptLevel].reset(new legacy::PassManager());

  m_MPM[OptLevel]->add(new KeepLocalGVPass());
  // The function __cuda_module_ctor and __cuda_module_dtor will just generated,
  // if a CUDA fatbinary file exist. Without file path there is no need for the
  // function pass.
  if(!m_CGOpts.CudaGpuBinaryFileNames.empty())
    m_MPM[OptLevel]->add(new UniqueCUDAStructorName());
  m_MPM[OptLevel]->add(createTargetTransformInfoWrapperPass(
                                                   m_TM.getTargetIRAnalysis()));

  m_TM.adjustPassManager(PMBuilder);

  PMBuilder.addExtension(PassManagerBuilder::EP_EarlyAsPossible,
                         [&](const PassManagerBuilder &,
                             legacy::PassManagerBase &PM) {
                              PM.add(createAddDiscriminatorsPass());
                            });

  //if (!CGOpts.RewriteMapFiles.empty())
  //  addSymbolRewriterPass(CGOpts, m_MPM);

  PMBuilder.populateModulePassManager(*m_MPM[OptLevel]);

  m_FPM[OptLevel].reset(new legacy::FunctionPassManager(&M));
  m_FPM[OptLevel]->add(createTargetTransformInfoWrapperPass(
                                                   m_TM.getTargetIRAnalysis()));
  if (m_CGOpts.VerifyModule)
      m_FPM[OptLevel]->add(createVerifierPass());
  PMBuilder.populateFunctionPassManager(*m_FPM[OptLevel]);
}

void BackendPasses::runOnModule(Module& M, int OptLevel) {

  if (OptLevel < 0)
    OptLevel = 0;
  if (OptLevel > 3)
    OptLevel = 3;

  if (!m_MPM[OptLevel])
    CreatePasses(M, OptLevel);

  static constexpr std::array<llvm::CodeGenOpt::Level, 4> CGOptLevel {{
    llvm::CodeGenOpt::None,
    llvm::CodeGenOpt::Less,
    llvm::CodeGenOpt::Default,
    llvm::CodeGenOpt::Aggressive
  }};
  // TM's OptLevel is used to build orc::SimpleCompiler passes for every Module.
  m_TM.setOptLevel(CGOptLevel[OptLevel]);

  // Run the per-function passes on the module.
  m_FPM[OptLevel]->doInitialization();
  for (auto&& I: M.functions())
    if (!I.isDeclaration())
      m_FPM[OptLevel]->run(I);
  m_FPM[OptLevel]->doFinalization();

  m_MPM[OptLevel]->run(M);
}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "lxqtcpuload.h"
#include "../panel/ilxqtpanelplugin.h"
#include "../panel/pluginsettings.h"
#include <QtCore>
#include <QPainter>
#include <QLinearGradient>
#include <QHBoxLayout>

extern "C" {
#include <statgrab.h>
}

#ifdef __sg_public
// since libstatgrab 0.90 this macro is defined, so we use it for version check
#define STATGRAB_NEWER_THAN_0_90 	1
#endif

#define BAR_ORIENT_BOTTOMUP "bottomUp"
#define BAR_ORIENT_TOPDOWN "topDown"
#define BAR_ORIENT_LEFTRIGHT "leftRight"
#define BAR_ORIENT_RIGHTLEFT "rightLeft"

LXQtCpuLoad::LXQtCpuLoad(ILXQtPanelPlugin* plugin, QWidget* parent):
    QFrame(parent),
    mPlugin(plugin),
    m_showText(false),
    m_barWidth(20),
    m_barOrientation(TopDownBar),
    m_timerID(-1)
{
    setObjectName("LXQtCpuLoad");

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(&m_stuff);

    /* Initialise statgrab */
#ifdef STATGRAB_NEWER_THAN_0_90
    sg_init(0);
#else
    sg_init();
#endif

    /* Drop setuid/setgid privileges. */
    if (sg_drop_privileges() != 0) {
        perror("Error. Failed to drop privileges");
    }

    m_font.setPointSizeF(8);

    settingsChanged();
}

LXQtCpuLoad::~LXQtCpuLoad()
{
}

void LXQtCpuLoad::setSizes()
{
    if (m_barOrientation == RightToLeftBar || m_barOrientation == LeftToRightBar)
    {
        m_stuff.setFixedHeight(m_barWidth);
        m_stuff.setMinimumWidth(24);
    }
    else
    {
        m_stuff.setFixedWidth(m_barWidth);
        m_stuff.setMinimumHeight(24);
    }
}

void LXQtCpuLoad::resizeEvent(QResizeEvent *)
{
    setSizes();
    update();
}

double LXQtCpuLoad::getLoadCpu() const
{
#ifdef STATGRAB_NEWER_THAN_0_90
    size_t count;
    sg_cpu_percents* cur = sg_get_cpu_percents(&count);
#else
    sg_cpu_percents* cur = sg_get_cpu_percents();
#endif
    return (cur->user + cur->kernel + cur->nice);
}

void LXQtCpuLoad::timerEvent(QTimerEvent *event)
{
    double avg = getLoadCpu();
    if ( qAbs(m_avg-avg)>1 )
    {
        m_avg = avg;
        setToolTip(tr("CPU load %1%").arg(m_avg));
        update();
    }
}

void LXQtCpuLoad::paintEvent ( QPaintEvent * )
{
    QPainter p(this);
    QPen pen;
    pen.setWidth(2);
    p.setPen(pen);
    p.setRenderHint(QPainter::Antialiasing, true);

    p.setFont(m_font);
    QRectF r = rect();

    QRectF r1;
    QLinearGradient shade(0,0,1,1);
    if (m_barOrientation == RightToLeftBar || m_barOrientation == LeftToRightBar)
    {
        float vo = (r.height() - static_cast<double>(m_barWidth))/2.0;
        float ho = r.width()*(1-m_avg*0.01);

        if (m_barOrientation == RightToLeftBar)
        {
            r1.setRect(r.left()+ho, r.top()+vo, r.width()-ho, r.height()-2*vo );
        }
        else // LeftToRightBar
        {
            r1.setRect(r.left(), r.top()+vo, r.width()-ho, r.height()-2*vo );
        }
        shade.setFinalStop(0, r1.height());
    }
    else // BottomUpBar || TopDownBar
    {
        float vo = r.height()*(1-m_avg*0.01);
        float ho = (r.width() - static_cast<double>(m_barWidth) )/2.0;

        if (m_barOrientation == TopDownBar)
        {
            r1.setRect(r.left()+ho, r.top(), r.width()-2*ho, r.height()-vo );
        }
        else // BottomUpBar
        {
            r1.setRect(r.left()+ho, r.top()+vo, r.width()-2*ho, r.height()-vo );
        }
        shade.setFinalStop(r1.width(), 0);
    }

    shade.setSpread(QLinearGradient::ReflectSpread);
    shade.setColorAt(0, QColor(0, 196, 0, 128));
    shade.setColorAt(0.5, QColor(0, 128, 0, 255) );
    shade.setColorAt(1, QColor(0, 196, 0 , 128));

    p.fillRect(r1, shade);

    if (m_showText)
    {
        p.setPen(fontColor);
        p.drawText(rect(), Qt::AlignCenter, QString::number(m_avg));
    }
}

void LXQtCpuLoad::settingsChanged()
{
    if (m_timerID != -1)
        killTimer(m_timerID);

    m_showText = mPlugin->settings()->value("showText", false).toBool();
    m_barWidth = mPlugin->settings()->value("barWidth", 20).toInt();
    m_updateInterval = mPlugin->settings()->value("updateInterval", 1000).toInt();

    QString barOrientation = mPlugin->settings()->value("barOrientation", BAR_ORIENT_BOTTOMUP).toString();
    if (barOrientation == BAR_ORIENT_RIGHTLEFT)
        m_barOrientation = RightToLeftBar;
    else if (barOrientation == BAR_ORIENT_LEFTRIGHT)
        m_barOrientation = LeftToRightBar;
    else if (barOrientation == BAR_ORIENT_TOPDOWN)
        m_barOrientation = TopDownBar;
    else
        m_barOrientation = BottomUpBar;

    m_timerID = startTimer(m_updateInterval);
    setSizes();
    update();
}
<commit_msg>cpuload: Do proper cleanup<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2012 Razor team
 * Authors:
 *   Alexander Sokoloff <sokoloff.a@gmail.com>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include "lxqtcpuload.h"
#include "../panel/ilxqtpanelplugin.h"
#include "../panel/pluginsettings.h"
#include <QtCore>
#include <QPainter>
#include <QLinearGradient>
#include <QHBoxLayout>

extern "C" {
#include <statgrab.h>
}

#ifdef __sg_public
// since libstatgrab 0.90 this macro is defined, so we use it for version check
#define STATGRAB_NEWER_THAN_0_90 	1
#endif

#define BAR_ORIENT_BOTTOMUP "bottomUp"
#define BAR_ORIENT_TOPDOWN "topDown"
#define BAR_ORIENT_LEFTRIGHT "leftRight"
#define BAR_ORIENT_RIGHTLEFT "rightLeft"

LXQtCpuLoad::LXQtCpuLoad(ILXQtPanelPlugin* plugin, QWidget* parent):
    QFrame(parent),
    mPlugin(plugin),
    m_avg(0),
    m_showText(false),
    m_barWidth(20),
    m_barOrientation(TopDownBar),
    m_timerID(-1)
{
    setObjectName("LXQtCpuLoad");

    QHBoxLayout *layout = new QHBoxLayout(this);
    layout->setSpacing(0);
    layout->setContentsMargins(0, 0, 0, 0);
    layout->addWidget(&m_stuff);

    /* Initialise statgrab */
#ifdef STATGRAB_NEWER_THAN_0_90
    sg_init(0);
#else
    sg_init();
#endif

    /* Drop setuid/setgid privileges. */
    if (sg_drop_privileges() != 0) {
        perror("Error. Failed to drop privileges");
    }

    m_font.setPointSizeF(8);

    settingsChanged();
}

LXQtCpuLoad::~LXQtCpuLoad()
{
  sg_shutdown();
}

void LXQtCpuLoad::setSizes()
{
    if (m_barOrientation == RightToLeftBar || m_barOrientation == LeftToRightBar)
    {
        m_stuff.setFixedHeight(m_barWidth);
        m_stuff.setMinimumWidth(24);
    }
    else
    {
        m_stuff.setFixedWidth(m_barWidth);
        m_stuff.setMinimumHeight(24);
    }
}

void LXQtCpuLoad::resizeEvent(QResizeEvent *)
{
    setSizes();
    update();
}

double LXQtCpuLoad::getLoadCpu() const
{
#ifdef STATGRAB_NEWER_THAN_0_90
    size_t count;
    sg_cpu_percents* cur = sg_get_cpu_percents(&count);
#else
    sg_cpu_percents* cur = sg_get_cpu_percents();
#endif
    return (cur->user + cur->kernel + cur->nice);
}

void LXQtCpuLoad::timerEvent(QTimerEvent *event)
{
    double avg = getLoadCpu();
    if ( qAbs(m_avg-avg)>1 )
    {
        m_avg = avg;
        setToolTip(tr("CPU load %1%").arg(m_avg));
        update();
    }
}

void LXQtCpuLoad::paintEvent ( QPaintEvent * )
{
    QPainter p(this);
    QPen pen;
    pen.setWidth(2);
    p.setPen(pen);
    p.setRenderHint(QPainter::Antialiasing, true);

    p.setFont(m_font);
    QRectF r = rect();

    QRectF r1;
    QLinearGradient shade(0,0,1,1);
    if (m_barOrientation == RightToLeftBar || m_barOrientation == LeftToRightBar)
    {
        float vo = (r.height() - static_cast<double>(m_barWidth))/2.0;
        float ho = r.width()*(1-m_avg*0.01);

        if (m_barOrientation == RightToLeftBar)
        {
            r1.setRect(r.left()+ho, r.top()+vo, r.width()-ho, r.height()-2*vo );
        }
        else // LeftToRightBar
        {
            r1.setRect(r.left(), r.top()+vo, r.width()-ho, r.height()-2*vo );
        }
        shade.setFinalStop(0, r1.height());
    }
    else // BottomUpBar || TopDownBar
    {
        float vo = r.height()*(1-m_avg*0.01);
        float ho = (r.width() - static_cast<double>(m_barWidth) )/2.0;

        if (m_barOrientation == TopDownBar)
        {
            r1.setRect(r.left()+ho, r.top(), r.width()-2*ho, r.height()-vo );
        }
        else // BottomUpBar
        {
            r1.setRect(r.left()+ho, r.top()+vo, r.width()-2*ho, r.height()-vo );
        }
        shade.setFinalStop(r1.width(), 0);
    }

    shade.setSpread(QLinearGradient::ReflectSpread);
    shade.setColorAt(0, QColor(0, 196, 0, 128));
    shade.setColorAt(0.5, QColor(0, 128, 0, 255) );
    shade.setColorAt(1, QColor(0, 196, 0 , 128));

    p.fillRect(r1, shade);

    if (m_showText)
    {
        p.setPen(fontColor);
        p.drawText(rect(), Qt::AlignCenter, QString::number(m_avg));
    }
}

void LXQtCpuLoad::settingsChanged()
{
    if (m_timerID != -1)
        killTimer(m_timerID);

    m_showText = mPlugin->settings()->value("showText", false).toBool();
    m_barWidth = mPlugin->settings()->value("barWidth", 20).toInt();
    m_updateInterval = mPlugin->settings()->value("updateInterval", 1000).toInt();

    QString barOrientation = mPlugin->settings()->value("barOrientation", BAR_ORIENT_BOTTOMUP).toString();
    if (barOrientation == BAR_ORIENT_RIGHTLEFT)
        m_barOrientation = RightToLeftBar;
    else if (barOrientation == BAR_ORIENT_LEFTRIGHT)
        m_barOrientation = LeftToRightBar;
    else if (barOrientation == BAR_ORIENT_TOPDOWN)
        m_barOrientation = TopDownBar;
    else
        m_barOrientation = BottomUpBar;

    m_timerID = startTimer(m_updateInterval);
    setSizes();
    update();
}
<|endoftext|>