<commit_before>
#include <togo/error/assert.hpp>
#include <togo/utility/utility.hpp>
#include <togo/math/math.hpp>
#include <togo/log/log.hpp>
#include <togo/resource/types.hpp>
#include <togo/resource/resource_handler.hpp>
#include <togo/resource/resource_manager.hpp>
#include <togo/gfx/types.hpp>
#include <togo/gfx/gfx.hpp>
#include <togo/gfx/display.hpp>
#include <togo/gfx/renderer.hpp>
#include <togo/gfx/renderer/types.hpp>
#include <togo/gfx/renderer/private.hpp>
#include <togo/gfx/renderer/opengl.hpp>
#include <togo/input/input.hpp>
#include <togo/app/app.hpp>

#include "../common/helpers.hpp"

#include <cmath>
#include <initializer_list>

using namespace togo;
using namespace togo::gfx::hash_literals;

struct Vertex {
	Vec2 pos;
	Vec3 color;
};

static gfx::VertexFormat const triangle_vformat{
	{gfx::Primitive::f32, 2, false}, // a_pos
	{gfx::Primitive::f32, 3, false}, // a_color
};

static Vertex const triangle_vertices[]{
	{Vec2{ 0.0f, 1.0f}, Vec3{1.0f,0.0f,0.0f}}, // Vertex 0: top, red
	{Vec2{ 1.0f,-1.0f}, Vec3{0.0f,0.0f,1.0f}}, // Vertex 1: right, blue
	{Vec2{-1.0f,-1.0f}, Vec3{0.0f,1.0f,0.0f}}, // Vertex 2: left, green
};

struct ColorFactors {
	f32 rg;
	f32 gb;
};

struct Oscillator {
	f32 time;
};

struct TestAppData {
	bool osc_paused;
	ColorFactors p_color_factors;
	Oscillator p_osc;

	gfx::BufferID triangle_buffer;
	gfx::BufferBindingID triangle_binding;
	gfx::BufferID pb_buffer;
	gfx::ShaderID shader;

	gfx::ParamBlockBinding p_color_factors_binding;
	gfx::ParamBlockBinding p_osc_binding;
};

using TestApp = App<TestAppData>;
using TestAppModel = AppModel<TestAppData>;

template<>
void TestAppModel::init(TestApp& app) {
	resource_manager::add_package(app._resource_manager, "test_data");
	gfx::display::set_swap_mode(app._display, gfx::DisplaySwapMode::wait_refresh);

	app._data.osc_paused = false;

	// Setup mesh data
	app._data.triangle_buffer = gfx::renderer::create_buffer(
		app._renderer, sizeof(triangle_vertices), triangle_vertices
	);
	app._data.triangle_binding = gfx::renderer::create_buffer_binding(
		app._renderer, array_extent(triangle_vertices), 0, {},
		{{app._data.triangle_buffer, &triangle_vformat, 0}}
	);

	// Setup parameter block buffer
	unsigned const pb_block_size = max(sizeof(ColorFactors), sizeof(Oscillator));
	unsigned const pb_buffer_size = gfx::renderer::block_aligned_buffer_size(
		app._renderer, 2, pb_block_size
	);
	TOGO_LOGF("pb_block_size = %u, pb_buffer_size = %u\n", pb_block_size, pb_buffer_size);
	app._data.pb_buffer = gfx::renderer::create_buffer(
		app._renderer,
		pb_buffer_size,
		nullptr, gfx::BufferDataBinding::dynamic
	);

	// Setup ColorFactors parameter block
	app._data.p_color_factors.rg = 1.0f;
	app._data.p_color_factors.gb = 1.0f;
	app._data.p_color_factors_binding = gfx::renderer::make_param_block_binding(
		app._renderer,
		app._data.pb_buffer, pb_block_size * 0, sizeof(ColorFactors)
	);
	gfx::renderer::set_fixed_param_block(
		app._renderer,
		0, "ColorFactors"_param_block_name,
		app._data.p_color_factors_binding
	);

	// Setup Oscillator parameter block
	app._data.p_osc.time = MC_PI;
	app._data.p_osc_binding = gfx::renderer::make_param_block_binding(
		app._renderer,
		app._data.pb_buffer, pb_block_size * 1, sizeof(Oscillator)
	);

	// Load shader
	app._data.shader = resource::load_shader(
		app._resource_manager,
		"test/gfx/simple-oscillate"_resource_name
	);
}

template<>
void TestAppModel::shutdown(TestApp& app) {
	gfx::renderer::destroy_buffer(app._renderer, app._data.pb_buffer);
	gfx::renderer::destroy_buffer_binding(app._renderer, app._data.triangle_binding);
	gfx::renderer::destroy_buffer(app._renderer, app._data.triangle_buffer);
}

f32 usin(f32 x) {
	return std::fabs(std::sin(x));
}

template<>
void TestAppModel::update(TestApp& app, float dt) {
	if (input::key_released(app._display, KeyCode::space)) {
		app._data.osc_paused = !app._data.osc_paused;
	}
	if (input::key_released(app._display, KeyCode::escape)) {
		app::quit(app);
	}

	// Update p_osc
	constexpr f32 const m = MC_TAU * 100.0f;
	if (!app._data.osc_paused) {
		app._data.p_osc.time = std::fmod(app._data.p_osc.time + dt, m);
	}

	// Update p_color_factors
	Vec2 const mp = input::mouse_position(app._display);
	app._data.p_color_factors.rg = mp.x / static_cast<f32>(gfx::display::width(app._display));
	app._data.p_color_factors.gb = mp.y / static_cast<f32>(gfx::display::height(app._display));
}

template<>
void TestAppModel::render(TestApp& app) {
	gfx::renderer::clear_backbuffer(app._renderer);
	gfx::renderer::map_buffer(
		app._renderer,
		app._data.p_color_factors_binding, &app._data.p_color_factors
	);
	gfx::renderer::map_buffer(
		app._renderer,
		app._data.p_osc_binding, &app._data.p_osc
	);
	gfx::renderer::render_objects(
		app._renderer,
		app._data.shader,
		1, &app._data.p_osc_binding,
		1, &app._data.triangle_binding
	);
}

signed main(signed argc, char* argv[]) {
	memory_init();

	TestApp app{
		unsigned_cast(max(0, argc - 1)),
		argv,
		"data/project/package/",
		1.0f / 30.0f,
		TestAppData{}
	};
	app::run(app);
	return 0;
}
<commit_msg>test/gfx/renderer_triangle: URC (gfx/renderer).<commit_after>
#include <togo/error/assert.hpp>
#include <togo/utility/utility.hpp>
#include <togo/math/math.hpp>
#include <togo/log/log.hpp>
#include <togo/resource/types.hpp>
#include <togo/resource/resource_handler.hpp>
#include <togo/resource/resource_manager.hpp>
#include <togo/gfx/types.hpp>
#include <togo/gfx/gfx.hpp>
#include <togo/gfx/display.hpp>
#include <togo/gfx/renderer.hpp>
#include <togo/gfx/renderer/types.hpp>
#include <togo/gfx/renderer/private.hpp>
#include <togo/gfx/renderer/opengl.hpp>
#include <togo/input/input.hpp>
#include <togo/app/app.hpp>

#include "../common/helpers.hpp"

#include <cmath>
#include <initializer_list>

using namespace togo;
using namespace togo::gfx::hash_literals;

struct Vertex {
	Vec2 pos;
	Vec3 color;
};

static gfx::VertexFormat const triangle_vformat{
	{gfx::Primitive::f32, 2, false}, // a_pos
	{gfx::Primitive::f32, 3, false}, // a_color
};

static Vertex const triangle_vertices[]{
	{Vec2{ 0.0f, 1.0f}, Vec3{1.0f,0.0f,0.0f}}, // Vertex 0: top, red
	{Vec2{ 1.0f,-1.0f}, Vec3{0.0f,0.0f,1.0f}}, // Vertex 1: right, blue
	{Vec2{-1.0f,-1.0f}, Vec3{0.0f,1.0f,0.0f}}, // Vertex 2: left, green
};

struct ColorFactors {
	f32 rg;
	f32 gb;
};

struct Oscillator {
	f32 time;
};

struct TestAppData {
	bool osc_paused;
	ColorFactors p_color_factors;
	Oscillator p_osc;

	gfx::BufferID triangle_buffer;
	gfx::BufferBindingID triangle_binding;
	gfx::BufferID pb_buffer;
	gfx::ShaderID shader;

	gfx::ParamBlockBinding p_color_factors_binding;
	gfx::ParamBlockBinding p_osc_binding;
};

using TestApp = App<TestAppData>;
using TestAppModel = AppModel<TestAppData>;

template<>
void TestAppModel::init(TestApp& app) {
	resource_manager::add_package(app._resource_manager, "test_data");
	gfx::display::set_swap_mode(app._display, gfx::DisplaySwapMode::wait_refresh);

	app._data.osc_paused = false;

	// Setup mesh data
	app._data.triangle_buffer = gfx::renderer::create_buffer(
		app._renderer, sizeof(triangle_vertices), triangle_vertices
	);
	app._data.triangle_binding = gfx::renderer::create_buffer_binding(
		app._renderer, array_extent(triangle_vertices), 0, {},
		{{app._data.triangle_buffer, &triangle_vformat, 0}}
	);

	// Setup parameter block buffer
	unsigned const pb_block_size = max(sizeof(ColorFactors), sizeof(Oscillator));
	unsigned const pb_buffer_size = gfx::renderer::param_block_buffer_size(
		app._renderer, 2, pb_block_size
	);
	TOGO_LOGF("pb_block_size = %u, pb_buffer_size = %u\n", pb_block_size, pb_buffer_size);
	app._data.pb_buffer = gfx::renderer::create_buffer(
		app._renderer,
		pb_buffer_size,
		nullptr, gfx::BufferDataBinding::dynamic
	);

	// Setup ColorFactors parameter block
	app._data.p_color_factors.rg = 1.0f;
	app._data.p_color_factors.gb = 1.0f;
	app._data.p_color_factors_binding = gfx::renderer::make_param_block_binding(
		app._renderer,
		app._data.pb_buffer,
		gfx::renderer::param_block_offset(app._renderer, 0, pb_block_size),
		sizeof(ColorFactors)
	);
	gfx::renderer::set_fixed_param_block(
		app._renderer,
		0, "ColorFactors"_param_block_name,
		app._data.p_color_factors_binding
	);

	// Setup Oscillator parameter block
	app._data.p_osc.time = MC_PI;
	app._data.p_osc_binding = gfx::renderer::make_param_block_binding(
		app._renderer,
		app._data.pb_buffer,
		gfx::renderer::param_block_offset(app._renderer, 1, pb_block_size),
		sizeof(Oscillator)
	);

	// Load shader
	app._data.shader = resource::load_shader(
		app._resource_manager,
		"test/gfx/simple-oscillate"_resource_name
	);
}

