<commit_before>#include "Soldier.h"
#include "j1Render.h"
#include "j1Textures.h"
#include "j1App.h"
#include "p2Defs.h"
#include "j1Scene.h"
#include "j1Input.h"
#include "j1Item.h"
#include "j1Collision.h"
#include "j1EntityElementsScene.h"
#include "j1Audio.h"
#include "j1Player.h"
#include "j1Weapon.h"
#include "j1DynamicObjects.h"

Soldier::Soldier():NPC()
{
	name = "Soldier";
	type = CREATURE;
	srand(time(NULL));
}

Soldier::~Soldier()
{}

bool Soldier::Awake(pugi::xml_node &conf, uint id)
{
	bool stop_search = false;
	for (int s_id = conf.attribute("id").as_int(0); stop_search == false; s_id = conf.next_sibling().attribute("id").as_int(0))
	{
		if (id == s_id)
		{
			hp = conf.attribute("hp").as_int(0);
			position.x = conf.attribute("pos_x").as_int(0);
			position.y = conf.attribute("pos_y").as_int(0);
			std::string temp = conf.attribute("file").as_string("");

			item_id = conf.attribute("item_id").as_int(0);

			temp = conf.attribute("dir").as_string("");
			if (temp == "up")
				direction = UP;
			else if (temp == "down")
				direction = DOWN;
			else if (temp == "left")
				direction = LEFT;
			else
				direction = RIGHT;

			movable = conf.attribute("canMove").as_bool(false);
			destructible = conf.attribute("destructible").as_bool(false);

			if (destructible == false)
			{
				soldier_type = PASSIVE;
			}
			else
			{
				soldier_type = AGGRESSIVE;
			}

			npc_id = id;
			stop_search = true;
		}
	}

	return true;
}

bool Soldier::CleanUp()
{
	return true;
}

void Soldier::OnCollision(Collider* c1, Collider* c2)
{
	if (c1 != nullptr && c2 != nullptr)
	{
		//SWORD COLLISION
		if (c1 == collision_feet && c2->type == COLLIDER_SWORD && c1->callback != nullptr)
		{
			if (destructible == true && state != S_HIT)
			{
				App->audio->PlayFx(12);
				knockback_time.Start();
				hp--;
				state = S_HIT;
				anim_state = S_IDLE;
				dir_hit = c2->callback->direction;
				prev_position = position;
			}
		}

		//ARROW COLLISION
		if (c1 == collision_feet && c2->type == COLLIDER_ARROW && c2->arrow_callback != nullptr)
		{
			if (c2->arrow_callback->step == AIR && destructible == true && state != S_HIT)
			{
				App->audio->PlayFx(12);
				knockback_time.Start();
				hp--;
				state = S_HIT;
				anim_state = S_IDLE;
				dir_hit = c2->arrow_callback->direction;
				prev_position = position;
				c2->arrow_callback->step = IMPACT; // TODO MED -> set step to impact: this will reproduce the impact animation and, when finished, set step to DIE.
			}
		}

		//DYNOBJECT COLLISION
		if (c1 == collision_feet && c2->type == COLLIDER_DYNOBJECT && c2->callback != nullptr)
		{
			if (((DynamicObjects*)c2->callback)->GetState() == D_AIR)
			{
				App->audio->PlayFx(12);
				knockback_time.Start();
				hp -= 2; // TODO LOW -> set attack dmg to each type of dynobject.
				state = S_HIT;
				anim_state = S_IDLE;
				dir_hit = c2->callback->direction;
				prev_position = position;
				((DynamicObjects*)c2->callback)->SetState(D_DYING);
			}
		}
	}
}

bool Soldier::Start()
{
	if (soldier_type == AGGRESSIVE)
	{
		offset_x = 8;
		offset_y = 15;
		state = S_IDLE;
		anim_state = S_IDLE;
		speed = 40;
		timetoplay = SDL_GetTicks();
		reset_distance = false;
		reset_run = true;
		radar = 75;
		chase_speed = 50;
	}

	else if (soldier_type == PASSIVE)
	{
		offset_x = 8;
		offset_y = 15;
		anim_state = S_GUARD;
	}

	//Set collider
	collision_feet = App->collision->AddCollider({ position.x - offset_x, position.y - offset_y, 16, 15 }, COLLIDER_ENEMY, this);

	//Get the animations
	animation = *App->anim_manager->GetAnimStruct(SOLDIER);

	return true;
}

bool Soldier::Update(float dt)
{
	BROFILER_CATEGORY("DoUpdate_Soldier", Profiler::Color::Pink);
	// STATE MACHINE ------------------
		if (App->scene->gamestate == INGAME)
		{
			if (soldier_type == AGGRESSIVE)
			{
				switch (state)
				{
				case S_IDLE:
				{
					CheckPlayerPos();
					Idle();
					break;
				}
				case S_WALKING:
				{
					CheckPlayerPos();
					Walking(dt);
					break;
				}
				case S_DYING:
				{
					Die();
					break;
				}
				case S_HIT:
				{
					Movebyhit(dt);
					break;
				}
				case S_CHASING:
				{
					CheckPlayerPos();
					Chase(dt);
					break;
				}
				case S_ATTACKING:
				{
					Attack();
					break;
				}
				default:
				{
					break;
				}
				}

		}

		collision_feet->SetPos(position.x - offset_x, position.y - offset_y);

	}
	else if (App->scene->gamestate == INMENU)
	{

	}
	/*else if (App->scene->gamestate == TIMETOPLAY)
	{
		if (SDL_GetTicks() - timetoplay > 1000)
		{
			App->scene->gamestate = INGAME;
		}
	}*/
	return true;
}

void Soldier::Draw()
{
	BROFILER_CATEGORY("Draw_SOLDIER", Profiler::Color::Yellow);
	//App->anim_manager->Drawing_Manager(state, direction, position, 6);

	if (direction == UP)
	{
		anim_rect = animation.anim[anim_state].North_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].North_action.GetCurrentOffset();
	}
	else if (direction == DOWN)
	{
		anim_rect = animation.anim[anim_state].South_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].South_action.GetCurrentOffset();
	}
	else if (direction == LEFT)
	{
		anim_rect = animation.anim[anim_state].West_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].West_action.GetCurrentOffset();
	}
	else if (direction == RIGHT)
	{
		anim_rect = animation.anim[anim_state].East_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].East_action.GetCurrentOffset();
	}

	App->render->Blit(animation.graphics, position.x - pivot.x, position.y - pivot.y, &anim_rect);

}

bool Soldier::CheckPlayerPos()
{
	int distance_player = App->scene->player->position.DistanceTo(position);

	if (distance_player <= radar && App->scene->player->invincible_timer.ReadSec() >= 1)
	{
		state = S_CHASING;
		anim_state = S_WALKING;
	}
	else
	{
		state = S_IDLE;
		anim_state = S_IDLE;
	}

	return true;
}

bool Soldier::Idle()
{
	if (movable)
	{
		if (reset_run)
		{
			timetorun = SDL_GetTicks();
			reset_run = false;
		}
		else
		{
			if (SDL_GetTicks() - timetorun > 2000)
			{
				int direc_select = rand() % 4 + 1;
				if (direc_select == 1)
				{
					direction = UP;
				}
				else if (direc_select == 2)
				{
					direction = DOWN;
				}
				else if (direc_select == 3)
				{
					direction = LEFT;
				}
				else if (direc_select == 4)
				{
					direction = RIGHT;
				}
				state = S_WALKING;
				anim_state = S_WALKING;
				reset_distance = true;
			}
		}
	}
	return true;
}

bool Soldier::Walking(float dt)
{
	walking = false;

	if (reset_distance)
	{
		distance = rand() % 100 + 20;
		dis_moved = 0;
		reset_distance = false;
	}

	Move(dt);

	if(dis_moved >= distance)
	{
		walking = false;
		reset_run = true;
	}

	if (walking == false)
	{
		state = S_IDLE;
		anim_state = S_IDLE;
	}

	else
	{
		state = S_WALKING;
		anim_state = S_WALKING;
	}

	return true;
}

bool Soldier::Move(float dt)
{
	if (direction == LEFT)
	{
		if (App->map->MovementCost(collision_feet->rect.x - ceil(speed*dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, LEFT) == 0)
		{
			position.x -= ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}

	if (direction == RIGHT)
	{
		if (App->map->MovementCost(collision_feet->rect.x + collision_feet->rect.w + ceil(speed*dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, RIGHT) == 0)
		{
			position.x += ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}
	if (direction == UP)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y - ceil(speed*dt), collision_feet->rect.w, collision_feet->rect.h, UP) == 0)
		{
			position.y -= ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}
	if (direction == DOWN)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y + collision_feet->rect.h + ceil(speed*dt), collision_feet->rect.w, collision_feet->rect.h, DOWN) == 0)
		{
			position.y += ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}

	return true;
}

bool Soldier::Chase(float dt)
{
	//path.clear();
	//attack_time.Start();

	if (App->scene->player->GetState() != L_HIT)
	{
		iPoint player_pos = App->map->WorldToMap(App->scene->player->position.x, App->scene->player->position.y);
		GoTo(player_pos, ceil(dt*chase_speed));
		Orientate();
	}
	return true;
}

bool Soldier::Attack()
{

	return true;
}

bool Soldier::Die()
{
	App->audio->PlayFx(11);
	if (item_id != 0)
	{
		App->entity_elements->CreateItem(item_id, position);
	}
	App->entity_elements->DeleteEnemy(this);
	return true;
}

