<commit_before>
#include "../Flare.h"
#include "../Game/FlareSimulatedSector.h"
#include "../Game/FlareGame.h"
#include "../Game/FlareWorld.h"
#include "../Player/FlarePlayerController.h"
#include "../Economy/FlareCargoBay.h"
#include "../Economy/FlareFactory.h"
#include "../Spacecrafts/Subsystems/FlareSpacecraftDamageSystemInterface.h"
#include "../Data/FlareFactoryCatalogEntry.h"
#include "FlareSimulatedSpacecraft.h"

#define LOCTEXT_NAMESPACE "FlareSimulatedSpacecraft"

/*----------------------------------------------------
	Constructor
----------------------------------------------------*/

UFlareSimulatedSpacecraft::UFlareSimulatedSpacecraft(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	ActiveSpacecraft = NULL;
}

void UFlareSimulatedSpacecraft::Load(const FFlareSpacecraftSave& Data)
{
	Game = Cast<UFlareCompany>(GetOuter())->GetGame();
	SpacecraftData = Data;

	// Load spacecraft description
	SpacecraftDescription = Game->GetSpacecraftCatalog()->Get(Data.Identifier);

	// Initialize damage system
	DamageSystem = NewObject<UFlareSimulatedSpacecraftDamageSystem>(this, UFlareSimulatedSpacecraftDamageSystem::StaticClass());
	DamageSystem->Initialize(this, &SpacecraftData);

	// Initialize weapons system
	WeaponsSystem = NewObject<UFlareSimulatedSpacecraftWeaponsSystem>(this, UFlareSimulatedSpacecraftWeaponsSystem::StaticClass());
	WeaponsSystem->Initialize(this, &SpacecraftData);

	Game->GetGameWorld()->ClearFactories(this);
	Factories.Empty();

	// Load factories
	for (int FactoryIndex = 0; FactoryIndex < SpacecraftDescription->Factories.Num(); FactoryIndex++)
	{
		FFlareFactorySave FactoryData;
		FFlareFactoryDescription* FactoryDescription = &SpacecraftDescription->Factories[FactoryIndex]->Data;

		if (FactoryIndex < SpacecraftData.FactoryStates.Num())
		{
			FactoryData = SpacecraftData.FactoryStates[FactoryIndex];
		}
		else
		{
				FactoryData.Active = FactoryDescription->AutoStart;
				FactoryData.CostReserved = 0;
				FactoryData.ProductedDuration = 0;
				FactoryData.InfiniteCycle = true;
				FactoryData.CycleCount = 0;
				FactoryData.TargetShipClass = NAME_None;
				FactoryData.TargetShipCompany = NAME_None;
				FactoryData.OrderShipClass = NAME_None;
				FactoryData.OrderShipCompany = NAME_None;
				FactoryData.OrderShipAdvancePayment = 0;
		}

		UFlareFactory* Factory = NewObject<UFlareFactory>(GetGame()->GetGameWorld(), UFlareFactory::StaticClass());
		Factory->Load(this, FactoryDescription, FactoryData);
		Factories.Add(Factory);
		Game->GetGameWorld()->AddFactory(Factory);
	}

	CargoBay = NewObject<UFlareCargoBay>(this, UFlareCargoBay::StaticClass());
	CargoBay->Load(this, SpacecraftData.Cargo);

	// Lock resources
	LockResources();

	if(ActiveSpacecraft)
	{
		ActiveSpacecraft->Load(this);
	}
}

FFlareSpacecraftSave* UFlareSimulatedSpacecraft::Save()
{
	SpacecraftData.FactoryStates.Empty();
	for (int FactoryIndex = 0; FactoryIndex < Factories.Num(); FactoryIndex++)
	{
		SpacecraftData.FactoryStates.Add(*Factories[FactoryIndex]->Save());
	}

	SpacecraftData.Cargo = *CargoBay->Save();

	if(IsActive())
	{
		GetActive()->Save();
	}

	return &SpacecraftData;
}

UFlareCompany* UFlareSimulatedSpacecraft::GetCompany() const
{
	// TODO Cache
	return Game->GetGameWorld()->FindCompany(SpacecraftData.CompanyIdentifier);
}

EFlarePartSize::Type UFlareSimulatedSpacecraft::GetSize()
{
	return SpacecraftDescription->Size;
}

bool UFlareSimulatedSpacecraft::IsMilitary() const
{
	return FFlareSpacecraftDescription::IsMilitary(SpacecraftDescription);
}

bool UFlareSimulatedSpacecraft::IsStation() const
{
	return FFlareSpacecraftDescription::IsStation(SpacecraftDescription);
}

bool UFlareSimulatedSpacecraft::CanFight() const
{
	return GetDamageSystem()->IsAlive() && IsMilitary() && GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Weapon) > 0;
}

bool UFlareSimulatedSpacecraft::CanTravel() const
{
	return !IsTrading() && GetDamageSystem()->IsAlive() && GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Propulsion) > 0;
}

FName UFlareSimulatedSpacecraft::GetImmatriculation() const
{
	return SpacecraftData.Immatriculation;
}

UFlareSimulatedSpacecraftDamageSystem* UFlareSimulatedSpacecraft::GetDamageSystem() const
{
	return DamageSystem;
}

UFlareSimulatedSpacecraftWeaponsSystem* UFlareSimulatedSpacecraft::GetWeaponsSystem() const
{
	return WeaponsSystem;
}

void UFlareSimulatedSpacecraft::SetSpawnMode(EFlareSpawnMode::Type SpawnMode)
{
	SpacecraftData.SpawnMode = SpawnMode;
}

bool UFlareSimulatedSpacecraft::CanBeFlown(FText& OutInfo) const
{
	UFlareFleet* PlayerFleet = GetGame()->GetPC()->GetPlayerFleet();

	if (IsStation())
	{
		return false;
	}
	else if (!GetDamageSystem()->IsAlive())
	{
		OutInfo = LOCTEXT("CantFlyDestroyedInfo", "This ship has been destroyed");
		return false;
	}
	else if (PlayerFleet && GetCurrentFleet() != PlayerFleet)
	{
		OutInfo = LOCTEXT("CantFlyOtherInfo", "You can only switch ships from whithin the same fleet");
		return false;
	}
	else if (!IsActive())
	{
		OutInfo = LOCTEXT("CantFlyDistantInfo", "You can't fly a ship from another sector");
		return false;
	}
	else
	{
		return true;
	}
}

/*----------------------------------------------------
	Gameplay
----------------------------------------------------*/

void UFlareSimulatedSpacecraft::SetCurrentSector(UFlareSimulatedSector* Sector)
{
	CurrentSector = Sector;

	// Mark the sector as visited
	if (!Sector->IsTravelSector())
	{
		GetCompany()->VisitSector(Sector);
	}
}

/*----------------------------------------------------
	Resources
----------------------------------------------------*/

bool UFlareSimulatedSpacecraft::CanTradeWith(UFlareSimulatedSpacecraft* OtherSpacecraft)
{
	// Check if both spacecraft are in the same sector
	if(GetCurrentSector() != OtherSpacecraft->GetCurrentSector())
	{
		return false;
	}

	// Check if spacecraft are not both stations
	if(IsStation() && OtherSpacecraft->IsStation())
	{
		return false;
	}

	// Check if spacecraft are not both ships
	if(!IsStation() && !OtherSpacecraft->IsStation())
	{
		return false;
	}

	// Check if spacecraft are are not already trading
	if(IsTrading() || OtherSpacecraft->IsTrading())
	{
		return false;
	}

	// Check if both spacecraft are not at war
	if(GetCompany()->GetWarState(OtherSpacecraft->GetCompany()) == EFlareHostility::Hostile)
	{
		return false;
	}

	return true;
}

EFlareResourcePriceContext::Type UFlareSimulatedSpacecraft::GetResourceUseType(FFlareResourceDescription* Resource)
{
	// Check we're and station
	if (!IsStation())
	{
		return EFlareResourcePriceContext::Default;
	}

	// Parse factories
	for (int FactoryIndex = 0; FactoryIndex < SpacecraftDescription->Factories.Num(); FactoryIndex++)
	{
		FFlareFactoryDescription* FactoryDescription = &SpacecraftDescription->Factories[FactoryIndex]->Data;

		// Is input resource of a station ?
		for (int32 ResourceIndex = 0; ResourceIndex < FactoryDescription->CycleCost.InputResources.Num(); ResourceIndex++)
		{
			const FFlareFactoryResource* FactoryResource = &FactoryDescription->CycleCost.InputResources[ResourceIndex];
			if (&FactoryResource->Resource->Data == Resource)
			{
				return EFlareResourcePriceContext::FactoryInput;
			}
		}

		// Is output resource of a station ?
		for (int32 ResourceIndex = 0; ResourceIndex < FactoryDescription->CycleCost.OutputResources.Num(); ResourceIndex++)
		{
			const FFlareFactoryResource* FactoryResource = &FactoryDescription->CycleCost.OutputResources[ResourceIndex];
			if (&FactoryResource->Resource->Data == Resource)
			{
				return EFlareResourcePriceContext::FactoryOutput;
			}
		}
	}

	// Customer resource ?
	if (SpacecraftDescription->Capabilities.Contains(EFlareSpacecraftCapability::Consumer) && GetGame()->GetResourceCatalog()->IsCustomerResource(Resource))
	{
		return EFlareResourcePriceContext::ConsumerConsumption;
	}

	// Maintenance resource ?
	if (SpacecraftDescription->Capabilities.Contains(EFlareSpacecraftCapability::Maintenance) && GetGame()->GetResourceCatalog()->IsMaintenanceResource(Resource))
	{
		return EFlareResourcePriceContext::MaintenanceConsumption;
	}

	return EFlareResourcePriceContext::Default;
}