template<>
void TestAppModel::shutdown(TestApp& app) {
	gfx::renderer::destroy_buffer(app._renderer, app._data.pb_buffer);
	gfx::renderer::destroy_buffer_binding(app._renderer, app._data.triangle_binding);
	gfx::renderer::destroy_buffer(app._renderer, app._data.triangle_buffer);
}

f32 usin(f32 x) {
	return std::fabs(std::sin(x));
}

template<>
void TestAppModel::update(TestApp& app, float dt) {
	if (input::key_released(app._display, KeyCode::space)) {
		app._data.osc_paused = !app._data.osc_paused;
	}
	if (input::key_released(app._display, KeyCode::escape)) {
		app::quit(app);
	}

	// Update p_osc
	constexpr f32 const m = MC_TAU * 100.0f;
	if (!app._data.osc_paused) {
		app._data.p_osc.time = std::fmod(app._data.p_osc.time + dt, m);
	}

	// Update p_color_factors
	Vec2 const mp = input::mouse_position(app._display);
	app._data.p_color_factors.rg = mp.x / static_cast<f32>(gfx::display::width(app._display));
	app._data.p_color_factors.gb = mp.y / static_cast<f32>(gfx::display::height(app._display));
}

template<>
void TestAppModel::render(TestApp& app) {
	gfx::renderer::clear_backbuffer(app._renderer);
	gfx::renderer::map_buffer(
		app._renderer,
		app._data.p_color_factors_binding, &app._data.p_color_factors
	);
	gfx::renderer::map_buffer(
		app._renderer,
		app._data.p_osc_binding, &app._data.p_osc
	);
	gfx::renderer::render_objects(
		app._renderer,
		app._data.shader,
		1, &app._data.p_osc_binding,
		1, &app._data.triangle_binding
	);
}