bool Soldier::Movebyhit(float dt)
{
	if (hp <= 0)
	{
		state = S_DYING;
		anim_state = S_IDLE;
		return true;
	}

	if (knockback_time.ReadSec() >= 0.2)
	{
		state = S_CHASING;
		anim_state = S_WALKING;
		return true;
	}

	if (dir_hit == UP)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y - ceil(240*dt), collision_feet->rect.w, collision_feet->rect.h, UP) == 0)
		{
			position.y -= ceil(240 * dt);
		}
	}
	else if (dir_hit == DOWN)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y + collision_feet->rect.h + ceil(240 * dt), collision_feet->rect.w, collision_feet->rect.h, DOWN) == 0)
		{
			position.y += ceil(240 * dt);
		}
	}
	else if (dir_hit == LEFT)
	{
		if (App->map->MovementCost(collision_feet->rect.x - ceil(240 * dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, LEFT) == 0)
		{
			position.x -= ceil(240 * dt);
		}
	}
	else if (dir_hit == RIGHT)
	{
		if (App->map->MovementCost(collision_feet->rect.x + collision_feet->rect.w + ceil(240 * dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, RIGHT) == 0)
		{
			position.x += ceil(240 * dt);
		}
	}
	/*if (position.x > (prev_position.x + 65) ||
	position.x < (prev_position.x + 65) ||
	position.y >(prev_position.y + 65) ||
	position.y < (prev_position.y + 65))
	{
	state = L_IDLE;
	}*/
	return true;
}

SoldierState Soldier::GetState() const
{
	return state;
}

void Soldier::SetState(SoldierState s_state)
{
	state = s_state;
}

void Soldier::SetAnimState(SoldierState a_state)
{
	anim_state = a_state;
}

SoldierType Soldier::GetType() const
{
	return soldier_type;
}

<commit_msg>Soldier collision bug fixed<commit_after>#include "Soldier.h"
#include "j1Render.h"
#include "j1Textures.h"
#include "j1App.h"
#include "p2Defs.h"
#include "j1Scene.h"
#include "j1Input.h"
#include "j1Item.h"
#include "j1Collision.h"
#include "j1EntityElementsScene.h"
#include "j1Audio.h"
#include "j1Player.h"
#include "j1Weapon.h"
#include "j1DynamicObjects.h"

Soldier::Soldier():NPC()
{
	name = "Soldier";
	type = CREATURE;
	srand(time(NULL));
}

Soldier::~Soldier()
{}

bool Soldier::Awake(pugi::xml_node &conf, uint id)
{
	bool stop_search = false;
	for (int s_id = conf.attribute("id").as_int(0); stop_search == false; s_id = conf.next_sibling().attribute("id").as_int(0))
	{
		if (id == s_id)
		{
			hp = conf.attribute("hp").as_int(0);
			position.x = conf.attribute("pos_x").as_int(0);
			position.y = conf.attribute("pos_y").as_int(0);
			std::string temp = conf.attribute("file").as_string("");

			item_id = conf.attribute("item_id").as_int(0);

			temp = conf.attribute("dir").as_string("");
			if (temp == "up")
				direction = UP;
			else if (temp == "down")
				direction = DOWN;
			else if (temp == "left")
				direction = LEFT;
			else
				direction = RIGHT;

			movable = conf.attribute("canMove").as_bool(false);
			destructible = conf.attribute("destructible").as_bool(false);

			if (destructible == false)
			{
				soldier_type = PASSIVE;
			}
			else
			{
				soldier_type = AGGRESSIVE;
			}

			npc_id = id;
			stop_search = true;
		}
	}

	return true;
}

bool Soldier::CleanUp()
{
	return true;
}

void Soldier::OnCollision(Collider* c1, Collider* c2)
{
	if (c1 != nullptr && c2 != nullptr)
	{
		//SWORD COLLISION
		if (c1 == collision_feet && c2->type == COLLIDER_SWORD && c1->callback != nullptr)
		{
			if (destructible == true && state != S_HIT)
			{
				App->audio->PlayFx(12);
				knockback_time.Start();
				hp--;
				state = S_HIT;
				anim_state = S_IDLE;
				dir_hit = c2->callback->direction;
				prev_position = position;
			}
		}

		//ARROW COLLISION
		if (c1 == collision_feet && c2->type == COLLIDER_ARROW && c2->arrow_callback != nullptr)
		{
			if (c2->arrow_callback->step == AIR && destructible == true && state != S_HIT)
			{
				App->audio->PlayFx(12);
				knockback_time.Start();
				hp--;
				state = S_HIT;
				anim_state = S_IDLE;
				dir_hit = c2->arrow_callback->direction;
				prev_position = position;
				c2->arrow_callback->step = IMPACT; // TODO MED -> set step to impact: this will reproduce the impact animation and, when finished, set step to DIE.
			}
		}

		//DYNOBJECT COLLISION
		if (c1 == collision_feet && c2->type == COLLIDER_DYNOBJECT && c2->callback != nullptr)
		{
			if (((DynamicObjects*)c2->callback)->GetState() == D_AIR)
			{
				App->audio->PlayFx(12);
				knockback_time.Start();
				hp -= 2; // TODO LOW -> set attack dmg to each type of dynobject.
				state = S_HIT;
				anim_state = S_IDLE;
				dir_hit = c2->callback->direction;
				prev_position = position;
				((DynamicObjects*)c2->callback)->SetState(D_DYING);
			}
		}
	}
}

bool Soldier::Start()
{
	if (soldier_type == AGGRESSIVE)
	{
		offset_x = 8;
		offset_y = 15;
		state = S_IDLE;
		anim_state = S_IDLE;
		speed = 40;
		timetoplay = SDL_GetTicks();
		reset_distance = false;
		reset_run = true;
		radar = 75;
		chase_speed = 50;
	}

	else if (soldier_type == PASSIVE)
	{
		offset_x = 8;
		offset_y = 15;
		anim_state = S_GUARD;
	}

	//Set collider
	collision_feet = App->collision->AddCollider({ position.x - offset_x, position.y - offset_y, 16, 15 }, COLLIDER_ENEMY, this);

	//Get the animations
	animation = *App->anim_manager->GetAnimStruct(SOLDIER);

	return true;
}

bool Soldier::Update(float dt)
{
	BROFILER_CATEGORY("DoUpdate_Soldier", Profiler::Color::Pink);
	// STATE MACHINE ------------------
	if (App->scene->gamestate == INGAME)
	{
		if (soldier_type == AGGRESSIVE)
		{
			switch (state)
			{
			case S_IDLE:
			{
				CheckPlayerPos();
				Idle();
				break;
			}
			case S_WALKING:
			{
				CheckPlayerPos();
				Walking(dt);
				break;
			}
			case S_DYING:
			{
				Die();
				break;
			}
			case S_HIT:
			{
				Movebyhit(dt);
				break;
			}
			case S_CHASING:
			{
				CheckPlayerPos();
				Chase(dt);
				break;
			}
			case S_ATTACKING:
			{
				Attack();
				break;
			}
			default:
			{
				break;
			}
			}
		}
		if (collision_feet != nullptr)
		{
			collision_feet->SetPos(position.x - offset_x, position.y - offset_y);
		}
	}

	else if (App->scene->gamestate == INMENU)
	{

	}
	/*else if (App->scene->gamestate == TIMETOPLAY)
	{
		if (SDL_GetTicks() - timetoplay > 1000)
		{
			App->scene->gamestate = INGAME;
		}
	}*/
	return true;
}

void Soldier::Draw()
{
	BROFILER_CATEGORY("Draw_SOLDIER", Profiler::Color::Yellow);
	//App->anim_manager->Drawing_Manager(state, direction, position, 6);

	if (direction == UP)
	{
		anim_rect = animation.anim[anim_state].North_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].North_action.GetCurrentOffset();
	}
	else if (direction == DOWN)
	{
		anim_rect = animation.anim[anim_state].South_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].South_action.GetCurrentOffset();
	}
	else if (direction == LEFT)
	{
		anim_rect = animation.anim[anim_state].West_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].West_action.GetCurrentOffset();
	}
	else if (direction == RIGHT)
	{
		anim_rect = animation.anim[anim_state].East_action.GetCurrentFrame();
		pivot = animation.anim[anim_state].East_action.GetCurrentOffset();
	}

	App->render->Blit(animation.graphics, position.x - pivot.x, position.y - pivot.y, &anim_rect);

}

bool Soldier::CheckPlayerPos()
{
	int distance_player = App->scene->player->position.DistanceTo(position);

	if (distance_player <= radar && App->scene->player->invincible_timer.ReadSec() >= 1)
	{
		state = S_CHASING;
		anim_state = S_WALKING;
	}
	else
	{
		state = S_IDLE;
		anim_state = S_IDLE;
	}

	return true;
}

bool Soldier::Idle()
{
	if (movable)
	{
		if (reset_run)
		{
			timetorun = SDL_GetTicks();
			reset_run = false;
		}
		else
		{
			if (SDL_GetTicks() - timetorun > 2000)
			{
				int direc_select = rand() % 4 + 1;
				if (direc_select == 1)
				{
					direction = UP;
				}
				else if (direc_select == 2)
				{
					direction = DOWN;
				}
				else if (direc_select == 3)
				{
					direction = LEFT;
				}
				else if (direc_select == 4)
				{
					direction = RIGHT;
				}
				state = S_WALKING;
				anim_state = S_WALKING;
				reset_distance = true;
			}
		}
	}
	return true;
}

bool Soldier::Walking(float dt)
{
	walking = false;

	if (reset_distance)
	{
		distance = rand() % 100 + 20;
		dis_moved = 0;
		reset_distance = false;
	}

	Move(dt);

	if(dis_moved >= distance)
	{
		walking = false;
		reset_run = true;
	}

	if (walking == false)
	{
		state = S_IDLE;
		anim_state = S_IDLE;
	}

	else
	{
		state = S_WALKING;
		anim_state = S_WALKING;
	}

	return true;
}

bool Soldier::Move(float dt)
{
	if (direction == LEFT)
	{
		if (App->map->MovementCost(collision_feet->rect.x - ceil(speed*dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, LEFT) == 0)
		{
			position.x -= ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}

	if (direction == RIGHT)
	{
		if (App->map->MovementCost(collision_feet->rect.x + collision_feet->rect.w + ceil(speed*dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, RIGHT) == 0)
		{
			position.x += ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}
	if (direction == UP)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y - ceil(speed*dt), collision_feet->rect.w, collision_feet->rect.h, UP) == 0)
		{
			position.y -= ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}
	if (direction == DOWN)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y + collision_feet->rect.h + ceil(speed*dt), collision_feet->rect.w, collision_feet->rect.h, DOWN) == 0)
		{
			position.y += ceil(speed*dt);
			dis_moved++;
		}
		else
		{
			dis_moved++;
		}
		walking = true;
	}

	return true;
}

bool Soldier::Chase(float dt)
{
	//path.clear();
	//attack_time.Start();

	if (App->scene->player->GetState() != L_HIT)
	{
		iPoint player_pos = App->map->WorldToMap(App->scene->player->position.x, App->scene->player->position.y);
		GoTo(player_pos, ceil(dt*chase_speed));
		Orientate();
	}
	return true;
}

bool Soldier::Attack()
{

	return true;
}

bool Soldier::Die()
{
	App->audio->PlayFx(11);
	if (item_id != 0)
	{
		App->entity_elements->CreateItem(item_id, position);
	}
	App->entity_elements->DeleteEnemy(this);
	return true;
}

bool Soldier::Movebyhit(float dt)
{
	if (hp <= 0)
	{
		state = S_DYING;
		anim_state = S_IDLE;
		return true;
	}

	if (knockback_time.ReadSec() >= 0.2)
	{
		state = S_CHASING;
		anim_state = S_WALKING;
		return true;
	}

	if (dir_hit == UP)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y - ceil(240*dt), collision_feet->rect.w, collision_feet->rect.h, UP) == 0)
		{
			position.y -= ceil(240 * dt);
		}
	}
	else if (dir_hit == DOWN)
	{
		if (App->map->MovementCost(collision_feet->rect.x, collision_feet->rect.y + collision_feet->rect.h + ceil(240 * dt), collision_feet->rect.w, collision_feet->rect.h, DOWN) == 0)
		{
			position.y += ceil(240 * dt);
		}
	}
	else if (dir_hit == LEFT)
	{
		if (App->map->MovementCost(collision_feet->rect.x - ceil(240 * dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, LEFT) == 0)
		{
			position.x -= ceil(240 * dt);
		}
	}
	else if (dir_hit == RIGHT)
	{
		if (App->map->MovementCost(collision_feet->rect.x + collision_feet->rect.w + ceil(240 * dt), collision_feet->rect.y, collision_feet->rect.w, collision_feet->rect.h, RIGHT) == 0)
		{
			position.x += ceil(240 * dt);
		}
	}
	/*if (position.x > (prev_position.x + 65) ||
	position.x < (prev_position.x + 65) ||
	position.y >(prev_position.y + 65) ||
	position.y < (prev_position.y + 65))
	{
	state = L_IDLE;
	}*/
	return true;
}

SoldierState Soldier::GetState() const
{
	return state;
}

void Soldier::SetState(SoldierState s_state)
{
	state = s_state;
}

void Soldier::SetAnimState(SoldierState a_state)
{
	anim_state = a_state;
}

SoldierType Soldier::GetType() const
{
	return soldier_type;
}

<|endoftext|>


<commit_before>#include<bits/stdc++.h>
#include<random>
#include<chrono>

#define ui unsigned int
using namespace std;

