<commit_before>/*************************************************************************/
/*  file_access_jandroid.cpp                                             */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#ifndef ANDROID_NATIVE_ACTIVITY

#include "file_access_jandroid.h"
#include "os/os.h"
#include <unistd.h>
#include "thread_jandroid.h"

jobject FileAccessJAndroid::io=NULL;
jclass FileAccessJAndroid::cls;
jmethodID FileAccessJAndroid::_file_open=0;
jmethodID FileAccessJAndroid::_file_get_size=0;
jmethodID FileAccessJAndroid::_file_seek=0;
jmethodID FileAccessJAndroid::_file_read=0;
jmethodID FileAccessJAndroid::_file_tell=0;
jmethodID FileAccessJAndroid::_file_eof=0;
jmethodID FileAccessJAndroid::_file_close=0;

FileAccess* FileAccessJAndroid::create_jandroid() {

	return memnew(FileAccessJAndroid);
}

Error FileAccessJAndroid::_open(const String& p_path, int p_mode_flags) {

	if (is_open())
		close();

	String path=fix_path(p_path).simplify_path();
	if (path.begins_with("/"))
		path=path.substr(1,path.length());
	else if (path.begins_with("res://"))
		path=path.substr(6,path.length());

	JNIEnv *env = ThreadAndroid::get_env();

	jstring js = env->NewStringUTF(path.utf8().get_data());
	int res = env->CallIntMethod(io,_file_open,js,p_mode_flags&WRITE?true:false);
	env->DeleteLocalRef(js);

	OS::get_singleton()->print("fopen: '%s' ret %i\n",path.utf8().get_data(),res);

	if (res<=0)
		return ERR_FILE_CANT_OPEN;
	id=res;

	return OK;
}

void FileAccessJAndroid::close() {

	if (!is_open())
		return;

	JNIEnv *env = ThreadAndroid::get_env();

	env->CallVoidMethod(io,_file_close,id);
	id=0;

}
bool FileAccessJAndroid::is_open() const {

	return id!=0;
}

void FileAccessJAndroid::seek(size_t p_position) {

	JNIEnv *env = ThreadAndroid::get_env();

	ERR_FAIL_COND(!is_open());
	env->CallVoidMethod(io,_file_seek,id,p_position);
}
void FileAccessJAndroid::seek_end(int64_t p_position) {

	ERR_FAIL_COND(!is_open());

	seek(get_len());

}
size_t FileAccessJAndroid::get_pos() const {

	JNIEnv *env = ThreadAndroid::get_env();
	ERR_FAIL_COND_V(!is_open(),0);
	return env->CallIntMethod(io,_file_tell,id);

}
size_t FileAccessJAndroid::get_len() const {

	JNIEnv *env = ThreadAndroid::get_env();
	ERR_FAIL_COND_V(!is_open(),0);
	return env->CallIntMethod(io,_file_get_size,id);

}

bool FileAccessJAndroid::eof_reached() const {

	JNIEnv *env = ThreadAndroid::get_env();
	ERR_FAIL_COND_V(!is_open(),0);
	return env->CallIntMethod(io,_file_eof,id);

}

uint8_t FileAccessJAndroid::get_8() const {

	ERR_FAIL_COND_V(!is_open(),0);
	uint8_t byte;
	get_buffer(&byte,1);
	return byte;
}
int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {

	ERR_FAIL_COND_V(!is_open(),0);
	if (p_length==0)
		return 0;
	JNIEnv *env = ThreadAndroid::get_env();

	jbyteArray jca = (jbyteArray)env->CallObjectMethod(io,_file_read,id,p_length);

	int len = env->GetArrayLength(jca);
	env->GetByteArrayRegion(jca,0,len,(jbyte*)p_dst);
	env->DeleteLocalRef((jobject)jca);

	return len;

}

Error FileAccessJAndroid::get_error() const {

	if (eof_reached())
		return ERR_FILE_EOF;
	return OK;
}

void FileAccessJAndroid::store_8(uint8_t p_dest) {

}

bool FileAccessJAndroid::file_exists(const String& p_path) {

	JNIEnv *env = ThreadAndroid::get_env();

	String path=fix_path(p_path).simplify_path();
	if (path.begins_with("/"))
		path=path.substr(1,path.length());
	else if (path.begins_with("res://"))
		path=path.substr(6,path.length());

	jstring js = env->NewStringUTF(path.utf8().get_data());
	int res = env->CallIntMethod(io,_file_open,js,false);
	if (res<=0)
		return false;
	env->CallVoidMethod(io,_file_close,res);
	env->DeleteLocalRef(js);
	return true;

}

void FileAccessJAndroid::setup(  jobject p_io) {

	io=p_io;
	JNIEnv *env = ThreadAndroid::get_env();

	__android_log_print(ANDROID_LOG_INFO,"godot","STEP5");

	jclass c = env->GetObjectClass(io);
	__android_log_print(ANDROID_LOG_INFO,"godot","STEP6");
	cls=(jclass)env->NewGlobalRef(c);

	_file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I");
	if(_file_open != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_open ok!!");
	}
	_file_get_size = env->GetMethodID(cls, "file_get_size", "(I)I");
	if(_file_get_size != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_get_size ok!!");
	}
	_file_tell = env->GetMethodID(cls, "file_tell", "(I)I");
	if(_file_tell != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_tell ok!!");
	}
	_file_eof = env->GetMethodID(cls, "file_eof", "(I)Z");

	if(_file_eof != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_eof ok!!");
	}
	_file_seek = env->GetMethodID(cls, "file_seek", "(II)V");
	if(_file_seek != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_seek ok!!");
	}
	_file_read = env->GetMethodID(cls, "file_read", "(II)[B");
	if(_file_read != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_read ok!!");
	}
	_file_close = env->GetMethodID(cls, "file_close", "(I)V");
	if(_file_close != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_close ok!!");
	}

//	(*env)->CallVoidMethod(env,obj,aMethodID, myvar);
}

FileAccessJAndroid::FileAccessJAndroid()
{

	id=0;
}

FileAccessJAndroid::~FileAccessJAndroid()
{

	if (is_open())
		close();
}

#endif
<commit_msg>Fix crash in FileAccessJAndroid::file_exists (does not free local ref)<commit_after>/*************************************************************************/
/*  file_access_jandroid.cpp                                             */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#ifndef ANDROID_NATIVE_ACTIVITY

#include "file_access_jandroid.h"
#include "os/os.h"
#include <unistd.h>
#include "thread_jandroid.h"

jobject FileAccessJAndroid::io=NULL;
jclass FileAccessJAndroid::cls;
jmethodID FileAccessJAndroid::_file_open=0;
jmethodID FileAccessJAndroid::_file_get_size=0;
jmethodID FileAccessJAndroid::_file_seek=0;
jmethodID FileAccessJAndroid::_file_read=0;
jmethodID FileAccessJAndroid::_file_tell=0;
jmethodID FileAccessJAndroid::_file_eof=0;
jmethodID FileAccessJAndroid::_file_close=0;

FileAccess* FileAccessJAndroid::create_jandroid() {

	return memnew(FileAccessJAndroid);
}

Error FileAccessJAndroid::_open(const String& p_path, int p_mode_flags) {

	if (is_open())
		close();

	String path=fix_path(p_path).simplify_path();
	if (path.begins_with("/"))
		path=path.substr(1,path.length());
	else if (path.begins_with("res://"))
		path=path.substr(6,path.length());

	JNIEnv *env = ThreadAndroid::get_env();

	jstring js = env->NewStringUTF(path.utf8().get_data());
	int res = env->CallIntMethod(io,_file_open,js,p_mode_flags&WRITE?true:false);
	env->DeleteLocalRef(js);

	OS::get_singleton()->print("fopen: '%s' ret %i\n",path.utf8().get_data(),res);

	if (res<=0)
		return ERR_FILE_CANT_OPEN;
	id=res;

	return OK;
}

void FileAccessJAndroid::close() {

	if (!is_open())
		return;

	JNIEnv *env = ThreadAndroid::get_env();

	env->CallVoidMethod(io,_file_close,id);
	id=0;

}
bool FileAccessJAndroid::is_open() const {

	return id!=0;
}