signed main(signed argc, char* argv[]) {
	memory_init();

	TestApp app{
		unsigned_cast(max(0, argc - 1)),
		argv,
		"data/project/package/",
		1.0f / 30.0f,
		TestAppData{}
	};
	app::run(app);
	return 0;
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "sys_net_native.h"

void Network_PostEvent( unsigned int eventType, unsigned int flags )
{
    PostManagedEvent( EVENT_NETWORK, eventType, flags, 0 );
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::InitializeNetworkInterfaceSettings___VOID( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    HAL_Configuration_NetworkInterface config;
    CLR_RT_HeapBlock* pConfig           = stack.Arg0().Dereference();  _ASSERTE(pConfig != NULL);

    CLR_UINT32 interfaceIndex           = pConfig[ FIELD___interfaceIndex ].NumericByRefConst().u4;

    NANOCLR_CLEAR(config);

    // load network interface configuration from storage
    if(!ConfigurationManager_GetConfigurationBlock((void*)&config, DeviceConfigurationOption_Network, interfaceIndex))
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }
    _ASSERTE(config.StartupAddressMode > 0);

    // now load adapter configuration on top of the stored config
    NANOCLR_CHECK_HRESULT(SOCK_CONFIGURATION_LoadAdapterConfiguration(&config, interfaceIndex));

    pConfig[ FIELD___ipv4Address            ].SetInteger( (CLR_UINT32)config.IPv4Address);
    pConfig[ FIELD___ipv4GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv4GatewayAddress);
    pConfig[ FIELD___ipv4NetMask            ].SetInteger( (CLR_UINT32)config.IPv4NetMask);
    pConfig[ FIELD___ipv4dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress1);
    pConfig[ FIELD___ipv4dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress2);

    // FIXME IPV6
    // pConfig[ FIELD___ipv6Address            ].SetInteger( (CLR_UINT32)config.IPv6Address);
    // pConfig[ FIELD___ipv6GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv6GatewayAddress);
    // pConfig[ FIELD___ipv6NetMask            ].SetInteger( (CLR_UINT32)config.IPv6NetMask);
    // pConfig[ FIELD___ipv6dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress1);
    // pConfig[ FIELD___ipv6dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress2);

    pConfig[ FIELD___automaticDns           ].SetInteger( (CLR_UINT32)config.AutomaticDNS);
    pConfig[ FIELD___networkInterfaceType   ].SetInteger( (CLR_UINT32)config.InterfaceType);
    pConfig[ FIELD___specificConfigId       ].SetInteger( (CLR_UINT32)config.SpecificConfigId);
    pConfig[ FIELD___startupAddressMode     ].SetInteger( (CLR_UINT32)config.StartupAddressMode);

    NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( pConfig[ FIELD___macAddress ], NETIF_MAX_HWADDR_LEN, g_CLR_RT_WellKnownTypes.m_UInt8));
    memcpy(pConfig[ FIELD___macAddress ].DereferenceArray()->GetFirstElement(), config.MacAddress, NETIF_MAX_HWADDR_LEN);

    NANOCLR_NOCLEANUP();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::UpdateConfiguration___VOID__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    HAL_Configuration_NetworkInterface config;
    CLR_RT_HeapBlock* pConfig           = stack.Arg0().Dereference();  _ASSERTE(pConfig != NULL);
    CLR_UINT32 interfaceIndex           = pConfig[ FIELD___interfaceIndex ].NumericByRefConst().u4;
    CLR_UINT32 updateFlags              = stack.Arg1().NumericByRef().u4;
    CLR_RT_HeapBlock_Array* pMACAddress = pConfig[ FIELD___macAddress ].DereferenceArray();

    NANOCLR_CLEAR(config);

    config.IPv4Address           = pConfig[ FIELD___ipv4Address        ].NumericByRef().u4;
    config.IPv4GatewayAddress    = pConfig[ FIELD___ipv4GatewayAddress ].NumericByRef().u4;
    config.IPv4NetMask           = pConfig[ FIELD___ipv4NetMask        ].NumericByRef().u4;
    config.IPv4DNSAddress1       = pConfig[ FIELD___ipv4dnsAddress1    ].NumericByRef().u4;
    config.IPv4DNSAddress2       = pConfig[ FIELD___ipv4dnsAddress2    ].NumericByRef().u4;

    // FIXME IPV6
    // config.IPv6Address           = pConfig[ FIELD___ipv6Address        ].NumericByRef().u4;
    // config.IPv6GatewayAddress    = pConfig[ FIELD___ipv6GatewayAddress ].NumericByRef().u4;
    // config.IPv6NetMask           = pConfig[ FIELD___ipv6NetMask        ].NumericByRef().u4;
    // config.IPv6DNSAddress1       = pConfig[ FIELD___ipv6dnsAddress1    ].NumericByRef().u4;
    // config.IPv6DNSAddress2       = pConfig[ FIELD___ipv6dnsAddress2    ].NumericByRef().u4;

    config.AutomaticDNS         =                           pConfig[ FIELD___automaticDns         ].NumericByRef().u4;
    config.InterfaceType        = (NetworkInterfaceType)    pConfig[ FIELD___networkInterfaceType ].NumericByRef().u4;
    config.SpecificConfigId     = (CLR_UINT32)              pConfig[ FIELD___specificConfigId     ].NumericByRef().u4;
    config.StartupAddressMode   = (AddressMode)             pConfig[ FIELD___startupAddressMode   ].NumericByRef().u4;

    if(pMACAddress != NULL)
    {
        memcpy( &config.MacAddress, pMACAddress->GetFirstElement(), NETIF_MAX_HWADDR_LEN );
    }

    // store configuration, updating the configuration block
    if(ConfigurationManager_UpdateConfigurationBlock(&config, DeviceConfigurationOption_Network, interfaceIndex) != TRUE)
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    NANOCLR_CHECK_HRESULT(SOCK_CONFIGURATION_UpdateAdapterConfiguration(&config, interfaceIndex, updateFlags));

    NANOCLR_NOCLEANUP();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterfaceCount___STATIC__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    // grab the count right from the structure
    stack.SetResult_I4( g_TargetConfiguration.NetworkInterfaceConfigs->Count );

    NANOCLR_NOCLEANUP_NOLABEL();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterface___STATIC__SystemNetNetworkInformationNetworkInterface__U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    HAL_Configuration_NetworkInterface config;
    CLR_RT_HeapBlock*         pConfig;
    CLR_UINT32                interfaceIndex = stack.Arg0().NumericByRef().u4;
    CLR_RT_HeapBlock&         top            = stack.PushValueAndClear();

    NANOCLR_CLEAR(config);

    // load network interface configuration from storage
    if(!ConfigurationManager_GetConfigurationBlock((void*)&config, DeviceConfigurationOption_Network, interfaceIndex))
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }
    _ASSERTE(config.StartupAddressMode > 0);

    // now load adapter configuration on top of the stored config
    NANOCLR_CHECK_HRESULT(SOCK_CONFIGURATION_LoadConfiguration(&config, interfaceIndex));

    NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( top, g_CLR_RT_WellKnownTypes.m_NetworkInterface ));

    pConfig = top.Dereference(); FAULT_ON_NULL(pConfig);

    pConfig[ FIELD___ipv4Address            ].SetInteger( (CLR_UINT32)config.IPv4Address);
    pConfig[ FIELD___ipv4GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv4GatewayAddress);
    pConfig[ FIELD___ipv4NetMask            ].SetInteger( (CLR_UINT32)config.IPv4NetMask);
    pConfig[ FIELD___ipv4dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress1);
    pConfig[ FIELD___ipv4dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress2);

    // FIXME IPV6
    // pConfig[ FIELD___ipv6Address            ].SetInteger( (CLR_UINT32)config.IPv6Address);
    // pConfig[ FIELD___ipv6GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv6GatewayAddress);
    // pConfig[ FIELD___ipv6NetMask            ].SetInteger( (CLR_UINT32)config.IPv6NetMask);
    // pConfig[ FIELD___ipv6dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress1);
    // pConfig[ FIELD___ipv6dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress2);

    pConfig[ FIELD___automaticDns           ].SetInteger( (CLR_UINT32)config.AutomaticDNS);
    pConfig[ FIELD___networkInterfaceType   ].SetInteger( (CLR_UINT32)config.InterfaceType);
    pConfig[ FIELD___specificConfigId       ].SetInteger( (CLR_UINT32)config.SpecificConfigId);
    pConfig[ FIELD___startupAddressMode     ].SetInteger( (CLR_UINT32)config.StartupAddressMode);

    NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( pConfig[ FIELD___macAddress ], NETIF_MAX_HWADDR_LEN, g_CLR_RT_WellKnownTypes.m_UInt8 ));
    memcpy( pConfig[ FIELD___macAddress ].DereferenceArray()->GetFirstElement(), config.MacAddress, NETIF_MAX_HWADDR_LEN );

    NANOCLR_NOCLEANUP();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::IPAddressFromString___STATIC__U4__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    LPCSTR szName = stack.Arg0().RecoverString();
    struct SOCK_addrinfo hints;
    struct SOCK_addrinfo* addr = NULL;
    struct SOCK_sockaddr_in* addr_in;
    int ret;

    memset( &hints, 0, sizeof(hints) );

    ret = SOCK_getaddrinfo( szName, NULL, &hints, &addr );

    // getaddrinfo returns a winsock error code rather than SOCK_SOCKET_ERROR, so pass this on to the exception handling
    if(ret != 0 || addr == NULL || addr->ai_family != SOCK_AF_INET)
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    _ASSERTE(addr->ai_addr != NULL);
    _ASSERTE(addr->ai_addrlen >= sizeof(SOCK_sockaddr_in));

    addr_in = (struct SOCK_sockaddr_in*)addr->ai_addr;

    stack.PushValue().SetInteger( (CLR_UINT32)addr_in->sin_addr.S_un.S_addr );

    NANOCLR_CLEANUP();

    if( addr ) SOCK_freeaddrinfo( addr );

    NANOCLR_CLEANUP_END();
}
<commit_msg>Add missing field in GetNetworkInterface (#1256)<commit_after>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "sys_net_native.h"

void Network_PostEvent( unsigned int eventType, unsigned int flags )
{
    PostManagedEvent( EVENT_NETWORK, eventType, flags, 0 );
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::InitializeNetworkInterfaceSettings___VOID( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    HAL_Configuration_NetworkInterface config;
    CLR_RT_HeapBlock* pConfig           = stack.Arg0().Dereference();  _ASSERTE(pConfig != NULL);

    CLR_UINT32 interfaceIndex           = pConfig[ FIELD___interfaceIndex ].NumericByRefConst().u4;

    NANOCLR_CLEAR(config);

    // load network interface configuration from storage
    if(!ConfigurationManager_GetConfigurationBlock((void*)&config, DeviceConfigurationOption_Network, interfaceIndex))
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }
    _ASSERTE(config.StartupAddressMode > 0);

    // now load adapter configuration on top of the stored config
    NANOCLR_CHECK_HRESULT(SOCK_CONFIGURATION_LoadAdapterConfiguration(&config, interfaceIndex));

    pConfig[ FIELD___ipv4Address            ].SetInteger( (CLR_UINT32)config.IPv4Address);
    pConfig[ FIELD___ipv4GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv4GatewayAddress);
    pConfig[ FIELD___ipv4NetMask            ].SetInteger( (CLR_UINT32)config.IPv4NetMask);
    pConfig[ FIELD___ipv4dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress1);
    pConfig[ FIELD___ipv4dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress2);

    // FIXME IPV6
    // pConfig[ FIELD___ipv6Address            ].SetInteger( (CLR_UINT32)config.IPv6Address);
    // pConfig[ FIELD___ipv6GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv6GatewayAddress);
    // pConfig[ FIELD___ipv6NetMask            ].SetInteger( (CLR_UINT32)config.IPv6NetMask);
    // pConfig[ FIELD___ipv6dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress1);
    // pConfig[ FIELD___ipv6dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress2);

    pConfig[ FIELD___automaticDns           ].SetInteger( (CLR_UINT32)config.AutomaticDNS);
    pConfig[ FIELD___networkInterfaceType   ].SetInteger( (CLR_UINT32)config.InterfaceType);
    pConfig[ FIELD___specificConfigId       ].SetInteger( (CLR_UINT32)config.SpecificConfigId);
    pConfig[ FIELD___startupAddressMode     ].SetInteger( (CLR_UINT32)config.StartupAddressMode);

    NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( pConfig[ FIELD___macAddress ], NETIF_MAX_HWADDR_LEN, g_CLR_RT_WellKnownTypes.m_UInt8));
    memcpy(pConfig[ FIELD___macAddress ].DereferenceArray()->GetFirstElement(), config.MacAddress, NETIF_MAX_HWADDR_LEN);

    NANOCLR_NOCLEANUP();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::UpdateConfiguration___VOID__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    HAL_Configuration_NetworkInterface config;
    CLR_RT_HeapBlock* pConfig           = stack.Arg0().Dereference();  _ASSERTE(pConfig != NULL);
    CLR_UINT32 interfaceIndex           = pConfig[ FIELD___interfaceIndex ].NumericByRefConst().u4;
    CLR_UINT32 updateFlags              = stack.Arg1().NumericByRef().u4;
    CLR_RT_HeapBlock_Array* pMACAddress = pConfig[ FIELD___macAddress ].DereferenceArray();

    NANOCLR_CLEAR(config);

    config.IPv4Address           = pConfig[ FIELD___ipv4Address        ].NumericByRef().u4;
    config.IPv4GatewayAddress    = pConfig[ FIELD___ipv4GatewayAddress ].NumericByRef().u4;
    config.IPv4NetMask           = pConfig[ FIELD___ipv4NetMask        ].NumericByRef().u4;
    config.IPv4DNSAddress1       = pConfig[ FIELD___ipv4dnsAddress1    ].NumericByRef().u4;
    config.IPv4DNSAddress2       = pConfig[ FIELD___ipv4dnsAddress2    ].NumericByRef().u4;

    // FIXME IPV6
    // config.IPv6Address           = pConfig[ FIELD___ipv6Address        ].NumericByRef().u4;
    // config.IPv6GatewayAddress    = pConfig[ FIELD___ipv6GatewayAddress ].NumericByRef().u4;
    // config.IPv6NetMask           = pConfig[ FIELD___ipv6NetMask        ].NumericByRef().u4;
    // config.IPv6DNSAddress1       = pConfig[ FIELD___ipv6dnsAddress1    ].NumericByRef().u4;
    // config.IPv6DNSAddress2       = pConfig[ FIELD___ipv6dnsAddress2    ].NumericByRef().u4;

    config.AutomaticDNS         =                           pConfig[ FIELD___automaticDns         ].NumericByRef().u4;
    config.InterfaceType        = (NetworkInterfaceType)    pConfig[ FIELD___networkInterfaceType ].NumericByRef().u4;
    config.SpecificConfigId     = (CLR_UINT32)              pConfig[ FIELD___specificConfigId     ].NumericByRef().u4;
    config.StartupAddressMode   = (AddressMode)             pConfig[ FIELD___startupAddressMode   ].NumericByRef().u4;

    if(pMACAddress != NULL)
    {
        memcpy( &config.MacAddress, pMACAddress->GetFirstElement(), NETIF_MAX_HWADDR_LEN );
    }

    // store configuration, updating the configuration block
    if(ConfigurationManager_UpdateConfigurationBlock(&config, DeviceConfigurationOption_Network, interfaceIndex) != TRUE)
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    NANOCLR_CHECK_HRESULT(SOCK_CONFIGURATION_UpdateAdapterConfiguration(&config, interfaceIndex, updateFlags));

    NANOCLR_NOCLEANUP();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterfaceCount___STATIC__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    // grab the count right from the structure
    stack.SetResult_I4( g_TargetConfiguration.NetworkInterfaceConfigs->Count );

    NANOCLR_NOCLEANUP_NOLABEL();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::GetNetworkInterface___STATIC__SystemNetNetworkInformationNetworkInterface__U4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    HAL_Configuration_NetworkInterface config;
    CLR_RT_HeapBlock*         pConfig;
    CLR_UINT32                interfaceIndex = stack.Arg0().NumericByRef().u4;
    CLR_RT_HeapBlock&         top            = stack.PushValueAndClear();

    NANOCLR_CLEAR(config);

    // load network interface configuration from storage
    if(!ConfigurationManager_GetConfigurationBlock((void*)&config, DeviceConfigurationOption_Network, interfaceIndex))
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }
    _ASSERTE(config.StartupAddressMode > 0);

    // now load adapter configuration on top of the stored config
    NANOCLR_CHECK_HRESULT(SOCK_CONFIGURATION_LoadConfiguration(&config, interfaceIndex));

    NANOCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex( top, g_CLR_RT_WellKnownTypes.m_NetworkInterface ));

    pConfig = top.Dereference(); FAULT_ON_NULL(pConfig);

    pConfig[ FIELD___ipv4Address            ].SetInteger( (CLR_UINT32)config.IPv4Address);
    pConfig[ FIELD___ipv4GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv4GatewayAddress);
    pConfig[ FIELD___ipv4NetMask            ].SetInteger( (CLR_UINT32)config.IPv4NetMask);
    pConfig[ FIELD___ipv4dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress1);
    pConfig[ FIELD___ipv4dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv4DNSAddress2);

    // FIXME IPV6
    // pConfig[ FIELD___ipv6Address            ].SetInteger( (CLR_UINT32)config.IPv6Address);
    // pConfig[ FIELD___ipv6GatewayAddress     ].SetInteger( (CLR_UINT32)config.IPv6GatewayAddress);
    // pConfig[ FIELD___ipv6NetMask            ].SetInteger( (CLR_UINT32)config.IPv6NetMask);
    // pConfig[ FIELD___ipv6dnsAddress1        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress1);
    // pConfig[ FIELD___ipv6dnsAddress2        ].SetInteger( (CLR_UINT32)config.IPv6DNSAddress2);

    pConfig[ FIELD___automaticDns           ].SetInteger( (CLR_UINT32)config.AutomaticDNS);
    pConfig[ FIELD___networkInterfaceType   ].SetInteger( (CLR_UINT32)config.InterfaceType);
    pConfig[ FIELD___specificConfigId       ].SetInteger( (CLR_UINT32)config.SpecificConfigId);
    pConfig[ FIELD___startupAddressMode     ].SetInteger( (CLR_UINT32)config.StartupAddressMode);
    pConfig[ FIELD___interfaceIndex         ].SetInteger( (CLR_UINT32)interfaceIndex);

    NANOCLR_CHECK_HRESULT(CLR_RT_HeapBlock_Array::CreateInstance( pConfig[ FIELD___macAddress ], NETIF_MAX_HWADDR_LEN, g_CLR_RT_WellKnownTypes.m_UInt8 ));
    memcpy( pConfig[ FIELD___macAddress ].DereferenceArray()->GetFirstElement(), config.MacAddress, NETIF_MAX_HWADDR_LEN );

    NANOCLR_NOCLEANUP();
}