int main()
    {

    ui n=1000,d=5,epsi,m,l,s;

    cout<<"Enter the number of Nodes (n) where n > 49 : "<<endl;
    cin>>n;
    assert(n>49);

    cout<<"Enter the degree of each node (d) where d > 3 : "<<endl;
    cin>>d;
    assert(d > 3);

    cout<<"Enter the value of epsilon (epsi) where 0 < epsi < 1  : "<<endl;
    cin>>epsi;
    assert(epsi>0 && epsi<1);

    cout<<"Enter the value to repeat the loop (s) where  s>=48/epsi : "<<endl;
    cin>>s;
    assert(s>=48/epsi);

    cout<<"Enter the no of random walks (m) where  m>=s*12*sqrt(n)/(epsi^2) : "<<endl;
    cin>>m;
    assert(m>=(s*12*sqrt(n)/pow(epsi,2)));

    cout<<"Enter the length of random walk (l) where  l>=16*(d^2)*ln(n/epsi) : "<<endl;
    cin>>l;
    assert(l>=(16*(d^2)*ln(n/epsi)));

    /**************************************************************/
    /*     Generating Random Graph                                */
    /*                                                            */
    /**************************************************************/
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

  std::default_random_engine generator (seed);

  std::uniform_int_distribution<ui> distribution(1,n);

        vector<set <ui> > G(n+1);

    for(unsigned int i=1;i<=n;++i)
        {

            while(G[i].size()!=5)
        {
            ui neighbour;
            neighbour = distribution(generator);

            if(G[neighbour].size()!=5)
                auto newno = G[i].insert(neighbour);

            if(newno.second==true)
                G[neighbour].insert(i);
        }

  }
    for(ui i=1;i<=n;++i)
        {
        cout<<"Node "<<i<<": " ;
        for(auto it = G[i].begin(); it != G[i].end();++it)
            {
                cout<<" "<<*it;
        }
        cout<<endl;
    }

    /**************************************************************/
    /*     Random Walks & Expansion Tester                        */
    /*                                                            */
    /**************************************************************/

    ui s=50;
    distribution.reset();

    while(s--)
        {
            ui v;
        v = distribution(generator);
        vector< ui> pairs1;

        for(ui m=1; m<=(sqrt(n)); ++m)
            {
                ui w=v;
            std::uniform_int_distribution<ui> dVertex (1,5);
            for(ui l=1; l<= log2(n);++l)
                {

                    auto it=G[w].begin();

                    w = dVertex(generator);

                    while(w--)
                    {
                        it++;
                    }

                    w=*it;

            }

            pairs1.push_back(w);

        }
            sort(pairs1.begin(),pairs1.end());

            ui collision= pairs1.size();

            vector<ui>::iterator it;

            it = unique (pairs1.begin(), pairs1.end());

            pairs1.resize(distance(pairs1.begin(),it) );

            collision = collision- pairs1.size();
            if(collision < (((sqrt(n))*((sqrt(n))-1))/(2*n)))
                {cout<<"Reject"<<endl;return 0;}

    }
        cout<<"Accept"<<endl;

    return 0;
}
<commit_msg>Update TestingExpansion.cpp<commit_after>#include<bits/stdc++.h>
#include<random>
#include<chrono>

#define ui unsigned int
using namespace std;

int main()
    {

    ui n=1000,d=5,m,l,s;
    double epsi;

    cout<<"Enter the number of Nodes (n) where n > 49 : "<<endl;
    cin>>n;
    assert(n>49);

    cout<<"Enter the degree of each node (d) where d > 3 : "<<endl;
    cin>>d;
    assert(d > 3);

    cout<<"Enter the value of epsilon (epsi) where 0 < epsi < 1  : "<<endl;
    cin>>epsi;
    assert(epsi>0 && epsi<1);

    cout<<"Enter the value to repeat the loop (s) where  s>=48/epsi : "<<endl;
    cin>>s;
    assert(s>=48/epsi);

    cout<<"Enter the no of random walks (m) where  m>=s*12*sqrt(n)/(epsi^2) : "<<endl;
    cin>>m;
    assert(m>=(s*12*sqrt(n)/pow(epsi,2)));

    cout<<"Enter the length of random walk (l) where  l>=16*(d^2)*ln(n/epsi) : "<<endl;
    cin>>l;
    assert(l>=(16*(d^2)*ln(n/epsi)));

    /**************************************************************/
    /*     Generating Random Graph                                */
    /*                                                            */
    /**************************************************************/
  unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();

  std::default_random_engine generator (seed);

  std::uniform_int_distribution<ui> distribution(1,n);

        vector<set <ui> > G(n+1);

    for(unsigned int i=1;i<=n;++i)
        {

            while(G[i].size()!=5)
        {
            ui neighbour;
            neighbour = distribution(generator);

            if(G[neighbour].size()!=5)
                auto newno = G[i].insert(neighbour);

            if(newno.second==true)
                G[neighbour].insert(i);
        }

  }
    for(ui i=1;i<=n;++i)
        {
        cout<<"Node "<<i<<": " ;
        for(auto it = G[i].begin(); it != G[i].end();++it)
            {
                cout<<" "<<*it;
        }
        cout<<endl;
    }

    /**************************************************************/
    /*     Random Walks & Expansion Tester                        */
    /*                                                            */
    /**************************************************************/

    ui s=50;
    distribution.reset();

    while(s--)
        {
            ui v;
        v = distribution(generator);
        vector< ui> pairs1;

        for(ui m=1; m<=(sqrt(n)); ++m)
            {
                ui w=v;
            std::uniform_int_distribution<ui> dVertex (1,5);
            for(ui l=1; l<= log2(n);++l)
                {

                    auto it=G[w].begin();

                    w = dVertex(generator);

                    while(w--)
                    {
                        it++;
                    }

                    w=*it;

            }

            pairs1.push_back(w);

        }
            sort(pairs1.begin(),pairs1.end());

            ui collision= pairs1.size();

            vector<ui>::iterator it;

            it = unique (pairs1.begin(), pairs1.end());

            pairs1.resize(distance(pairs1.begin(),it) );

            collision = collision- pairs1.size();
            if(collision < (((sqrt(n))*((sqrt(n))-1))/(2*n)))
                {cout<<"Reject"<<endl;return 0;}

    }
        cout<<"Accept"<<endl;

    return 0;
}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "SceneManager.h"
#include "Scene.h"

namespace ouzel
{
    namespace scene
    {
        SceneManager::SceneManager()
        {

        }

        SceneManager::~SceneManager()
        {

        }

        void SceneManager::setScene(const ScenePtr& newScene)
        {
            if (scene != newScene)
            {
                if (locked)
                {
                    nextScene = scene;
                }
                else
                {
                    scene = newScene;

                    if (scene)
                    {
                        scene->recalculateProjection();
                    }
                }
            }
        }

        void SceneManager::draw()
        {
            if (scene)
            {
                lock();

                scene->draw();

                unlock();
            }
        }

        void SceneManager::recalculateProjection()
        {
            if (scene)
            {
                scene->recalculateProjection();
            }
        }

        void SceneManager::lock()
        {
            ++locked;
        }

        void SceneManager::unlock()
        {
            if (--locked == 0 && nextScene)
            {
                setScene(nextScene);
                nextScene.reset();
            }
        }
    } // namespace scene
} // namespace ouzel
<commit_msg>Fix scene replace<commit_after>// Copyright (C) 2016 Elviss Strazdins
// This file is part of the Ouzel engine.

#include "SceneManager.h"
#include "Scene.h"

namespace ouzel
{
    namespace scene
    {
        SceneManager::SceneManager()
        {

        }

        SceneManager::~SceneManager()
        {

        }

        void SceneManager::setScene(const ScenePtr& newScene)
        {
            if (scene != newScene)
            {
                if (locked)
                {
                    nextScene = newScene;
                }
                else
                {
                    scene = newScene;

                    if (scene)
                    {
                        scene->recalculateProjection();
                    }
                }
            }
        }

        void SceneManager::draw()
        {
            if (scene)
            {
                lock();

                scene->draw();

                unlock();
            }
        }

        void SceneManager::recalculateProjection()
        {
            if (scene)
            {
                scene->recalculateProjection();
            }
        }

        void SceneManager::lock()
        {
            ++locked;
        }

        void SceneManager::unlock()
        {
            if (--locked == 0 && nextScene)
            {
                setScene(nextScene);
                nextScene.reset();
            }
        }
    } // namespace scene
} // namespace ouzel
<|endoftext|>


<commit_before>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/Core>
#include <Eigen/Geometry>

#include <Eigen/LU> // required for MatrixBase::determinant
#include <Eigen/SVD> // required for SVD

using namespace Eigen;

//  Constructs a random matrix from the unitary group U(size).
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixUnitary(int size)
{
  typedef T Scalar;
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;

  MatrixType Q;

  int max_tries = 40;
  double is_unitary = false;

  while (!is_unitary && max_tries > 0)
  {
    // initialize random matrix
    Q = MatrixType::Random(size, size);

    // orthogonalize columns using the Gram-Schmidt algorithm
    for (int col = 0; col < size; ++col)
    {
      typename MatrixType::ColXpr colVec = Q.col(col);
      for (int prevCol = 0; prevCol < col; ++prevCol)
      {
        typename MatrixType::ColXpr prevColVec = Q.col(prevCol);
        colVec -= colVec.dot(prevColVec)*prevColVec;
      }
      Q.col(col) = colVec.normalized();
    }

    // this additional orthogonalization is not necessary in theory but should enhance
    // the numerical orthogonality of the matrix
    for (int row = 0; row < size; ++row)
    {
      typename MatrixType::RowXpr rowVec = Q.row(row);
      for (int prevRow = 0; prevRow < row; ++prevRow)
      {
        typename MatrixType::RowXpr prevRowVec = Q.row(prevRow);
        rowVec -= rowVec.dot(prevRowVec)*prevRowVec;
      }
      Q.row(row) = rowVec.normalized();
    }

    // final check
    is_unitary = Q.isUnitary();
    --max_tries;
  }

  if (max_tries == 0)
    eigen_assert(false && "randMatrixUnitary: Could not construct unitary matrix!");

  return Q;
}

//  Constructs a random matrix from the special unitary group SU(size).
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixSpecialUnitary(int size)
{
  typedef T Scalar;

  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;

  // initialize unitary matrix
  MatrixType Q = randMatrixUnitary<Scalar>(size);

  // tweak the first column to make the determinant be 1
  Q.col(0) *= numext::conj(Q.determinant());

  return Q;
}

template <typename MatrixType>
void run_test(int dim, int num_elements)
{
  using std::abs;
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
  typedef Matrix<Scalar, Eigen::Dynamic, 1> VectorX;

  // MUST be positive because in any other case det(cR_t) may become negative for
  // odd dimensions!
  const Scalar c = abs(internal::random<Scalar>());

  MatrixX R = randMatrixSpecialUnitary<Scalar>(dim);
  VectorX t = Scalar(50)*VectorX::Random(dim,1);

  MatrixX cR_t = MatrixX::Identity(dim+1,dim+1);
  cR_t.block(0,0,dim,dim) = c*R;
  cR_t.block(0,dim,dim,1) = t;

  MatrixX src = MatrixX::Random(dim+1, num_elements);
  src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));

  MatrixX dst = cR_t*src;

  MatrixX cR_t_umeyama = umeyama(src.block(0,0,dim,num_elements), dst.block(0,0,dim,num_elements));

  const Scalar error = ( cR_t_umeyama*src - dst ).norm() / dst.norm();
  VERIFY(error < Scalar(40)*std::numeric_limits<Scalar>::epsilon());
}

template<typename Scalar, int Dimension>
void run_fixed_size_test(int num_elements)
{
  using std::abs;
  typedef Matrix<Scalar, Dimension+1, Dynamic> MatrixX;
  typedef Matrix<Scalar, Dimension+1, Dimension+1> HomMatrix;
  typedef Matrix<Scalar, Dimension, Dimension> FixedMatrix;
  typedef Matrix<Scalar, Dimension, 1> FixedVector;

  const int dim = Dimension;

  // MUST be positive because in any other case det(cR_t) may become negative for
  // odd dimensions!
  const Scalar c = abs(internal::random<Scalar>());

  FixedMatrix R = randMatrixSpecialUnitary<Scalar>(dim);
  FixedVector t = Scalar(50)*FixedVector::Random(dim,1);

  HomMatrix cR_t = HomMatrix::Identity(dim+1,dim+1);
  cR_t.block(0,0,dim,dim) = c*R;
  cR_t.block(0,dim,dim,1) = t;

  MatrixX src = MatrixX::Random(dim+1, num_elements);
  src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));

  MatrixX dst = cR_t*src;

  Block<MatrixX, Dimension, Dynamic> src_block(src,0,0,dim,num_elements);
  Block<MatrixX, Dimension, Dynamic> dst_block(dst,0,0,dim,num_elements);

  HomMatrix cR_t_umeyama = umeyama(src_block, dst_block);

  const Scalar error = ( cR_t_umeyama*src - dst ).array().square().sum();

  VERIFY(error < Scalar(10)*std::numeric_limits<Scalar>::epsilon());
}