void FileAccessJAndroid::seek(size_t p_position) {

	JNIEnv *env = ThreadAndroid::get_env();

	ERR_FAIL_COND(!is_open());
	env->CallVoidMethod(io,_file_seek,id,p_position);
}
void FileAccessJAndroid::seek_end(int64_t p_position) {

	ERR_FAIL_COND(!is_open());

	seek(get_len());

}
size_t FileAccessJAndroid::get_pos() const {

	JNIEnv *env = ThreadAndroid::get_env();
	ERR_FAIL_COND_V(!is_open(),0);
	return env->CallIntMethod(io,_file_tell,id);

}
size_t FileAccessJAndroid::get_len() const {

	JNIEnv *env = ThreadAndroid::get_env();
	ERR_FAIL_COND_V(!is_open(),0);
	return env->CallIntMethod(io,_file_get_size,id);

}

bool FileAccessJAndroid::eof_reached() const {

	JNIEnv *env = ThreadAndroid::get_env();
	ERR_FAIL_COND_V(!is_open(),0);
	return env->CallIntMethod(io,_file_eof,id);

}

uint8_t FileAccessJAndroid::get_8() const {

	ERR_FAIL_COND_V(!is_open(),0);
	uint8_t byte;
	get_buffer(&byte,1);
	return byte;
}
int FileAccessJAndroid::get_buffer(uint8_t *p_dst, int p_length) const {

	ERR_FAIL_COND_V(!is_open(),0);
	if (p_length==0)
		return 0;
	JNIEnv *env = ThreadAndroid::get_env();

	jbyteArray jca = (jbyteArray)env->CallObjectMethod(io,_file_read,id,p_length);

	int len = env->GetArrayLength(jca);
	env->GetByteArrayRegion(jca,0,len,(jbyte*)p_dst);
	env->DeleteLocalRef((jobject)jca);

	return len;

}

Error FileAccessJAndroid::get_error() const {

	if (eof_reached())
		return ERR_FILE_EOF;
	return OK;
}

void FileAccessJAndroid::store_8(uint8_t p_dest) {

}

bool FileAccessJAndroid::file_exists(const String& p_path) {

	JNIEnv *env = ThreadAndroid::get_env();

	String path=fix_path(p_path).simplify_path();
	if (path.begins_with("/"))
		path=path.substr(1,path.length());
	else if (path.begins_with("res://"))
		path=path.substr(6,path.length());

	jstring js = env->NewStringUTF(path.utf8().get_data());
	int res = env->CallIntMethod(io,_file_open,js,false);
	if (res<=0) {
		env->DeleteLocalRef(js);
		return false;
	}
	env->CallVoidMethod(io,_file_close,res);
	env->DeleteLocalRef(js);
	return true;

}

void FileAccessJAndroid::setup(  jobject p_io) {

	io=p_io;
	JNIEnv *env = ThreadAndroid::get_env();

	__android_log_print(ANDROID_LOG_INFO,"godot","STEP5");

	jclass c = env->GetObjectClass(io);
	__android_log_print(ANDROID_LOG_INFO,"godot","STEP6");
	cls=(jclass)env->NewGlobalRef(c);

	_file_open = env->GetMethodID(cls, "file_open", "(Ljava/lang/String;Z)I");
	if(_file_open != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_open ok!!");
	}
	_file_get_size = env->GetMethodID(cls, "file_get_size", "(I)I");
	if(_file_get_size != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_get_size ok!!");
	}
	_file_tell = env->GetMethodID(cls, "file_tell", "(I)I");
	if(_file_tell != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_tell ok!!");
	}
	_file_eof = env->GetMethodID(cls, "file_eof", "(I)Z");

	if(_file_eof != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_eof ok!!");
	}
	_file_seek = env->GetMethodID(cls, "file_seek", "(II)V");
	if(_file_seek != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_seek ok!!");
	}
	_file_read = env->GetMethodID(cls, "file_read", "(II)[B");
	if(_file_read != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_read ok!!");
	}
	_file_close = env->GetMethodID(cls, "file_close", "(I)V");
	if(_file_close != 0) {
		__android_log_print(ANDROID_LOG_INFO,"godot","*******GOT METHOD _file_close ok!!");
	}

//	(*env)->CallVoidMethod(env,obj,aMethodID, myvar);
}

FileAccessJAndroid::FileAccessJAndroid()
{

	id=0;
}

FileAccessJAndroid::~FileAccessJAndroid()
{

	if (is_open())
		close();
}

#endif
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI widget_arrow クラス @n
			※矢印ボタンクラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 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_utils.hpp"

namespace gui {

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

		typedef widget_arrow value_type;

		typedef std::function< void(uint32_t) > select_func_type;

		typedef std::function< void(int32_t) > level_func_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_arrow 方向型
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class direction {
			none,	///< 無し
			up,		///< 上
			down,	///< 下
			left,	///< 左
			right,	///< 右
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_arrow パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {
			plate_param		plate_param_;	///< 平面描画パラメーター
			color_param		color_param_;	///< 頂点カラーで変調する場合のパラメーター
			const img::i_img*	image_;		///< ボタンに画像を使う場合
			gl::mobj::handle	handle_;	///< ボタンにモーションオブジェクトを使う場合
			uint32_t			id_;		///< セレクト ID （押された回数に相当）
			int32_t				level_;		///< レベル
			int32_t				min_;		///< 最小値
			int32_t				max_;		///< 最大値
			uint32_t			delay_;		///< カウントアップ・ディレイ（フレーム単位）
			widget_arrow*		master_;	///< カウンター・マスター

			select_func_type	select_func_;	///< セレクト関数
			level_func_type		level_func_;	///< レベル関数

			direction			dir_;

			param(direction dir = direction::none) :
				plate_param_(), color_param_(widget_director::default_button_color_),
				image_(nullptr), handle_(0), id_(0),
				level_(0), min_(0), max_(100), delay_(16), master_(nullptr),
				select_func_(nullptr), level_func_(nullptr), dir_(dir)
				{ }
		};

	private:
		widget_director&	wd_;

		param				param_;

		gl::mobj::handle	objh_;

		uint32_t			id_;
		int32_t				level_;
		uint32_t			count_;

	void update_level_()
	{
		if(param_.master_ == nullptr) {
			++param_.level_;
			if(param_.level_ > param_.max_) {
				param_.level_ = param_.max_;
			}
		} else {
			int32_t& level = param_.master_->at_local_param().level_;
			--level;
			if(level < param_.master_->get_local_param().min_) {
				level = param_.master_->get_local_param().min_;
			}
		}
	}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_arrow(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p), objh_(0), id_(0), level_(0), count_(0) { }

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

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

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

		//-----------------------------------------------------------------//
		/*!
			@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	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			// ボタンは標準的に固定、サイズ固定、選択時拡大
			at_param().state_.set(widget::state::SERVICE);
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::MOVE_STALL);
			at_param().action_.set(widget::action::SELECT_SCALE);

			using namespace img;

			if(param_.handle_) {
				at_rect().size = wd_.at_mobj().get_size(param_.handle_);
				objh_ = param_.handle_;
			} else if(param_.image_) {
				paint pa;
				const vtx::spos& size = get_rect().size;
				create_image_base(param_.image_, size, pa);
				at_rect().size = pa.get_size();
				objh_ = wd_.at_mobj().install(&pa);
			} else {
				switch(param_.dir_) {
				case direction::up:
					objh_ = wd_.get_share_image().up_box_;
					break;
				case direction::down:
					objh_ = wd_.get_share_image().down_box_;
					break;
				case direction::left:
					objh_ = wd_.get_share_image().left_box_;
					break;
				case direction::right:
					objh_ = wd_.get_share_image().right_box_;
					break;
				default:
					break;
				}
				if(objh_ != 0) {
					at_rect().size = wd_.at_mobj().get_size(objh_);
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(!get_state(widget::state::ENABLE)) {
				return;
			}

			if(get_select()) {
				++count_;
				if(count_ >= param_.delay_) {
					count_ = 0;
					update_level_();
				}
			} else {
				count_ = 0;
			}
			if(get_selected()) {
				++param_.id_;
				update_level_();
				count_ = 0;
			}
		}

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

			if(level_ != param_.level_) {
				if(param_.level_func_ != nullptr) {
					param_.level_func_(param_.level_);
				}
				level_ = param_.level_;
			}
			if(id_ != param_.id_) {
				if(param_.select_func_ != nullptr) {
					param_.select_func_(param_.id_);
				}
				id_ = param_.id_;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			if(objh_ == 0) return;

			if(param_.plate_param_.resizeble_) {
				wd_.at_mobj().resize(objh_, get_param().rect_.size);
			}

			vtx::spos pos(0);
			wd_.at_mobj().draw(objh_, gl::mobj::attribute::normal, pos);
		}

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

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

		//-----------------------------------------------------------------//
		/*!
			@brief	レベルを取得
			@return レベル
		*/
		//-----------------------------------------------------------------//
		int32_t get_level() const { return param_.level_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	レベルを設定
			@param[in]	level	レベル
		*/
		//-----------------------------------------------------------------//
		void set_level(int32_t level) {
			param_.level_ = level;
			level_ = level;
			count_ = 0;
		}
	};
}
<commit_msg>update: cleanup<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI widget_arrow クラス @n
			※矢印ボタンクラス
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 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_utils.hpp"

namespace gui {

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