HRESULT Library_sys_net_native_System_Net_NetworkInformation_NetworkInterface::IPAddressFromString___STATIC__U4__STRING( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_NETWORK();
    NANOCLR_HEADER();

    LPCSTR szName = stack.Arg0().RecoverString();
    struct SOCK_addrinfo hints;
    struct SOCK_addrinfo* addr = NULL;
    struct SOCK_sockaddr_in* addr_in;
    int ret;

    memset( &hints, 0, sizeof(hints) );

    ret = SOCK_getaddrinfo( szName, NULL, &hints, &addr );

    // getaddrinfo returns a winsock error code rather than SOCK_SOCKET_ERROR, so pass this on to the exception handling
    if(ret != 0 || addr == NULL || addr->ai_family != SOCK_AF_INET)
    {
        NANOCLR_SET_AND_LEAVE(CLR_E_FAIL);
    }

    _ASSERTE(addr->ai_addr != NULL);
    _ASSERTE(addr->ai_addrlen >= sizeof(SOCK_sockaddr_in));

    addr_in = (struct SOCK_sockaddr_in*)addr->ai_addr;

    stack.PushValue().SetInteger( (CLR_UINT32)addr_in->sin_addr.S_un.S_addr );

    NANOCLR_CLEANUP();

    if( addr ) SOCK_freeaddrinfo( addr );

    NANOCLR_CLEANUP_END();
}
<|endoftext|>


<commit_before>#include "t200_thruster.h"
//#include "sub_thruster_library/seabotix_thruster.h"
#include "generic_thruster.h"
#include "sub_trajectory/ThrusterCmd.h"
#include <json/json.h>

#include <ros/ros.h>
#include <std_srvs/Empty.h>
#include <diagnostic_msgs/DiagnosticStatus.h>
#include <diagnostic_msgs/DiagnosticArray.h>
#include <diagnostic_msgs/SelfTest.h> //TODO: implement self tests
#include <self_test/self_test.h>

#include <iostream>
#include <fstream>
#include <memory>

inline const std::string BoolToString(const bool b); //http://stackoverflow.com/a/29798

class ThrusterManager {
    ros::NodeHandle nh_;
    ros::Subscriber command_subscriber;
    ros::Publisher diagnostics_output;
    self_test::TestRunner self_test_;
    std::string configPath;

    sub_trajectory::ThrusterCmd savedMsg;

    std::map<int, std::unique_ptr<GenericThruster>> thrusterMap;

    int updateRate;
    int expectedThrusters;

    ros::ServiceServer initServer;

public:
    ThrusterManager() : self_test_()
    {
        for(int i = 0; i < 8; i++) {
            savedMsg.cmd.push_back(0.0);
        }

        command_subscriber = nh_.subscribe("/thrusters/cmd_vel", 1000, &ThrusterManager::thrusterCb, this);

        diagnostics_output = nh_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1000);

        self_test_.add("Test connections", this, &ThrusterManager::testThrusterConnections);

        initServer = nh_.advertiseService("initThrusters", &ThrusterManager::initService, this);

        nh_.param("/updateRate", updateRate, 30);
        nh_.param("/thrusterConfigPath", configPath, std::string("config.json"));
    }

    Json::Value loadConfig(std::string filename)
    {
        ifstream configFile(filename);
        if(!configFile.is_open()){
            ROS_ERROR("Thruster controller couldn't open config file");
            //status.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Config file didn't load");
            Json::Value obj;
            return obj;
        }

        ROS_INFO("Thruster controller config loading");
        Json::Value obj;
        configFile >> obj;
        ROS_INFO("Thruster controller config loaded");
        return obj;
    }
    bool initService(std_srvs::Empty::Request& req, std_srvs::Empty::Response& resp)
    {
        init();
        return true;
    }

    void init()
    {
        thrusterMap.clear();
        Json::Value thrustersJson = loadConfig(configPath)["COMPUTE"];

        savedMsg = sub_trajectory::ThrusterCmd();
        savedMsg.cmd.resize(thrustersJson.size(), 0.0);
        expectedThrusters = thrustersJson.size();

        diagnostic_msgs::DiagnosticArray diag;

        for(int i = 0; i < thrustersJson.size(); i++) {
            int thrusterID = thrustersJson[i]["ID"].asInt();
            int thrusterType = thrustersJson[i]["Type"].asInt(); //TODO: support for multiple thruster types
            int thrusterAddress = thrustersJson[i]["Address"].asInt();
            ROS_INFO("Initializing thruster %d", thrusterID);
            try{
                  thrusterMap[i] = std::unique_ptr<GenericThruster>(new T200Thruster(1,thrusterAddress));
            }
            catch(I2CException e){
                //If we get here there's a bus problem
                ROS_ERROR("I2C error while connecting to thruster address %x", thrusterAddress);
                thrusterMap.erase(i);
                //Publish an error message for the diagnostic system to do something about
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thruster_"+thrustersJson[i]["Address"].asString();
                status.hardware_id = "Thruster_"+thrustersJson[i]["Address"].asString();
                status.message = std::string("Couldn't connect");
                status.level = status.ERROR;
                diag.status.push_back(status);
            }
        }
        diagnostics_output.publish(diag);
        ros::spinOnce();
        ROS_INFO("Done initializing thrusters");
    }

    void spin()
    {
        ros::Rate rate(updateRate);
        int loopCount;
        while(ros::ok()) {
            diagnostic_msgs::DiagnosticArray diag;
            ROS_DEBUG("Updating thrusters");
            if(loopCount++ > updateRate*2 && thrusterMap.size() < expectedThrusters)
            {
                init();
                loopCount = 0;
            }

            if(thrusterMap.size() == 0)
            {
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thrusters";
                status.hardware_id = "Thrusters";
                status.level = status.WARN;
                diag.status.push_back(status);
                ROS_WARN("No thrusters initialized");
            }
            else if(savedMsg.cmd.size() == 0)
            {
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thrusters";
                status.hardware_id = "Thrusters";
                status.level = status.WARN;
                diag.status.push_back(status);
                ROS_WARN("No comand message");
            }
            else if(thrusterMap.size() != savedMsg.cmd.size())
            {
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thrusters";
                status.hardware_id = "Thrusters";
                status.level = status.ERROR;
                diag.status.push_back(status);
                ROS_ERROR("Thrusters command has wrong number of values");
            }
            else
            {
                for(auto& iter:thrusterMap)
                {
                    diagnostic_msgs::DiagnosticStatus status;
                    status.name = "Thruster_"+std::to_string(iter.first);
                    status.hardware_id = "Thruster_"+std::to_string(iter.first);

                    try {
                        iter.second->updateStatus();
                        iter.second->setVelocityRatio(savedMsg.cmd.at(iter.first));
                    } catch(I2CException e) {
                        //Publish an error message for the diagnostic system to do something about
                        status.level = status.ERROR;
                    } catch (std::out_of_range e) {
                        ROS_ERROR("Thrusters command has not enough values");
                    }

                    if (thrusterOk(iter.second) && status.level != status.ERROR)
                        status.level = status.OK;
                    else
                        status.level = status.ERROR;

                    PushDiagData(status, iter.second, std::to_string(iter.first));
                    diag.status.push_back(status);
                }
            }

            diagnostics_output.publish(diag);
            ros::spinOnce();
            self_test_.checkTest();
            rate.sleep();
        }
    }

    bool thrusterOk (std::unique_ptr<GenericThruster> & thruster)
    {
        return thruster->isAlive() && thruster->inLimits();
    }

    void PushDiagData(diagnostic_msgs::DiagnosticStatus & statusmsg, std::unique_ptr<GenericThruster> & thruster, std::string thrusterName)
    {
        diagnostic_msgs::KeyValue thrusterValue;

        thrusterValue.key = "Thruster Type";
        thrusterValue.value = thruster->getType();
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Alive";
        thrusterValue.value = BoolToString(thruster->isAlive());
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Voltage";
        thrusterValue.value = std::to_string(thruster->getVoltage());
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Current";
        thrusterValue.value = std::to_string(thruster->getCurrent());
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Temperature";
        thrusterValue.value = std::to_string(thruster->getTemperature());
        statusmsg.values.push_back(thrusterValue);
    }

    void thrusterCb(const sub_trajectory::ThrusterCmd &msg)
    {
        savedMsg = msg;
    }

    //Self test function
    void testThrusterConnections(diagnostic_updater::DiagnosticStatusWrapper& status)
    {
        self_test_.setID("thrusterController");
        std::stringstream failedThrusters;
        Json::Value& thrustersJson = loadConfig(configPath)["COMPUTE"];
        for(int i = 0; i < thrustersJson.size(); i++)
        {
            int thrusterID = thrustersJson[i]["ID"].asInt();
            int thrusterType = thrustersJson[i]["Type"].asInt(); //TODO: support for multiple thruster types
            int thrusterAddress = thrustersJson[i]["Address"].asInt();

            try{
                T200Thruster(1, thrusterAddress).updateStatus();
            }
            catch(I2CException e){
                failedThrusters << thrusterAddress << " ";
            }
        }

        if(failedThrusters.str().length() > 0){
            status.add("Failures", failedThrusters.str());
            status.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Thruster couldn't connect");
        } else {
            status.summary(diagnostic_msgs::DiagnosticStatus::OK, "All thrusters OK");
        }
    }
};