void UFlareSimulatedSpacecraft::LockResources()
{
	GetCargoBay()->UnlockAll();

	if (GetDescription()->Factories.Num() > 0)
	{
		FFlareFactoryDescription* Factory = &GetDescription()->Factories[0]->Data;

		for (int32 ResourceIndex = 0 ; ResourceIndex < Factory->CycleCost.InputResources.Num() ; ResourceIndex++)
		{
			const FFlareFactoryResource* Resource = &Factory->CycleCost.InputResources[ResourceIndex];

			if (!GetCargoBay()->LockSlot(&Resource->Resource->Data, EFlareResourceLock::Input, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *(&Resource->Resource->Data)->Name.ToString(), *GetImmatriculation().ToString());
			}
		}

		for (int32 ResourceIndex = 0 ; ResourceIndex < Factory->CycleCost.OutputResources.Num() ; ResourceIndex++)
		{
			const FFlareFactoryResource* Resource = &Factory->CycleCost.OutputResources[ResourceIndex];

			if (!GetCargoBay()->LockSlot(&Resource->Resource->Data, EFlareResourceLock::Output, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *(&Resource->Resource->Data)->Name.ToString(), *GetImmatriculation().ToString());
			}
		}
	}

	if (HasCapability(EFlareSpacecraftCapability::Consumer))
	{
		for (int32 ResourceIndex = 0; ResourceIndex < GetGame()->GetResourceCatalog()->ConsumerResources.Num(); ResourceIndex++)
		{
			FFlareResourceDescription* Resource = &GetGame()->GetResourceCatalog()->ConsumerResources[ResourceIndex]->Data;
			if (!GetCargoBay()->LockSlot(Resource, EFlareResourceLock::Input, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *Resource->Name.ToString(), *GetImmatriculation().ToString());
			}
		}
	}

	if (HasCapability(EFlareSpacecraftCapability::Maintenance))
	{
		for (int32 ResourceIndex = 0; ResourceIndex < GetGame()->GetResourceCatalog()->MaintenanceResources.Num(); ResourceIndex++)
		{
			FFlareResourceDescription* Resource = &GetGame()->GetResourceCatalog()->MaintenanceResources[ResourceIndex]->Data;

			if (!GetCargoBay()->LockSlot(Resource, EFlareResourceLock::Input, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *Resource->Name.ToString(), *GetImmatriculation().ToString());
			}
		}
	}
}

void UFlareSimulatedSpacecraft::SetAsteroidData(FFlareAsteroidSave* Data)
{
	SpacecraftData.AsteroidData.Identifier = Data->Identifier;
	SpacecraftData.AsteroidData.AsteroidMeshID = Data->AsteroidMeshID;
	SpacecraftData.AsteroidData.Scale = Data->Scale;
	SpacecraftData.Location = Data->Location;
	SpacecraftData.Rotation = Data->Rotation;
}

void UFlareSimulatedSpacecraft::SetDynamicComponentState(FName Identifier, float Progress)
{
	SpacecraftData.DynamicComponentStateIdentifier = Identifier;
	SpacecraftData.DynamicComponentStateProgress = Progress;
}

void UFlareSimulatedSpacecraft::ForceUndock()
{
	SpacecraftData.DockedTo = NAME_None;
	SpacecraftData.DockedAt = -1;
}

void UFlareSimulatedSpacecraft::SetTrading(bool Trading)
{
	if(IsStation())
	{
		FLOGV("Fail to set trading state to %s : station are never locked in trading state", *GetImmatriculation().ToString());
		return;
	}
	SpacecraftData.IsTrading = Trading;
}

EFlareHostility::Type UFlareSimulatedSpacecraft::GetPlayerWarState() const
{
	return GetCompany()->GetPlayerWarState();
}

const FSlateBrush* FFlareSpacecraftDescription::GetIcon(FFlareSpacecraftDescription* Characteristic)
{
	if (Characteristic)
	{
		if (FFlareSpacecraftDescription::IsStation(Characteristic))
		{
			return FFlareStyleSet::GetIcon("SS");
		}
		else if (FFlareSpacecraftDescription::IsMilitary(Characteristic))
		{
			if (Characteristic->Size == EFlarePartSize::S)
			{
				return FFlareStyleSet::GetIcon("MS");
			}
			else if (Characteristic->Size == EFlarePartSize::M)
			{
				return FFlareStyleSet::GetIcon("MM");
			}
			else if (Characteristic->Size == EFlarePartSize::L)
			{
				return FFlareStyleSet::GetIcon("ML");
			}
		}
		else
		{
			if (Characteristic->Size == EFlarePartSize::S)
			{
				return FFlareStyleSet::GetIcon("CS");
			}
			else if (Characteristic->Size == EFlarePartSize::M)
			{
				return FFlareStyleSet::GetIcon("CM");
			}
			else if (Characteristic->Size == EFlarePartSize::L)
			{
				return FFlareStyleSet::GetIcon("CL");
			}
		}
	}
	return NULL;
}

bool FFlareSpacecraftDescription::IsStation(FFlareSpacecraftDescription* SpacecraftDesc)
{
	return SpacecraftDesc->OrbitalEngineCount == 0;
}

bool FFlareSpacecraftDescription::IsMilitary(FFlareSpacecraftDescription* SpacecraftDesc)
{
	return SpacecraftDesc->GunSlots.Num() > 0 || SpacecraftDesc->TurretSlots.Num() > 0;
}

#undef LOCTEXT_NAMESPACE
<commit_msg>#438 Add a notification after end of trade if the fleet is not in a trade route<commit_after>
#include "../Flare.h"
#include "../Game/FlareSimulatedSector.h"
#include "../Game/FlareGame.h"
#include "../Game/FlareWorld.h"
#include "../Player/FlarePlayerController.h"
#include "../Economy/FlareCargoBay.h"
#include "../Economy/FlareFactory.h"
#include "../Spacecrafts/Subsystems/FlareSpacecraftDamageSystemInterface.h"
#include "../Data/FlareFactoryCatalogEntry.h"
#include "FlareSimulatedSpacecraft.h"

#define LOCTEXT_NAMESPACE "FlareSimulatedSpacecraft"

/*----------------------------------------------------
	Constructor
----------------------------------------------------*/

UFlareSimulatedSpacecraft::UFlareSimulatedSpacecraft(const FObjectInitializer& ObjectInitializer)
	: Super(ObjectInitializer)
{
	ActiveSpacecraft = NULL;
}

void UFlareSimulatedSpacecraft::Load(const FFlareSpacecraftSave& Data)
{
	Game = Cast<UFlareCompany>(GetOuter())->GetGame();
	SpacecraftData = Data;

	// Load spacecraft description
	SpacecraftDescription = Game->GetSpacecraftCatalog()->Get(Data.Identifier);

	// Initialize damage system
	DamageSystem = NewObject<UFlareSimulatedSpacecraftDamageSystem>(this, UFlareSimulatedSpacecraftDamageSystem::StaticClass());
	DamageSystem->Initialize(this, &SpacecraftData);

	// Initialize weapons system
	WeaponsSystem = NewObject<UFlareSimulatedSpacecraftWeaponsSystem>(this, UFlareSimulatedSpacecraftWeaponsSystem::StaticClass());
	WeaponsSystem->Initialize(this, &SpacecraftData);

	Game->GetGameWorld()->ClearFactories(this);
	Factories.Empty();

	// Load factories
	for (int FactoryIndex = 0; FactoryIndex < SpacecraftDescription->Factories.Num(); FactoryIndex++)
	{
		FFlareFactorySave FactoryData;
		FFlareFactoryDescription* FactoryDescription = &SpacecraftDescription->Factories[FactoryIndex]->Data;

		if (FactoryIndex < SpacecraftData.FactoryStates.Num())
		{
			FactoryData = SpacecraftData.FactoryStates[FactoryIndex];
		}
		else
		{
				FactoryData.Active = FactoryDescription->AutoStart;
				FactoryData.CostReserved = 0;
				FactoryData.ProductedDuration = 0;
				FactoryData.InfiniteCycle = true;
				FactoryData.CycleCount = 0;
				FactoryData.TargetShipClass = NAME_None;
				FactoryData.TargetShipCompany = NAME_None;
				FactoryData.OrderShipClass = NAME_None;
				FactoryData.OrderShipCompany = NAME_None;
				FactoryData.OrderShipAdvancePayment = 0;
		}

		UFlareFactory* Factory = NewObject<UFlareFactory>(GetGame()->GetGameWorld(), UFlareFactory::StaticClass());
		Factory->Load(this, FactoryDescription, FactoryData);
		Factories.Add(Factory);
		Game->GetGameWorld()->AddFactory(Factory);
	}

	CargoBay = NewObject<UFlareCargoBay>(this, UFlareCargoBay::StaticClass());
	CargoBay->Load(this, SpacecraftData.Cargo);

	// Lock resources
	LockResources();

	if(ActiveSpacecraft)
	{
		ActiveSpacecraft->Load(this);
	}
}