		typedef widget_arrow value_type;

		typedef std::function< void(uint32_t) > select_func_type;

		typedef std::function< void(int32_t) > level_func_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_arrow 方向型
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		enum class direction {
			none,	///< 無し
			up,		///< 上
			down,	///< 下
			left,	///< 左
			right,	///< 右
		};

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_arrow パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {
			plate_param		plate_param_;	///< 平面描画パラメーター
			color_param		color_param_;	///< 頂点カラーで変調する場合のパラメーター
			const img::i_img*	image_;		///< ボタンに画像を使う場合
			gl::mobj::handle	handle_;	///< ボタンにモーションオブジェクトを使う場合
			uint32_t			id_;		///< セレクト ID （押された回数に相当）
			int32_t				level_;		///< レベル
			int32_t				min_;		///< 最小値
			int32_t				max_;		///< 最大値
			uint32_t			delay_;		///< カウントアップ・ディレイ（フレーム単位）
			widget_arrow*		master_;	///< カウンター・マスター

			select_func_type	select_func_;	///< セレクト関数
			level_func_type		level_func_;	///< レベル関数

			direction			dir_;

			param(direction dir = direction::none) :
				plate_param_(), color_param_(widget_director::default_button_color_),
				image_(nullptr), handle_(0), id_(0),
				level_(0), min_(0), max_(100), delay_(16), master_(nullptr),
				select_func_(nullptr), level_func_(nullptr), dir_(dir)
				{ }
		};

	private:
		widget_director&	wd_;

		param				param_;

		gl::mobj::handle	objh_;

		uint32_t			id_;
		int32_t				level_;
		uint32_t			count_;

	void update_level_()
	{
		if(param_.master_ == nullptr) {
			++param_.level_;
			if(param_.level_ > param_.max_) {
				param_.level_ = param_.max_;
			}
		} else {
			int32_t& level = param_.master_->at_local_param().level_;
			--level;
			if(level < param_.master_->get_local_param().min_) {
				level = param_.master_->get_local_param().min_;
			}
		}
	}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_arrow(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p), objh_(0), id_(0), level_(0), count_(0) { }

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

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

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

		//-----------------------------------------------------------------//
		/*!
			@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	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			// ボタンは標準的に固定、サイズ固定、選択時拡大
			at_param().state_.set(widget::state::SERVICE);
			at_param().state_.set(widget::state::POSITION_LOCK);
			at_param().state_.set(widget::state::SIZE_LOCK);
			at_param().state_.set(widget::state::MOVE_STALL);
			at_param().action_.set(widget::action::SELECT_SCALE);

			using namespace img;

			if(param_.handle_) {
				at_rect().size = wd_.at_mobj().get_size(param_.handle_);
				objh_ = param_.handle_;
			} else if(param_.image_) {
				paint pa;
				const vtx::spos& size = get_rect().size;
				create_image_base(param_.image_, size, pa);
				at_rect().size = pa.get_size();
				objh_ = wd_.at_mobj().install(&pa);
			} else {
				switch(param_.dir_) {
				case direction::up:
					objh_ = wd_.get_share_image().up_box_;
					break;
				case direction::down:
					objh_ = wd_.get_share_image().down_box_;
					break;
				case direction::left:
					objh_ = wd_.get_share_image().left_box_;
					break;
				case direction::right:
					objh_ = wd_.get_share_image().right_box_;
					break;
				default:
					break;
				}
				if(objh_ != 0) {
					at_rect().size = wd_.at_mobj().get_size(objh_);
				}
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(get_select()) {
				++count_;
				if(count_ >= param_.delay_) {
					count_ = 0;
					update_level_();
				}
			} else {
				count_ = 0;
			}
			if(get_selected()) {
				++param_.id_;
				update_level_();
				count_ = 0;
			}
		}

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

			if(level_ != param_.level_) {
				if(param_.level_func_ != nullptr) {
					param_.level_func_(param_.level_);
				}
				level_ = param_.level_;
			}
			if(id_ != param_.id_) {
				if(param_.select_func_ != nullptr) {
					param_.select_func_(param_.id_);
				}
				id_ = param_.id_;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			if(objh_ == 0) return;

			if(param_.plate_param_.resizeble_) {
				wd_.at_mobj().resize(objh_, get_param().rect_.size);
			}

			vtx::spos pos(0);
			wd_.at_mobj().draw(objh_, gl::mobj::attribute::normal, pos);
		}

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

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

		//-----------------------------------------------------------------//
		/*!
			@brief	レベルを取得
			@return レベル
		*/
		//-----------------------------------------------------------------//
		int32_t get_level() const { return param_.level_; }

		//-----------------------------------------------------------------//
		/*!
			@brief	レベルを設定
			@param[in]	level	レベル
		*/
		//-----------------------------------------------------------------//
		void set_level(int32_t level) {
			param_.level_ = level;
			level_ = level;
			count_ = 0;
		}
	};
}
<|endoftext|>


<commit_before><commit_msg>fix wday,mon string<commit_after><|endoftext|>


<commit_before>/**
 * @file
 * brief description, full stop.
 *
 * long description, many sentences.
 *
 */
#include "angort.h"
#include "cycle.h"

using namespace angort;

Closure::Closure(const CodeBlock *c,int tabsize,Value *t) : GarbageCollected() {
    if(c)
        Types::tCode->set(&codeBlockValue,c);
    CycleDetector::getInstance()->add(this);
    ct=tabsize;
    table=t;
//    printf("creating closure %p\n",this);
}

Closure::~Closure(){
    //    printf("closure deletion\n");
    delete [] table; // should delete AND DECREF the contained objects
    CycleDetector::getInstance()->remove(this);
//    printf("deleting closure %p\n",this);
}

void ClosureType::set(Value *v,Closure *c){
    v->clr();
    v->v.closure=c;
    v->t = Types::tClosure;
    incRef(v);
}

class ClosureIterator : public Iterator<Value *>{
    Value v; //!< the current value, as an actual value
    int idx; //!< current index
    Closure *c; //!< the range we're iterating over

public:
    /// create a list iterator for a list
    ClosureIterator(Closure *r){
        idx=0;
        c = r;
        c->incRefCt();
    }

    /// on destruction, delete the iterator
    virtual ~ClosureIterator(){
        if(c->decRefCt()){
            delete c;
        }
        v.clr();
    }

    /// set the current value to the first item
    virtual void first(){
        idx=0;
        if(idx<c->ct)
            v.copy(c->table+idx);
        else
            v.clr();
    }
    /// set the current value to the next item
    virtual void next(){
        idx++;
        if(idx<c->ct)
            v.copy(c->table+idx);
        else
            v.clr();
    }

    /// return true if we're out of bounds
    virtual bool isDone() const{
        return idx>=c->ct;
    }

    /// return the current value
    virtual Value *current(){
        return &v;
    }
};

Iterator<class Value *> *Closure::makeValueIterator(){
    return new ClosureIterator(this);
}
<commit_msg>Closures too - missed the save.<commit_after>/**
 * @file
 * brief description, full stop.
 *
 * long description, many sentences.
 *
 */
#include "angort.h"
#include "cycle.h"