int main(int argc, char** argv)
{
    ros::init(argc, argv, "thruster_driver");
    ThrusterManager tc;
    tc.init();
    ROS_INFO("Thruster controller initialized, spinning");
    tc.spin();
    return 0;
}

inline const std::string BoolToString(const bool b)
{
  return b ? "true" : "false";
}
<commit_msg>I2C thruster manager now publishes thruster status for vector controller<commit_after>#include "t200_thruster.h"
//#include "sub_thruster_library/seabotix_thruster.h"
#include "generic_thruster.h"
#include "sub_trajectory/ThrusterCmd.h"
#include "sub_trajectory/ThrusterStatus.h"
#include <json/json.h>

#include <ros/ros.h>
#include <std_srvs/Empty.h>
#include <diagnostic_msgs/DiagnosticStatus.h>
#include <diagnostic_msgs/DiagnosticArray.h>
#include <diagnostic_msgs/SelfTest.h> //TODO: implement self tests
#include <self_test/self_test.h>

#include <iostream>
#include <fstream>
#include <memory>

inline const std::string BoolToString(const bool b); //http://stackoverflow.com/a/29798

class ThrusterManager {
    ros::NodeHandle nh_;
    ros::Subscriber command_subscriber;
    ros::Publisher diagnostics_output;
    ros:Subscriber status_output;
    self_test::TestRunner self_test_;
    std::string configPath;

    sub_trajectory::ThrusterCmd savedMsg;

    std::map<int, std::unique_ptr<GenericThruster>> thrusterMap;

    int updateRate;
    int expectedThrusters;

    ros::ServiceServer initServer;

public:
    ThrusterManager() : self_test_()
    {
        for(int i = 0; i < 8; i++) {
            savedMsg.cmd.push_back(0.0);
        }

        command_subscriber = nh_.subscribe("/thrusters/cmd_vel", 1000, &ThrusterManager::thrusterCb, this);

        diagnostics_output = nh_.advertise<diagnostic_msgs::DiagnosticArray>("/diagnostics", 1000);
        status_output = nh_.advertise<ThrusterStatus>("/thrusterStatus", 1000)

        self_test_.add("Test connections", this, &ThrusterManager::testThrusterConnections);

        initServer = nh_.advertiseService("initThrusters", &ThrusterManager::initService, this);

        nh_.param("/updateRate", updateRate, 30);
        nh_.param("/thrusterConfigPath", configPath, std::string("config.json"));
    }

    Json::Value loadConfig(std::string filename)
    {
        ifstream configFile(filename);
        if(!configFile.is_open()){
            ROS_ERROR("Thruster controller couldn't open config file");
            //status.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Config file didn't load");
            Json::Value obj;
            return obj;
        }

        ROS_INFO("Thruster controller config loading");
        Json::Value obj;
        configFile >> obj;
        ROS_INFO("Thruster controller config loaded");
        return obj;
    }
    bool initService(std_srvs::Empty::Request& req, std_srvs::Empty::Response& resp)
    {
        init();
        return true;
    }

    void init()
    {
        thrusterMap.clear();
        Json::Value thrustersJson = loadConfig(configPath)["COMPUTE"];

        savedMsg = sub_trajectory::ThrusterCmd();
        savedMsg.cmd.resize(thrustersJson.size(), 0.0);
        expectedThrusters = thrustersJson.size();

        diagnostic_msgs::DiagnosticArray diag;

        for(int i = 0; i < thrustersJson.size(); i++) {
            int thrusterID = thrustersJson[i]["ID"].asInt();
            int thrusterType = thrustersJson[i]["Type"].asInt(); //TODO: support for multiple thruster types
            int thrusterAddress = thrustersJson[i]["Address"].asInt();
            ROS_INFO("Initializing thruster %d", thrusterID);
            try{
                  thrusterMap[i] = std::unique_ptr<GenericThruster>(new T200Thruster(1,thrusterAddress));
            }
            catch(I2CException e){
                //If we get here there's a bus problem
                ROS_ERROR("I2C error while connecting to thruster address %x", thrusterAddress);
                thrusterMap.erase(i);
                //Publish an error message for the diagnostic system to do something about
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thruster_"+thrustersJson[i]["Address"].asString();
                status.hardware_id = "Thruster_"+thrustersJson[i]["Address"].asString();
                status.message = std::string("Couldn't connect");
                status.level = status.ERROR;
                diag.status.push_back(status);
            }
        }
        diagnostics_output.publish(diag);
        ros::spinOnce();
        ROS_INFO("Done initializing thrusters");
    }

    void spin()
    {
        ros::Rate rate(updateRate);
        int loopCount;
        ThrusterStatus thrusterStatusMsg = ThrusterStatus();
        while(ros::ok()) {
            diagnostic_msgs::DiagnosticArray diag;
            ROS_DEBUG("Updating thrusters");
            if(loopCount++ > updateRate*2 && thrusterMap.size() < expectedThrusters)
            {
                init();
                loopCount = 0;
            }

            if(thrusterMap.size() == 0)
            {
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thrusters";
                status.hardware_id = "Thrusters";
                status.level = status.WARN;
                diag.status.push_back(status);
                ROS_WARN("No thrusters initialized");
            }
            else if(savedMsg.cmd.size() == 0)
            {
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thrusters";
                status.hardware_id = "Thrusters";
                status.level = status.WARN;
                diag.status.push_back(status);
                ROS_WARN("No comand message");
            }
            else if(thrusterMap.size() != savedMsg.cmd.size())
            {
                diagnostic_msgs::DiagnosticStatus status;
                status.name = "Thrusters";
                status.hardware_id = "Thrusters";
                status.level = status.ERROR;
                diag.status.push_back(status);
                ROS_ERROR("Thrusters command has wrong number of values");
            }
            else
            {
                for(auto& iter:thrusterMap)
                {
                    diagnostic_msgs::DiagnosticStatus status;
                    status.name = "Thruster_"+std::to_string(iter.first);
                    status.hardware_id = "Thruster_"+std::to_string(iter.first);
                    thrusterStatusMsg.thrusterChannel = iter.first;
                    try {
                        iter.second->updateStatus();
                        iter.second->setVelocityRatio(savedMsg.cmd.at(iter.first));
                        thrusterStatusMsg.thrusterOk = true;
                    } catch(I2CException e) {
                        //Publish an error message for the diagnostic system to do something about
                        status.level = status.ERROR;
                        thrusterStatusMsg.thrusterOk = false;
                    } catch (std::out_of_range e) {
                        ROS_ERROR("Thrusters command has not enough values");
                        thrusterStatusMsg.thrusterOk = false;
                    }

                    if (thrusterOk(iter.second) && status.level != status.ERROR)
                        status.level = status.OK;
                    else {
                        status.level = status.ERROR;
                        thrusterStatusMsg.thrusterOk = false;
                    }
                    PushDiagData(status, iter.second, std::to_string(iter.first));
                    diag.status.push_back(status);
                    thrusterStatusMsg.header.stamp = ros::Time::now();
                    status_output.publish(thrusterStatusMsg);
                }
            }

            diagnostics_output.publish(diag);
            ros::spinOnce();
            self_test_.checkTest();
            rate.sleep();
        }
    }

    bool thrusterOk (std::unique_ptr<GenericThruster> & thruster)
    {
        return thruster->isAlive() && thruster->inLimits();
    }

    void PushDiagData(diagnostic_msgs::DiagnosticStatus & statusmsg, std::unique_ptr<GenericThruster> & thruster, std::string thrusterName)
    {
        diagnostic_msgs::KeyValue thrusterValue;

        thrusterValue.key = "Thruster Type";
        thrusterValue.value = thruster->getType();
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Alive";
        thrusterValue.value = BoolToString(thruster->isAlive());
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Voltage";
        thrusterValue.value = std::to_string(thruster->getVoltage());
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Current";
        thrusterValue.value = std::to_string(thruster->getCurrent());
        statusmsg.values.push_back(thrusterValue);

        thrusterValue.key = thrusterName + " Temperature";
        thrusterValue.value = std::to_string(thruster->getTemperature());
        statusmsg.values.push_back(thrusterValue);
    }

    void thrusterCb(const sub_trajectory::ThrusterCmd &msg)
    {
        savedMsg = msg;
    }