FFlareSpacecraftSave* UFlareSimulatedSpacecraft::Save()
{
	SpacecraftData.FactoryStates.Empty();
	for (int FactoryIndex = 0; FactoryIndex < Factories.Num(); FactoryIndex++)
	{
		SpacecraftData.FactoryStates.Add(*Factories[FactoryIndex]->Save());
	}

	SpacecraftData.Cargo = *CargoBay->Save();

	if(IsActive())
	{
		GetActive()->Save();
	}

	return &SpacecraftData;
}

UFlareCompany* UFlareSimulatedSpacecraft::GetCompany() const
{
	// TODO Cache
	return Game->GetGameWorld()->FindCompany(SpacecraftData.CompanyIdentifier);
}

EFlarePartSize::Type UFlareSimulatedSpacecraft::GetSize()
{
	return SpacecraftDescription->Size;
}

bool UFlareSimulatedSpacecraft::IsMilitary() const
{
	return FFlareSpacecraftDescription::IsMilitary(SpacecraftDescription);
}

bool UFlareSimulatedSpacecraft::IsStation() const
{
	return FFlareSpacecraftDescription::IsStation(SpacecraftDescription);
}

bool UFlareSimulatedSpacecraft::CanFight() const
{
	return GetDamageSystem()->IsAlive() && IsMilitary() && GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Weapon) > 0;
}

bool UFlareSimulatedSpacecraft::CanTravel() const
{
	return !IsTrading() && GetDamageSystem()->IsAlive() && GetDamageSystem()->GetSubsystemHealth(EFlareSubsystem::SYS_Propulsion) > 0;
}

FName UFlareSimulatedSpacecraft::GetImmatriculation() const
{
	return SpacecraftData.Immatriculation;
}

UFlareSimulatedSpacecraftDamageSystem* UFlareSimulatedSpacecraft::GetDamageSystem() const
{
	return DamageSystem;
}

UFlareSimulatedSpacecraftWeaponsSystem* UFlareSimulatedSpacecraft::GetWeaponsSystem() const
{
	return WeaponsSystem;
}

void UFlareSimulatedSpacecraft::SetSpawnMode(EFlareSpawnMode::Type SpawnMode)
{
	SpacecraftData.SpawnMode = SpawnMode;
}

bool UFlareSimulatedSpacecraft::CanBeFlown(FText& OutInfo) const
{
	UFlareFleet* PlayerFleet = GetGame()->GetPC()->GetPlayerFleet();

	if (IsStation())
	{
		return false;
	}
	else if (!GetDamageSystem()->IsAlive())
	{
		OutInfo = LOCTEXT("CantFlyDestroyedInfo", "This ship has been destroyed");
		return false;
	}
	else if (PlayerFleet && GetCurrentFleet() != PlayerFleet)
	{
		OutInfo = LOCTEXT("CantFlyOtherInfo", "You can only switch ships from whithin the same fleet");
		return false;
	}
	else if (!IsActive())
	{
		OutInfo = LOCTEXT("CantFlyDistantInfo", "You can't fly a ship from another sector");
		return false;
	}
	else
	{
		return true;
	}
}

/*----------------------------------------------------
	Gameplay
----------------------------------------------------*/

void UFlareSimulatedSpacecraft::SetCurrentSector(UFlareSimulatedSector* Sector)
{
	CurrentSector = Sector;

	// Mark the sector as visited
	if (!Sector->IsTravelSector())
	{
		GetCompany()->VisitSector(Sector);
	}
}

/*----------------------------------------------------
	Resources
----------------------------------------------------*/

bool UFlareSimulatedSpacecraft::CanTradeWith(UFlareSimulatedSpacecraft* OtherSpacecraft)
{
	// Check if both spacecraft are in the same sector
	if(GetCurrentSector() != OtherSpacecraft->GetCurrentSector())
	{
		return false;
	}

	// Check if spacecraft are not both stations
	if(IsStation() && OtherSpacecraft->IsStation())
	{
		return false;
	}

	// Check if spacecraft are not both ships
	if(!IsStation() && !OtherSpacecraft->IsStation())
	{
		return false;
	}

	// Check if spacecraft are are not already trading
	if(IsTrading() || OtherSpacecraft->IsTrading())
	{
		return false;
	}

	// Check if both spacecraft are not at war
	if(GetCompany()->GetWarState(OtherSpacecraft->GetCompany()) == EFlareHostility::Hostile)
	{
		return false;
	}

	return true;
}

EFlareResourcePriceContext::Type UFlareSimulatedSpacecraft::GetResourceUseType(FFlareResourceDescription* Resource)
{
	// Check we're and station
	if (!IsStation())
	{
		return EFlareResourcePriceContext::Default;
	}

	// Parse factories
	for (int FactoryIndex = 0; FactoryIndex < SpacecraftDescription->Factories.Num(); FactoryIndex++)
	{
		FFlareFactoryDescription* FactoryDescription = &SpacecraftDescription->Factories[FactoryIndex]->Data;

		// Is input resource of a station ?
		for (int32 ResourceIndex = 0; ResourceIndex < FactoryDescription->CycleCost.InputResources.Num(); ResourceIndex++)
		{
			const FFlareFactoryResource* FactoryResource = &FactoryDescription->CycleCost.InputResources[ResourceIndex];
			if (&FactoryResource->Resource->Data == Resource)
			{
				return EFlareResourcePriceContext::FactoryInput;
			}
		}

		// Is output resource of a station ?
		for (int32 ResourceIndex = 0; ResourceIndex < FactoryDescription->CycleCost.OutputResources.Num(); ResourceIndex++)
		{
			const FFlareFactoryResource* FactoryResource = &FactoryDescription->CycleCost.OutputResources[ResourceIndex];
			if (&FactoryResource->Resource->Data == Resource)
			{
				return EFlareResourcePriceContext::FactoryOutput;
			}
		}
	}

	// Customer resource ?
	if (SpacecraftDescription->Capabilities.Contains(EFlareSpacecraftCapability::Consumer) && GetGame()->GetResourceCatalog()->IsCustomerResource(Resource))
	{
		return EFlareResourcePriceContext::ConsumerConsumption;
	}

	// Maintenance resource ?
	if (SpacecraftDescription->Capabilities.Contains(EFlareSpacecraftCapability::Maintenance) && GetGame()->GetResourceCatalog()->IsMaintenanceResource(Resource))
	{
		return EFlareResourcePriceContext::MaintenanceConsumption;
	}

	return EFlareResourcePriceContext::Default;
}

void UFlareSimulatedSpacecraft::LockResources()
{
	GetCargoBay()->UnlockAll();

	if (GetDescription()->Factories.Num() > 0)
	{
		FFlareFactoryDescription* Factory = &GetDescription()->Factories[0]->Data;

		for (int32 ResourceIndex = 0 ; ResourceIndex < Factory->CycleCost.InputResources.Num() ; ResourceIndex++)
		{
			const FFlareFactoryResource* Resource = &Factory->CycleCost.InputResources[ResourceIndex];

			if (!GetCargoBay()->LockSlot(&Resource->Resource->Data, EFlareResourceLock::Input, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *(&Resource->Resource->Data)->Name.ToString(), *GetImmatriculation().ToString());
			}
		}

		for (int32 ResourceIndex = 0 ; ResourceIndex < Factory->CycleCost.OutputResources.Num() ; ResourceIndex++)
		{
			const FFlareFactoryResource* Resource = &Factory->CycleCost.OutputResources[ResourceIndex];

			if (!GetCargoBay()->LockSlot(&Resource->Resource->Data, EFlareResourceLock::Output, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *(&Resource->Resource->Data)->Name.ToString(), *GetImmatriculation().ToString());
			}
		}
	}

	if (HasCapability(EFlareSpacecraftCapability::Consumer))
	{
		for (int32 ResourceIndex = 0; ResourceIndex < GetGame()->GetResourceCatalog()->ConsumerResources.Num(); ResourceIndex++)
		{
			FFlareResourceDescription* Resource = &GetGame()->GetResourceCatalog()->ConsumerResources[ResourceIndex]->Data;
			if (!GetCargoBay()->LockSlot(Resource, EFlareResourceLock::Input, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *Resource->Name.ToString(), *GetImmatriculation().ToString());
			}
		}
	}

	if (HasCapability(EFlareSpacecraftCapability::Maintenance))
	{
		for (int32 ResourceIndex = 0; ResourceIndex < GetGame()->GetResourceCatalog()->MaintenanceResources.Num(); ResourceIndex++)
		{
			FFlareResourceDescription* Resource = &GetGame()->GetResourceCatalog()->MaintenanceResources[ResourceIndex]->Data;

			if (!GetCargoBay()->LockSlot(Resource, EFlareResourceLock::Input, false))
			{
				FLOGV("Fail to lock a slot of %s in %s", *Resource->Name.ToString(), *GetImmatriculation().ToString());
			}
		}
	}
}

void UFlareSimulatedSpacecraft::SetAsteroidData(FFlareAsteroidSave* Data)
{
	SpacecraftData.AsteroidData.Identifier = Data->Identifier;
	SpacecraftData.AsteroidData.AsteroidMeshID = Data->AsteroidMeshID;
	SpacecraftData.AsteroidData.Scale = Data->Scale;
	SpacecraftData.Location = Data->Location;
	SpacecraftData.Rotation = Data->Rotation;
}