namespace angort {

Closure::Closure(const CodeBlock *c,int tabsize,Value *t) : GarbageCollected() {
    if(c)
        Types::tCode->set(&codeBlockValue,c);
    CycleDetector::getInstance()->add(this);
    ct=tabsize;
    table=t;
//    printf("creating closure %p\n",this);
}

Closure::~Closure(){
    //    printf("closure deletion\n");
    delete [] table; // should delete AND DECREF the contained objects
    CycleDetector::getInstance()->remove(this);
//    printf("deleting closure %p\n",this);
}

void ClosureType::set(Value *v,Closure *c){
    v->clr();
    v->v.closure=c;
    v->t = Types::tClosure;
    incRef(v);
}

class ClosureIterator : public Iterator<Value *>{
    Value v; //!< the current value, as an actual value
    int idx; //!< current index
    Closure *c; //!< the range we're iterating over

public:
    /// create a list iterator for a list
    ClosureIterator(Closure *r){
        idx=0;
        c = r;
        c->incRefCt();
    }

    /// on destruction, delete the iterator
    virtual ~ClosureIterator(){
        if(c->decRefCt()){
            delete c;
        }
        v.clr();
    }

    /// set the current value to the first item
    virtual void first(){
        idx=0;
        if(idx<c->ct)
            v.copy(c->table+idx);
        else
            v.clr();
    }
    /// set the current value to the next item
    virtual void next(){
        idx++;
        if(idx<c->ct)
            v.copy(c->table+idx);
        else
            v.clr();
    }

    /// return true if we're out of bounds
    virtual bool isDone() const{
        return idx>=c->ct;
    }

    /// return the current value
    virtual Value *current(){
        return &v;
    }
};

Iterator<class Value *> *Closure::makeValueIterator(){
    return new ClosureIterator(this);
}

}
<|endoftext|>


<commit_before>#include <Bull/Core/Exception/RuntimeError.hpp>

#include <Bull/Render/Buffer/VertexArrayObject.hpp>
#include <Bull/Render/OpenGL.hpp>

namespace Bull
{
    VertexArrayObject::VertexArrayObject() :
        m_vao(0)
    {
        gl::genVertexArrays(1, &m_vao);

        if(!gl::isVertexArray(m_vao))
        {
            throw RuntimeError("Failed to create VAO");
        }
    }

    VertexArrayObject::~VertexArrayObject()
    {
        gl::deleteVertexArrays(1, &m_vao);
    }

    void VertexArrayObject::runBound(const Functor<void>& functor) const
    {
        gl::bindVertexArray(m_vao);
        functor();
        gl::bindVertexArray(0);
    }
}<commit_msg>[Render/Texture] Rename creation method to avoid ambiguity with resource loading<commit_after>#include <Bull/Core/Exception/RuntimeError.hpp>

#include <Bull/Render/Buffer/VertexArrayObject.hpp>
#include <Bull/Render/OpenGL.hpp>

namespace Bull
{
    VertexArrayObject::VertexArrayObject() :
        m_vao(0)
    {
        gl::genVertexArrays(1, &m_vao);

        if(!m_vao)
        {
            throw RuntimeError("Failed to create VAO");
        }
    }

    VertexArrayObject::~VertexArrayObject()
    {
        gl::deleteVertexArrays(1, &m_vao);
    }

    void VertexArrayObject::runBound(const Functor<void>& functor) const
    {
        gl::bindVertexArray(m_vao);
        functor();
        gl::bindVertexArray(0);
    }
}<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI widget_table クラス（ヘッダー）
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 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_null.hpp"

namespace gui {

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

		typedef widget_table value_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_table パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {

			std::vector<widget_null*>	cell_;

			param() : cell_()
			{ }
		};

	private:
		widget_director&	wd_;

		param		param_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_table(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p)
		{ }

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

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

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

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

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

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

		//-----------------------------------------------------------------//
		/*!
			@brief	有効・無効の設定
			@param[in]	f	無効にする場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool f = true) { wd_.enable(this, f, true); }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			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);

			for(auto w : param_.cell_) {

			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
		}

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

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{

		}

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

			int err = 0;

			return err == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override
		{
			std::string path;
			path += '/';
			path += wd_.create_widget_name(this);

			int err = 0;

			return err == 0;
		}
	};
}
<commit_msg>update: scroll manage for mouse dial<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI widget_table クラス（ヘッダー）
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 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_null.hpp"

namespace gui {

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

		typedef widget_table value_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_table パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {

			std::vector<widget*>	cell_;

			bool		scroll_ctrl_;	///< スクロール・コントロール（マウスのダイアル）

			param() : cell_(), scroll_ctrl_(true)
			{ }
		};

	private:
		widget_director&	wd_;

		param				param_;

		vtx::iposs			ref_poss_;
		vtx::ipos			ref_size_;
		vtx::fpos			offset_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_table(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p), ref_poss_(), ref_size_(0), offset_(0.0f)
		{ }

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

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

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

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

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

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

		//-----------------------------------------------------------------//
		/*!
			@brief	有効・無効の設定
			@param[in]	f	無効にする場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool f = true) { wd_.enable(this, f, true); }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			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);

			// 基準の位置をセーブしておく
			for(auto w : param_.cell_) {
				ref_poss_.push_back(w->at_param().rect_.org);
				if(ref_size_.x < w->get_param().rect_.end_x()) {
					ref_size_.x = w->get_param().rect_.end_x();
				}
				if(ref_size_.y < w->get_param().rect_.end_y()) {
					ref_size_.y = w->get_param().rect_.end_y();
				}
				w->at_param().parents_ = this;
				w->at_param().state_.set(widget::state::CLIP_PARENTS);
//				w->at_param().state_.set(widget::state::AREA_ROOT);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(get_focus()) {
				auto szy = get_param().rect_.size.y;
				if(ref_size_.y > szy) {
					if(param_.scroll_ctrl_) {
						const vtx::spos& scr = wd_.get_scroll();
						offset_.y += static_cast<float>(scr.y * 8);
						if(offset_.y > 0.0f) offset_.y = 0.0f;
						else if(offset_.y < -static_cast<float>(ref_size_.y - szy)) {
							offset_.y = -static_cast<float>(ref_size_.y - szy);
						}
					}
				}
			}

			uint32_t i = 0;
			for(auto w : param_.cell_) {
				w->at_param().rect_.org.x = ref_poss_[i].x + static_cast<int>(offset_.x);
				w->at_param().rect_.org.y = ref_poss_[i].y + static_cast<int>(offset_.y);
				++i;
			}
		}

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

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
		}

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

			int err = 0;
			if(!pre.put_position(path + "/locate",  vtx::ipos(get_rect().org))) ++err;

			return err == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override
		{
			std::string path;
			path += '/';
			path += wd_.create_widget_name(this);

			int err = 0;
			vtx::ipos p;
			if(pre.get_position(path + "/locate", p)) {
				at_rect().org = p;
			} else {
				++err;
			}
			return err == 0;
		}
	};
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI widget_table クラス（ヘッダー）
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 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_null.hpp"

namespace gui {

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

		typedef widget_table value_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_table パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {

			std::vector<widget*>	cell_;

			bool		scroll_ctrl_;	///< スクロール・コントロール（マウスのダイアル）

			param() : cell_(), scroll_ctrl_(true)
			{ }
		};

	private:
		widget_director&	wd_;

		param				param_;

		vtx::iposs			ref_poss_;
		vtx::ipos			ref_size_;
		vtx::fpos			offset_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_table(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), param_(p), ref_poss_(), ref_size_(0), offset_(0.0f)
		{ }

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

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

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

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

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

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

		//-----------------------------------------------------------------//
		/*!
			@brief	有効・無効の設定
			@param[in]	f	無効にする場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool f = true) { wd_.enable(this, f, true); }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			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);

			// 基準の位置をセーブしておく
			for(auto w : param_.cell_) {
				ref_poss_.push_back(w->at_param().rect_.org);
				if(ref_size_.x < w->get_param().rect_.end_x()) {
					ref_size_.x = w->get_param().rect_.end_x();
				}
				if(ref_size_.y < w->get_param().rect_.end_y()) {
					ref_size_.y = w->get_param().rect_.end_y();
				}
				w->at_param().parents_ = this;
				w->at_param().state_.set(widget::state::CLIP_PARENTS);
//				w->at_param().state_.set(widget::state::AREA_ROOT);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(get_focus()) {
				auto szy = get_param().rect_.size.y;
				if(ref_size_.y > szy) {
					if(param_.scroll_ctrl_) {
						const vtx::spos& scr = wd_.get_scroll();
						offset_.y += static_cast<float>(scr.y * 8);
						if(offset_.y > 0.0f) offset_.y = 0.0f;
						else if(offset_.y < -static_cast<float>(ref_size_.y - szy)) {
							offset_.y = -static_cast<float>(ref_size_.y - szy);
						}
					}
				}
			}

			uint32_t i = 0;
			for(auto w : param_.cell_) {
				w->at_param().rect_.org.x = ref_poss_[i].x + static_cast<int>(offset_.x);
				w->at_param().rect_.org.y = ref_poss_[i].y + static_cast<int>(offset_.y);
				++i;
			}
		}

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

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
		}

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

			int err = 0;
			if(!pre.put_position(path + "/locate",  vtx::ipos(get_rect().org))) ++err;

			return err == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override
		{
			std::string path;
			path += '/';
			path += wd_.create_widget_name(this);

			int err = 0;
			vtx::ipos p;
			if(pre.get_position(path + "/locate", p)) {
				at_rect().org = p;
			} else {
				++err;
			}
			return err == 0;
		}
	};
}
<commit_msg>update: scroll-bar manage<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	GUI widget_table クラス（ヘッダー）
    @author 平松邦仁 (hira@rvf-rc45.net)
	@copyright	Copyright (C) 2018 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_slider.hpp"

namespace gui {

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

		typedef widget_table value_type;

		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		/*!
			@brief	widget_table パラメーター
		*/
		//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
		struct param {