    //Self test function
    void testThrusterConnections(diagnostic_updater::DiagnosticStatusWrapper& status)
    {
        self_test_.setID("thrusterController");
        std::stringstream failedThrusters;
        Json::Value& thrustersJson = loadConfig(configPath)["COMPUTE"];
        for(int i = 0; i < thrustersJson.size(); i++)
        {
            int thrusterID = thrustersJson[i]["ID"].asInt();
            int thrusterType = thrustersJson[i]["Type"].asInt(); //TODO: support for multiple thruster types
            int thrusterAddress = thrustersJson[i]["Address"].asInt();

            try{
                T200Thruster(1, thrusterAddress).updateStatus();
            }
            catch(I2CException e){
                failedThrusters << thrusterAddress << " ";
            }
        }

        if(failedThrusters.str().length() > 0){
            status.add("Failures", failedThrusters.str());
            status.summary(diagnostic_msgs::DiagnosticStatus::ERROR, "Thruster couldn't connect");
        } else {
            status.summary(diagnostic_msgs::DiagnosticStatus::OK, "All thrusters OK");
        }
    }
};

int main(int argc, char** argv)
{
    ros::init(argc, argv, "thruster_driver");
    ThrusterManager tc;
    tc.init();
    ROS_INFO("Thruster controller initialized, spinning");
    tc.spin();
    return 0;
}

inline const std::string BoolToString(const bool b)
{
  return b ? "true" : "false";
}
<|endoftext|>


<commit_before>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#pragma once
#include <appbase/application.hpp>
#include <eosio/http_plugin/http_plugin.hpp>

namespace eosio {

using namespace appbase;

class txn_test_gen_plugin : public appbase::plugin<txn_test_gen_plugin> {
public:
   txn_test_gen_plugin();
   ~txn_test_gen_plugin();

   APPBASE_PLUGIN_REQUIRES((http_plugin))
   virtual void set_program_options(options_description&, options_description& cfg) override;

   void plugin_initialize(const variables_map& options);
   void plugin_startup();
   void plugin_shutdown();

private:
   std::unique_ptr<struct txn_test_gen_plugin_impl> my;
};

}
<commit_msg>Add missing requires for chain_plugin<commit_after>/**
 *  @file
 *  @copyright defined in eos/LICENSE.txt
 */
#pragma once
#include <appbase/application.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>

namespace eosio {

using namespace appbase;

class txn_test_gen_plugin : public appbase::plugin<txn_test_gen_plugin> {
public:
   txn_test_gen_plugin();
   ~txn_test_gen_plugin();

   APPBASE_PLUGIN_REQUIRES((http_plugin)(chain_plugin))
   virtual void set_program_options(options_description&, options_description& cfg) override;

   void plugin_initialize(const variables_map& options);
   void plugin_startup();
   void plugin_shutdown();

private:
   std::unique_ptr<struct txn_test_gen_plugin_impl> my;
};

}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(EXSLT_DYNAMICIMPL_HEADER_GUARD_1357924680)
#define EXSLT_DYNAMICIMPL_HEADER_GUARD_1357924680

#include "XalanEXSLTDefinitions.hpp"

#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>

#include <xalanc/XPath/Function.hpp>

#include <xalanc/XalanExtensions/FunctionEvaluate.hpp>

XALAN_CPP_NAMESPACE_BEGIN

class XALAN_EXSLT_EXPORT XalanEXSLTFunctionEvaluate : public FunctionEvaluate
{
public:

	typedef FunctionEvaluate	ParentType;
#if !defined(XALAN_NO_USING_DECLARATION)
	using ParentType::execute;
#endif

	XalanEXSLTFunctionEvaluate() :
		FunctionEvaluate()
	{
	}

	virtual
	~XalanEXSLTFunctionEvaluate()
	{
	}

#if !defined(XALAN_NO_USING_DECLARATION)
	using ParentType::execute;
#endif

	virtual XObjectPtr
	execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const;

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
	virtual Function*
#else
	virtual XalanEXSLTFunctionEvaluate*
#endif
	clone() const
	{
		return new XalanEXSLTFunctionEvaluate(*this);
	}

protected:

	virtual const XalanDOMString
	getError() const
	{
		return XalanMessageLoader::getMessage(XalanMessages::EXSLTFunctionAcceptsOneArgument_1Param,"evaluate()");
	}

private:

	// Not implemented...
	XalanEXSLTFunctionEvaluate&
	operator=(const XalanEXSLTFunctionEvaluate&);

	bool
	operator==(const XalanEXSLTFunctionEvaluate&) const;
};

XALAN_CPP_NAMESPACE_END

#endif	// EXSLT_DYNAMICIMPL_HEADER_GUARD_1357924680
<commit_msg>Removed duplicate definition from bad merge.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 1999-2003 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#if !defined(EXSLT_DYNAMICIMPL_HEADER_GUARD_1357924680)
#define EXSLT_DYNAMICIMPL_HEADER_GUARD_1357924680

#include "XalanEXSLTDefinitions.hpp"

#include <xalanc/PlatformSupport/XalanMessageLoader.hpp>

#include <xalanc/XPath/Function.hpp>

#include <xalanc/XalanExtensions/FunctionEvaluate.hpp>

XALAN_CPP_NAMESPACE_BEGIN

class XALAN_EXSLT_EXPORT XalanEXSLTFunctionEvaluate : public FunctionEvaluate
{
public:

	typedef FunctionEvaluate	ParentType;

	XalanEXSLTFunctionEvaluate() :
		FunctionEvaluate()
	{
	}

	virtual
	~XalanEXSLTFunctionEvaluate()
	{
	}

#if !defined(XALAN_NO_USING_DECLARATION)
	using ParentType::execute;
#endif

	virtual XObjectPtr
	execute(
			XPathExecutionContext&			executionContext,
			XalanNode*						context,
			const XObjectArgVectorType&		args,
			const LocatorType*				locator) const;

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
	virtual Function*
#else
	virtual XalanEXSLTFunctionEvaluate*
#endif
	clone() const
	{
		return new XalanEXSLTFunctionEvaluate(*this);
	}

protected:

	virtual const XalanDOMString
	getError() const
	{
		return XalanMessageLoader::getMessage(XalanMessages::EXSLTFunctionAcceptsOneArgument_1Param,"evaluate()");
	}

private:

	// Not implemented...
	XalanEXSLTFunctionEvaluate&
	operator=(const XalanEXSLTFunctionEvaluate&);

	bool
	operator==(const XalanEXSLTFunctionEvaluate&) const;
};

XALAN_CPP_NAMESPACE_END

#endif	// EXSLT_DYNAMICIMPL_HEADER_GUARD_1357924680
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objectformattertxtfrm.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-02-03 17:18:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _OBJECTFORMATTERTXTFRM_HXX
#define _OBJECTFORMATTERTXTFRM_HXX

#ifndef _OBJECTFORMATTER_HXX
#include <objectformatter.hxx>
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

class SwTxtFrm;

// -----------------------------------------------------------------------------
// OD 2004-07-01 #i28701#
// Format floating screen objects, which are anchored at a given anchor text frame
// and registered at the given page frame.
// -----------------------------------------------------------------------------
class SwObjectFormatterTxtFrm : public SwObjectFormatter
{
    private:
        // anchor text frame
        SwTxtFrm& mrAnchorTxtFrm;

        // 'master' anchor text frame
        SwTxtFrm* mpMasterAnchorTxtFrm;

        SwObjectFormatterTxtFrm( SwTxtFrm& _rAnchorTxtFrm,
                                 const SwPageFrm& _rPageFrm,
                                 SwTxtFrm* _pMasterAnchorTxtFrm,
                                 SwLayAction* _pLayAction );