void UFlareSimulatedSpacecraft::SetDynamicComponentState(FName Identifier, float Progress)
{
	SpacecraftData.DynamicComponentStateIdentifier = Identifier;
	SpacecraftData.DynamicComponentStateProgress = Progress;
}

void UFlareSimulatedSpacecraft::ForceUndock()
{
	SpacecraftData.DockedTo = NAME_None;
	SpacecraftData.DockedAt = -1;
}

void UFlareSimulatedSpacecraft::SetTrading(bool Trading)
{
	if (IsStation())
	{
		FLOGV("Fail to set trading state to %s : station are never locked in trading state", *GetImmatriculation().ToString());
		return;
	}

	// Notify end of state if not on trade route
	if (!Trading
		&& SpacecraftData.IsTrading
		&& GetCompany() == GetGame()->GetPC()->GetCompany()
		&& GetCurrentTradeRoute() == NULL)
	{
		FFlareMenuParameterData Data;
		Data.Spacecraft = this;
		Game->GetPC()->Notify(LOCTEXT("TradingStateEnd", "Trading complete"),
			FText::Format(LOCTEXT("TravelEndedFormat", "{0} finished trading at {1}"),
				FText::FromString(GetImmatriculation().ToString()),
				GetCurrentSector()->GetSectorName()),
			FName("trading-state-end"),
			EFlareNotification::NT_Economy,
			false,
			EFlareMenu::MENU_Ship,
			Data);
	}

	SpacecraftData.IsTrading = Trading;
}

EFlareHostility::Type UFlareSimulatedSpacecraft::GetPlayerWarState() const
{
	return GetCompany()->GetPlayerWarState();
}

const FSlateBrush* FFlareSpacecraftDescription::GetIcon(FFlareSpacecraftDescription* Characteristic)
{
	if (Characteristic)
	{
		if (FFlareSpacecraftDescription::IsStation(Characteristic))
		{
			return FFlareStyleSet::GetIcon("SS");
		}
		else if (FFlareSpacecraftDescription::IsMilitary(Characteristic))
		{
			if (Characteristic->Size == EFlarePartSize::S)
			{
				return FFlareStyleSet::GetIcon("MS");
			}
			else if (Characteristic->Size == EFlarePartSize::M)
			{
				return FFlareStyleSet::GetIcon("MM");
			}
			else if (Characteristic->Size == EFlarePartSize::L)
			{
				return FFlareStyleSet::GetIcon("ML");
			}
		}
		else
		{
			if (Characteristic->Size == EFlarePartSize::S)
			{
				return FFlareStyleSet::GetIcon("CS");
			}
			else if (Characteristic->Size == EFlarePartSize::M)
			{
				return FFlareStyleSet::GetIcon("CM");
			}
			else if (Characteristic->Size == EFlarePartSize::L)
			{
				return FFlareStyleSet::GetIcon("CL");
			}
		}
	}
	return NULL;
}

bool FFlareSpacecraftDescription::IsStation(FFlareSpacecraftDescription* SpacecraftDesc)
{
	return SpacecraftDesc->OrbitalEngineCount == 0;
}

bool FFlareSpacecraftDescription::IsMilitary(FFlareSpacecraftDescription* SpacecraftDesc)
{
	return SpacecraftDesc->GunSlots.Num() > 0 || SpacecraftDesc->TurretSlots.Num() > 0;
}

#undef LOCTEXT_NAMESPACE
<|endoftext|>


<commit_before>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/external_pref_extension_provider.h"

#include "app/app_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/version.h"
#include "chrome/common/json_value_serializer.h"

// Constants for keeping track of extension preferences.
const wchar_t kLocation[] = L"location";
const wchar_t kState[] = L"state";
const wchar_t kExternalCrx[] = L"external_crx";
const wchar_t kExternalVersion[] = L"external_version";

ExternalPrefExtensionProvider::ExternalPrefExtensionProvider() {
  FilePath json_file;
  PathService::Get(app::DIR_EXTERNAL_EXTENSIONS, &json_file);
  json_file = json_file.Append(FILE_PATH_LITERAL("external_extensions.json"));

  JSONFileValueSerializer serializer(json_file);
  SetPreferences(&serializer);
}

ExternalPrefExtensionProvider::~ExternalPrefExtensionProvider() {
}

void ExternalPrefExtensionProvider::SetPreferencesForTesting(
    std::string json_data_for_testing) {
  JSONStringValueSerializer serializer(json_data_for_testing);
  SetPreferences(&serializer);
}

void ExternalPrefExtensionProvider::VisitRegisteredExtension(
    Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
  for (DictionaryValue::key_iterator i = prefs_->begin_keys();
       i != prefs_->end_keys(); ++i) {
    const std::wstring& extension_id = *i;
    if (ids_to_ignore.find(WideToASCII(extension_id)) != ids_to_ignore.end())
      continue;

    DictionaryValue* extension = NULL;
    if (!prefs_->GetDictionary(extension_id, &extension)) {
      continue;
    }

    FilePath::StringType external_crx;
    std::string external_version;
    if (!extension->GetString(kExternalCrx, &external_crx) ||
        !extension->GetString(kExternalVersion, &external_version)) {
      LOG(WARNING) << "Malformed extension dictionary for extension: "
                   << extension_id.c_str();
      continue;
    }

    if (external_crx.find(FilePath::kParentDirectory) != StringPiece::npos) {
      LOG(WARNING) << "Path traversal not allowed in path: "
                   << external_crx.c_str();
      continue;
    }

    // See if it's an absolute path...
    FilePath path(external_crx);
    if (!path.IsAbsolute()) {
      // Try path as relative path from external extension dir.
      FilePath base_path;
      PathService::Get(app::DIR_EXTERNAL_EXTENSIONS, &base_path);
      path = base_path.Append(external_crx);
    }

    scoped_ptr<Version> version;
    version.reset(Version::GetVersionFromString(external_version));
    visitor->OnExternalExtensionFound(
        WideToASCII(extension_id), version.get(), path);
  }
}

Version* ExternalPrefExtensionProvider::RegisteredVersion(
    std::string id, Extension::Location* location) const {
  DictionaryValue* extension = NULL;
  if (!prefs_->GetDictionary(ASCIIToWide(id), &extension))
    return NULL;

  std::string external_version;
  if (!extension->GetString(kExternalVersion, &external_version))
    return NULL;

  if (location)
    *location = Extension::EXTERNAL_PREF;
  return Version::GetVersionFromString(external_version);
}

void ExternalPrefExtensionProvider::SetPreferences(
    ValueSerializer* serializer) {
  std::string error_msg;
  Value* extensions = serializer->Deserialize(&error_msg);
  scoped_ptr<DictionaryValue> dictionary(new DictionaryValue());
  if (!error_msg.empty()) {
    NOTREACHED() << L"Unable to deserialize json data: "
                 << error_msg.c_str();
  } else {
    // This can be null if the json file specified does not exist.
    if (extensions) {
      if (!extensions->IsType(Value::TYPE_DICTIONARY)) {
        NOTREACHED() << L"Invalid json data";
      } else {
        dictionary.reset(static_cast<DictionaryValue*>(extensions));
      }
    }
  }
  prefs_.reset(dictionary.release());
}
<commit_msg>Fix build. <commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/extensions/external_pref_extension_provider.h"

#include "app/app_paths.h"
#include "base/file_path.h"
#include "base/file_util.h"
#include "base/path_service.h"
#include "base/string_util.h"
#include "base/version.h"
#include "chrome/common/json_value_serializer.h"

// Constants for keeping track of extension preferences.
const wchar_t kLocation[] = L"location";
const wchar_t kState[] = L"state";
const wchar_t kExternalCrx[] = L"external_crx";
const wchar_t kExternalVersion[] = L"external_version";

ExternalPrefExtensionProvider::ExternalPrefExtensionProvider() {
  FilePath json_file;
  PathService::Get(app::DIR_EXTERNAL_EXTENSIONS, &json_file);
  json_file = json_file.Append(FILE_PATH_LITERAL("external_extensions.json"));

  JSONFileValueSerializer serializer(json_file);
  SetPreferences(&serializer);
}

ExternalPrefExtensionProvider::~ExternalPrefExtensionProvider() {
}

void ExternalPrefExtensionProvider::SetPreferencesForTesting(
    std::string json_data_for_testing) {
  JSONStringValueSerializer serializer(json_data_for_testing);
  SetPreferences(&serializer);
}

void ExternalPrefExtensionProvider::VisitRegisteredExtension(
    Visitor* visitor, const std::set<std::string>& ids_to_ignore) const {
  for (DictionaryValue::key_iterator i = prefs_->begin_keys();
       i != prefs_->end_keys(); ++i) {
    const std::wstring& extension_id = *i;
    if (ids_to_ignore.find(WideToASCII(extension_id)) != ids_to_ignore.end())
      continue;

    DictionaryValue* extension = NULL;
    if (!prefs_->GetDictionary(extension_id, &extension)) {
      continue;
    }

    FilePath::StringType external_crx;
    std::string external_version;
    if (!extension->GetString(kExternalCrx, &external_crx) ||
        !extension->GetString(kExternalVersion, &external_version)) {
      LOG(WARNING) << "Malformed extension dictionary for extension: "
                   << extension_id.c_str();
      continue;
    }

    if (external_crx.find(FilePath::kParentDirectory) != StringPiece::npos) {
      LOG(WARNING) << "Path traversal not allowed in path: "
                   << external_crx.c_str();
      continue;
    }

    // See if it's an absolute path...
    FilePath path(external_crx);
    if (!path.IsAbsolute()) {
      // Try path as relative path from external extension dir.
      FilePath base_path;
      PathService::Get(app::DIR_EXTERNAL_EXTENSIONS, &base_path);
      path = base_path.Append(external_crx);
    }

    scoped_ptr<Version> version;
    version.reset(Version::GetVersionFromString(external_version));
    visitor->OnExternalExtensionFound(
        WideToASCII(extension_id), version.get(), path);
  }
}