			std::vector<widget*>	cell_;

			bool		scroll_bar_h_;	///< 水平スクロール・バーによる制御
			bool		scroll_bar_v_;	///< 垂直スクロール・バーによる制御
			bool		scroll_ctrl_;	///< スクロール・コントロール（マウスのダイアル）

			param() : cell_(), scroll_bar_h_(false), scroll_bar_v_(false),
				scroll_ctrl_(true)
			{ }
		};

	private:
		widget_director&	wd_;

		widget_slider*		slider_h_;
		widget_slider*		slider_v_;

		param				param_;

		vtx::iposs			ref_poss_;
		vtx::ipos			ref_size_;
		vtx::fpos			offset_;
		vtx::ipos			chip_size_;

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
		*/
		//-----------------------------------------------------------------//
		widget_table(widget_director& wd, const widget::param& bp, const param& p) :
			widget(bp), wd_(wd), slider_h_(nullptr), slider_v_(nullptr),
			param_(p), ref_poss_(), ref_size_(0), offset_(0.0f),
			chip_size_(0)
		{ }

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

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

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

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

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

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

		//-----------------------------------------------------------------//
		/*!
			@brief	有効・無効の設定
			@param[in]	f	無効にする場合「false」
		*/
		//-----------------------------------------------------------------//
		void enable(bool f = true) { wd_.enable(this, f, true); }

		//-----------------------------------------------------------------//
		/*!
			@brief	初期化
		*/
		//-----------------------------------------------------------------//
		void initialize() override
		{
			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::RESIZE_ROOT);
//			at_param().state_.set(widget::state::MOVE_STALL);
//			at_param().state_.set(widget::state::MOVE_ROOT, false);
//			at_param().state_.set(widget::state::CLIP_PARENTS);
//			at_param().state_.set(widget::state::AREA_ROOT);

			auto h = wd_.get_share_image().down_box_;
			chip_size_ = wd_.at_mobj().get_size(h);

			if(param_.scroll_bar_h_) {
				widget::param wp(vtx::irect(chip_size_.x, get_rect().size.y - chip_size_.y,
					get_rect().size.x - chip_size_.x * 2, chip_size_.y), this);
				widget_slider::param wp_(0.0f, slider_param::direction::HOLIZONTAL);
				wp_.slider_param_.handle_ratio_ = 0.5f;
				slider_h_ = wd_.add_widget<widget_slider>(wp, wp_);
				at_rect().size.y -= chip_size_.y;
			}
			if(param_.scroll_bar_v_) {
				widget::param wp(vtx::irect(get_rect().size.x - chip_size_.x, chip_size_.y,
					chip_size_.x, get_rect().size.y - chip_size_.y * 2), this);
				widget_slider::param wp_(0.0f, slider_param::direction::VERTICAL);
				wp_.slider_param_.handle_ratio_ = 0.5f;
				slider_v_ = wd_.add_widget<widget_slider>(wp, wp_);
				at_rect().size.x -= chip_size_.x;
			}

			// 基準の位置をセーブしておく
			for(auto w : param_.cell_) {
				ref_poss_.push_back(w->at_param().rect_.org);
				if(ref_size_.x < w->get_param().rect_.end_x()) {
					ref_size_.x = w->get_param().rect_.end_x();
				}
				if(ref_size_.y < w->get_param().rect_.end_y()) {
					ref_size_.y = w->get_param().rect_.end_y();
				}
				w->at_param().parents_ = this;
				w->at_param().state_.set(widget::state::CLIP_PARENTS);
//				w->at_param().state_.set(widget::state::MOVE_STALL);
//				w->at_param().state_.set(widget::state::MOVE_ROOT, false);
//				w->at_param().state_.set(widget::state::AREA_ROOT);
			}
			// 親の状態を子に継承
			if(get_param().parents_ != nullptr) {
				wd_.enable(this, get_param().parents_->get_enable(), true);
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	アップデート
		*/
		//-----------------------------------------------------------------//
		void update() override
		{
			if(get_focus()) {
				const vtx::spos& size = get_rect().size;
				if(ref_size_.y > size.y) {
					if(param_.scroll_ctrl_) {
						const vtx::spos& scr = wd_.get_scroll();
						offset_.y += static_cast<float>(scr.y * 8);
						if(offset_.y > 0.0f) offset_.y = 0.0f;
						else if(offset_.y < -static_cast<float>(ref_size_.y - size.y)) {
							offset_.y = -static_cast<float>(ref_size_.y - size.y);
						}
					}
				}

//				vtx::spos pos(size.x - chip_size_.x, 0);

#if 0
				gl::core& core = gl::core::get_instance();
				const gl::device& dev = core.get_device();
				int step = param_.page_step_;
				if(param_.page_div_ != 0) {
					step = (param_.max_pos_ - param_.min_pos_) / param_.page_div_;
				}
				if(dev.get_positive(gl::device::key::PAGE_UP)) {
					d =  step;
					st = state::inc;
				} else if(dev.get_positive(gl::device::key::PAGE_DOWN)) {
					d = -step;
					st = state::dec;
				} else if(dev.get_positive(gl::device::key::UP)) {
					d = step >= 0 ? 1 : -1;
					st = state::inc;
				} else if(dev.get_positive(gl::device::key::DOWN)) {
					d = step < 0 ? -1 : 1;
				}
#endif
			}

			if(slider_v_ != nullptr) {
//				slider_v_->
			}

			uint32_t i = 0;
			for(auto w : param_.cell_) {
				w->at_param().rect_.org.x = ref_poss_[i].x + static_cast<int>(offset_.x);
				w->at_param().rect_.org.y = ref_poss_[i].y + static_cast<int>(offset_.y);
				++i;
			}
		}

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

		//-----------------------------------------------------------------//
		/*!
			@brief	レンダリング
		*/
		//-----------------------------------------------------------------//
		void render() override
		{
			using namespace gl;

			if(param_.scroll_bar_h_ || param_.scroll_bar_v_) {
				core& core = core::get_instance();
				const vtx::spos& siz = core.get_rect().size;
				wd_.at_mobj().setup_matrix(siz.x, siz.y);
				wd_.set_TSC();
			}
			if(param_.scroll_bar_v_) {  // チップの描画
				gl::mobj::handle uph = wd_.get_share_image().up_box_;
				gl::mobj::handle dnh = wd_.get_share_image().down_box_;
				const vtx::spos& bs = wd_.at_mobj().get_size(uph);  // uph, dnh は同じ大きさ
				const vtx::spos& size = get_rect().size;
				vtx::spos pos(size.x, 0);
				wd_.at_mobj().draw(uph, gl::mobj::attribute::normal, pos);
				pos.y = size.y - bs.y;
				wd_.at_mobj().draw(dnh, gl::mobj::attribute::normal, pos);
			}
		}

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

			int err = 0;
			if(!pre.put_position(path + "/locate",  vtx::ipos(get_rect().org))) ++err;

			return err == 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief	状態のロード
			@param[in]	pre	プリファレンス参照
			@return エラーが無い場合「true」
		*/
		//-----------------------------------------------------------------//
		bool load(const sys::preference& pre) override
		{
			std::string path;
			path += '/';
			path += wd_.create_widget_name(this);

			int err = 0;
			vtx::ipos p;
			if(pre.get_position(path + "/locate", p)) {
				at_rect().org = p;
			} else {
				++err;
			}
			return err == 0;
		}
	};
}
<|endoftext|>