        /* method to invalidate objects, anchored previous to given object at
           the anchor text frame

            @param _rAnchoredObj
            reference to anchored object - objects, anchored previous to
            this one will be invalidated.

            @author OD
        */
        void _InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj );

        /* method to invalidate objects, anchored after the given object at
           the page frame

            @param _rAnchoredObj
            reference to anchored object - objects, anchored after this one will
            be invalidated.

            @param _bInclObj
            boolean indicates, if given anchored object <_rAnchoredObj> also have
            to be invalidated.

            @author OD
        */
        void _InvalidateFollowObjs( SwAnchoredObject& _rAnchoredObj,
                                    const bool _bInclObj );

        /** method to determine first anchored object, whose 'anchor is moved
            forward'.

            'anchor (of an object) is moved forward', if the anchor frame
            respectively the anchor character of the object isn't on the
            proposed page frame. Instead its on a following page
            OD 2004-10-04 #i26945# - For at-character anchored objects,
            it has also to be checked, if the anchor character is in a follow
            text frame, which would move to the next page.
            OD 2005-03-30 #i43913# - add output parameter <_boInFollow>

            @author OD

            @param _nWrapInfluenceOnPosition
            input parameter - only object with this given wrapping style
            influence are investigated.

            @param _nFromPageNum
            input parameter - number of page frame, the 'anchor' should be

            @param _noToPageNum
            output parameter - number of page frame, the 'anchor' of the returned
            anchored object is.

            @param _boInFollow
            output parameter - boolean, indicating that anchor text frame is
            currently on the same page, but it's a follow of in a follow row,
            which will move forward. value only relevant, if method returns
            an anchored object

            @return SwAnchoredObject*
            anchored object with a 'moved forward anchor'. If NULL, no such
            anchored object is found.
        */
        SwAnchoredObject* _GetFirstObjWithMovedFwdAnchor(
                                    const sal_Int16 _nWrapInfluenceOnPosition,
                                    sal_uInt32& _noToPageNum,
                                    bool& _boInFollow );

        /** method to format the anchor frame for checking of the move forward condition

            OD 2005-01-11 #i40141#

            @author OD
        */
        void _FormatAnchorFrmForCheckMoveFwd();

    protected:

        virtual SwFrm& GetAnchorFrm();

    public:
        virtual ~SwObjectFormatterTxtFrm();

        // --> OD 2005-01-10 #i40147# - add parameter <_bCheckForMovedFwd>.
        virtual bool DoFormatObj( SwAnchoredObject& _rAnchoredObj,
                                  const bool _bCheckForMovedFwd = false );
        // <--
        virtual bool DoFormatObjs();

        /** method to create an instance of <SwObjectFormatterTxtFrm> is
            necessary.

            @author OD
        */
        static SwObjectFormatterTxtFrm* CreateObjFormatter(
                                                SwTxtFrm& _rAnchorTxtFrm,
                                                const SwPageFrm& _rPageFrm,
                                                SwLayAction* _pLayAction );

        /** method to format given anchor text frame and its previous frames

            OD 2005-11-17 #i56300#
            Usage: Needed to check, if the anchor text frame is moved forward
            due to the positioning and wrapping of its anchored objects, and
            to format the frames, which have become invalid due to the anchored
            object formatting in the iterative object positioning algorithm

            @author OD

            @param _rAnchorTxtFrm
            input parameter - reference to anchor text frame, which has to be
            formatted including its previous frames of the page.
        */
        static void FormatAnchorFrmAndItsPrevs( SwTxtFrm& _rAnchorTxtFrm );

        /** method to check the conditions, if 'anchor is moved forward'

            OD 2004-10-11 #i26945#
            OD 2005-03-30 #i43913# - add output parameter <_boInFollow>
            OD 2006-01-27 #i58182# - replace method by a corresponding static
            method, because it's needed for the iterative positioning algorithm.

            @author OD

            @param _rAnchoredObj
            input parameter - anchored object, for which the condition has to checked.

            @param _nFromPageNum
            input parameter - number of the page, on which the check is performed

            @param _bAnchoredAtMasterBeforeFormatAnchor
            input parameter - boolean indicating, that the given anchored object
            was anchored at the master frame before the anchor frame has been
            formatted.

            @param _noToPageNum
            output parameter - number of page frame, the 'anchor' of the returned
            anchored object is.

            @param _boInFollow
            output parameter - boolean, indicating that anchor text frame is
            currently on the same page, but it's a follow of in a follow row,
            which will move forward. value only relevant, if method return <true>.

            @return boolean
            indicating, if 'anchor is moved forward'
        */
        static bool CheckMovedFwdCondition( SwAnchoredObject& _rAnchoredObj,
                                            const sal_uInt32 _nFromPageNum,
                                            const bool _bAnchoredAtMasterBeforeFormatAnchor,
                                            sal_uInt32& _noToPageNum,
                                            bool& _boInFollow );
};

#endif
<commit_msg>INTEGRATION: CWS swqbf75 (1.8.252); FILE MERGED 2006/07/24 11:50:11 od 1.8.252.1: #b6449874# - adjust consideration of anchored objects, whose wrapping 	     style influence is temporarly considered, for formatting 	     of anchor frame for checking move forward condition.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: objectformattertxtfrm.hxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: rt $ $Date: 2006-07-26 08:17:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _OBJECTFORMATTERTXTFRM_HXX
#define _OBJECTFORMATTERTXTFRM_HXX

#ifndef _OBJECTFORMATTER_HXX
#include <objectformatter.hxx>
#endif
#ifndef _SAL_TYPES_H_
#include <sal/types.h>
#endif

class SwTxtFrm;

// -----------------------------------------------------------------------------
// OD 2004-07-01 #i28701#
// Format floating screen objects, which are anchored at a given anchor text frame
// and registered at the given page frame.
// -----------------------------------------------------------------------------
class SwObjectFormatterTxtFrm : public SwObjectFormatter
{
    private:
        // anchor text frame
        SwTxtFrm& mrAnchorTxtFrm;

        // 'master' anchor text frame
        SwTxtFrm* mpMasterAnchorTxtFrm;

        SwObjectFormatterTxtFrm( SwTxtFrm& _rAnchorTxtFrm,
                                 const SwPageFrm& _rPageFrm,
                                 SwTxtFrm* _pMasterAnchorTxtFrm,
                                 SwLayAction* _pLayAction );

        /* method to invalidate objects, anchored previous to given object at
           the anchor text frame

            @param _rAnchoredObj
            reference to anchored object - objects, anchored previous to
            this one will be invalidated.

            @author OD
        */
        void _InvalidatePrevObjs( SwAnchoredObject& _rAnchoredObj );

        /* method to invalidate objects, anchored after the given object at
           the page frame

            @param _rAnchoredObj
            reference to anchored object - objects, anchored after this one will
            be invalidated.

            @param _bInclObj
            boolean indicates, if given anchored object <_rAnchoredObj> also have
            to be invalidated.

            @author OD
        */
        void _InvalidateFollowObjs( SwAnchoredObject& _rAnchoredObj,
                                    const bool _bInclObj );

        /** method to determine first anchored object, whose 'anchor is moved
            forward'.

            'anchor (of an object) is moved forward', if the anchor frame
            respectively the anchor character of the object isn't on the
            proposed page frame. Instead its on a following page
            OD 2004-10-04 #i26945# - For at-character anchored objects,
            it has also to be checked, if the anchor character is in a follow
            text frame, which would move to the next page.
            OD 2005-03-30 #i43913# - add output parameter <_boInFollow>

            @author OD

            @param _nWrapInfluenceOnPosition
            input parameter - only object with this given wrapping style
            influence are investigated.

            @param _nFromPageNum
            input parameter - number of page frame, the 'anchor' should be

            @param _noToPageNum
            output parameter - number of page frame, the 'anchor' of the returned
            anchored object is.

            @param _boInFollow
            output parameter - boolean, indicating that anchor text frame is
            currently on the same page, but it's a follow of in a follow row,
            which will move forward. value only relevant, if method returns
            an anchored object

            @return SwAnchoredObject*
            anchored object with a 'moved forward anchor'. If NULL, no such
            anchored object is found.
        */
        SwAnchoredObject* _GetFirstObjWithMovedFwdAnchor(
                                    const sal_Int16 _nWrapInfluenceOnPosition,
                                    sal_uInt32& _noToPageNum,
                                    bool& _boInFollow );

        /** method to format the anchor frame for checking of the move forward condition

            OD 2005-01-11 #i40141#

            @author OD
        */
        void _FormatAnchorFrmForCheckMoveFwd();

        /** method to determine if at least one anchored object has state
            <temporarly consider wrapping style influence> set.

            OD 2006-07-24 #b6449874#

            @author OD
        */
        bool _AtLeastOneObjIsTmpConsiderWrapInfluence();

    protected:

        virtual SwFrm& GetAnchorFrm();

    public:
        virtual ~SwObjectFormatterTxtFrm();

        // --> OD 2005-01-10 #i40147# - add parameter <_bCheckForMovedFwd>.
        virtual bool DoFormatObj( SwAnchoredObject& _rAnchoredObj,
                                  const bool _bCheckForMovedFwd = false );
        // <--
        virtual bool DoFormatObjs();

        /** method to create an instance of <SwObjectFormatterTxtFrm> is
            necessary.

            @author OD
        */
        static SwObjectFormatterTxtFrm* CreateObjFormatter(
                                                SwTxtFrm& _rAnchorTxtFrm,
                                                const SwPageFrm& _rPageFrm,
                                                SwLayAction* _pLayAction );

        /** method to format given anchor text frame and its previous frames

            OD 2005-11-17 #i56300#
            Usage: Needed to check, if the anchor text frame is moved forward
            due to the positioning and wrapping of its anchored objects, and
            to format the frames, which have become invalid due to the anchored
            object formatting in the iterative object positioning algorithm

            @author OD

            @param _rAnchorTxtFrm
            input parameter - reference to anchor text frame, which has to be
            formatted including its previous frames of the page.
        */
        static void FormatAnchorFrmAndItsPrevs( SwTxtFrm& _rAnchorTxtFrm );

        /** method to check the conditions, if 'anchor is moved forward'

            OD 2004-10-11 #i26945#
            OD 2005-03-30 #i43913# - add output parameter <_boInFollow>
            OD 2006-01-27 #i58182# - replace method by a corresponding static
            method, because it's needed for the iterative positioning algorithm.

            @author OD

            @param _rAnchoredObj
            input parameter - anchored object, for which the condition has to checked.

            @param _nFromPageNum
            input parameter - number of the page, on which the check is performed

            @param _bAnchoredAtMasterBeforeFormatAnchor
            input parameter - boolean indicating, that the given anchored object
            was anchored at the master frame before the anchor frame has been
            formatted.

            @param _noToPageNum
            output parameter - number of page frame, the 'anchor' of the returned
            anchored object is.

            @param _boInFollow
            output parameter - boolean, indicating that anchor text frame is
            currently on the same page, but it's a follow of in a follow row,
            which will move forward. value only relevant, if method return <true>.

            @return boolean
            indicating, if 'anchor is moved forward'
        */
        static bool CheckMovedFwdCondition( SwAnchoredObject& _rAnchoredObj,
                                            const sal_uInt32 _nFromPageNum,
                                            const bool _bAnchoredAtMasterBeforeFormatAnchor,
                                            sal_uInt32& _noToPageNum,
                                            bool& _boInFollow );
};

#endif
<|endoftext|>


<commit_before>// Test the behavior of malloc/calloc/realloc when the allocation causes OOM
// in the secondary allocator.
// By default (allocator_may_return_null=0) the process should crash.
// With allocator_may_return_null=1 the allocator should return 0.
// Set the limit to 20.5T on 64 bits to account for ASan shadow memory,
// allocator buffers etc. so that the test allocation of ~1T will trigger OOM.
// Limit this test to Linux since we're relying on allocator internal
// limits (shadow memory size, allocation limits etc.)

// RUN: %clangxx_asan -O0 %s -o %t
// RUN: ulimit -v 22024290304
// RUN: not %run %t malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-NULL
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t calloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-NULL
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t realloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-NULL
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t realloc-after-malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-NULL