Version* ExternalPrefExtensionProvider::RegisteredVersion(
    std::string id, Extension::Location* location) const {
  DictionaryValue* extension = NULL;
  if (!prefs_->GetDictionary(ASCIIToWide(id), &extension))
    return NULL;

  std::string external_version;
  if (!extension->GetString(kExternalVersion, &external_version))
    return NULL;

  if (location)
    *location = Extension::EXTERNAL_PREF;
  return Version::GetVersionFromString(external_version);
}

void ExternalPrefExtensionProvider::SetPreferences(
    ValueSerializer* serializer) {
  std::string error_msg;
  Value* extensions = serializer->Deserialize(&error_msg);
  scoped_ptr<DictionaryValue> dictionary(new DictionaryValue());
  if (!error_msg.empty()) {
    LOG(WARNING) << L"Unable to deserialize json data: "
                 << error_msg.c_str();
  } else {
    // This can be null if the json file specified does not exist.
    if (extensions) {
      if (!extensions->IsType(Value::TYPE_DICTIONARY)) {
        NOTREACHED() << L"Invalid json data";
      } else {
        dictionary.reset(static_cast<DictionaryValue*>(extensions));
      }
    }
  }
  prefs_.reset(dictionary.release());
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/process_util.h"
#include "base/test/test_timeouts.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/service/service_process_control_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/service_process_util.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

class ServiceProcessControlBrowserTest
    : public InProcessBrowserTest {
 public:
  ServiceProcessControlBrowserTest()
      : service_process_handle_(base::kNullProcessHandle) {
  }
  ~ServiceProcessControlBrowserTest() {
    base::CloseProcessHandle(service_process_handle_);
    service_process_handle_ = base::kNullProcessHandle;
    // Delete all instances of ServiceProcessControl.
    ServiceProcessControlManager::GetInstance()->Shutdown();
  }

#if defined(OS_MACOSX)
  virtual void TearDown() {
    // ForceServiceProcessShutdown removes the process from launchd on Mac.
    ForceServiceProcessShutdown("", 0);
  }
#endif  // OS_MACOSX

 protected:
  void LaunchServiceProcessControl() {
    ServiceProcessControl* process =
        ServiceProcessControlManager::GetInstance()->GetProcessControl(
            browser()->profile());
    process_ = process;

    // Launch the process asynchronously.
    process->Launch(
        NewRunnableMethod(
            this,
            &ServiceProcessControlBrowserTest::ProcessControlLaunched),
        NewRunnableMethod(
            this,
            &ServiceProcessControlBrowserTest::ProcessControlLaunchFailed));

    // Then run the message loop to keep things running.
    ui_test_utils::RunMessageLoop();
  }

  // Send a remoting host status request and wait reply from the service.
  void SendRequestAndWait() {
    process()->GetCloudPrintProxyStatus(NewCallback(
        this, &ServiceProcessControlBrowserTest::CloudPrintStatusCallback));
    ui_test_utils::RunMessageLoop();
  }

  void CloudPrintStatusCallback(
      bool enabled, std::string email) {
    MessageLoop::current()->Quit();
  }

  void Disconnect() {
    // This will delete all instances of ServiceProcessControl and close the IPC
    // connections.
    ServiceProcessControlManager::GetInstance()->Shutdown();
    process_ = NULL;
  }

  void WaitForShutdown() {
    EXPECT_TRUE(base::WaitForSingleProcess(
        service_process_handle_,
        TestTimeouts::wait_for_terminate_timeout_ms()));
  }

  void ProcessControlLaunched() {
    base::ProcessId service_pid;
    EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
    EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
    EXPECT_TRUE(base::OpenProcessHandleWithAccess(
        service_pid,
        base::kProcessAccessWaitForTermination,
        &service_process_handle_));
    // Quit the current message. Post a QuitTask instead of just calling Quit()
    // because this can get invoked in the context of a Launch() call and we
    // may not be in Run() yet.
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
  }

  void ProcessControlLaunchFailed() {
    ADD_FAILURE();
    // Quit the current message.
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
  }

  ServiceProcessControl* process() { return process_; }

 private:
  ServiceProcessControl* process_;
  base::ProcessHandle service_process_handle_;
};

// They way that the IPC is implemented only works on windows. This has to
// change when we implement a different scheme for IPC.
// Times out flakily, http://crbug.com/70076.
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       DISABLED_LaunchAndIPC) {
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SendRequestAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}

// This tests the case when a service process is launched when browser
// starts but we try to launch it again in the remoting setup dialog.
// Fails on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_LaunchTwice FAILS_LaunchTwice
#else
#define MAYBE_LaunchTwice LaunchTwice
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_LaunchTwice) {
  // Launch the service process the first time.
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SendRequestAndWait();

  // Launch the service process again.
  LaunchServiceProcessControl();
  EXPECT_TRUE(process()->is_connected());
  SendRequestAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}

static void DecrementUntilZero(int* count) {
  (*count)--;
  if (!(*count))
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}

// Invoke multiple Launch calls in succession and ensure that all the tasks
// get invoked.
// Fails on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_MultipleLaunchTasks FAILS_MultipleLaunchTasks
#else
#define MAYBE_MultipleLaunchTasks MultipleLaunchTasks
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       MAYBE_MultipleLaunchTasks) {
  ServiceProcessControl* process =
      ServiceProcessControlManager::GetInstance()->GetProcessControl(
          browser()->profile());
  int launch_count = 5;
  for (int i = 0; i < launch_count; i++) {
    // Launch the process asynchronously.
    process->Launch(
        NewRunnableFunction(&DecrementUntilZero, &launch_count),
        new MessageLoop::QuitTask());
  }
  // Then run the message loop to keep things running.
  ui_test_utils::RunMessageLoop();
  EXPECT_EQ(0, launch_count);
  // And then shutdown the service process.
  EXPECT_TRUE(process->Shutdown());
}

// Make sure using the same task for success and failure tasks works.
// Fails on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_SameLaunchTask FAILS_SameLaunchTask
#else
#define MAYBE_SameLaunchTask SameLaunchTask
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_SameLaunchTask) {
  ServiceProcessControl* process =
      ServiceProcessControlManager::GetInstance()->GetProcessControl(
          browser()->profile());
  int launch_count = 5;
  for (int i = 0; i < launch_count; i++) {
    // Launch the process asynchronously.
    Task * task = NewRunnableFunction(&DecrementUntilZero, &launch_count);
    process->Launch(task, task);
  }
  // Then run the message loop to keep things running.
  ui_test_utils::RunMessageLoop();
  EXPECT_EQ(0, launch_count);
  // And then shutdown the service process.
  EXPECT_TRUE(process->Shutdown());
}

// Tests whether disconnecting from the service IPC causes the service process
// to die.
// Fails on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_DieOnDisconnect FAILS_DieOnDisconnect
#else
#define MAYBE_DieOnDisconnect DieOnDisconnect
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       MAYBE_DieOnDisconnect) {
  // Launch the service process.
  LaunchServiceProcessControl();
  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  Disconnect();
  WaitForShutdown();
}

//http://code.google.com/p/chromium/issues/detail?id=70793
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       DISABLED_ForceShutdown) {
  // Launch the service process.
  LaunchServiceProcessControl();
  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  base::ProcessId service_pid;
  EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
  EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
  chrome::VersionInfo version_info;
  ForceServiceProcessShutdown(version_info.Version(), service_pid);
  WaitForShutdown();
}

// Fails on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_CheckPid FAILS_CheckPid
#else
#define MAYBE_CheckPid CheckPid
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_CheckPid) {
  base::ProcessId service_pid;
  EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid));
  // Launch the service process.
  LaunchServiceProcessControl();
  EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
  EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
}

DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcessControlBrowserTest);
<commit_msg>Tests are timing out, so disabling.<commit_after>// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/process_util.h"
#include "base/test/test_timeouts.h"
#include "chrome/browser/service/service_process_control.h"
#include "chrome/browser/service/service_process_control_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/service_process_util.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"