<commit_before><?hh // strict
namespace Decouple\Repo\Console\Command;
use \Decouple\Console\Service\Log;
use \Decouple\Console\Service\Env;
class Install extends \Decouple\Console\Command {
  public function execute(Log $log, Env $env) : void {
    $log->log("Checking dependencies...");
    $config = \Decouple\Repo\Console\Service\Validator::getConfig($env);
    $validator = \Decouple\Repo\Console\Service\Validator::validate($config);
    $valid = (bool)$validator->get('valid');
    $installed = (int)$validator->get('gh_installed');
    $not_installed = (int)$validator->get('gh_not_installed');
    $outdated = (int)$validator->get('gh_outdated');
    $root = (string)$env->variables->get('root');
    if($valid) {
      if($outdated > 0) {
        exit("Outdated packages detected. Run `./decouple update` instead.\n");
      } else if($not_installed == 0) {
        exit("\nAll packages are installed and up to date\n");
      }
      // Install packages!!!
      $to_install = $validator->get('to_install');
      $full_command = '';
      @mkdir($root . '/vendor');
      chdir($root . '/vendor');
      if(is_array($to_install)) {
        foreach($to_install as $repo) {
          if(is_array($repo)) {
            list($repo,$version) = $repo;
            $repo = (string)$repo;
            $version = (string)$version;
            $command = sprintf("git submodule add -b %s https://github.com/%s.git ./vendor/%s", $version, $repo, $repo);
            $log->log(sprintf("Cloning %s:%s", $repo, $version));
            $full_command .= $command . ' & ';
          }
        }
        $full_command = substr($full_command, 0, -3);
        $output = getExecOutput($full_command, $root);
        getExecOutput('git submodule update', $root);
        if($output) {
          $log->log("Installation complete.\n");
        }
      } else {
        exit("An unexpected error has occurred. Check the syntax in decouple.ini\n");
      }
    } else {
      exit("This project has not been initialized. Run `./decouple init` to begin.\n");
    }
  }
}
<commit_msg>Updating submodule install<commit_after><?hh // strict
namespace Decouple\Repo\Console\Command;
use \Decouple\Console\Service\Log;
use \Decouple\Console\Service\Env;
class Install extends \Decouple\Console\Command {
  public function execute(Log $log, Env $env) : void {
    $log->log("Checking dependencies...");
    $config = \Decouple\Repo\Console\Service\Validator::getConfig($env);
    $validator = \Decouple\Repo\Console\Service\Validator::validate($config);
    $valid = (bool)$validator->get('valid');
    $installed = (int)$validator->get('gh_installed');
    $not_installed = (int)$validator->get('gh_not_installed');
    $outdated = (int)$validator->get('gh_outdated');
    $root = (string)$env->variables->get('root');
    if($valid) {
      if($outdated > 0) {
        exit("Outdated packages detected. Run `./decouple update` instead.\n");
      } else if($not_installed == 0) {
        exit("\nAll packages are installed and up to date\n");
      }
      // Install packages!!!
      $to_install = $validator->get('to_install');
      $full_command = '';
      @mkdir($root . '/vendor');
      chdir($root . '/vendor');
      if(is_array($to_install)) {
        foreach($to_install as $repo) {
          if(is_array($repo)) {
            list($repo,$version) = $repo;
            $repo = (string)$repo;
            $version = (string)$version;
            $command = sprintf("git submodule add -b %s https://github.com/%s.git ./vendor/%s", $version, $repo, $repo);
            $log->log(sprintf("Cloning %s:%s", $repo, $version));
            $output[] = getExecOutput($command, $root);
            $full_command .= $command . ' & ';
          }
        }
        $output[] = getExecOutput('git submodule update', $root);
        if($output) {
          $log->log("Installation complete.\n");
        }
      } else {
        exit("An unexpected error has occurred. Check the syntax in decouple.ini\n");
      }
    } else {
      exit("This project has not been initialized. Run `./decouple init` to begin.\n");
    }
  }
}
<|endoftext|>


<commit_before>/* ========================================================================= *
 * File: poller.cpp
 *
 * This file is part of Memory Notification Library (libmemnotifyqt)
 *
 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
 *
 * Contacts: Leonid Moiseichuk <leonid.moiseichuk@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * 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 <memnotify/poller.hpp>
#include <memnotify/memory_notification.hpp>

BEGIN_MEMNOTIFY_NAMESPACE

/* ========================================================================= *
* Class Poller.
* ========================================================================= */

Poller :: Poller(QObject* notification, const int* handlers, const uint counter)
  : QThread(notification), myHandlers(NULL), myCounter((const nfds_t)counter)
{
  if (handlers && counter)
  {
    myHandlers = new pollfd[counter];
    if (myHandlers)
    {
      for (uint index = 0; index < counter; index++)
      {
        myHandlers[index].fd = handlers[index];
        myHandlers[index].events  = POLLIN|POLLPRI|POLLOUT;
        myHandlers[index].revents = 0;
      }
      setTerminationEnabled(true);
      start();
    }
  }
} /* Poller */

Poller :: ~Poller()
{
  wait();
  if ( myHandlers )
  {
    delete myHandlers;
  }
}

#include <errno.h>

void Poller :: run()
{
  forever
  {
    /* block in the poll() call, the descriptors might be closed during that */
    const int retcode = poll(myHandlers, myCounter, -1);
    if (retcode <= 0)
    {
      printf ("poll failed with retcode %d error %s\n", retcode, strerror(errno));
      return;
    }

    /* scans the incoming event */
    int  incoming[ myCounter ];
    uint iget;
    uint iput;
    for (iget = 0, iput = 0; iget < myCounter; iget++)
    {
      /* anything loaded means we should handle it */
      if ( myHandlers[iget].revents )
      {
        /* something as expected, this fd should be re-checked for detailed info */
        myHandlers[iget].revents = 0;
        incoming[iput++] = myHandlers[iget].fd;
      }
    }

    /* Notify the parent object */
    if ( !parent() )
      return;

    if ( !reinterpret_cast<MemoryNotification*>(parent())->process(incoming, iput) )
      return;
  } /* forever */
} /* run */

END_MEMOTIFY_NAMESPACE

/* ==================[ end of file memnotify/poller.cpp ]=================== */
<commit_msg>removed debugging printf from Poller<commit_after>/* ========================================================================= *
 * File: poller.cpp
 *
 * This file is part of Memory Notification Library (libmemnotifyqt)
 *
 * Copyright (C) 2010 Nokia Corporation. All rights reserved.
 *
 * Contacts: Leonid Moiseichuk <leonid.moiseichuk@nokia.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * version 2.1 as published by the Free Software Foundation.
 *
 * 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 <memnotify/poller.hpp>
#include <memnotify/memory_notification.hpp>

BEGIN_MEMNOTIFY_NAMESPACE

/* ========================================================================= *
* Class Poller.
* ========================================================================= */

Poller :: Poller(QObject* notification, const int* handlers, const uint counter)
  : QThread(notification), myHandlers(NULL), myCounter((const nfds_t)counter)
{
  if (handlers && counter)
  {
    myHandlers = new pollfd[counter];
    if (myHandlers)
    {
      for (uint index = 0; index < counter; index++)
      {
        myHandlers[index].fd = handlers[index];
        myHandlers[index].events  = POLLIN|POLLPRI|POLLOUT;
        myHandlers[index].revents = 0;
      }
      setTerminationEnabled(true);
      start();
    }
  }
} /* Poller */