void test_umeyama()
{
  for (int i=0; i<g_repeat; ++i)
  {
    const int num_elements = internal::random<int>(40,500);

    // works also for dimensions bigger than 3...
    for (int dim=2; dim<8; ++dim)
    {
      CALL_SUBTEST_1(run_test<MatrixXd>(dim, num_elements));
      CALL_SUBTEST_2(run_test<MatrixXf>(dim, num_elements));
    }

    CALL_SUBTEST_3((run_fixed_size_test<float, 2>(num_elements)));
    CALL_SUBTEST_4((run_fixed_size_test<float, 3>(num_elements)));
    CALL_SUBTEST_5((run_fixed_size_test<float, 4>(num_elements)));

    CALL_SUBTEST_6((run_fixed_size_test<double, 2>(num_elements)));
    CALL_SUBTEST_7((run_fixed_size_test<double, 3>(num_elements)));
    CALL_SUBTEST_8((run_fixed_size_test<double, 4>(num_elements)));
  }

  // Those two calls don't compile and result in meaningful error messages!
  // umeyama(MatrixXcf(),MatrixXcf());
  // umeyama(MatrixXcd(),MatrixXcd());
}
<commit_msg>Relaxed umeyama test. Problem was ill-posed if linear part was scaled with very small number. This should fix bug 744.<commit_after>// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#include "main.h"

#include <Eigen/Core>
#include <Eigen/Geometry>

#include <Eigen/LU> // required for MatrixBase::determinant
#include <Eigen/SVD> // required for SVD

using namespace Eigen;

//  Constructs a random matrix from the unitary group U(size).
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixUnitary(int size)
{
  typedef T Scalar;
  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;

  MatrixType Q;

  int max_tries = 40;
  double is_unitary = false;

  while (!is_unitary && max_tries > 0)
  {
    // initialize random matrix
    Q = MatrixType::Random(size, size);

    // orthogonalize columns using the Gram-Schmidt algorithm
    for (int col = 0; col < size; ++col)
    {
      typename MatrixType::ColXpr colVec = Q.col(col);
      for (int prevCol = 0; prevCol < col; ++prevCol)
      {
        typename MatrixType::ColXpr prevColVec = Q.col(prevCol);
        colVec -= colVec.dot(prevColVec)*prevColVec;
      }
      Q.col(col) = colVec.normalized();
    }

    // this additional orthogonalization is not necessary in theory but should enhance
    // the numerical orthogonality of the matrix
    for (int row = 0; row < size; ++row)
    {
      typename MatrixType::RowXpr rowVec = Q.row(row);
      for (int prevRow = 0; prevRow < row; ++prevRow)
      {
        typename MatrixType::RowXpr prevRowVec = Q.row(prevRow);
        rowVec -= rowVec.dot(prevRowVec)*prevRowVec;
      }
      Q.row(row) = rowVec.normalized();
    }

    // final check
    is_unitary = Q.isUnitary();
    --max_tries;
  }

  if (max_tries == 0)
    eigen_assert(false && "randMatrixUnitary: Could not construct unitary matrix!");

  return Q;
}

//  Constructs a random matrix from the special unitary group SU(size).
template <typename T>
Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixSpecialUnitary(int size)
{
  typedef T Scalar;

  typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;

  // initialize unitary matrix
  MatrixType Q = randMatrixUnitary<Scalar>(size);

  // tweak the first column to make the determinant be 1
  Q.col(0) *= numext::conj(Q.determinant());

  return Q;
}

template <typename MatrixType>
void run_test(int dim, int num_elements)
{
  using std::abs;
  typedef typename internal::traits<MatrixType>::Scalar Scalar;
  typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;
  typedef Matrix<Scalar, Eigen::Dynamic, 1> VectorX;

  // MUST be positive because in any other case det(cR_t) may become negative for
  // odd dimensions!
  const Scalar c = abs(internal::random<Scalar>());

  MatrixX R = randMatrixSpecialUnitary<Scalar>(dim);
  VectorX t = Scalar(50)*VectorX::Random(dim,1);

  MatrixX cR_t = MatrixX::Identity(dim+1,dim+1);
  cR_t.block(0,0,dim,dim) = c*R;
  cR_t.block(0,dim,dim,1) = t;

  MatrixX src = MatrixX::Random(dim+1, num_elements);
  src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));

  MatrixX dst = cR_t*src;

  MatrixX cR_t_umeyama = umeyama(src.block(0,0,dim,num_elements), dst.block(0,0,dim,num_elements));

  const Scalar error = ( cR_t_umeyama*src - dst ).norm() / dst.norm();
  VERIFY(error < Scalar(40)*std::numeric_limits<Scalar>::epsilon());
}

template<typename Scalar, int Dimension>
void run_fixed_size_test(int num_elements)
{
  using std::abs;
  typedef Matrix<Scalar, Dimension+1, Dynamic> MatrixX;
  typedef Matrix<Scalar, Dimension+1, Dimension+1> HomMatrix;
  typedef Matrix<Scalar, Dimension, Dimension> FixedMatrix;
  typedef Matrix<Scalar, Dimension, 1> FixedVector;

  const int dim = Dimension;

  // MUST be positive because in any other case det(cR_t) may become negative for
  // odd dimensions!
  // Also if c is to small compared to t.norm(), problem is ill-posed (cf. Bug 744)
  const Scalar c = internal::random<Scalar>(0.5, 2.0);

  FixedMatrix R = randMatrixSpecialUnitary<Scalar>(dim);
  FixedVector t = Scalar(32)*FixedVector::Random(dim,1);

  HomMatrix cR_t = HomMatrix::Identity(dim+1,dim+1);
  cR_t.block(0,0,dim,dim) = c*R;
  cR_t.block(0,dim,dim,1) = t;

  MatrixX src = MatrixX::Random(dim+1, num_elements);
  src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));

  MatrixX dst = cR_t*src;

  Block<MatrixX, Dimension, Dynamic> src_block(src,0,0,dim,num_elements);
  Block<MatrixX, Dimension, Dynamic> dst_block(dst,0,0,dim,num_elements);

  HomMatrix cR_t_umeyama = umeyama(src_block, dst_block);

  const Scalar error = ( cR_t_umeyama*src - dst ).squaredNorm();

  VERIFY(error < Scalar(16)*std::numeric_limits<Scalar>::epsilon());
}

void test_umeyama()
{
  for (int i=0; i<g_repeat; ++i)
  {
    const int num_elements = internal::random<int>(40,500);

    // works also for dimensions bigger than 3...
    for (int dim=2; dim<8; ++dim)
    {
      CALL_SUBTEST_1(run_test<MatrixXd>(dim, num_elements));
      CALL_SUBTEST_2(run_test<MatrixXf>(dim, num_elements));
    }

    CALL_SUBTEST_3((run_fixed_size_test<float, 2>(num_elements)));
    CALL_SUBTEST_4((run_fixed_size_test<float, 3>(num_elements)));
    CALL_SUBTEST_5((run_fixed_size_test<float, 4>(num_elements)));

    CALL_SUBTEST_6((run_fixed_size_test<double, 2>(num_elements)));
    CALL_SUBTEST_7((run_fixed_size_test<double, 3>(num_elements)));
    CALL_SUBTEST_8((run_fixed_size_test<double, 4>(num_elements)));
  }

  // Those two calls don't compile and result in meaningful error messages!
  // umeyama(MatrixXcf(),MatrixXcf());
  // umeyama(MatrixXcd(),MatrixXcd());
}
<|endoftext|>


<commit_before>// @(#)root/proof:$Name:  $:$Id: TCondor.cxx,v 1.4 2003/09/04 23:19:31 rdm Exp $
// Author: Maarten Ballintijn   06/12/03

/*************************************************************************
 * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TCondor                                                              //
//                                                                      //
// Interface to the Condor system. TCondor provides a (partial) API for //
// querying and controlling the Condor system, including experimental   //
// extensions like COD (computing on demand)                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TCondor.h"
#include "TList.h"
#include "TSystem.h"
#include "TObjString.h"
#include "TRegexp.h"
#include "TProofDebug.h"
#include "Riostream.h"

ClassImp(TCondorSlave)
ClassImp(TCondor)

//______________________________________________________________________________
TCondor::TCondor(const char *pool) : fPool(pool), fState(kFree)
{
   // Create Condor interface object. Uses Condor apps since there is no
   // API yet.

   fClaims = new TList;

   // hack our path :-/
   TString path = gSystem->Getenv("PATH");
   path = "/opt/condor/bin:" + path;
   gSystem->Setenv("PATH",path);
   gSystem->Setenv("CONDOR_CONFIG","/opt/condor/etc/condor_config");
}

//______________________________________________________________________________
TCondor::~TCondor()
{
   // Cleanup Condor interface.

   PDB(kCondor,1) Info("~TCondor","fState %d", fState );

   if (fState != kFree) {
      Release();
   }
   delete fClaims;
}

//______________________________________________________________________________
void TCondor::Print(Option_t * opt) const
{
   cout << "OBJ: " << IsA()->GetName()
      << "\tPool: \"" << fPool << "\""
      << "\tState: " << fState << endl;
   fClaims->Print(opt);
}

//______________________________________________________________________________
TCondorSlave *TCondor::ClaimVM(const char *vm, const char * /*cmd*/, Int_t &port)
{
   // Claim a VirtualMachine for PROOF usage.

   TString claimCmd = Form("condor_cod request -name %s -timeout 10 2>/dev/null", vm );

   PDB(kCondor,2) Info("ClaimVM","command: %s", claimCmd.Data());
   FILE  *pipe = gSystem->OpenPipe(claimCmd, "r");

   if (!pipe) {
      SysError("ClaimVM","cannot run command: %s", claimCmd.Data());
      return 0;
   }

   TString claimId;
   TString line;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("ClaimVM","line = %s", line.Data());

      if (line.BeginsWith("ClaimId = \"")) {
         line.Remove(0, line.Index("\"")+1);
         line.Chop(); // remove trailing "
         claimId = line;
         PDB(kCondor,1) Info("ClaimVM","claim = '%s'", claimId.Data());
         TRegexp r("[0-9]*$");
         TString num = line(r);
         port = 37000 + atoi(num.Data());
         PDB(kCondor,1) Info("ClaimVM","port = %d", port);
      }
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("ClaimVM","command: %s returned %d", claimCmd.Data(), r);

   TString jobad("jobad");
   FILE *jf = gSystem->TempFilename(jobad);

   if (jf == 0) return 0;

   fputs("JobUniverse = 5\n", jf); // vanilla
   fputs("Cmd = \"/usr/local/root/bin/proofd\"\n", jf);
   fputs("Iwd = \"/tmp\"\n", jf);
   fputs("In = \"/dev/null\"\n", jf);
   fprintf(jf, "Out = \"/tmp/proofd.out.%d\"\n", port);
   fprintf(jf, "Err = \"/tmp/proofd.err.%d\"\n", port);
   fprintf(jf, "Args = \"-f -p %d -d 3 /usr/local/root\"\n", port);
   fclose(jf);

   TString activateCmd = Form("condor_cod activate -id '%s' -jobad %s",
                              claimId.Data(), jobad.Data() );

   PDB(kCondor,2) Info("ClaimVM","command: %s", activateCmd.Data());
   pipe = gSystem->OpenPipe(activateCmd, "r");

   if (!pipe) {
      SysError("ClaimVM","cannot run command: %s", activateCmd.Data());
      return 0;
   }

   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("ClaimVM","Activate: line = %s", line.Data());
   }

   r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("ClaimVM","command: %s returned %d", activateCmd.Data(), r);

   gSystem->Unlink(jobad.Data());

   // TODO: get info at the start for all nodes ...
   TCondorSlave *claim = new TCondorSlave;
   claim->fClaimID = claimId;
   TString node(vm);
   node = node.Remove(0, node.Index("@")+1);
   claim->fHostname = node;
   claim->fPort = port;
   if ( !GetVmInfo(vm, claim->fImage, claim->fPerfIdx) ) {
      // assume vm is gone
      delete claim;
      return 0;
   }

   return claim;
}

//______________________________________________________________________________
TList *TCondor::GetVirtualMachines() const
{
   // Get the names of the virtual machines in the pool.
   // Return a TList of TObjString or 0 in case of failure

   TString poolopt = fPool ? "" : Form("-pool %s", fPool.Data());
   TString cmd = Form("condor_status %s -format \"%%s\\n\" Name", poolopt.Data());

   PDB(kCondor,2) Info("GetVirtualMachines","command: %s", cmd.Data());

   FILE  *pipe = gSystem->OpenPipe(cmd, "r");

   if (!pipe) {
      SysError("GetVirtualMachines","cannot run command: %s", cmd.Data());
      return 0;
   }

   TString line;
   TList *l = new TList;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("GetVirtualMachines","line = %s", line.Data());
      if (line != "") l->Add(new TObjString(line));
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("GetVirtualMachines","command: %s returned %d", cmd.Data(), r);

   return l;
}