class ServiceProcessControlBrowserTest
    : public InProcessBrowserTest {
 public:
  ServiceProcessControlBrowserTest()
      : service_process_handle_(base::kNullProcessHandle) {
  }
  ~ServiceProcessControlBrowserTest() {
    base::CloseProcessHandle(service_process_handle_);
    service_process_handle_ = base::kNullProcessHandle;
    // Delete all instances of ServiceProcessControl.
    ServiceProcessControlManager::GetInstance()->Shutdown();
  }

#if defined(OS_MACOSX)
  virtual void TearDown() {
    // ForceServiceProcessShutdown removes the process from launchd on Mac.
    ForceServiceProcessShutdown("", 0);
  }
#endif  // OS_MACOSX

 protected:
  void LaunchServiceProcessControl() {
    ServiceProcessControl* process =
        ServiceProcessControlManager::GetInstance()->GetProcessControl(
            browser()->profile());
    process_ = process;

    // Launch the process asynchronously.
    process->Launch(
        NewRunnableMethod(
            this,
            &ServiceProcessControlBrowserTest::ProcessControlLaunched),
        NewRunnableMethod(
            this,
            &ServiceProcessControlBrowserTest::ProcessControlLaunchFailed));

    // Then run the message loop to keep things running.
    ui_test_utils::RunMessageLoop();
  }

  // Send a remoting host status request and wait reply from the service.
  void SendRequestAndWait() {
    process()->GetCloudPrintProxyStatus(NewCallback(
        this, &ServiceProcessControlBrowserTest::CloudPrintStatusCallback));
    ui_test_utils::RunMessageLoop();
  }

  void CloudPrintStatusCallback(
      bool enabled, std::string email) {
    MessageLoop::current()->Quit();
  }

  void Disconnect() {
    // This will delete all instances of ServiceProcessControl and close the IPC
    // connections.
    ServiceProcessControlManager::GetInstance()->Shutdown();
    process_ = NULL;
  }

  void WaitForShutdown() {
    EXPECT_TRUE(base::WaitForSingleProcess(
        service_process_handle_,
        TestTimeouts::wait_for_terminate_timeout_ms()));
  }

  void ProcessControlLaunched() {
    base::ProcessId service_pid;
    EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
    EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
    EXPECT_TRUE(base::OpenProcessHandleWithAccess(
        service_pid,
        base::kProcessAccessWaitForTermination,
        &service_process_handle_));
    // Quit the current message. Post a QuitTask instead of just calling Quit()
    // because this can get invoked in the context of a Launch() call and we
    // may not be in Run() yet.
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
  }

  void ProcessControlLaunchFailed() {
    ADD_FAILURE();
    // Quit the current message.
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
  }

  ServiceProcessControl* process() { return process_; }

 private:
  ServiceProcessControl* process_;
  base::ProcessHandle service_process_handle_;
};

// They way that the IPC is implemented only works on windows. This has to
// change when we implement a different scheme for IPC.
// Times out flakily, http://crbug.com/70076.
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       DISABLED_LaunchAndIPC) {
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SendRequestAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}

// This tests the case when a service process is launched when browser
// starts but we try to launch it again in the remoting setup dialog.
// Crashes on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_LaunchTwice DISABLED_LaunchTwice
#else
#define MAYBE_LaunchTwice LaunchTwice
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_LaunchTwice) {
  // Launch the service process the first time.
  LaunchServiceProcessControl();

  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  SendRequestAndWait();

  // Launch the service process again.
  LaunchServiceProcessControl();
  EXPECT_TRUE(process()->is_connected());
  SendRequestAndWait();

  // And then shutdown the service process.
  EXPECT_TRUE(process()->Shutdown());
}

static void DecrementUntilZero(int* count) {
  (*count)--;
  if (!(*count))
    MessageLoop::current()->PostTask(FROM_HERE, new MessageLoop::QuitTask());
}

// Invoke multiple Launch calls in succession and ensure that all the tasks
// get invoked.
// Crashes on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_MultipleLaunchTasks DISABLED_MultipleLaunchTasks
#else
#define MAYBE_MultipleLaunchTasks MultipleLaunchTasks
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       MAYBE_MultipleLaunchTasks) {
  ServiceProcessControl* process =
      ServiceProcessControlManager::GetInstance()->GetProcessControl(
          browser()->profile());
  int launch_count = 5;
  for (int i = 0; i < launch_count; i++) {
    // Launch the process asynchronously.
    process->Launch(
        NewRunnableFunction(&DecrementUntilZero, &launch_count),
        new MessageLoop::QuitTask());
  }
  // Then run the message loop to keep things running.
  ui_test_utils::RunMessageLoop();
  EXPECT_EQ(0, launch_count);
  // And then shutdown the service process.
  EXPECT_TRUE(process->Shutdown());
}

// Make sure using the same task for success and failure tasks works.
// Crashes on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_SameLaunchTask DISABLED_SameLaunchTask
#else
#define MAYBE_SameLaunchTask SameLaunchTask
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_SameLaunchTask) {
  ServiceProcessControl* process =
      ServiceProcessControlManager::GetInstance()->GetProcessControl(
          browser()->profile());
  int launch_count = 5;
  for (int i = 0; i < launch_count; i++) {
    // Launch the process asynchronously.
    Task * task = NewRunnableFunction(&DecrementUntilZero, &launch_count);
    process->Launch(task, task);
  }
  // Then run the message loop to keep things running.
  ui_test_utils::RunMessageLoop();
  EXPECT_EQ(0, launch_count);
  // And then shutdown the service process.
  EXPECT_TRUE(process->Shutdown());
}

// Tests whether disconnecting from the service IPC causes the service process
// to die.
// Crashes on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_DieOnDisconnect DISABLED_DieOnDisconnect
#else
#define MAYBE_DieOnDisconnect DieOnDisconnect
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       MAYBE_DieOnDisconnect) {
  // Launch the service process.
  LaunchServiceProcessControl();
  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  Disconnect();
  WaitForShutdown();
}

//http://code.google.com/p/chromium/issues/detail?id=70793
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
                       DISABLED_ForceShutdown) {
  // Launch the service process.
  LaunchServiceProcessControl();
  // Make sure we are connected to the service process.
  EXPECT_TRUE(process()->is_connected());
  base::ProcessId service_pid;
  EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
  EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
  chrome::VersionInfo version_info;
  ForceServiceProcessShutdown(version_info.Version(), service_pid);
  WaitForShutdown();
}

// Crashes on mac. http://crbug.com/75518
#if defined(OS_MACOSX)
#define MAYBE_CheckPid DISABLED_CheckPid
#else
#define MAYBE_CheckPid CheckPid
#endif
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, MAYBE_CheckPid) {
  base::ProcessId service_pid;
  EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid));
  // Launch the service process.
  LaunchServiceProcessControl();
  EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
  EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
}

DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcessControlBrowserTest);
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <sys/time.h>

#include <opencv2/opencv.hpp>

#include "cJSON/cJSON.h"

#include "RobotStruct.h"
#include "DataCenter.h"
#include "ColorSegmentation.h"
#include "TeamDetect.h"
#include "Image2World.h"
#include "Broadcaster.h"

const std::string aboutString = "LocalizationServer v0.1.0";
const std::string paramKeys =
    "{help h    |   |Print help}";

void helpMessage(cv::CommandLineParser& in_parser)
{
    if(in_parser.has("help"))
    {
        in_parser.about(aboutString);
        in_parser.printMessage();
        exit(0);
    }
}