Poller :: ~Poller()
{
  wait();
  if ( myHandlers )
  {
    delete myHandlers;
  }
}

void Poller :: run()
{
  forever
  {
    /* block in the poll() call, the descriptors might be closed during that */
    const int retcode = poll(myHandlers, myCounter, -1);
    if (retcode <= 0)
      return;

    /* scans the incoming event */
    int  incoming[ myCounter ];
    uint iget;
    uint iput;
    for (iget = 0, iput = 0; iget < myCounter; iget++)
    {
      /* anything loaded means we should handle it */
      if ( myHandlers[iget].revents )
      {
        /* something as expected, this fd should be re-checked for detailed info */
        myHandlers[iget].revents = 0;
        incoming[iput++] = myHandlers[iget].fd;
      }
    }

    /* Notify the parent object which is MemoryNotification */
    if (iput > 0)
    {
      QObject* p = parent();
      if (!p || !reinterpret_cast<MemoryNotification*>(p)->process(incoming, iput))
        return;
    }
  } /* forever */
} /* run */

END_MEMOTIFY_NAMESPACE

/* ==================[ end of file memnotify/poller.cpp ]=================== */
<|endoftext|>


<commit_before>#include <Bull/Render/OpenGL.hpp>
#include <Bull/Render/RenderTarget.hpp>

namespace Bull
{
    /*! \brief Destructor
     *
     */
    RenderTarget::~RenderTarget()
    {
        /// Nothing
    }

    /*! \brief Clear the RenderTarget with the specified color
     *
     * \param red   The red component of the color
     * \param green The green component of the color
     * \param blue  The blue component of the color
     * \param alpha The alpha component of the color
     *
     */
    void RenderTarget::clear(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha)
    {
        if(setActive())
        {
            glClearColor(static_cast<float>(red / 255.f),
                         static_cast<float>(green / 255.f),
                         static_cast<float>(blue / 255.f),
                         static_cast<float>(alpha / 255.f));

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
    }

    /*! \brief Clear the RenderTarget with the specified color
     *
     * \param color The color to use
     *
     */
    void RenderTarget::clear(const Color& color)
    {
        clear(color.red, color.green, color.blue, color.alpha);
    }
}
<commit_msg>[Render/RenderTarget] Fix color order<commit_after>#include <Bull/Render/OpenGL.hpp>
#include <Bull/Render/RenderTarget.hpp>

namespace Bull
{
    /*! \brief Destructor
     *
     */
    RenderTarget::~RenderTarget()
    {
        /// Nothing
    }

    /*! \brief Clear the RenderTarget with the specified color
     *
     * \param red   The red component of the color
     * \param green The green component of the color
     * \param blue  The blue component of the color
     * \param alpha The alpha component of the color
     *
     */
    void RenderTarget::clear(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha)
    {
        if(setActive())
        {
            glClearColor(static_cast<float>(red)   / 255.f,
                         static_cast<float>(green) / 255.f,
                         static_cast<float>(blue)  / 255.f,
                         static_cast<float>(alpha) / 255.f);

            glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        }
    }