//______________________________________________________________________________
TList *TCondor::Claim(Int_t n, const char *cmd)
{
   if (fState != kFree) {
      Error("Claim","not in state Free");
      return 0;
   }

   TList *vms = GetVirtualMachines();

   TIter next(vms);
   TObjString *vm;
   for(Int_t i=0; i < n && (vm = (TObjString*) next()) != 0; i++ ) {
      Int_t port = 17000+i; // hard code port for the moment
      TCondorSlave *claim = ClaimVM(vm->GetName(), cmd, port);
      if (claim != 0) {

         fClaims->Add(claim);

      }
   }

   fState = kActive;

   return fClaims;
}

//______________________________________________________________________________
Bool_t TCondor::SetState(EState state)
{
   TIter next(fClaims);
   TCondorSlave *claim;
   while((claim = (TCondorSlave*) next()) != 0) {
      TString cmd = Form("condor_cod %s -id '%s'",
                         state == kSuspended ? "suspend" : "resume",
                         claim->fClaimID.Data());

      PDB(kCondor,2) Info("SetState","command: %s", cmd.Data());
      FILE  *pipe = gSystem->OpenPipe(cmd, "r");

      if (!pipe) {
         SysError("SetState","cannot run command: %s", cmd.Data());
         return kFALSE;
      }

      TString line;
      while (line.Gets(pipe)) {
         PDB(kCondor,3) Info("SetState","line = %s", line.Data());
      }

      Int_t r = gSystem->ClosePipe(pipe);
      PDB(kCondor,1) Info("SetState","command: %s returned %d", cmd.Data(), r);
   }

   fState = state;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TCondor::Suspend()
{
   if (fState != kActive) {
      Error("Suspend","not in state Active");
      return kFALSE;
   }

   return SetState(kSuspended);
}

//______________________________________________________________________________
Bool_t TCondor::Resume()
{
   if (fState != kSuspended) {
      Error("Suspend","not in state Suspended");
      return kFALSE;
   }

   return SetState(kActive);
}

//______________________________________________________________________________
Bool_t TCondor::Release()
{
   if (fState == kFree) {
      Error("Suspend","not in state Active or Suspended");
      return kFALSE;
   }

   TCondorSlave *claim;
   while((claim = (TCondorSlave*) fClaims->First()) != 0) {
      TString cmd = Form("condor_cod release -id '%s'", claim->fClaimID.Data());

      PDB(kCondor,2) Info("SetState","command: %s", cmd.Data());
      FILE  *pipe = gSystem->OpenPipe(cmd, "r");

      if (!pipe) {
         SysError("Release","cannot run command: %s", cmd.Data());
         return kFALSE;
      }

      TString line;
      while (line.Gets(pipe)) {
         PDB(kCondor,3) Info("Release","line = %s", line.Data());
      }

      Int_t r = gSystem->ClosePipe(pipe);
      PDB(kCondor,1) Info("Release","command: %s returned %d", cmd.Data(), r);

      fClaims->Remove(claim);
      delete claim;
   }

   fState = kFree;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TCondor::GetVmInfo(const char *vm, TString &image, Int_t &perfidx) const
{
   TString cmd = Form("condor_status -format \"%%d:\" Mips -format \"%%s\\n\" FileSystemDomain "
                      "-const 'Name==\"%s\"'", vm);

   PDB(kCondor,2) Info("GetVmInfo","command: %s", cmd.Data());
   FILE  *pipe = gSystem->OpenPipe(cmd, "r");

   if (!pipe) {
      SysError("GetVmInfo","cannot run command: %s", cmd.Data());
      return 0;
   }

   TString line;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("GetVmInfo","line = %s", line.Data());
      if (line != "") {
         TString amips = line(TRegexp("^[0-9]*"));
         perfidx = atoi(amips);
         image = line(TRegexp("[^:]+$"));
         break;
      }
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("GetVmInfo","command: %s returned %d", cmd.Data(), r);

   return kTRUE;
}

//______________________________________________________________________________
TString TCondor::GetImage(const char *host) const
{
   TString cmd = Form("condor_status -direct %s -format \"Image:%%s\\n\" "
                      "FileSystemDomain", host);

   PDB(kCondor,2) Info("GetImage","command: %s", cmd.Data());

   FILE  *pipe = gSystem->OpenPipe(cmd, "r");

   if (!pipe) {
      SysError("GetImage","cannot run command: %s", cmd.Data());
      return 0;
   }

   TString image;
   TString line;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("GetImage","line = %s", line.Data());
      if (line != "") {
         image = line(TRegexp("[^:]+$"));
         break;
      }
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("GetImage","command: %s returned %d", cmd.Data(), r);

   return image;
}

//______________________________________________________________________________
void TCondorSlave::Print(Option_t * /*opt*/ ) const
{
   cout << "OBJ: " << IsA()->GetName()
      << " " << fHostname << ":" << fPort
      << "  Perf: " << fPerfIdx
      << "  Image: " << fImage << endl;
}

<commit_msg>change TempFilename() to TempFileName().<commit_after>// @(#)root/proof:$Name:  $:$Id: TCondor.cxx,v 1.5 2003/09/23 08:54:50 rdm Exp $
// Author: Maarten Ballintijn   06/12/03

/*************************************************************************
 * Copyright (C) 1995-2001, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TCondor                                                              //
//                                                                      //
// Interface to the Condor system. TCondor provides a (partial) API for //
// querying and controlling the Condor system, including experimental   //
// extensions like COD (computing on demand)                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TCondor.h"
#include "TList.h"
#include "TSystem.h"
#include "TObjString.h"
#include "TRegexp.h"
#include "TProofDebug.h"
#include "Riostream.h"

ClassImp(TCondorSlave)
ClassImp(TCondor)

//______________________________________________________________________________
TCondor::TCondor(const char *pool) : fPool(pool), fState(kFree)
{
   // Create Condor interface object. Uses Condor apps since there is no
   // API yet.

   fClaims = new TList;

   // hack our path :-/
   TString path = gSystem->Getenv("PATH");
   path = "/opt/condor/bin:" + path;
   gSystem->Setenv("PATH",path);
   gSystem->Setenv("CONDOR_CONFIG","/opt/condor/etc/condor_config");
}

//______________________________________________________________________________
TCondor::~TCondor()
{
   // Cleanup Condor interface.

   PDB(kCondor,1) Info("~TCondor","fState %d", fState );

   if (fState != kFree) {
      Release();
   }
   delete fClaims;
}

//______________________________________________________________________________
void TCondor::Print(Option_t * opt) const
{
   cout << "OBJ: " << IsA()->GetName()
      << "\tPool: \"" << fPool << "\""
      << "\tState: " << fState << endl;
   fClaims->Print(opt);
}

//______________________________________________________________________________
TCondorSlave *TCondor::ClaimVM(const char *vm, const char * /*cmd*/, Int_t &port)
{
   // Claim a VirtualMachine for PROOF usage.

   TString claimCmd = Form("condor_cod request -name %s -timeout 10 2>/dev/null", vm );

   PDB(kCondor,2) Info("ClaimVM","command: %s", claimCmd.Data());
   FILE  *pipe = gSystem->OpenPipe(claimCmd, "r");

   if (!pipe) {
      SysError("ClaimVM","cannot run command: %s", claimCmd.Data());
      return 0;
   }

   TString claimId;
   TString line;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("ClaimVM","line = %s", line.Data());

      if (line.BeginsWith("ClaimId = \"")) {
         line.Remove(0, line.Index("\"")+1);
         line.Chop(); // remove trailing "
         claimId = line;
         PDB(kCondor,1) Info("ClaimVM","claim = '%s'", claimId.Data());
         TRegexp r("[0-9]*$");
         TString num = line(r);
         port = 37000 + atoi(num.Data());
         PDB(kCondor,1) Info("ClaimVM","port = %d", port);
      }
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("ClaimVM","command: %s returned %d", claimCmd.Data(), r);

   TString jobad("jobad");
   FILE *jf = gSystem->TempFileName(jobad);

   if (jf == 0) return 0;

   fputs("JobUniverse = 5\n", jf); // vanilla
   fputs("Cmd = \"/usr/local/root/bin/proofd\"\n", jf);
   fputs("Iwd = \"/tmp\"\n", jf);
   fputs("In = \"/dev/null\"\n", jf);
   fprintf(jf, "Out = \"/tmp/proofd.out.%d\"\n", port);
   fprintf(jf, "Err = \"/tmp/proofd.err.%d\"\n", port);
   fprintf(jf, "Args = \"-f -p %d -d 3 /usr/local/root\"\n", port);
   fclose(jf);

   TString activateCmd = Form("condor_cod activate -id '%s' -jobad %s",
                              claimId.Data(), jobad.Data() );

   PDB(kCondor,2) Info("ClaimVM","command: %s", activateCmd.Data());
   pipe = gSystem->OpenPipe(activateCmd, "r");

   if (!pipe) {
      SysError("ClaimVM","cannot run command: %s", activateCmd.Data());
      return 0;
   }

   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("ClaimVM","Activate: line = %s", line.Data());
   }

   r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("ClaimVM","command: %s returned %d", activateCmd.Data(), r);

   gSystem->Unlink(jobad.Data());

   // TODO: get info at the start for all nodes ...
   TCondorSlave *claim = new TCondorSlave;
   claim->fClaimID = claimId;
   TString node(vm);
   node = node.Remove(0, node.Index("@")+1);
   claim->fHostname = node;
   claim->fPort = port;
   if ( !GetVmInfo(vm, claim->fImage, claim->fPerfIdx) ) {
      // assume vm is gone
      delete claim;
      return 0;
   }

   return claim;
}

//______________________________________________________________________________
TList *TCondor::GetVirtualMachines() const
{
   // Get the names of the virtual machines in the pool.
   // Return a TList of TObjString or 0 in case of failure

   TString poolopt = fPool ? "" : Form("-pool %s", fPool.Data());
   TString cmd = Form("condor_status %s -format \"%%s\\n\" Name", poolopt.Data());

   PDB(kCondor,2) Info("GetVirtualMachines","command: %s", cmd.Data());

   FILE  *pipe = gSystem->OpenPipe(cmd, "r");

   if (!pipe) {
      SysError("GetVirtualMachines","cannot run command: %s", cmd.Data());
      return 0;
   }

   TString line;
   TList *l = new TList;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("GetVirtualMachines","line = %s", line.Data());
      if (line != "") l->Add(new TObjString(line));
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("GetVirtualMachines","command: %s returned %d", cmd.Data(), r);

   return l;
}

//______________________________________________________________________________
TList *TCondor::Claim(Int_t n, const char *cmd)
{
   if (fState != kFree) {
      Error("Claim","not in state Free");
      return 0;
   }

   TList *vms = GetVirtualMachines();

   TIter next(vms);
   TObjString *vm;
   for(Int_t i=0; i < n && (vm = (TObjString*) next()) != 0; i++ ) {
      Int_t port = 17000+i; // hard code port for the moment
      TCondorSlave *claim = ClaimVM(vm->GetName(), cmd, port);
      if (claim != 0) {

         fClaims->Add(claim);

      }
   }

   fState = kActive;

   return fClaims;
}