int main(int argc, char** argv)
{
    cv::CommandLineParser parser(argc, argv, paramKeys);
    helpMessage(parser);

    DataCenter dataCenter;
    ColorSegmentation obsSegmentation;
    ColorSegmentation redSegmentation;
    ColorSegmentation greenSegmentation;
    ColorSegmentation numb1Segmentation;
    ColorSegmentation numb2Segmentation;

    obsSegmentation.setThreshold(dataCenter.m_cartesianMin, dataCenter.m_cartesianMax);
    redSegmentation.setThreshold(dataCenter.m_teamAMin, dataCenter.m_teamAMax);
    greenSegmentation.setThreshold(dataCenter.m_teamBMin, dataCenter.m_teamBMax);
    numb1Segmentation.setThreshold(dataCenter.m_teamNumb1Min, dataCenter.m_teamNumb1Max);
    numb2Segmentation.setThreshold(dataCenter.m_teamNumb2Min, dataCenter.m_teamNumb2Max);

    Image2World image2World(&dataCenter);

    TeamDetect teamDetect;

    cv::VideoCapture camera;
    if(dataCenter.m_cameraString.length() == 1)
    {
    	int videoIndex = std::stoi(dataCenter.m_cameraString);
    	camera.open(videoIndex);
    }
    else
    {
    	camera.open(dataCenter.m_cameraString);
    }
    camera.set(cv::CAP_PROP_FRAME_WIDTH, dataCenter.m_imageWidth);
    camera.set(cv::CAP_PROP_FRAME_HEIGHT, dataCenter.m_imageHeight);
    for(int timeout=60; timeout > 0; timeout--)
    {
        camera.grab();
    }

    //cv::namedWindow("LocalizationServer", cv::WINDOW_KEEPRATIO);
    cv::Mat rawImage, realImage;

    std::vector<cv::Point2d> obsPoints, realObsPoints;
    std::vector<cv::Point2d> redPoints, realRedPoints;
    std::vector<cv::Point2d> greenPoints, realGreenPoints;
    std::vector<cv::Point2d> numb1Points, realNumb1Points;
    std::vector<cv::Point2d> numb2Points, realNumb2Points;

    double timeUse;
    struct timeval startTime, stopTime;

	Broadcaster bk(dataCenter.m_mqttNodeName.c_str(),
			dataCenter.m_mqttLocalizationTopic.c_str(),
			dataCenter.m_mqttMasterIP.c_str());
	bk.connectServer();

    int button;
    bool running = true;
    while(running)
    {
        std::cout << "================== Start ==================" << std::endl;
        gettimeofday(&startTime, NULL);

        camera >> rawImage;
        rawImage.copyTo(realImage);

        obsSegmentation.getBlocks(rawImage, obsPoints);
        redSegmentation.getBlocks(rawImage, redPoints);
        greenSegmentation.getBlocks(rawImage, greenPoints);
        numb1Segmentation.getBlocks(rawImage, numb1Points);
        numb2Segmentation.getBlocks(rawImage, numb2Points);

        obsSegmentation.drawPoints(realImage, cv::Scalar(255, 255, 255));
        redSegmentation.drawPoints(realImage, cv::Scalar(0, 0, 255));
        greenSegmentation.drawPoints(realImage, cv::Scalar(0, 255, 0));
        numb1Segmentation.drawPoints(realImage, cv::Scalar(255, 255, 0));
        numb2Segmentation.drawPoints(realImage, cv::Scalar(0, 255, 255));

        obsSegmentation.drawContours(realImage, cv::Scalar(255, 255, 255));
        redSegmentation.drawContours(realImage, cv::Scalar(0, 0, 255));
        greenSegmentation.drawContours(realImage, cv::Scalar(0, 255, 0));
        numb1Segmentation.drawContours(realImage, cv::Scalar(255, 255, 0));
        numb2Segmentation.drawContours(realImage, cv::Scalar(0, 255, 255));

        image2World.convert2Field(obsPoints, realObsPoints, dataCenter.m_obsHeight);
		image2World.convert2Field(redPoints, realRedPoints, dataCenter.m_robotHeight);
		image2World.convert2Field(greenPoints, realGreenPoints, dataCenter.m_robotHeight);
		image2World.convert2Field(numb1Points, realNumb1Points, dataCenter.m_robotHeight);
		image2World.convert2Field(numb2Points, realNumb2Points, dataCenter.m_robotHeight);

		dataCenter.m_obstacles.clear();
		Obstacle tmpObstacle;
		for(int j=0; j<realObsPoints.size(); j++)
		{
			tmpObstacle.id = dataCenter.m_obstacles.size();
			tmpObstacle.x = realObsPoints[j].x;
			tmpObstacle.y = realObsPoints[j].y;
			dataCenter.m_obstacles.push_back(tmpObstacle);

			std::cout << realObsPoints[j] << std::endl;
		}
/*		std::cout << realRedPoints << std::endl;
		std::cout << realGreenPoints << std::endl;
		std::cout << realNumb1Points << std::endl;
		std::cout << realNumb2Points << std::endl;
*/
		teamDetect.getTeam(realRedPoints, realNumb1Points, realNumb2Points, dataCenter.m_teamA);
		//teamDetect.drawTeam(fieldImage, cv::Scalar(0, 0, 255), dataCenter.m_teamA);

		teamDetect.getTeam(realGreenPoints, realNumb1Points, realNumb2Points, dataCenter.m_teamB);
		//teamDetect.drawTeam(fieldImage, cv::Scalar(0, 255, 0), dataCenter.m_teamB);

        std::cout << "> Red Team <" << std::endl;
        for(int i=0; i<4; i++)
        {
            if(dataCenter.m_teamA.robots[i].online)
            {
                std::cout << "id: " << int(dataCenter.m_teamA.robots[i].id);
                std::cout << ",\t x: " << dataCenter.m_teamA.robots[i].x;
                std::cout << ",\t y: " << dataCenter.m_teamA.robots[i].y;
                std::cout << ",\t th: " << dataCenter.m_teamA.robots[i].theta;
                std::cout << std::endl;
            }
        }
        std::cout << "> Green Team <" << std::endl;
        for(int i=0; i<4; i++)
        {
            if(dataCenter.m_teamB.robots[i].online)
            {
                std::cout << "id: " << int(dataCenter.m_teamB.robots[i].id);
                std::cout << ",\t x: " << dataCenter.m_teamB.robots[i].x;
                std::cout << ",\t y: " << dataCenter.m_teamB.robots[i].y;
                std::cout << ",\t th: " << dataCenter.m_teamB.robots[i].theta;
                std::cout << std::endl;
            }
        }
        std::cout << "> Obstacle <" << std::endl;
        for(int i=0; i<dataCenter.m_obstacles.size(); i++)
        {
			std::cout << "id: " << int(dataCenter.m_obstacles[i].id);
			std::cout << ",\t x: " << dataCenter.m_obstacles[i].x;
			std::cout << ",\t y: " << dataCenter.m_obstacles[i].y;
			std::cout << std::endl;
        }

        gettimeofday(&stopTime, NULL);
        timeUse = (stopTime.tv_sec - startTime.tv_sec)*1000000.0 + (stopTime.tv_usec - startTime.tv_usec);
        std::cout << "FPS: " << 1000000.0 / timeUse << std::endl;

    	bk.publishLocalization(dataCenter.m_teamA, dataCenter.m_teamB, dataCenter.m_obstacles);

        cv::imshow("LocalizationServer", realImage);
        button = cv::waitKey(1);
    	if(button == 113 || button == 10)
    	{
    		running = false;
    	}
    }

    camera.release();

    return 0;
}
<commit_msg>Fix some bugs on Obstacle detect<commit_after>#include <iostream>
#include <string>
#include <sys/time.h>

#include <opencv2/opencv.hpp>

#include "cJSON/cJSON.h"

#include "RobotStruct.h"
#include "DataCenter.h"
#include "ColorSegmentation.h"
#include "TeamDetect.h"
#include "Image2World.h"
#include "Broadcaster.h"

const std::string aboutString = "LocalizationServer v0.1.0";
const std::string paramKeys =
    "{help h    |   |Print help}";

void helpMessage(cv::CommandLineParser& in_parser)
{
    if(in_parser.has("help"))
    {
        in_parser.about(aboutString);
        in_parser.printMessage();
        exit(0);
    }
}