    /*! \brief Clear the RenderTarget with the specified color
     *
     * \param color The color to use
     *
     */
    void RenderTarget::clear(const Color& color)
    {
        clear(color.red, color.green, color.blue, color.alpha);
    }
}
<|endoftext|>


<commit_before>/*

Copyright 2015-2021 Igor Petrovic

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

#include "board/Board.h"
#include "board/common/io/Helpers.h"
#include "board/common/constants/IO.h"
#include "board/Internal.h"
#include "core/src/general/Helpers.h"
#include "core/src/general/Atomic.h"
#include "Pins.h"
#include "io/leds/LEDs.h"

namespace
{
#if !defined(NUMBER_OF_OUT_SR) || defined(NUMBER_OF_LED_COLUMNS)
    core::io::mcuPin_t pin;
#endif
    uint8_t          ledID;
    uint8_t          arrayIndex;
    uint8_t          ledBit;
    uint8_t          pwmCounter;
    volatile uint8_t ledState[(MAX_NUMBER_OF_LEDS / 8) + 1][static_cast<uint8_t>(Board::io::ledBrightness_t::b100)];

#ifdef NUMBER_OF_LED_COLUMNS
    /// Holds value of currently active output matrix column.
    volatile uint8_t activeOutColumn = NUMBER_OF_LED_COLUMNS;

    /// Used to turn the given LED row off.
    inline void ledRowOff(uint8_t row)
    {
        pin = Board::detail::map::ledPin(row);
        EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
    }

    inline void ledRowOn(uint8_t row)
    {
        pin = Board::detail::map::ledPin(row);
        EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
    }
#endif
}    // namespace

namespace Board
{
    namespace io
    {
        void writeLEDstate(size_t ledID, io::ledBrightness_t ledBrightness)
        {
            if (ledID >= MAX_NUMBER_OF_LEDS)
                return;

            ledID = detail::map::ledIndex(ledID);

            ATOMIC_SECTION
            {
                for (int i = 0; i < static_cast<int>(ledBrightness_t::b100); i++)
                {
                    uint8_t arrayIndex = ledID / 8;
                    uint8_t bit        = ledID - 8 * arrayIndex;

                    BIT_WRITE(ledState[arrayIndex][i], bit, i < static_cast<int>(ledBrightness) ? 1 : 0);
                }
            }
        }

        size_t rgbSignalIndex(size_t rgbID, Board::io::rgbIndex_t index)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t column  = rgbID % NUMBER_OF_LED_COLUMNS;
            uint8_t row     = (rgbID / NUMBER_OF_LED_COLUMNS) * 3;
            uint8_t address = column + NUMBER_OF_LED_COLUMNS * row;

            switch (index)
            {
            case rgbIndex_t::r:
                return address;

            case rgbIndex_t::g:
                return address + NUMBER_OF_LED_COLUMNS * 1;

            case rgbIndex_t::b:
                return address + NUMBER_OF_LED_COLUMNS * 2;
            }

            return 0;
#else
            return rgbID * 3 + static_cast<uint8_t>(index);
#endif
        }

        size_t rgbIndex(size_t ledID)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t row = ledID / NUMBER_OF_LED_COLUMNS;

            uint8_t mod = row % 3;
            row -= mod;

            uint8_t column = ledID % NUMBER_OF_LED_COLUMNS;

            uint8_t result = (row * NUMBER_OF_LED_COLUMNS) / 3 + column;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#else
            uint8_t result = ledID / 3;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#endif
        }
    }    // namespace io

    namespace detail
    {
        namespace io
        {
#ifdef NUMBER_OF_LED_COLUMNS
            void checkDigitalOutputs()
            {
                if (!pwmCounter)
                {
                    for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                        ledRowOff(i);

                    if (++activeOutColumn == NUMBER_OF_LED_COLUMNS)
                        activeOutColumn = 0;

                    BIT_READ(activeOutColumn, 0) ? CORE_IO_SET_HIGH(DEC_LM_PORT_A0, DEC_LM_PIN_A0) : CORE_IO_SET_LOW(DEC_LM_PORT_A0, DEC_LM_PIN_A0);
                    BIT_READ(activeOutColumn, 1) ? CORE_IO_SET_HIGH(DEC_LM_PORT_A1, DEC_LM_PIN_A1) : CORE_IO_SET_LOW(DEC_LM_PORT_A1, DEC_LM_PIN_A1);
                    BIT_READ(activeOutColumn, 2) ? CORE_IO_SET_HIGH(DEC_LM_PORT_A2, DEC_LM_PIN_A2) : CORE_IO_SET_LOW(DEC_LM_PORT_A2, DEC_LM_PIN_A2);
                }

                for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                {
                    ledID      = activeOutColumn + i * NUMBER_OF_LED_COLUMNS;
                    arrayIndex = ledID / 8;
                    ledBit     = ledID - 8 * arrayIndex;

                    BIT_READ(ledState[arrayIndex][pwmCounter], ledBit) ? ledRowOn(i) : ledRowOff(i);
                }

                if (++pwmCounter >= static_cast<uint8_t>(Board::io::ledBrightness_t::b100))
                    pwmCounter = 0;
            }
#elif defined(NUMBER_OF_OUT_SR)
            void checkDigitalOutputs()
            {
                CORE_IO_SET_LOW(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

                for (int j = 0; j < NUMBER_OF_OUT_SR; j++)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        ledID      = i + j * 8;
                        arrayIndex = ledID / 8;
                        ledBit     = ledID - 8 * arrayIndex;

                        BIT_READ(ledState[arrayIndex][pwmCounter], ledBit) ? EXT_LED_ON(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN) : EXT_LED_OFF(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN);
                        CORE_IO_SET_LOW(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                        detail::io::sr595wait();
                        CORE_IO_SET_HIGH(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                    }
                }

                CORE_IO_SET_HIGH(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

                if (++pwmCounter >= static_cast<uint8_t>(Board::io::ledBrightness_t::b100))
                    pwmCounter = 0;
            }
#else
            void checkDigitalOutputs()
            {
                for (ledID = 0; ledID < MAX_NUMBER_OF_LEDS; ledID++)
                {
                    arrayIndex = ledID / 8;
                    ledBit     = ledID - 8 * arrayIndex;

                    pin = Board::detail::map::ledPin(ledID);
                    BIT_READ(ledState[arrayIndex][pwmCounter], ledBit) ? EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin)) : EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
                }

                if (++pwmCounter >= static_cast<uint8_t>(Board::io::ledBrightness_t::b100))
                    pwmCounter = 0;
            }
#endif
        }    // namespace io
    }        // namespace detail
}    // namespace Board<commit_msg>board: remove unused header<commit_after>/*

Copyright 2015-2021 Igor Petrovic

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

#include "board/Board.h"
#include "board/common/io/Helpers.h"
#include "board/common/constants/IO.h"
#include "board/Internal.h"
#include "core/src/general/Helpers.h"
#include "core/src/general/Atomic.h"
#include "Pins.h"

namespace
{
#if !defined(NUMBER_OF_OUT_SR) || defined(NUMBER_OF_LED_COLUMNS)
    core::io::mcuPin_t pin;
#endif
    uint8_t          ledID;
    uint8_t          arrayIndex;
    uint8_t          ledBit;
    uint8_t          pwmCounter;
    volatile uint8_t ledState[(MAX_NUMBER_OF_LEDS / 8) + 1][static_cast<uint8_t>(Board::io::ledBrightness_t::b100)];

#ifdef NUMBER_OF_LED_COLUMNS
    /// Holds value of currently active output matrix column.
    volatile uint8_t activeOutColumn = NUMBER_OF_LED_COLUMNS;

    /// Used to turn the given LED row off.
    inline void ledRowOff(uint8_t row)
    {
        pin = Board::detail::map::ledPin(row);
        EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
    }

    inline void ledRowOn(uint8_t row)
    {
        pin = Board::detail::map::ledPin(row);
        EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
    }
#endif
}    // namespace

namespace Board
{
    namespace io
    {
        void writeLEDstate(size_t ledID, io::ledBrightness_t ledBrightness)
        {
            if (ledID >= MAX_NUMBER_OF_LEDS)
                return;

            ledID = detail::map::ledIndex(ledID);

            ATOMIC_SECTION
            {
                for (int i = 0; i < static_cast<int>(ledBrightness_t::b100); i++)
                {
                    uint8_t arrayIndex = ledID / 8;
                    uint8_t bit        = ledID - 8 * arrayIndex;

                    BIT_WRITE(ledState[arrayIndex][i], bit, i < static_cast<int>(ledBrightness) ? 1 : 0);
                }
            }
        }

        size_t rgbSignalIndex(size_t rgbID, Board::io::rgbIndex_t index)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t column  = rgbID % NUMBER_OF_LED_COLUMNS;
            uint8_t row     = (rgbID / NUMBER_OF_LED_COLUMNS) * 3;
            uint8_t address = column + NUMBER_OF_LED_COLUMNS * row;

            switch (index)
            {
            case rgbIndex_t::r:
                return address;

            case rgbIndex_t::g:
                return address + NUMBER_OF_LED_COLUMNS * 1;

            case rgbIndex_t::b:
                return address + NUMBER_OF_LED_COLUMNS * 2;
            }

            return 0;
#else
            return rgbID * 3 + static_cast<uint8_t>(index);
#endif
        }

        size_t rgbIndex(size_t ledID)
        {
#ifdef NUMBER_OF_LED_COLUMNS
            uint8_t row = ledID / NUMBER_OF_LED_COLUMNS;

            uint8_t mod = row % 3;
            row -= mod;

            uint8_t column = ledID % NUMBER_OF_LED_COLUMNS;

            uint8_t result = (row * NUMBER_OF_LED_COLUMNS) / 3 + column;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#else
            uint8_t result = ledID / 3;

            if (result >= MAX_NUMBER_OF_RGB_LEDS)
                return MAX_NUMBER_OF_RGB_LEDS - 1;
            else
                return result;
#endif
        }
    }    // namespace io

    namespace detail
    {
        namespace io
        {
#ifdef NUMBER_OF_LED_COLUMNS
            void checkDigitalOutputs()
            {
                if (!pwmCounter)
                {
                    for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                        ledRowOff(i);

                    if (++activeOutColumn == NUMBER_OF_LED_COLUMNS)
                        activeOutColumn = 0;

                    BIT_READ(activeOutColumn, 0) ? CORE_IO_SET_HIGH(DEC_LM_PORT_A0, DEC_LM_PIN_A0) : CORE_IO_SET_LOW(DEC_LM_PORT_A0, DEC_LM_PIN_A0);
                    BIT_READ(activeOutColumn, 1) ? CORE_IO_SET_HIGH(DEC_LM_PORT_A1, DEC_LM_PIN_A1) : CORE_IO_SET_LOW(DEC_LM_PORT_A1, DEC_LM_PIN_A1);
                    BIT_READ(activeOutColumn, 2) ? CORE_IO_SET_HIGH(DEC_LM_PORT_A2, DEC_LM_PIN_A2) : CORE_IO_SET_LOW(DEC_LM_PORT_A2, DEC_LM_PIN_A2);
                }

                for (int i = 0; i < NUMBER_OF_LED_ROWS; i++)
                {
                    ledID      = activeOutColumn + i * NUMBER_OF_LED_COLUMNS;
                    arrayIndex = ledID / 8;
                    ledBit     = ledID - 8 * arrayIndex;

                    BIT_READ(ledState[arrayIndex][pwmCounter], ledBit) ? ledRowOn(i) : ledRowOff(i);
                }

                if (++pwmCounter >= static_cast<uint8_t>(Board::io::ledBrightness_t::b100))
                    pwmCounter = 0;
            }
#elif defined(NUMBER_OF_OUT_SR)
            void checkDigitalOutputs()
            {
                CORE_IO_SET_LOW(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

                for (int j = 0; j < NUMBER_OF_OUT_SR; j++)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        ledID      = i + j * 8;
                        arrayIndex = ledID / 8;
                        ledBit     = ledID - 8 * arrayIndex;

                        BIT_READ(ledState[arrayIndex][pwmCounter], ledBit) ? EXT_LED_ON(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN) : EXT_LED_OFF(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN);
                        CORE_IO_SET_LOW(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                        detail::io::sr595wait();
                        CORE_IO_SET_HIGH(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
                    }
                }

                CORE_IO_SET_HIGH(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

                if (++pwmCounter >= static_cast<uint8_t>(Board::io::ledBrightness_t::b100))
                    pwmCounter = 0;
            }
#else
            void checkDigitalOutputs()
            {
                for (ledID = 0; ledID < MAX_NUMBER_OF_LEDS; ledID++)
                {
                    arrayIndex = ledID / 8;
                    ledBit     = ledID - 8 * arrayIndex;

                    pin = Board::detail::map::ledPin(ledID);
                    BIT_READ(ledState[arrayIndex][pwmCounter], ledBit) ? EXT_LED_ON(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin)) : EXT_LED_OFF(CORE_IO_MCU_PIN_PORT(pin), CORE_IO_MCU_PIN_INDEX(pin));
                }

                if (++pwmCounter >= static_cast<uint8_t>(Board::io::ledBrightness_t::b100))
                    pwmCounter = 0;
            }
#endif
        }    // namespace io
    }        // namespace detail
}    // namespace Board<|endoftext|>