// ASan shadow memory on s390 is too large for this test.
// TODO(alekseys): Android lit do not run ulimit on device.
// UNSUPPORTED: s390,android

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

int main(int argc, char **argv) {
  assert(argc == 2);
  const char *action = argv[1];
  fprintf(stderr, "%s:\n", action);

  // Allocate just a bit less than max allocation size enforced by ASan's
  // allocator (currently 1T and 3G).
  const size_t size =
#if __LP64__
      (1ULL << 40) - (1ULL << 30);
#else
      (3ULL << 30) - (1ULL << 20);
#endif

  void *x = 0;

  if (!strcmp(action, "malloc")) {
    x = malloc(size);
  } else if (!strcmp(action, "calloc")) {
    x = calloc(size / 4, 4);
  } else if (!strcmp(action, "realloc")) {
    x = realloc(0, size);
  } else if (!strcmp(action, "realloc-after-malloc")) {
    char *t = (char*)malloc(100);
    *t = 42;
    x = realloc(t, size);
    assert(*t == 42);
    free(t);
  } else {
    assert(0);
  }

  // The NULL pointer is printed differently on different systems, while (long)0
  // is always the same.
  fprintf(stderr, "x: %lx\n", (long)x);
  free(x);

  return x != 0;
}

// CHECK-MALLOC: malloc:
// CHECK-CALLOC: calloc:
// CHECK-REALLOC: realloc:
// CHECK-MALLOC-REALLOC: realloc-after-malloc:

// CHECK-CRASH: AddressSanitizer's allocator is terminating the process
// CHECK-NULL: x: 0
<commit_msg>Mark allocator_oom_test.cc unsupported on arm & aarch64 (PR33972)<commit_after>// Test the behavior of malloc/calloc/realloc when the allocation causes OOM
// in the secondary allocator.
// By default (allocator_may_return_null=0) the process should crash.
// With allocator_may_return_null=1 the allocator should return 0.
// Set the limit to 20.5T on 64 bits to account for ASan shadow memory,
// allocator buffers etc. so that the test allocation of ~1T will trigger OOM.
// Limit this test to Linux since we're relying on allocator internal
// limits (shadow memory size, allocation limits etc.)

// RUN: %clangxx_asan -O0 %s -o %t
// RUN: ulimit -v 22024290304
// RUN: not %run %t malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC,CHECK-NULL
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t calloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-CALLOC,CHECK-NULL
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t realloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-REALLOC,CHECK-NULL
// RUN: %env_asan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-CRASH
// RUN: %env_asan_opts=allocator_may_return_null=1     %run %t realloc-after-malloc 2>&1 \
// RUN:   | FileCheck %s --check-prefixes=CHECK-MALLOC-REALLOC,CHECK-NULL

// ASan shadow memory on s390 is too large for this test.
// AArch64 bots fail on this test.
// TODO(alekseys): Android lit do not run ulimit on device.
// UNSUPPORTED: s390,android,arm,aarch64

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>

int main(int argc, char **argv) {
  assert(argc == 2);
  const char *action = argv[1];
  fprintf(stderr, "%s:\n", action);

  // Allocate just a bit less than max allocation size enforced by ASan's
  // allocator (currently 1T and 3G).
  const size_t size =
#if __LP64__
      (1ULL << 40) - (1ULL << 30);
#else
      (3ULL << 30) - (1ULL << 20);
#endif

  void *x = 0;

  if (!strcmp(action, "malloc")) {
    x = malloc(size);
  } else if (!strcmp(action, "calloc")) {
    x = calloc(size / 4, 4);
  } else if (!strcmp(action, "realloc")) {
    x = realloc(0, size);
  } else if (!strcmp(action, "realloc-after-malloc")) {
    char *t = (char*)malloc(100);
    *t = 42;
    x = realloc(t, size);
    assert(*t == 42);
    free(t);
  } else {
    assert(0);
  }

  // The NULL pointer is printed differently on different systems, while (long)0
  // is always the same.
  fprintf(stderr, "x: %lx\n", (long)x);
  free(x);

  return x != 0;
}

// CHECK-MALLOC: malloc:
// CHECK-CALLOC: calloc:
// CHECK-REALLOC: realloc:
// CHECK-MALLOC-REALLOC: realloc-after-malloc:

// CHECK-CRASH: AddressSanitizer's allocator is terminating the process
// CHECK-NULL: x: 0
<|endoftext|>


<commit_before>/*
 * PlaceCityHallComponent.cpp
 *
 *  Created on: Feb 5, 2012
 *      Author: xyborn
 */

#include "PlaceCityHallComponent.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/tangible/deed/Deed.h"
#include "server/zone/objects/player/sui/inputbox/SuiInputBox.h"
#include "server/zone/objects/region/CityRegion.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/structure/StructureObject.h"
#include "server/zone/objects/building/BuildingObject.h"
#include "server/zone/objects/player/sui/callbacks/PlaceCityHallSuiCallback.h"
#include "server/zone/objects/area/ActiveArea.h"

int PlaceCityHallComponent::placeStructure(StructureDeed* deed, CreatureObject* creature, float x, float y, int angle) {
	PlayerObject* ghost = creature->getPlayerObject();

	if (ghost == NULL)
		return 1;

	ManagedReference<BuildingObject*> declaredResidence = ghost->getDeclaredResidence();

	if (declaredResidence != NULL) {
		ManagedReference<CityRegion*> city = declaredResidence->getCityRegion();

		if (city != NULL && city->isMayor(creature->getObjectID())) {
			creature->sendSystemMessage("@city/city:already_mayor"); //You are already the mayor of a city.  You may not be mayor of another city.
			return 1;
		}
	}

	ManagedReference<SuiInputBox*> inputBox = new SuiInputBox(creature, SuiWindowType::CITY_CREATE, 0);
	inputBox->setPromptTitle("@city/city:city_name_t"); //Enter City Name
	inputBox->setPromptText("@city/city:city_name_d"); //Enter the desired name for your new city. Note that you must have at least 10 citizens join your city within 24 hours of placement in order for your city to be approved.
	inputBox->setForceCloseDisabled();
	inputBox->setCallback(new PlaceCityHallSuiCallback(creature->getZone(), deed, x, y, angle));

	ghost->addSuiBox(inputBox);
	creature->sendMessage(inputBox->generateMessage());

	return 0;
}

int PlaceCityHallComponent::notifyStructurePlaced(StructureDeed* deed, CreatureObject* creature, StructureObject* structure) {
	PlaceStructureComponent::notifyStructurePlaced(deed, creature, structure);

	PlayerObject* ghost = creature->getPlayerObject();

	if (ghost != NULL && structure->isBuildingObject()) {
		ghost->setDeclaredResidence(((BuildingObject*) structure));
		//We also need to add him to the citizens...

		ManagedReference<CityRegion*> city = structure->getCityRegion();

		if (city != NULL && city->isMayor(creature->getObjectID())) {
			city->addCitizen(creature->getObjectID());
			city->setCityHall(structure);
		}
	}

	return 0;
}
<commit_msg>[fixed] stability issues<commit_after>/*
 * PlaceCityHallComponent.cpp
 *
 *  Created on: Feb 5, 2012
 *      Author: xyborn
 */

#include "PlaceCityHallComponent.h"
#include "server/zone/objects/creature/CreatureObject.h"
#include "server/zone/objects/tangible/deed/Deed.h"
#include "server/zone/objects/player/sui/inputbox/SuiInputBox.h"
#include "server/zone/objects/region/CityRegion.h"
#include "server/zone/objects/player/PlayerObject.h"
#include "server/zone/objects/structure/StructureObject.h"
#include "server/zone/objects/building/BuildingObject.h"
#include "server/zone/objects/player/sui/callbacks/PlaceCityHallSuiCallback.h"
#include "server/zone/objects/area/ActiveArea.h"

int PlaceCityHallComponent::placeStructure(StructureDeed* deed, CreatureObject* creature, float x, float y, int angle) {
	PlayerObject* ghost = creature->getPlayerObject();

	if (ghost == NULL)
		return 1;

	Zone* zone = creature->getZone();

	if (zone == NULL)
		return 1;

	ManagedReference<BuildingObject*> declaredResidence = ghost->getDeclaredResidence();

	if (declaredResidence != NULL) {
		ManagedReference<CityRegion*> city = declaredResidence->getCityRegion();

		if (city != NULL && city->isMayor(creature->getObjectID())) {
			creature->sendSystemMessage("@city/city:already_mayor"); //You are already the mayor of a city.  You may not be mayor of another city.
			return 1;
		}
	}

	ManagedReference<SuiInputBox*> inputBox = new SuiInputBox(creature, SuiWindowType::CITY_CREATE, 0);
	inputBox->setPromptTitle("@city/city:city_name_t"); //Enter City Name
	inputBox->setPromptText("@city/city:city_name_d"); //Enter the desired name for your new city. Note that you must have at least 10 citizens join your city within 24 hours of placement in order for your city to be approved.
	inputBox->setForceCloseDisabled();
	inputBox->setCallback(new PlaceCityHallSuiCallback(creature->getZone(), deed, x, y, angle));

	ghost->addSuiBox(inputBox);
	creature->sendMessage(inputBox->generateMessage());

	return 0;
}

int PlaceCityHallComponent::notifyStructurePlaced(StructureDeed* deed, CreatureObject* creature, StructureObject* structure) {
	PlaceStructureComponent::notifyStructurePlaced(deed, creature, structure);

	PlayerObject* ghost = creature->getPlayerObject();

	if (ghost != NULL && structure->isBuildingObject()) {
		ghost->setDeclaredResidence(((BuildingObject*) structure));
		//We also need to add him to the citizens...

		ManagedReference<CityRegion*> city = structure->getCityRegion();

		if (city != NULL && city->isMayor(creature->getObjectID())) {
			city->addCitizen(creature->getObjectID());
			city->setCityHall(structure);
		}
	}

	return 0;
}
<|endoftext|>