int main(int argc, char** argv)
{
    cv::CommandLineParser parser(argc, argv, paramKeys);
    helpMessage(parser);

    DataCenter dataCenter;
    ColorSegmentation obsSegmentation;
    ColorSegmentation redSegmentation;
    ColorSegmentation greenSegmentation;
    ColorSegmentation numb1Segmentation;
    ColorSegmentation numb2Segmentation;

    obsSegmentation.setThreshold(dataCenter.m_cartesianMin, dataCenter.m_cartesianMax);
    redSegmentation.setThreshold(dataCenter.m_teamAMin, dataCenter.m_teamAMax);
    greenSegmentation.setThreshold(dataCenter.m_teamBMin, dataCenter.m_teamBMax);
    numb1Segmentation.setThreshold(dataCenter.m_teamNumb1Min, dataCenter.m_teamNumb1Max);
    numb2Segmentation.setThreshold(dataCenter.m_teamNumb2Min, dataCenter.m_teamNumb2Max);

    Image2World image2World(&dataCenter);

    TeamDetect teamDetect;

    cv::VideoCapture camera;
    if(dataCenter.m_cameraString.length() == 1)
    {
    	int videoIndex = std::stoi(dataCenter.m_cameraString);
    	camera.open(videoIndex);
    }
    else
    {
    	camera.open(dataCenter.m_cameraString);
    }
    camera.set(cv::CAP_PROP_FRAME_WIDTH, dataCenter.m_imageWidth);
    camera.set(cv::CAP_PROP_FRAME_HEIGHT, dataCenter.m_imageHeight);
    for(int timeout=60; timeout > 0; timeout--)
    {
        camera.grab();
    }

    //cv::namedWindow("LocalizationServer", cv::WINDOW_KEEPRATIO);
    cv::Mat rawImage, realImage;

    std::vector<cv::Point2d> obsPoints, realObsPoints;
    std::vector<cv::Point2d> redPoints, realRedPoints;
    std::vector<cv::Point2d> greenPoints, realGreenPoints;
    std::vector<cv::Point2d> numb1Points, realNumb1Points;
    std::vector<cv::Point2d> numb2Points, realNumb2Points;

    double timeUse;
    struct timeval startTime, stopTime;

	Broadcaster bk(dataCenter.m_mqttNodeName.c_str(),
			dataCenter.m_mqttLocalizationTopic.c_str(),
			dataCenter.m_mqttMasterIP.c_str());
	bk.connectServer();

    int button;
    bool running = true;
    while(running)
    {
        std::cout << "================== Start ==================" << std::endl;
        gettimeofday(&startTime, NULL);

        camera >> rawImage;
        rawImage.copyTo(realImage);

        obsSegmentation.getBlocks(rawImage, obsPoints);
        redSegmentation.getBlocks(rawImage, redPoints);
        greenSegmentation.getBlocks(rawImage, greenPoints);
        numb1Segmentation.getBlocks(rawImage, numb1Points);
        numb2Segmentation.getBlocks(rawImage, numb2Points);

        obsSegmentation.drawPoints(realImage, cv::Scalar(255, 255, 255));
        redSegmentation.drawPoints(realImage, cv::Scalar(0, 0, 255));
        greenSegmentation.drawPoints(realImage, cv::Scalar(0, 255, 0));
        numb1Segmentation.drawPoints(realImage, cv::Scalar(255, 255, 0));
        numb2Segmentation.drawPoints(realImage, cv::Scalar(0, 255, 255));

        obsSegmentation.drawContours(realImage, cv::Scalar(255, 255, 255));
        redSegmentation.drawContours(realImage, cv::Scalar(0, 0, 255));
        greenSegmentation.drawContours(realImage, cv::Scalar(0, 255, 0));
        numb1Segmentation.drawContours(realImage, cv::Scalar(255, 255, 0));
        numb2Segmentation.drawContours(realImage, cv::Scalar(0, 255, 255));

        image2World.convert2Field(obsPoints, realObsPoints, dataCenter.m_obsHeight);
		image2World.convert2Field(redPoints, realRedPoints, dataCenter.m_robotHeight);
		image2World.convert2Field(greenPoints, realGreenPoints, dataCenter.m_robotHeight);
		image2World.convert2Field(numb1Points, realNumb1Points, dataCenter.m_robotHeight);
		image2World.convert2Field(numb2Points, realNumb2Points, dataCenter.m_robotHeight);

		dataCenter.m_obstacles.clear();
		Obstacle tmpObstacle;
		for(int j=0; j<realObsPoints.size(); j++)
		{
			if(realObsPoints[j].x > 0 && realObsPoints[j].x < dataCenter.m_imageWidth
					&& realObsPoints[j].y > 0 && realObsPoints[j].y < dataCenter.m_imageHeight)
			{
				tmpObstacle.id = dataCenter.m_obstacles.size();
				tmpObstacle.x = realObsPoints[j].x;
				tmpObstacle.y = realObsPoints[j].y;
				dataCenter.m_obstacles.push_back(tmpObstacle);

				std::cout << realObsPoints[j] << std::endl;
			}
		}
/*		std::cout << realRedPoints << std::endl;
		std::cout << realGreenPoints << std::endl;
		std::cout << realNumb1Points << std::endl;
		std::cout << realNumb2Points << std::endl;
*/
		teamDetect.getTeam(realRedPoints, realNumb1Points, realNumb2Points, dataCenter.m_teamA);
		//teamDetect.drawTeam(fieldImage, cv::Scalar(0, 0, 255), dataCenter.m_teamA);

		teamDetect.getTeam(realGreenPoints, realNumb1Points, realNumb2Points, dataCenter.m_teamB);
		//teamDetect.drawTeam(fieldImage, cv::Scalar(0, 255, 0), dataCenter.m_teamB);

        std::cout << "> Red Team <" << std::endl;
        for(int i=0; i<4; i++)
        {
            if(dataCenter.m_teamA.robots[i].online)
            {
                std::cout << "id: " << int(dataCenter.m_teamA.robots[i].id);
                std::cout << ",\t x: " << dataCenter.m_teamA.robots[i].x;
                std::cout << ",\t y: " << dataCenter.m_teamA.robots[i].y;
                std::cout << ",\t th: " << dataCenter.m_teamA.robots[i].theta;
                std::cout << std::endl;
            }
        }
        std::cout << "> Green Team <" << std::endl;
        for(int i=0; i<4; i++)
        {
            if(dataCenter.m_teamB.robots[i].online)
            {
                std::cout << "id: " << int(dataCenter.m_teamB.robots[i].id);
                std::cout << ",\t x: " << dataCenter.m_teamB.robots[i].x;
                std::cout << ",\t y: " << dataCenter.m_teamB.robots[i].y;
                std::cout << ",\t th: " << dataCenter.m_teamB.robots[i].theta;
                std::cout << std::endl;
            }
        }
        std::cout << "> Obstacle <" << std::endl;
        for(int i=0; i<dataCenter.m_obstacles.size(); i++)
        {
			std::cout << "id: " << int(dataCenter.m_obstacles[i].id);
			std::cout << ",\t x: " << dataCenter.m_obstacles[i].x;
			std::cout << ",\t y: " << dataCenter.m_obstacles[i].y;
			std::cout << std::endl;
        }

        gettimeofday(&stopTime, NULL);
        timeUse = (stopTime.tv_sec - startTime.tv_sec)*1000000.0 + (stopTime.tv_usec - startTime.tv_usec);
        std::cout << "FPS: " << 1000000.0 / timeUse << std::endl;

    	bk.publishLocalization(dataCenter.m_teamA, dataCenter.m_teamB, dataCenter.m_obstacles);

        cv::imshow("LocalizationServer", realImage);
        button = cv::waitKey(1);
    	if(button == 113 || button == 10)
    	{
    		running = false;
    	}
    }

    camera.release();

    return 0;
}
<|endoftext|>


<commit_before>#include <stutter/coroutine.h>
#include <stutter/log.h>

#ifdef USE_VALGRIND
#include <valgrind/valgrind.h>
#endif

#define COROUTINE_STACK_SIZE (32 * 1024)

using namespace std;

void
entry_point(void *ptr)
{
	Coroutine *co = reinterpret_cast<Coroutine*>(ptr);
	co->run();
}

////////////////////////////////////////////////////////////

Coroutine::Coroutine()
		: m_state(INIT)
		, m_stack(0)
{
	// create new context based on current one:
	create_stack();     // allocate stack for new context
	int gc = getcontext(&m_ctx); // copy current context into m_ctx
	if (gc != 0) {
		Log::get(Log::CRIT) << "Could not run getcontext"
		<< endl;
	} else {
		makecontext(&m_ctx, (void (*)())entry_point, 1, this); // create
	}
}

Coroutine::~Coroutine()
{
	if (m_stack) {
		delete[] m_stack;

#ifdef USE_VALGRIND
		VALGRIND_STACK_DEREGISTER(m_id);
#endif
	}
}

Coroutine::State
Coroutine::state() const
{
	return m_state;
}

void
Coroutine::run()
{
	int v = exec();
	m_state = DONE;
	yield(v);
}

int
Coroutine::resume()
{
	if (m_state == INIT)
		m_state = RUNNING;
	else if (m_state == DONE)
		return -1;

	ucontext_t prev_ctx = m_switcher.caller;
	swapcontext(&m_switcher.caller, &m_ctx); // switch to function
    // yield() brings us back here
	m_ctx = m_switcher.callee;               // save m_ctx
	m_switcher.caller = prev_ctx;            // save ctx for next use as "prev"

	return m_value;
}

void
Coroutine::yield(int value)
{
	// make available to .value()
	m_value = value;

	// switch out function context, get back to caller.
	swapcontext(&m_switcher.callee, &m_switcher.caller);
}

void
Coroutine::create_stack()
{
	m_stack = new char[COROUTINE_STACK_SIZE];

	m_ctx.uc_stack.ss_sp = (void*)m_stack;
	m_ctx.uc_stack.ss_size = COROUTINE_STACK_SIZE;
	m_ctx.uc_stack.ss_flags = 0;
	m_ctx.uc_link = 0;

#ifdef USE_VALGRIND
	m_id = VALGRIND_STACK_REGISTER(m_stack, m_stack + COROUTINE_STACK_SIZE);
#endif
}
<commit_msg>Fix stack creation as getcontext might clear it<commit_after>#include <stutter/coroutine.h>
#include <stutter/log.h>

#ifdef USE_VALGRIND
#include <valgrind/valgrind.h>
#endif

#define COROUTINE_STACK_SIZE (32 * 1024)

using namespace std;

void
entry_point(void *ptr)
{
	Coroutine *co = reinterpret_cast<Coroutine*>(ptr);
	co->run();
}

////////////////////////////////////////////////////////////

Coroutine::Coroutine()
		: m_state(INIT)
		, m_stack(0)
{
	// create new context based on current one:
	int gc = getcontext(&m_ctx); // copy current context into m_ctx
	create_stack();     // allocate stack for new context
	if (gc != 0) {
		Log::get(Log::CRIT) << "Could not run getcontext"
		<< endl;
	} else {
		makecontext(&m_ctx, (void (*)())entry_point, 1, this); // create
	}
}

Coroutine::~Coroutine()
{
	if (m_stack) {
		delete[] m_stack;

#ifdef USE_VALGRIND
		VALGRIND_STACK_DEREGISTER(m_id);
#endif
	}
}

Coroutine::State
Coroutine::state() const
{
	return m_state;
}

void
Coroutine::run()
{
	int v = exec();
	m_state = DONE;
	yield(v);
}

int
Coroutine::resume()
{
	if (m_state == INIT)
		m_state = RUNNING;
	else if (m_state == DONE)
		return -1;

	ucontext_t prev_ctx = m_switcher.caller;
	swapcontext(&m_switcher.caller, &m_ctx); // switch to function
    // yield() brings us back here
	m_ctx = m_switcher.callee;               // save m_ctx
	m_switcher.caller = prev_ctx;            // save ctx for next use as "prev"

	return m_value;
}

void
Coroutine::yield(int value)
{
	// make available to .value()
	m_value = value;

	// switch out function context, get back to caller.
	swapcontext(&m_switcher.callee, &m_switcher.caller);
}

void
Coroutine::create_stack()
{
	m_stack = new char[COROUTINE_STACK_SIZE];

	m_ctx.uc_stack.ss_sp = (void*)m_stack;
	m_ctx.uc_stack.ss_size = COROUTINE_STACK_SIZE;
	m_ctx.uc_stack.ss_flags = 0;
	m_ctx.uc_link = 0;

#ifdef USE_VALGRIND
	m_id = VALGRIND_STACK_REGISTER(m_stack, m_stack + COROUTINE_STACK_SIZE);
#endif
}
<|endoftext|>