//______________________________________________________________________________
Bool_t TCondor::SetState(EState state)
{
   TIter next(fClaims);
   TCondorSlave *claim;
   while((claim = (TCondorSlave*) next()) != 0) {
      TString cmd = Form("condor_cod %s -id '%s'",
                         state == kSuspended ? "suspend" : "resume",
                         claim->fClaimID.Data());

      PDB(kCondor,2) Info("SetState","command: %s", cmd.Data());
      FILE  *pipe = gSystem->OpenPipe(cmd, "r");

      if (!pipe) {
         SysError("SetState","cannot run command: %s", cmd.Data());
         return kFALSE;
      }

      TString line;
      while (line.Gets(pipe)) {
         PDB(kCondor,3) Info("SetState","line = %s", line.Data());
      }

      Int_t r = gSystem->ClosePipe(pipe);
      PDB(kCondor,1) Info("SetState","command: %s returned %d", cmd.Data(), r);
   }

   fState = state;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TCondor::Suspend()
{
   if (fState != kActive) {
      Error("Suspend","not in state Active");
      return kFALSE;
   }

   return SetState(kSuspended);
}

//______________________________________________________________________________
Bool_t TCondor::Resume()
{
   if (fState != kSuspended) {
      Error("Suspend","not in state Suspended");
      return kFALSE;
   }

   return SetState(kActive);
}

//______________________________________________________________________________
Bool_t TCondor::Release()
{
   if (fState == kFree) {
      Error("Suspend","not in state Active or Suspended");
      return kFALSE;
   }

   TCondorSlave *claim;
   while((claim = (TCondorSlave*) fClaims->First()) != 0) {
      TString cmd = Form("condor_cod release -id '%s'", claim->fClaimID.Data());

      PDB(kCondor,2) Info("SetState","command: %s", cmd.Data());
      FILE  *pipe = gSystem->OpenPipe(cmd, "r");

      if (!pipe) {
         SysError("Release","cannot run command: %s", cmd.Data());
         return kFALSE;
      }

      TString line;
      while (line.Gets(pipe)) {
         PDB(kCondor,3) Info("Release","line = %s", line.Data());
      }

      Int_t r = gSystem->ClosePipe(pipe);
      PDB(kCondor,1) Info("Release","command: %s returned %d", cmd.Data(), r);

      fClaims->Remove(claim);
      delete claim;
   }

   fState = kFree;
   return kTRUE;
}

//______________________________________________________________________________
Bool_t TCondor::GetVmInfo(const char *vm, TString &image, Int_t &perfidx) const
{
   TString cmd = Form("condor_status -format \"%%d:\" Mips -format \"%%s\\n\" FileSystemDomain "
                      "-const 'Name==\"%s\"'", vm);

   PDB(kCondor,2) Info("GetVmInfo","command: %s", cmd.Data());
   FILE  *pipe = gSystem->OpenPipe(cmd, "r");

   if (!pipe) {
      SysError("GetVmInfo","cannot run command: %s", cmd.Data());
      return 0;
   }

   TString line;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("GetVmInfo","line = %s", line.Data());
      if (line != "") {
         TString amips = line(TRegexp("^[0-9]*"));
         perfidx = atoi(amips);
         image = line(TRegexp("[^:]+$"));
         break;
      }
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("GetVmInfo","command: %s returned %d", cmd.Data(), r);

   return kTRUE;
}

//______________________________________________________________________________
TString TCondor::GetImage(const char *host) const
{
   TString cmd = Form("condor_status -direct %s -format \"Image:%%s\\n\" "
                      "FileSystemDomain", host);

   PDB(kCondor,2) Info("GetImage","command: %s", cmd.Data());

   FILE  *pipe = gSystem->OpenPipe(cmd, "r");

   if (!pipe) {
      SysError("GetImage","cannot run command: %s", cmd.Data());
      return 0;
   }

   TString image;
   TString line;
   while (line.Gets(pipe)) {
      PDB(kCondor,3) Info("GetImage","line = %s", line.Data());
      if (line != "") {
         image = line(TRegexp("[^:]+$"));
         break;
      }
   }

   Int_t r = gSystem->ClosePipe(pipe);
   PDB(kCondor,1) Info("GetImage","command: %s returned %d", cmd.Data(), r);

   return image;
}

//______________________________________________________________________________
void TCondorSlave::Print(Option_t * /*opt*/ ) const
{
   cout << "OBJ: " << IsA()->GetName()
      << " " << fHostname << ":" << fPort
      << "  Perf: " << fPerfIdx
      << "  Image: " << fImage << endl;
}

<|endoftext|>


<commit_before>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef __RESEMBLA_REGRESSION_HPP__
#define __RESEMBLA_REGRESSION_HPP__

#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <fstream>

#include "resembla_interface.hpp"
#include "reranker.hpp"
#include "regression/feature.hpp"
#include "regression/extractor/feature_extractor.hpp"

namespace resembla {

template<typename ScoreFunction>
class ResemblaRegression: public ResemblaInterface
{
public:
    ResemblaRegression(size_t max_candidate,
            std::shared_ptr<FeatureExtractor> feature_extractor, std::shared_ptr<ScoreFunction> score_func,
            std::string corpus_path = "", size_t feature_col = 2):
        max_candidate(max_candidate), preprocess(feature_extractor), score_func(score_func),
        reranker(), preprocess_corpus(!corpus_path.empty())
    {
        if(preprocess_corpus){
            loadCorpusFeatures(corpus_path, feature_col);
        }
    }

    void append(const std::string name, const std::shared_ptr<ResemblaInterface> resembla, bool is_primary = true)
    {
        resemblas[name] = resembla;
        if(is_primary && primary_resembla_name.empty()){
            primary_resembla_name = name;
        }
    }

    std::vector<output_type> find(const string_type& query, double threshold = 0.0, size_t max_response = 0)
    {
        std::vector<string_type> candidate_texts;
        std::unordered_map<string_type, StringFeatureMap> candidate_features;

        // primary resembla
        for(const auto& r: resemblas[primary_resembla_name]->find(query, threshold / 2.0, max_candidate * 2)){
            candidate_texts.push_back(r.text);
            candidate_features[r.text] = preprocess_corpus ? corpus_features[r.text] : (*preprocess)(r.text);
            candidate_features[r.text][primary_resembla_name] = Feature::toText(r.score);
        }

        // other resemblas
        for(const auto& p: resemblas){
            if(p.first == primary_resembla_name){
                continue;
            }
            for(auto r: p.second->eval(query, candidate_texts, threshold / 2.0, max_candidate * 2)){
                candidate_features[r.text][p.first] = Feature::toText(r.score);
            }
        }

        return eval(query, candidate_features, threshold, max_response);
    }

    std::vector<output_type> eval(const string_type& query, const std::vector<string_type>& targets, double threshold = 0.0, size_t max_response = 0) const
    {
        std::unordered_map<string_type, StringFeatureMap> candidate_features;
        for(const auto& t: targets){
            if(preprocess_corpus){
                auto i = corpus_features.find(t);
                if(i != std::end(corpus_features)){
                    candidate_features[t] = i->second;
                    continue;
                }
            }
            candidate_features[t] = (*preprocess)(t);
        }

        for(const auto& p: resemblas){
            for(const auto& r: p.second->eval(query, targets, threshold / 2.0, max_response * 2)){
                candidate_features[r.text][p.first] = Feature::toText(r.score);
            }
        }

        return eval(query, candidate_features, threshold, max_response);
    }

protected:
    std::vector<output_type> eval(const string_type& query, const std::unordered_map<string_type, StringFeatureMap>& candidate_features,
            double threshold, size_t max_response) const
    {
        // prepare data for reranking
        std::vector<WorkData> candidates;
        for(const auto& c: candidate_features){
            candidates.push_back(std::make_pair(c.first, c.second));
        }
        WorkData input_data = std::make_pair(query, (*preprocess)(query));

        // rerank by its own metric
        std::vector<ResemblaInterface::output_type> results;
        for(const auto& r: reranker.rerank(input_data, std::begin(candidates), std::end(candidates), *score_func, threshold, max_response)){
            results.push_back({r.first, score_func->name, r.second});
        }
        return results;
    }

    using WorkData = std::pair<string_type, typename FeatureExtractor::output_type>;

    std::unordered_map<std::string, std::shared_ptr<ResemblaInterface>> resemblas;
    std::string primary_resembla_name;
    const size_t max_candidate;

    const std::shared_ptr<FeatureExtractor> preprocess;
    const std::shared_ptr<ScoreFunction> score_func;
    const Reranker<string_type> reranker;

    const bool preprocess_corpus;
    std::unordered_map<string_type, typename FeatureExtractor::output_type> corpus_features;

    void loadCorpusFeatures(const std::string& corpus_path, size_t features_col)
    {
        std::ifstream ifs(corpus_path);
        if(ifs.fail()){
            throw std::runtime_error("input file is not available: " + corpus_path);
        }
        while(ifs.good()){
            std::string line;
            std::getline(ifs, line);
            if(ifs.eof() || line.length() == 0){
                break;
            }
            auto columns = split(line, '\t');
            if(features_col - 1 < columns.size()){
                corpus_features[cast_string<string_type>(columns[0])] = (*preprocess)(columns[0], columns[features_col - 1]);
            }
        }
    }
};

}
#endif
<commit_msg>improve corpus format support<commit_after>/*
Resembla: Word-based Japanese similar sentence search library
https://github.com/tuem/resembla

Copyright 2017 Takashi Uemura

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.
*/

#ifndef __RESEMBLA_REGRESSION_HPP__
#define __RESEMBLA_REGRESSION_HPP__

#include <string>
#include <vector>
#include <memory>
#include <unordered_map>
#include <fstream>

#include "resembla_interface.hpp"
#include "reranker.hpp"
#include "regression/feature.hpp"
#include "regression/extractor/feature_extractor.hpp"

namespace resembla {

template<typename ScoreFunction>
class ResemblaRegression: public ResemblaInterface
{
public:
    ResemblaRegression(size_t max_candidate,
            std::shared_ptr<FeatureExtractor> feature_extractor, std::shared_ptr<ScoreFunction> score_func,
            std::string corpus_path = "", size_t text_col = 1, size_t features_col = 2):
        max_candidate(max_candidate), preprocess(feature_extractor), score_func(score_func),
        reranker(), preprocess_corpus(!corpus_path.empty())
    {
        if(preprocess_corpus){
            loadCorpusFeatures(corpus_path, text_col, features_col);
        }
    }

    void append(const std::string name, const std::shared_ptr<ResemblaInterface> resembla, bool is_primary = true)
    {
        resemblas[name] = resembla;
        if(is_primary && primary_resembla_name.empty()){
            primary_resembla_name = name;
        }
    }

    std::vector<output_type> find(const string_type& query, double threshold = 0.0, size_t max_response = 0)
    {
        std::vector<string_type> candidate_texts;
        std::unordered_map<string_type, StringFeatureMap> candidate_features;

        // primary resembla
        for(const auto& r: resemblas[primary_resembla_name]->find(query, threshold / 2.0, max_candidate * 2)){
            candidate_texts.push_back(r.text);
            candidate_features[r.text] = preprocess_corpus ? corpus_features[r.text] : (*preprocess)(r.text);
            candidate_features[r.text][primary_resembla_name] = Feature::toText(r.score);
        }

        // other resemblas
        for(const auto& p: resemblas){
            if(p.first == primary_resembla_name){
                continue;
            }
            for(auto r: p.second->eval(query, candidate_texts, 0.0, 0)){
                candidate_features[r.text][p.first] = Feature::toText(r.score);
                candidate_features[r.text][p.first] = Feature::toText(r.score);
            }
        }

        return eval(query, candidate_features, threshold, max_response);
    }

    std::vector<output_type> eval(const string_type& query, const std::vector<string_type>& targets, double threshold = 0.0, size_t max_response = 0) const
    {
        std::unordered_map<string_type, StringFeatureMap> candidate_features;
        for(const auto& t: targets){
            if(preprocess_corpus){
                auto i = corpus_features.find(t);
                if(i != std::end(corpus_features)){
                    candidate_features[t] = i->second;
                    continue;
                }
            }
            candidate_features[t] = (*preprocess)(t);
        }

        for(const auto& p: resemblas){
            for(const auto& r: p.second->eval(query, targets, 0.0, 0)){
                candidate_features[r.text][p.first] = Feature::toText(r.score);
            }
        }

        return eval(query, candidate_features, threshold, max_response);
    }

protected:
    using WorkData = std::pair<string_type, typename FeatureExtractor::output_type>;

    std::unordered_map<std::string, std::shared_ptr<ResemblaInterface>> resemblas;
    std::string primary_resembla_name;
    const size_t max_candidate;

    const std::shared_ptr<FeatureExtractor> preprocess;
    const std::shared_ptr<ScoreFunction> score_func;
    const Reranker<string_type> reranker;

    const bool preprocess_corpus;
    std::unordered_map<string_type, typename FeatureExtractor::output_type> corpus_features;

    void loadCorpusFeatures(const std::string& corpus_path, size_t text_col, size_t features_col)
    {
        std::ifstream ifs(corpus_path);
        if(ifs.fail()){
            throw std::runtime_error("input file is not available: " + corpus_path);
        }

        while(ifs.good()){
            std::string line;
            std::getline(ifs, line);
            if(ifs.eof() || line.length() == 0){
                break;
            }
            auto columns = split(line, '\t');
            if(text_col - 1 < columns.size()){
                std::string raw_features =
                    features_col - 1 < columns.size() ? columns[features_col - 1] : "";
                corpus_features[cast_string<string_type>(columns[text_col - 1])] =
                    (*preprocess)(columns[text_col - 1], raw_features);
            }
        }
    }

    std::vector<output_type> eval(const string_type& query,
            const std::unordered_map<string_type, StringFeatureMap>& candidate_features,
            double threshold, size_t max_response) const
    {
        // prepare data for reranking
        std::vector<WorkData> candidates;
        for(const auto& c: candidate_features){
            candidates.push_back(std::make_pair(c.first, c.second));
        }
        WorkData input_data = std::make_pair(query, (*preprocess)(query));

        // rerank by its own metric
        std::vector<ResemblaInterface::output_type> results;
        for(const auto& r: reranker.rerank(input_data, std::begin(candidates), std::end(candidates), *score_func, threshold, max_response)){
            results.push_back({r.first, score_func->name, r.second});
        }
        return results;
    }
};

}
#endif
<|endoftext|>


<commit_before>#include <QSettings>
#include <QDir>
#include <QFile>
#include <QApplication>

#include "TranslatorHelper.h"
#include "Settings.h"

TranslatorHelper::TranslatorHelper ()
  : translatorsDir_ ("translators"), currentIndex_ (0), triesLeft_ (0) {
  translatorsDir_ = QApplication::applicationDirPath () + QDir::separator () + translatorsDir_;
}

void TranslatorHelper::setEnabledTranslators (const QStringList &enabled) const {
  QSettings settings;
  settings.beginGroup (settings_names::translationGroup);
  settings.setValue (settings_names::translators, enabled.join ("|"));
}

QStringList TranslatorHelper::possibleTranslators (QStringList &enabled) const {
#define GET(FIELD) settings.value (settings_names::FIELD, settings_values::FIELD)
  QSettings settings;
  settings.beginGroup (settings_names::translationGroup);
  QStringList exist = QDir (translatorsDir_).entryList (QStringList () << "*.js", QDir::Files);
  QStringList saved = GET (translators).toString ().split ("|", QString::SkipEmptyParts);
  QStringList on, off;
  std::copy_if (saved.begin (), saved.end (), std::back_inserter (on), [&](const QString &i) {
    return exist.contains (i);
  });
  on = on.isEmpty () ? exist : on;

  std::copy_if (exist.begin (), exist.end (), std::back_inserter (off), [&](const QString &i) {
    return !on.contains (i);
  });

  enabled = on;
  return (on + off);
#undef GET
}

QStringList TranslatorHelper::enabledTranslatorScripts () const {
  QStringList enabled;
  possibleTranslators (enabled);
  QStringList scripts;
  foreach (const QString &name, enabled) {
    QFile f (translatorsDir_ + QDir::separator () + name);
    if (f.open (QFile::ReadOnly)) {
      QString script = QString::fromUtf8 (f.readAll ());
      if (!script.isEmpty ()) {
        scripts << script;
      }
    }
  }
  return scripts;
}

void TranslatorHelper::loadScripts () {
  scripts_ = enabledTranslatorScripts ();
}

void TranslatorHelper::newItem (bool forceRotate) {
  triesLeft_ = scripts_.size ();
  currentIndex_ = forceRotate ? currentIndex_ + 1 : 0;
}

QString TranslatorHelper::nextScript () {
  --triesLeft_;

  if (++currentIndex_ >= scripts_.size ()) {
    currentIndex_ = 0;
  }

  return currentScript ();
}

QString TranslatorHelper::currentScript () const {
  return (triesLeft_ > 0 ? scripts_.at (currentIndex_) : QString ());
}

bool TranslatorHelper::gotScripts () const {
  return !scripts_.isEmpty ();
}
<commit_msg>Fixed possible wrong index usage<commit_after>#include <QSettings>
#include <QDir>
#include <QFile>
#include <QApplication>

#include "TranslatorHelper.h"
#include "Settings.h"

TranslatorHelper::TranslatorHelper ()
  : translatorsDir_ ("translators"), currentIndex_ (0), triesLeft_ (0) {
  translatorsDir_ = QApplication::applicationDirPath () + QDir::separator () + translatorsDir_;
}

void TranslatorHelper::setEnabledTranslators (const QStringList &enabled) const {
  QSettings settings;
  settings.beginGroup (settings_names::translationGroup);
  settings.setValue (settings_names::translators, enabled.join ("|"));
}

QStringList TranslatorHelper::possibleTranslators (QStringList &enabled) const {
#define GET(FIELD) settings.value (settings_names::FIELD, settings_values::FIELD)
  QSettings settings;
  settings.beginGroup (settings_names::translationGroup);
  QStringList exist = QDir (translatorsDir_).entryList (QStringList () << "*.js", QDir::Files);
  QStringList saved = GET (translators).toString ().split ("|", QString::SkipEmptyParts);
  QStringList on, off;
  std::copy_if (saved.begin (), saved.end (), std::back_inserter (on), [&](const QString &i) {
    return exist.contains (i);
  });
  on = on.isEmpty () ? exist : on;

  std::copy_if (exist.begin (), exist.end (), std::back_inserter (off), [&](const QString &i) {
    return !on.contains (i);
  });

  enabled = on;
  return (on + off);
#undef GET
}

QStringList TranslatorHelper::enabledTranslatorScripts () const {
  QStringList enabled;
  possibleTranslators (enabled);
  QStringList scripts;
  foreach (const QString &name, enabled) {
    QFile f (translatorsDir_ + QDir::separator () + name);
    if (f.open (QFile::ReadOnly)) {
      QString script = QString::fromUtf8 (f.readAll ());
      if (!script.isEmpty ()) {
        scripts << script;
      }
    }
  }
  return scripts;
}

void TranslatorHelper::loadScripts () {
  scripts_ = enabledTranslatorScripts ();
}

void TranslatorHelper::newItem (bool forceRotate) {
  triesLeft_ = scripts_.size ();
  currentIndex_ = forceRotate ? currentIndex_ + 1 : 0;
  if (currentIndex_ >= scripts_.size ()) {
    currentIndex_ = 0;
  }
}

QString TranslatorHelper::nextScript () {
  --triesLeft_;

  if (++currentIndex_ >= scripts_.size ()) {
    currentIndex_ = 0;
  }

  return currentScript ();
}

QString TranslatorHelper::currentScript () const {
  if (triesLeft_ > 0 && currentIndex_ < scripts_.size ()) {
    return scripts_.at (currentIndex_);
  }
  return QString ();
}

bool TranslatorHelper::gotScripts () const {
  return !scripts_.isEmpty ();
}
<|endoftext|>


<commit_before>/* $Id$ */

/* generate_extra_defs.cc
 *
 * Copyright (C) 2001 The Free Software Foundation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "generate_extra_defs.h"
#include <algorithm>

std::string get_properties(GType gtype)
{
  std::string strResult;
  std::string strObjectName = g_type_name(gtype);

  //Get the list of properties:
  GParamSpec** ppParamSpec = 0;
  guint iCount = 0;
  if(G_TYPE_IS_OBJECT(gtype))
  {
    GObjectClass* pGClass = G_OBJECT_CLASS(g_type_class_ref(gtype));
    ppParamSpec = g_object_class_list_properties (pGClass, &iCount);
    g_type_class_unref(pGClass);

    if(!ppParamSpec)
    {
      strResult += ";; Warning: g_object_class_list_properties() returned NULL for " + std::string(g_type_name(gtype)) + "\n";
    }
  }
  else if (G_TYPE_IS_INTERFACE(gtype))
  {
    gpointer pGInterface = g_type_default_interface_ref(gtype);
    if(pGInterface) //We check because this fails for G_TYPE_VOLUME, for some reason.
    {
      ppParamSpec = g_object_interface_list_properties(pGInterface, &iCount);
      g_type_default_interface_unref(pGInterface);

      if(!ppParamSpec)
      {
        strResult +=  ";; Warning: g_object_interface_list_properties() returned NULL for " + std::string(g_type_name(gtype)) + "\n";
      }
    }
  }

  //This extra check avoids an occasional crash, for instance for GVolume
  if(!ppParamSpec)
    iCount = 0;

  for(guint i = 0; i < iCount; i++)
  {
    GParamSpec* pParamSpec = ppParamSpec[i];
    // Generate the property if the specified gtype actually owns the property.
    // (Generally all properties, including any base classes' properties are
    // retrieved by g_object_interface_list_properties() for a given gtype.
    // The base classes' properties should not be generated).
    if(pParamSpec && pParamSpec->owner_type == gtype)
    {
      //Name and type:
      const std::string strName = g_param_spec_get_name(pParamSpec);
      const std::string strTypeName = G_PARAM_SPEC_TYPE_NAME(pParamSpec);

      const gchar* pchBlurb = g_param_spec_get_blurb(pParamSpec);
      std::string strDocs = (pchBlurb) ? pchBlurb : "";
      // Quick hack to get rid of nested double quotes:
      std::replace(strDocs.begin(), strDocs.end(), '"', '\'');

      strResult += "(define-property " + strName + "\n";
      strResult += "  (of-object \"" + strObjectName + "\")\n";
      strResult += "  (prop-type \"" + strTypeName + "\")\n";
      strResult += "  (docs \"" + strDocs + "\")\n";

      //Flags:
      GParamFlags flags = pParamSpec->flags;
      bool bReadable = (flags & G_PARAM_READABLE) == G_PARAM_READABLE;
      bool bWritable = (flags & G_PARAM_WRITABLE) == G_PARAM_WRITABLE;
      bool bConstructOnly = (flags & G_PARAM_CONSTRUCT_ONLY) == G_PARAM_CONSTRUCT_ONLY;

      //#t and #f aren't documented, but I guess that it's correct based on the example in the .defs spec.
      const std::string strTrue = "#t";
      const std::string strFalse = "#f";

      strResult += "  (readable " + (bReadable ? strTrue : strFalse) + ")\n";
      strResult += "  (writable " + (bWritable ? strTrue : strFalse) + ")\n";
      strResult += "  (construct-only " + (bConstructOnly ? strTrue : strFalse) + ")\n";

      strResult += ")\n\n"; //close (define-property
    }
  }

  g_free(ppParamSpec);

  return strResult;
}

bool gtype_is_a_pointer(GType gtype)
{
  return (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_BOXED));
}

std::string get_type_name(GType gtype, GTypeIsAPointerFunc is_a_pointer_func) //Adds a * if necessary.
{
  std::string strTypeName = g_type_name(gtype);

  if (is_a_pointer_func && is_a_pointer_func(gtype))
    strTypeName += "*";  //Add * to show that it's a pointer.
  else if( g_type_is_a(gtype, G_TYPE_STRING) )
    strTypeName = "gchar*"; //g_type_name() returns "gchararray".

  return strTypeName;
}

std::string get_type_name_parameter(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strTypeName = get_type_name(gtype, is_a_pointer_func);

  //All signal parameters that are registered as GTK_TYPE_STRING are actually const gchar*.
  if(strTypeName == "gchar*")
    strTypeName = "const-gchar*";

  return strTypeName;
}

std::string get_type_name_signal(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  return get_type_name_parameter(gtype, is_a_pointer_func); //At the moment, it needs the same stuff.
}

std::string get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strResult;
  std::string strObjectName = g_type_name(gtype);

  gpointer gclass_ref = 0;
  gpointer ginterface_ref = 0;

  if(G_TYPE_IS_OBJECT(gtype))
    gclass_ref = g_type_class_ref(gtype); //Ensures that class_init() is called.
  else if(G_TYPE_IS_INTERFACE(gtype))
    ginterface_ref = g_type_default_interface_ref(gtype); //install signals.

  //Get the list of signals:
  guint iCount = 0;
  guint* pIDs = g_signal_list_ids (gtype, &iCount);

  //Loop through the list of signals:
  if(pIDs)
  {
    for(guint i = 0; i < iCount; i++)
    {
      guint signal_id = pIDs[i];

      //Name:
      std::string strName = g_signal_name(signal_id);
      strResult += "(define-signal " + strName + "\n";
      strResult += "  (of-object \"" + strObjectName + "\")\n";

      //Other information about the signal:
      GSignalQuery signalQuery = { 0, 0, 0, GSignalFlags(0), 0, 0, 0, };
      g_signal_query(signal_id, &signalQuery);

      //Return type:
      std::string strReturnTypeName = get_type_name_signal( signalQuery.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func ); //The type is mangled with a flag. Hacky.
      //bool bReturnTypeHasStaticScope = (signalQuery.return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == G_SIGNAL_TYPE_STATIC_SCOPE;
      strResult += "  (return-type \"" + strReturnTypeName + "\")\n";

      //When:
      {
        bool bWhenFirst = (signalQuery.signal_flags & G_SIGNAL_RUN_FIRST) == G_SIGNAL_RUN_FIRST;
        bool bWhenLast = (signalQuery.signal_flags & G_SIGNAL_RUN_LAST) == G_SIGNAL_RUN_LAST;

        std::string strWhen = "unknown";

        if(bWhenFirst && bWhenLast)
          strWhen = "both";
        else if(bWhenFirst)
          strWhen = "first";
        else if(bWhenLast)
          strWhen = "last";

        strResult += "  (when \"" + strWhen + "\")\n";
      }

      //Loop through the list of parameters:
      const GType* pParameters = signalQuery.param_types;
      if(pParameters)
      {
        strResult += "  (parameters\n";

        for(unsigned i = 0; i < signalQuery.n_params; i++)
        {
          GType typeParamMangled = pParameters[i];

          //Parameter name:
          //TODO: How can we get the real parameter name?
          gchar* pchNum = g_strdup_printf("%d", i);
          std::string strParamName = "p" + std::string(pchNum);
          g_free(pchNum);
          pchNum = 0;

          //Just like above, for the return type:
          std::string strTypeName = get_type_name_signal( typeParamMangled & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func ); //The type is mangled with a flag. Hacky.
          //bool bReturnTypeHasStaticScope = (typeParamMangled & G_SIGNAL_TYPE_STATIC_SCOPE) == G_SIGNAL_TYPE_STATIC_SCOPE;

          strResult += "    '(\"" + strTypeName + "\" \"" + strParamName + "\")\n";
        }

        strResult += "  )\n"; //close (properties
      }

      strResult += ")\n\n"; //close (define=signal
    }
  }

  g_free(pIDs);

  if(gclass_ref)
    g_type_class_unref(gclass_ref); //to match the g_type_class_ref() above.
  else if(ginterface_ref)
    g_type_default_interface_unref(ginterface_ref); // for interface ref above.

  return strResult;
}

std::string get_defs(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strObjectName = g_type_name(gtype);
  std::string strDefs = ";; From " + strObjectName + "\n\n";

  if(G_TYPE_IS_OBJECT(gtype) || G_TYPE_IS_INTERFACE(gtype))
  {
    strDefs += get_signals(gtype, is_a_pointer_func);
    strDefs += get_properties(gtype);
  }

  return strDefs;
}
<commit_msg>tools/extra_defs_gen/generate_extra_defs.cc: Update some comments<commit_after>/* $Id$ */

/* generate_extra_defs.cc
 *
 * Copyright (C) 2001 The Free Software Foundation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include "generate_extra_defs.h"
#include <algorithm>

// Until the glib bug https://bugzilla.gnome.org/show_bug.cgi?id=465631
// is fixed, get_properties() must be called for a GObject before it's
// called for a GInterface.
std::string get_properties(GType gtype)
{
  std::string strResult;
  std::string strObjectName = g_type_name(gtype);

  //Get the list of properties:
  GParamSpec** ppParamSpec = 0;
  guint iCount = 0;
  if(G_TYPE_IS_OBJECT(gtype))
  {
    GObjectClass* pGClass = G_OBJECT_CLASS(g_type_class_ref(gtype));
    ppParamSpec = g_object_class_list_properties (pGClass, &iCount);
    g_type_class_unref(pGClass);

    if(!ppParamSpec)
    {
      strResult += ";; Warning: g_object_class_list_properties() returned NULL for " + std::string(g_type_name(gtype)) + "\n";
    }
  }
  else if (G_TYPE_IS_INTERFACE(gtype))
  {
    gpointer pGInterface = g_type_default_interface_ref(gtype);
    if(pGInterface)
    {
      ppParamSpec = g_object_interface_list_properties(pGInterface, &iCount);
      g_type_default_interface_unref(pGInterface);

      if(!ppParamSpec)
      {
        strResult += ";; Warning: g_object_interface_list_properties() returned NULL for " + std::string(g_type_name(gtype)) + "\n";
      }
    }
    else
      strResult += ";; Warning: g_type_default_interface_ref() returned NULL for " + std::string(g_type_name(gtype)) + "\n";
  }

  //This extra check avoids an occasional crash
  if(!ppParamSpec)
    iCount = 0;

  for(guint i = 0; i < iCount; i++)
  {
    GParamSpec* pParamSpec = ppParamSpec[i];
    // Generate the property if the specified gtype actually owns the property.
    // (Generally all properties, including any base classes' properties are
    // retrieved by g_object_interface_list_properties() for a given gtype.
    // The base classes' properties should not be generated).
    if(pParamSpec && pParamSpec->owner_type == gtype)
    {
      //Name and type:
      const std::string strName = g_param_spec_get_name(pParamSpec);
      const std::string strTypeName = G_PARAM_SPEC_TYPE_NAME(pParamSpec);

      const gchar* pchBlurb = g_param_spec_get_blurb(pParamSpec);
      std::string strDocs = (pchBlurb) ? pchBlurb : "";
      // Quick hack to get rid of nested double quotes:
      std::replace(strDocs.begin(), strDocs.end(), '"', '\'');

      strResult += "(define-property " + strName + "\n";
      strResult += "  (of-object \"" + strObjectName + "\")\n";
      strResult += "  (prop-type \"" + strTypeName + "\")\n";
      strResult += "  (docs \"" + strDocs + "\")\n";

      //Flags:
      GParamFlags flags = pParamSpec->flags;
      bool bReadable = (flags & G_PARAM_READABLE) == G_PARAM_READABLE;
      bool bWritable = (flags & G_PARAM_WRITABLE) == G_PARAM_WRITABLE;
      bool bConstructOnly = (flags & G_PARAM_CONSTRUCT_ONLY) == G_PARAM_CONSTRUCT_ONLY;

      //#t and #f aren't documented, but I guess that it's correct based on the example in the .defs spec.
      const std::string strTrue = "#t";
      const std::string strFalse = "#f";

      strResult += "  (readable " + (bReadable ? strTrue : strFalse) + ")\n";
      strResult += "  (writable " + (bWritable ? strTrue : strFalse) + ")\n";
      strResult += "  (construct-only " + (bConstructOnly ? strTrue : strFalse) + ")\n";

      strResult += ")\n\n"; //close (define-property
    }
  }

  g_free(ppParamSpec);

  return strResult;
}

bool gtype_is_a_pointer(GType gtype)
{
  return (g_type_is_a(gtype, G_TYPE_OBJECT) || g_type_is_a(gtype, G_TYPE_BOXED));
}

std::string get_type_name(GType gtype, GTypeIsAPointerFunc is_a_pointer_func) //Adds a * if necessary.
{
  std::string strTypeName = g_type_name(gtype);

  if (is_a_pointer_func && is_a_pointer_func(gtype))
    strTypeName += "*";  //Add * to show that it's a pointer.
  else if( g_type_is_a(gtype, G_TYPE_STRING) )
    strTypeName = "gchar*"; //g_type_name() returns "gchararray".

  return strTypeName;
}

std::string get_type_name_parameter(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strTypeName = get_type_name(gtype, is_a_pointer_func);

  //All signal parameters that are registered as GTK_TYPE_STRING are actually const gchar*.
  if(strTypeName == "gchar*")
    strTypeName = "const-gchar*";

  return strTypeName;
}

std::string get_type_name_signal(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  return get_type_name_parameter(gtype, is_a_pointer_func); //At the moment, it needs the same stuff.
}

std::string get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strResult;
  std::string strObjectName = g_type_name(gtype);

  gpointer gclass_ref = 0;
  gpointer ginterface_ref = 0;

  if(G_TYPE_IS_OBJECT(gtype))
    gclass_ref = g_type_class_ref(gtype); //Ensures that class_init() is called.
  else if(G_TYPE_IS_INTERFACE(gtype))
    ginterface_ref = g_type_default_interface_ref(gtype); //install signals.

  //Get the list of signals:
  guint iCount = 0;
  guint* pIDs = g_signal_list_ids (gtype, &iCount);

  //Loop through the list of signals:
  if(pIDs)
  {
    for(guint i = 0; i < iCount; i++)
    {
      guint signal_id = pIDs[i];

      //Name:
      std::string strName = g_signal_name(signal_id);
      strResult += "(define-signal " + strName + "\n";
      strResult += "  (of-object \"" + strObjectName + "\")\n";

      //Other information about the signal:
      GSignalQuery signalQuery = { 0, 0, 0, GSignalFlags(0), 0, 0, 0, };
      g_signal_query(signal_id, &signalQuery);

      //Return type:
      std::string strReturnTypeName = get_type_name_signal( signalQuery.return_type & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func ); //The type is mangled with a flag. Hacky.
      //bool bReturnTypeHasStaticScope = (signalQuery.return_type & G_SIGNAL_TYPE_STATIC_SCOPE) == G_SIGNAL_TYPE_STATIC_SCOPE;
      strResult += "  (return-type \"" + strReturnTypeName + "\")\n";

      //When:
      {
        bool bWhenFirst = (signalQuery.signal_flags & G_SIGNAL_RUN_FIRST) == G_SIGNAL_RUN_FIRST;
        bool bWhenLast = (signalQuery.signal_flags & G_SIGNAL_RUN_LAST) == G_SIGNAL_RUN_LAST;

        std::string strWhen = "unknown";

        if(bWhenFirst && bWhenLast)
          strWhen = "both";
        else if(bWhenFirst)
          strWhen = "first";
        else if(bWhenLast)
          strWhen = "last";

        strResult += "  (when \"" + strWhen + "\")\n";
      }

      //Loop through the list of parameters:
      const GType* pParameters = signalQuery.param_types;
      if(pParameters)
      {
        strResult += "  (parameters\n";

        for(unsigned i = 0; i < signalQuery.n_params; i++)
        {
          GType typeParamMangled = pParameters[i];

          //Parameter name:
          //We can't get the real parameter name from the GObject system. It's not registered with g_signal_new().
          gchar* pchNum = g_strdup_printf("%d", i);
          std::string strParamName = "p" + std::string(pchNum);
          g_free(pchNum);
          pchNum = 0;

          //Just like above, for the return type:
          std::string strTypeName = get_type_name_signal( typeParamMangled & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func ); //The type is mangled with a flag. Hacky.
          //bool bTypeHasStaticScope = (typeParamMangled & G_SIGNAL_TYPE_STATIC_SCOPE) == G_SIGNAL_TYPE_STATIC_SCOPE;

          strResult += "    '(\"" + strTypeName + "\" \"" + strParamName + "\")\n";
        }

        strResult += "  )\n"; //close (parameters
      }

      strResult += ")\n\n"; //close (define-signal
    }
  }

  g_free(pIDs);

  if(gclass_ref)
    g_type_class_unref(gclass_ref); //to match the g_type_class_ref() above.
  else if(ginterface_ref)
    g_type_default_interface_unref(ginterface_ref); // for interface ref above.

  return strResult;
}

std::string get_defs(GType gtype, GTypeIsAPointerFunc is_a_pointer_func)
{
  std::string strObjectName = g_type_name(gtype);
  std::string strDefs;

  if(G_TYPE_IS_OBJECT(gtype) || G_TYPE_IS_INTERFACE(gtype))
  {
    strDefs = ";; From " + strObjectName + "\n\n";
    strDefs += get_signals(gtype, is_a_pointer_func);
    strDefs += get_properties(gtype);
  }
  else
    strDefs = ";; " + strObjectName +
      " is neither a GObject nor a GInterface. Not checked for signals and properties.\n\n";

  return strDefs;
}
<|endoftext|>