<commit_before>/************************************************
 *  gen.hpp
 *  ESA++
 *
 *  Copyright (c) 2014, Chi-En Wu
 *  Distributed under The BSD 3-Clause License
 ************************************************/

#ifndef ESAPP_GEN_HPP_
#define ESAPP_GEN_HPP_

#include <iterator>
#include <type_traits>
#include <utility>

namespace esapp
{

/************************************************
 * Declaration: class generator_iterator
 ************************************************/

template <typename I, typename G>
class generator_iterator
    : public std::iterator<std::input_iterator_tag,
                           typename std::result_of<G(I &, I const &)>::type>
{
private: // Private Type(s)
    typedef std::iterator<
        std::input_iterator_tag,
        typename std::result_of<G(I &, I const &)>::type
    > base;

public: // Public Type(s)
    typedef typename base::iterator_category iterator_category;
    typedef typename base::value_type value_type;
    typedef typename base::reference reference;
    typedef typename base::pointer pointer;
    typedef typename base::difference_type difference_type;

    typedef I iterator;
    typedef G generator;

public: // Public Method(s)
    generator_iterator(iterator const &begin, iterator const &end,
                       generator const &g);
    template <typename Initializer>
    generator_iterator(iterator const &begin, iterator const &end,
                       generator const &g, Initializer const &init);
    generator_iterator(generator_iterator const &g);

    generator_iterator begin(void) const;
    generator_iterator end(void) const;

    generator_iterator &operator++(void);
    generator_iterator operator++(int);
    value_type &operator*(void);
    value_type *operator->(void) const;
    bool operator==(generator_iterator const &it) const;
    bool operator!=(generator_iterator const &it) const;

private: // Private Property(ies)
    iterator begin_, end_;
    generator g_;
    value_type val_;
    bool has_val_;
}; // class generator_iterator

/************************************************
 * Implementation: class generator_iterator
 ************************************************/

template <typename I, typename G>
inline generator_iterator<I, G>::generator_iterator(iterator const &begin,
                                                    iterator const &end,
                                                    generator const &g)
    : begin_(begin), end_(end), g_(g), has_val_(false)
{
    // do nothing
}

template <typename I, typename G>
template <typename Initializer>
inline generator_iterator<I, G>::generator_iterator(iterator const &begin,
                                                    iterator const &end,
                                                    generator const &g,
                                                    Initializer const &init)
    : begin_(begin), end_(end), g_(g), has_val_(false)
{
    init(begin_, end_);
}

template <typename I, typename G>
inline generator_iterator<I, G>::generator_iterator(generator_iterator const &g)
    : generator_iterator(g.begin_, g.end_, g.g_)
{
    // do nothing
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator
generator_iterator<I, G>::begin(void) const
{
    return *this;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator
generator_iterator<I, G>::end(void) const
{
    return generator_iterator(end_, end_, g_);
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator &
generator_iterator<I, G>::operator++(void)
{
    has_val_ = false;
    return *this;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator
generator_iterator<I, G>::operator++(int)
{
    generator_iterator it(*this);
    operator++();
    return it;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::value_type &
generator_iterator<I, G>::operator*(void)
{
    if (!has_val_) { val_ = g_(begin_, end_); }

    has_val_ = true;
    return val_;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::value_type *
generator_iterator<I, G>::operator->(void) const
{
    return &val_;
}

template <typename I, typename G>
inline bool generator_iterator<I, G>::operator==(generator_iterator const &it) const
{
    return begin_ == it.begin_ && end_ == it.end_;
}

template <typename I, typename G>
inline bool generator_iterator<I, G>::operator!=(generator_iterator const &it) const
{
    return !(*this == it);
}

} // namespace esapp

#endif // ESAPP_GEN_HPP_
<commit_msg>Correct generator_iterator<commit_after>/************************************************
 *  gen.hpp
 *  ESA++
 *
 *  Copyright (c) 2014, Chi-En Wu
 *  Distributed under The BSD 3-Clause License
 ************************************************/

#ifndef ESAPP_GEN_HPP_
#define ESAPP_GEN_HPP_

#include <iterator>
#include <type_traits>

namespace esapp
{

/************************************************
 * Declaration: class generator_iterator
 ************************************************/

template <typename I, typename G>
class generator_iterator
    : public std::iterator<std::input_iterator_tag,
                           typename std::result_of<G(I &, I const &)>::type>
{
private: // Private Type(s)
    typedef std::iterator<
        std::input_iterator_tag,
        typename std::result_of<G(I &, I const &)>::type
    > base;

public: // Public Type(s)
    typedef typename base::iterator_category iterator_category;
    typedef typename base::value_type value_type;
    typedef typename base::reference reference;
    typedef typename base::pointer pointer;
    typedef typename base::difference_type difference_type;

    typedef I iterator;
    typedef G generator;

public: // Public Method(s)
    generator_iterator(iterator const &begin, iterator const &end,
                       generator const &g);
    template <typename Initializer>
    generator_iterator(iterator const &begin, iterator const &end,
                       generator const &g, Initializer const &init);
    generator_iterator(generator_iterator const &it);

    generator_iterator begin(void) const;
    generator_iterator end(void) const;

    generator_iterator &operator++(void);
    generator_iterator operator++(int);
    value_type &operator*(void);
    value_type *operator->(void) const;
    bool operator==(generator_iterator const &it) const;
    bool operator!=(generator_iterator const &it) const;

private: // Private Property(ies)
    iterator begin_, end_;
    generator g_;
    value_type val_;
    bool has_val_;
}; // class generator_iterator

/************************************************
 * Implementation: class generator_iterator
 ************************************************/

template <typename I, typename G>
inline generator_iterator<I, G>::generator_iterator(iterator const &begin,
                                                    iterator const &end,
                                                    generator const &g)
    : begin_(begin), end_(end), g_(g)
{
    operator++();
}

template <typename I, typename G>
template <typename Initializer>
inline generator_iterator<I, G>::generator_iterator(iterator const &begin,
                                                    iterator const &end,
                                                    generator const &g,
                                                    Initializer const &init)
    : begin_(begin), end_(end), g_(g)
{
    init(begin_, end_);
    operator++();
}

template <typename I, typename G>
inline generator_iterator<I, G>::generator_iterator(generator_iterator const &it)
    : begin_(it.begin_), end_(it.end_), g_(it.g_),
      val_(it.val_), has_val_(it.has_val_)
{
    // do nothing
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator
generator_iterator<I, G>::begin(void) const
{
    return *this;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator
generator_iterator<I, G>::end(void) const
{
    return generator_iterator(end_, end_, g_);
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator &
generator_iterator<I, G>::operator++(void)
{
    has_val_ = begin_ != end_;
    val_ = has_val_ ? g_(begin_, end_) : decltype(val_)();

    return *this;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::generator_iterator
generator_iterator<I, G>::operator++(int)
{
    generator_iterator it(*this);
    operator++();
    return it;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::value_type &
generator_iterator<I, G>::operator*(void)
{
    return val_;
}

template <typename I, typename G>
inline typename generator_iterator<I, G>::value_type *
generator_iterator<I, G>::operator->(void) const
{
    return &val_;
}

template <typename I, typename G>
inline bool generator_iterator<I, G>::operator==(generator_iterator const &it) const
{
    return begin_ == it.begin_ && end_ == it.end_ && g_ == it.g_ &&
           val_ == it.val_ && has_val_ == it.has_val_;
}

template <typename I, typename G>
inline bool generator_iterator<I, G>::operator!=(generator_iterator const &it) const
{
    return !(*this == it);
}

} // namespace esapp

#endif // ESAPP_GEN_HPP_
<|endoftext|>


<commit_before>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
**********************************/

#include "FrameBuffer.h"
#include "TextureBinding.h"
#include "Material.h"

namespace n {
namespace graphics {

FrameBuffer::~FrameBuffer() {
	if(isActive()) {
		unbind();
	}
	gl::glDeleteFramebuffers(1, &handle);
	delete depth;
	delete[] drawBuffers;
	delete[] attachments;
}

bool FrameBuffer::isDepthEnabled() const {
	return depth;
}

bool FrameBuffer::isAttachmentEnabled(uint slot) const {
	return slot == Depth ? isDepthEnabled() : drawBuffers[slot] != GL_NONE;
}

void FrameBuffer::setup() {
	gl::glGenFramebuffers(1, &handle);
	bind();
	uint att = getMaxAttachment();
	for(uint i = 0; i != att; i++) {
		if(isAttachmentEnabled(i)) {
			attachments[i].prepare(true);
			gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, attachments[i].getHandle(), 0);
			if(!attachments[i].getHandle()) {
				fatal("Unable to create attachement.");
			}
		} else {
			gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
		}
	}
	if(depth) {
		depth->prepare(true);
		gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,  depth->getHandle(), 0);
	} else {
		gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,  0, 0);
	}
	gl::glDrawBuffers(att, drawBuffers);
	internal::TextureBinding::dirty();

	if(gl::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
		switch(gl::glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
			case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
				fatal("Unable to modify frame-buffer-object : missing attachment.");
			break;
			case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
				fatal("Unable to modify frame-buffer-object : incomplete attachment.");
			break;
			case GL_FRAMEBUFFER_UNSUPPORTED:
				fatal("Unable to modify frame-buffer-object : unsuported feature.");
			break;
			default:
				fatal("Unable to modify frame-buffer-object.");
			break;
		}
	}
}

bool FrameBuffer::isActive() const {
	return GLContext::getContext()->frameBuffer == this;
}

void FrameBuffer::bind() const {
	if(GLContext::getContext()->frameBuffer != this) {
		gl::glBindFramebuffer(GL_FRAMEBUFFER, handle);
		math::Vec2ui vp = GLContext::getContext()->getViewport();
		GLContext::getContext()->frameBuffer = this;
		if(vp != base) {
			gl::glViewport(0, 0, base.x(), base.y());
		}
	}
}

void FrameBuffer::unbind() {
	if(GLContext::getContext()->frameBuffer) {
		gl::glBindFramebuffer(GL_FRAMEBUFFER, 0);
		const FrameBuffer *fb = GLContext::getContext()->frameBuffer;
		GLContext::getContext()->frameBuffer = 0;
		if(GLContext::getContext()->getViewport() != fb->getSize()) {
			gl::glViewport(0, 0, GLContext::getContext()->getViewport().x(), GLContext::getContext()->getViewport().y());
		}
	}
}

void FrameBuffer::clear(bool color, bool depth) {
	gl::GLbitfield bits = (color ? GL_COLOR_BUFFER_BIT : 0) | (depth ? GL_DEPTH_BUFFER_BIT : 0);
	Material().bind(RenderFlag::DepthWriteOnly);
	gl::glClear(bits);
}

void FrameBuffer::blit(uint slot, bool depth) const {
	if(GLContext::getContext()->frameBuffer != this) {
		gl::glBindFramebuffer(GL_READ_FRAMEBUFFER, handle);
	}
	depth |= slot == Depth;
	bool color = slot != Depth;
	if(color) {
		static uint readBuffer = 0;
		if(slot != readBuffer) {
			gl::glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
			readBuffer = slot;
		}
	}
	gl::GLbitfield bits = (color ? GL_COLOR_BUFFER_BIT : 0) | (depth ? GL_DEPTH_BUFFER_BIT : 0);
	Material().bind(RenderFlag::DepthWriteOnly);
	gl::glBlitFramebuffer(0, 0, getSize().x(), getSize().y(), 0, 0, GLContext::getContext()->getViewport().x(), GLContext::getContext()->getViewport().y(), bits, GL_NEAREST);
}

}
}
<commit_msg>Fixed framebuffer state leaking issues.<commit_after>/*******************************
Copyright (C) 2013-2015 gregoire ANGERAND

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
**********************************/

#include "FrameBuffer.h"
#include "TextureBinding.h"
#include "Material.h"

namespace n {
namespace graphics {

FrameBuffer::~FrameBuffer() {
	if(isActive()) {
		unbind();
	}
	gl::glDeleteFramebuffers(1, &handle);
	delete depth;
	delete[] drawBuffers;
	delete[] attachments;
}

bool FrameBuffer::isDepthEnabled() const {
	return depth;
}

bool FrameBuffer::isAttachmentEnabled(uint slot) const {
	return slot == Depth ? isDepthEnabled() : drawBuffers[slot] != GL_NONE;
}

void FrameBuffer::setup() {
	const FrameBuffer *fb = GLContext::getContext()->frameBuffer;
	gl::glGenFramebuffers(1, &handle);
	bind();
	uint att = getMaxAttachment();
	for(uint i = 0; i != att; i++) {
		if(isAttachmentEnabled(i)) {
			attachments[i].prepare(true);
			gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, attachments[i].getHandle(), 0);
			if(!attachments[i].getHandle()) {
				fatal("Unable to create attachement.");
			}
		} else {
			gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i, GL_TEXTURE_2D, 0, 0);
		}
	}
	if(depth) {
		depth->prepare(true);
		gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,  depth->getHandle(), 0);
	} else {
		gl::glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,  0, 0);
	}
	gl::glDrawBuffers(att, drawBuffers);
	internal::TextureBinding::dirty();

	if(gl::glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
		switch(gl::glCheckFramebufferStatus(GL_FRAMEBUFFER)) {
			case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
				fatal("Unable to modify frame-buffer-object : missing attachment.");
			break;
			case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
				fatal("Unable to modify frame-buffer-object : incomplete attachment.");
			break;
			case GL_FRAMEBUFFER_UNSUPPORTED:
				fatal("Unable to modify frame-buffer-object : unsuported feature.");
			break;
			default:
				fatal("Unable to modify frame-buffer-object.");
			break;
		}
	}
	if(fb) {
		fb->bind();
	} else {
		FrameBuffer::unbind();
	}
}

bool FrameBuffer::isActive() const {
	return GLContext::getContext()->frameBuffer == this;
}

void FrameBuffer::bind() const {
	if(GLContext::getContext()->frameBuffer != this) {
		gl::glBindFramebuffer(GL_FRAMEBUFFER, handle);
		math::Vec2ui vp = GLContext::getContext()->getViewport();
		GLContext::getContext()->frameBuffer = this;
		if(vp != base) {
			gl::glViewport(0, 0, base.x(), base.y());
		}
	}
}

void FrameBuffer::unbind() {
	if(GLContext::getContext()->frameBuffer) {
		gl::glBindFramebuffer(GL_FRAMEBUFFER, 0);
		const FrameBuffer *fb = GLContext::getContext()->frameBuffer;
		GLContext::getContext()->frameBuffer = 0;
		if(GLContext::getContext()->getViewport() != fb->getSize()) {
			gl::glViewport(0, 0, GLContext::getContext()->getViewport().x(), GLContext::getContext()->getViewport().y());
		}
	}
}

void FrameBuffer::clear(bool color, bool depth) {
	gl::GLbitfield bits = (color ? GL_COLOR_BUFFER_BIT : 0) | (depth ? GL_DEPTH_BUFFER_BIT : 0);
	Material().bind(RenderFlag::DepthWriteOnly);
	gl::glClear(bits);
}

void FrameBuffer::blit(uint slot, bool depth) const {
	if(GLContext::getContext()->frameBuffer != this) {
		gl::glBindFramebuffer(GL_READ_FRAMEBUFFER, handle);
	}
	depth |= slot == Depth;
	bool color = slot != Depth;
	if(color) {
		static uint readBuffer = 0;
		if(slot != readBuffer) {
			gl::glReadBuffer(GL_COLOR_ATTACHMENT0 + slot);
			readBuffer = slot;
		}
	}
	gl::GLbitfield bits = (color ? GL_COLOR_BUFFER_BIT : 0) | (depth ? GL_DEPTH_BUFFER_BIT : 0);
	Material().bind(RenderFlag::DepthWriteOnly);
	gl::glBlitFramebuffer(0, 0, getSize().x(), getSize().y(), 0, 0, GLContext::getContext()->getViewport().x(), GLContext::getContext()->getViewport().y(), bits, GL_NEAREST);
}

}
}
<|endoftext|>


<commit_before>void min_index_avx512f(int32_t* array, size_t size, size_t* result) {

    common_assertions;

    const __m512i increment = _mm512_set1_epi32(16);
    __m512i indices         = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    __m512i minindices      = indices;
    __m512i minvalues       = _mm512_loadu_si512((__m512i*)array);

    for (size_t i=16; i < size; i += 16) {

        indices = _mm512_add_epi32(indices, increment);

        const __m512i values        = _mm512_loadu_si512((__m512i*)(array + i));
        const __mmask16 lt          = _mm512_cmplt_epi32_mask(values, minvalues);
        minindices = _mm512_mask_blend_epi32(lt, minindices, indices);
        minvalues  = _mm512_mask_blend_epi32(lt, minvalues, values);
    }

    // find min index in vector result (in an extremely naive way)
    int32_t values_array[16];
    uint32_t indices_array[16];

    _mm512_storeu_si512((__m512i*)values_array, minvalues);
    _mm512_storeu_si512((__m512i*)indices_array, minindices);

    size_t  minindex = indices_array[0];
    int32_t minvalue = values_array[0];
    for (int i=1; i < 16; i++) {
        if (values_array[i] < minvalue) {
            minvalue = values_array[i];
            minindex = indices_array[i];
        } else if (values_array[i] == minvalue) {
            minindex = std::min(minindex, size_t(indices_array[i]));
        }
    }

    *result = minindex;
}
<commit_msg>Use min instead of masked move -- it's faster<commit_after>void min_index_avx512f(int32_t* array, size_t size, size_t* result) {

    common_assertions;

    const __m512i increment = _mm512_set1_epi32(16);
    __m512i indices         = _mm512_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
    __m512i minindices      = indices;
    __m512i minvalues       = _mm512_loadu_si512((__m512i*)array);

    for (size_t i=16; i < size; i += 16) {

        indices = _mm512_add_epi32(indices, increment);

        const __m512i values        = _mm512_loadu_si512((__m512i*)(array + i));
        const __mmask16 lt          = _mm512_cmplt_epi32_mask(values, minvalues);
        minindices = _mm512_mask_blend_epi32(lt, minindices, indices);
        minvalues  = _mm512_min_epi32(minvalues, values);
    }

    // find min index in vector result (in an extremely naive way)
    int32_t values_array[16];
    uint32_t indices_array[16];

    _mm512_storeu_si512((__m512i*)values_array, minvalues);
    _mm512_storeu_si512((__m512i*)indices_array, minindices);

    size_t  minindex = indices_array[0];
    int32_t minvalue = values_array[0];
    for (int i=1; i < 16; i++) {
        if (values_array[i] < minvalue) {
            minvalue = values_array[i];
            minindex = indices_array[i];
        } else if (values_array[i] == minvalue) {
            minindex = std::min(minindex, size_t(indices_array[i]));
        }
    }

    *result = minindex;
}
<|endoftext|>


<commit_before>#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include "vgui_controls/Controls.h"
#include <vgui/IScheme.h>
#include <vgui_controls/Scrollbar.h>
#include "vgui/ISurface.h"
#include "vgui/KeyCode.h"
#include "vgui/missionchooser_tgaimagepanel.h"
#include "vgui/npc_spawns_panel.h"
#include "MapLayoutPanel.h"
#include "TileGenDialog.h"
#include "TileSource/RoomTemplate.h"
#include "TileSource/Room.h"
#include "TileSource/MapLayout.h"
#include "PlacedRoomTemplatePanel.h"

// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>

using namespace vgui;

CMapLayoutPanel::CMapLayoutPanel( Panel *parent, const char *name ) : BaseClass( parent, name )
{
	SetPaintBackgroundEnabled(true);
	SetMouseInputEnabled(true);

	m_pPlayerStartImagePanel = new CMissionChooserTGAImagePanel(this, "PlayerStartImagePanel");
	m_pPlayerStartImagePanel->SetZPos(10);	// make sure it's above the rooms

	m_pSpawnsPanel = new CNPC_Spawns_Panel( this, "SpawnsPanel" );
	m_pSpawnsPanel->SetZPos( 9 );
}

CMapLayoutPanel::~CMapLayoutPanel( void )
{
}

void CMapLayoutPanel::PerformLayout()
{
	BaseClass::PerformLayout();
	if (!g_pTileGenDialog)
		return;

	// make sure we're big enough to hold the max map size
	int w = g_pTileGenDialog->RoomTemplatePanelTileSize() * g_pTileGenDialog->MapLayoutTilesWide();
	SetSize(w, w);

	m_pPlayerStartImagePanel->SetSize(g_pTileGenDialog->RoomTemplatePanelTileSize(), g_pTileGenDialog->RoomTemplatePanelTileSize());
	// position playerstart within the grid
	int pos_y = GetMapLayout()->m_iPlayerStartTileY;
	pos_y = g_pTileGenDialog->MapLayoutTilesWide() - pos_y;	// reverse the Y axis

	int pos_x = GetMapLayout()->m_iPlayerStartTileX * g_pTileGenDialog->RoomTemplatePanelTileSize();
	pos_y *= g_pTileGenDialog->RoomTemplatePanelTileSize();
	m_pPlayerStartImagePanel->SetPos(pos_x, pos_y);
}

void CMapLayoutPanel::ApplySchemeSettings(vgui::IScheme *pScheme)
{
	BaseClass::ApplySchemeSettings(pScheme);
	SetBgColor(Color(0,0,0,255));
	SetPaintBackgroundEnabled(true);
	SetPaintBackgroundType(0);

	m_pPlayerStartImagePanel->SetTGA("tilegen/roomtemplates/playerstart.tga");
}

void CMapLayoutPanel::Paint()
{
	if ( !g_pTileGenDialog )
		return;

	int iTiles = g_pTileGenDialog->MapLayoutTilesWide();
	int iTileSize = g_pTileGenDialog->RoomTemplatePanelTileSize();

	// draw dark grid lines
	surface()->DrawSetColor(Color(32,32,32,255));
	for (int x=0;x<iTiles;x++)
	{
		if (x % 4 != 0)
		{
			vgui::surface()->DrawLine(x*iTileSize, 0, x*iTileSize, GetTall());
		}
	}
	for (int y=0;y<iTiles;y++)
	{
		if (y % 4 != 0)
		{
			vgui::surface()->DrawLine(0, y*iTileSize, GetWide(), y*iTileSize);
		}
	}

	// draw brighter grid lines
	surface()->DrawSetColor(Color(64,64,64,255));
	for (int x=0;x<iTiles;x++)
	{
		if (x % 4 == 0)
		{
			vgui::surface()->DrawLine(x*iTileSize, 0, x*iTileSize, GetTall());
		}
	}
	for (int y=0;y<iTiles;y++)
	{
		if (y % 4 == 0)
		{
			vgui::surface()->DrawLine(0, y*iTileSize, GetWide(), y*iTileSize);
		}
	}

	int sx, sy;
	if ( g_pTileGenDialog->GetRubberBandStart( sx, sy ) )
	{
		int mx, my;
		input()->GetCursorPos(mx, my);
		ScreenToLocal(mx, my);

		surface()->DrawSetColor( Color( 255,255,64,255 ) );

		if ( sx > mx )
		{
			int i = mx;
			mx = sx;
			sx = i;
		}
		if ( sy > my )
		{
			int i = my;
			my = sy;
			sy = i;
		}
		vgui::surface()->DrawOutlinedRect( sx, sy, mx, my );
	}
}

void CMapLayoutPanel::GetCursorTile(int &tilex, int &tiley)
{
	if ( !g_pTileGenDialog )
		return;

	// find the tile we clicked in
	int mx, my;
	input()->GetCursorPos(mx, my);
	ScreenToLocal(mx, my);
	tilex = mx / g_pTileGenDialog->RoomTemplatePanelTileSize();
	tiley = (my / g_pTileGenDialog->RoomTemplatePanelTileSize());
	// reverse the Y axis
	tiley = g_pTileGenDialog->MapLayoutTilesWide() - tiley - 1;
}

void CMapLayoutPanel::OnMouseReleased(vgui::MouseCode code)
{
	if (g_pTileGenDialog && g_pTileGenDialog->m_pCursorTemplate)	// if we're in 'room stamping down' mode
	{
		if (code == MOUSE_LEFT)	// if we left click with a room to stamp down
		{
			int iTileX = 0;
			int iTileY = 0;
			GetCursorTile(iTileX, iTileY);

			// check our room wouldn't go out of bounds if placed here
			if (iTileX < 0 || iTileY < 0 || iTileX >= g_pTileGenDialog->MapLayoutTilesWide() || iTileY >= g_pTileGenDialog->MapLayoutTilesWide())
				return;

			if (iTileX + g_pTileGenDialog->m_pCursorTemplate->GetTilesX() > g_pTileGenDialog->MapLayoutTilesWide()
				|| iTileY + g_pTileGenDialog->m_pCursorTemplate->GetTilesY() > g_pTileGenDialog->MapLayoutTilesWide())
				return;

			if ( !GetMapLayout()->TemplateFits( g_pTileGenDialog->m_pCursorTemplate, iTileX, iTileY ) )
			{
				Msg("  Template doesn't fit there!\n" );
				return;
			}

			// place the room
			AddRoom(g_pTileGenDialog->m_pCursorTemplate, iTileX, iTileY);
			Msg( "Manually added room %s at %d,%d\n", g_pTileGenDialog->m_pCursorTemplate->GetFullName(), iTileX, iTileY );
		}
		else if ( code == MOUSE_RIGHT )
		{
			// clear the current room attached to the cursor if we right click over the map
			g_pTileGenDialog->SetCursorRoomTemplate(NULL);
		}
	}
	else if ( g_pTileGenDialog )		// if we right click over the map without a room to stamp down, then manipulate existing rooms
	{
		//g_pTileGenDialog->ClearRoomSelection();

		int mx, my;
		input()->GetCursorPos(mx, my);
		ScreenToLocal(mx, my);

		g_pTileGenDialog->EndRubberBandSelection( mx, my );
	}
}

void CMapLayoutPanel::OnMousePressed(vgui::MouseCode code)
{
	if ( !g_pTileGenDialog )
		return;

	if ( !g_pTileGenDialog->m_pCursorTemplate && ( code == MOUSE_LEFT ) )
	{
		int mx, my;
		input()->GetCursorPos(mx, my);
		ScreenToLocal(mx, my);

		g_pTileGenDialog->StartRubberBandSelection( mx, my );
	}
}

void CMapLayoutPanel::AddRoom( const CRoomTemplate *pTemplate, int iTileX, int iTileY )
{
	if ( !g_pTileGenDialog )
		return;

	CRoom *pRoom = new CRoom( GetMapLayout(), g_pTileGenDialog->m_pCursorTemplate->GetFullName(), g_pTileGenDialog->m_pCursorTemplate->m_iszLevelTheme, iTileX, iTileY );
	CreateRoomUIPanel( pRoom );
}

void CMapLayoutPanel::RemoveRoom(CRoom *pRoom)
{
	delete pRoom;
}

void CMapLayoutPanel::CreateAllUIPanels()
{
	if ( !GetMapLayout() )
		return;

	for ( int i=0; i<GetMapLayout()->m_PlacedRooms.Count(); i++ )
	{
		CRoom *pRoom = GetMapLayout()->m_PlacedRooms[i];
		CreateRoomUIPanel( pRoom );
	}
}

void CMapLayoutPanel::CreateRoomUIPanel( CRoom *pRoom )
{
	if ( !pRoom->m_pPlacedRoomPanel )
	{
		pRoom->m_pPlacedRoomPanel = new CPlacedRoomTemplatePanel(pRoom, this, "PlacedRoomPanel");
	}
}

CMapLayout* CMapLayoutPanel::GetMapLayout()
{
	return g_pTileGenDialog ? g_pTileGenDialog->GetMapLayout() : NULL;
}<commit_msg>CRASH: fix inversion of parameters<commit_after>#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include "vgui_controls/Controls.h"
#include <vgui/IScheme.h>
#include <vgui_controls/Scrollbar.h>
#include "vgui/ISurface.h"
#include "vgui/KeyCode.h"
#include "vgui/missionchooser_tgaimagepanel.h"
#include "vgui/npc_spawns_panel.h"
#include "MapLayoutPanel.h"
#include "TileGenDialog.h"
#include "TileSource/RoomTemplate.h"
#include "TileSource/Room.h"
#include "TileSource/MapLayout.h"
#include "PlacedRoomTemplatePanel.h"

// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>

using namespace vgui;

CMapLayoutPanel::CMapLayoutPanel( Panel *parent, const char *name ) : BaseClass( parent, name )
{
	SetPaintBackgroundEnabled(true);
	SetMouseInputEnabled(true);

	m_pPlayerStartImagePanel = new CMissionChooserTGAImagePanel(this, "PlayerStartImagePanel");
	m_pPlayerStartImagePanel->SetZPos(10);	// make sure it's above the rooms

	m_pSpawnsPanel = new CNPC_Spawns_Panel( this, "SpawnsPanel" );
	m_pSpawnsPanel->SetZPos( 9 );
}

CMapLayoutPanel::~CMapLayoutPanel( void )
{
}

void CMapLayoutPanel::PerformLayout()
{
	BaseClass::PerformLayout();
	if (!g_pTileGenDialog)
		return;

	// make sure we're big enough to hold the max map size
	int w = g_pTileGenDialog->RoomTemplatePanelTileSize() * g_pTileGenDialog->MapLayoutTilesWide();
	SetSize(w, w);

	m_pPlayerStartImagePanel->SetSize(g_pTileGenDialog->RoomTemplatePanelTileSize(), g_pTileGenDialog->RoomTemplatePanelTileSize());
	// position playerstart within the grid
	int pos_y = GetMapLayout()->m_iPlayerStartTileY;
	pos_y = g_pTileGenDialog->MapLayoutTilesWide() - pos_y;	// reverse the Y axis

	int pos_x = GetMapLayout()->m_iPlayerStartTileX * g_pTileGenDialog->RoomTemplatePanelTileSize();
	pos_y *= g_pTileGenDialog->RoomTemplatePanelTileSize();
	m_pPlayerStartImagePanel->SetPos(pos_x, pos_y);
}

void CMapLayoutPanel::ApplySchemeSettings(vgui::IScheme *pScheme)
{
	BaseClass::ApplySchemeSettings(pScheme);
	SetBgColor(Color(0,0,0,255));
	SetPaintBackgroundEnabled(true);
	SetPaintBackgroundType(0);

	m_pPlayerStartImagePanel->SetTGA("tilegen/roomtemplates/playerstart.tga");
}

void CMapLayoutPanel::Paint()
{
	if ( !g_pTileGenDialog )
		return;

	int iTiles = g_pTileGenDialog->MapLayoutTilesWide();
	int iTileSize = g_pTileGenDialog->RoomTemplatePanelTileSize();

	// draw dark grid lines
	surface()->DrawSetColor(Color(32,32,32,255));
	for (int x=0;x<iTiles;x++)
	{
		if (x % 4 != 0)
		{
			vgui::surface()->DrawLine(x*iTileSize, 0, x*iTileSize, GetTall());
		}
	}
	for (int y=0;y<iTiles;y++)
	{
		if (y % 4 != 0)
		{
			vgui::surface()->DrawLine(0, y*iTileSize, GetWide(), y*iTileSize);
		}
	}

	// draw brighter grid lines
	surface()->DrawSetColor(Color(64,64,64,255));
	for (int x=0;x<iTiles;x++)
	{
		if (x % 4 == 0)
		{
			vgui::surface()->DrawLine(x*iTileSize, 0, x*iTileSize, GetTall());
		}
	}
	for (int y=0;y<iTiles;y++)
	{
		if (y % 4 == 0)
		{
			vgui::surface()->DrawLine(0, y*iTileSize, GetWide(), y*iTileSize);
		}
	}

	int sx, sy;
	if ( g_pTileGenDialog->GetRubberBandStart( sx, sy ) )
	{
		int mx, my;
		input()->GetCursorPos(mx, my);
		ScreenToLocal(mx, my);

		surface()->DrawSetColor( Color( 255,255,64,255 ) );

		if ( sx > mx )
		{
			int i = mx;
			mx = sx;
			sx = i;
		}
		if ( sy > my )
		{
			int i = my;
			my = sy;
			sy = i;
		}
		vgui::surface()->DrawOutlinedRect( sx, sy, mx, my );
	}
}

void CMapLayoutPanel::GetCursorTile(int &tilex, int &tiley)
{
	if ( !g_pTileGenDialog )
		return;

	// find the tile we clicked in
	int mx, my;
	input()->GetCursorPos(mx, my);
	ScreenToLocal(mx, my);
	tilex = mx / g_pTileGenDialog->RoomTemplatePanelTileSize();
	tiley = (my / g_pTileGenDialog->RoomTemplatePanelTileSize());
	// reverse the Y axis
	tiley = g_pTileGenDialog->MapLayoutTilesWide() - tiley - 1;
}

void CMapLayoutPanel::OnMouseReleased(vgui::MouseCode code)
{
	if (g_pTileGenDialog && g_pTileGenDialog->m_pCursorTemplate)	// if we're in 'room stamping down' mode
	{
		if (code == MOUSE_LEFT)	// if we left click with a room to stamp down
		{
			int iTileX = 0;
			int iTileY = 0;
			GetCursorTile(iTileX, iTileY);

			// check our room wouldn't go out of bounds if placed here
			if (iTileX < 0 || iTileY < 0 || iTileX >= g_pTileGenDialog->MapLayoutTilesWide() || iTileY >= g_pTileGenDialog->MapLayoutTilesWide())
				return;

			if (iTileX + g_pTileGenDialog->m_pCursorTemplate->GetTilesX() > g_pTileGenDialog->MapLayoutTilesWide()
				|| iTileY + g_pTileGenDialog->m_pCursorTemplate->GetTilesY() > g_pTileGenDialog->MapLayoutTilesWide())
				return;

			if ( !GetMapLayout()->TemplateFits( g_pTileGenDialog->m_pCursorTemplate, iTileX, iTileY ) )
			{
				Msg("  Template doesn't fit there!\n" );
				return;
			}

			// place the room
			AddRoom(g_pTileGenDialog->m_pCursorTemplate, iTileX, iTileY);
			Msg( "Manually added room %s at %d,%d\n", g_pTileGenDialog->m_pCursorTemplate->GetFullName(), iTileX, iTileY );
		}
		else if ( code == MOUSE_RIGHT )
		{
			// clear the current room attached to the cursor if we right click over the map
			g_pTileGenDialog->SetCursorRoomTemplate(NULL);
		}
	}
	else if ( g_pTileGenDialog )		// if we right click over the map without a room to stamp down, then manipulate existing rooms
	{
		//g_pTileGenDialog->ClearRoomSelection();

		int mx, my;
		input()->GetCursorPos(mx, my);
		ScreenToLocal(mx, my);

		g_pTileGenDialog->EndRubberBandSelection( mx, my );
	}
}

void CMapLayoutPanel::OnMousePressed(vgui::MouseCode code)
{
	if ( !g_pTileGenDialog )
		return;

	if ( !g_pTileGenDialog->m_pCursorTemplate && ( code == MOUSE_LEFT ) )
	{
		int mx, my;
		input()->GetCursorPos(mx, my);
		ScreenToLocal(mx, my);

		g_pTileGenDialog->StartRubberBandSelection( mx, my );
	}
}

void CMapLayoutPanel::AddRoom( const CRoomTemplate *pTemplate, int iTileX, int iTileY )
{
	if ( !g_pTileGenDialog )
		return;

	CRoom *pRoom = new CRoom(GetMapLayout(), g_pTileGenDialog->m_pCursorTemplate->m_iszLevelTheme, g_pTileGenDialog->m_pCursorTemplate->GetFullName(), iTileX, iTileY);
	CreateRoomUIPanel( pRoom );
}

void CMapLayoutPanel::RemoveRoom(CRoom *pRoom)
{
	delete pRoom;
}

void CMapLayoutPanel::CreateAllUIPanels()
{
	if ( !GetMapLayout() )
		return;

	for ( int i=0; i<GetMapLayout()->m_PlacedRooms.Count(); i++ )
	{
		CRoom *pRoom = GetMapLayout()->m_PlacedRooms[i];
		CreateRoomUIPanel( pRoom );
	}
}

void CMapLayoutPanel::CreateRoomUIPanel( CRoom *pRoom )
{
	if ( !pRoom->m_pPlacedRoomPanel )
	{
		pRoom->m_pPlacedRoomPanel = new CPlacedRoomTemplatePanel(pRoom, this, "PlacedRoomPanel");
	}
}

CMapLayout* CMapLayoutPanel::GetMapLayout()
{
	return g_pTileGenDialog ? g_pTileGenDialog->GetMapLayout() : NULL;
}<|endoftext|>


<commit_before>// ------------------------------------------------------------------------
// Pion is a development platform for building Reactors that process Events
// ------------------------------------------------------------------------
// Copyright (C) 2007-2010 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Pion is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// Pion 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 Affero General Public License for
// more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Pion.  If not, see <http://www.gnu.org/licenses/>.
//

#include <sstream>
#include <boost/bind.hpp>
#include <pion/PionId.hpp>
#include <pion/net/HTTPResponse.hpp>
#include <pion/net/HTTPResponseWriter.hpp>
#include "pion/platform/Event.hpp"
#include "PlatformConfig.hpp"
#include "MonitorService.hpp"

using namespace pion::net;
using namespace pion::server;
using namespace pion::platform;

namespace pion {		// begin namespace pion
namespace plugins {		// begin namespace plugins

const std::string dtd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

// MonitorHandler member functions

MonitorHandler::MonitorHandler(pion::platform::ReactionEngine &reaction_engine,
						 const std::string& reactor_id)
	: m_reaction_engine(reaction_engine),
	m_logger(PION_GET_LOGGER("pion.server.MonitorHandler")),
	m_connection_id(PionId().to_string()),
	m_reactor_id(reactor_id)
{}

bool MonitorHandler::sendResponse(void)
{
	// build some XML response content for the request
	std::stringstream ss;
	m_reaction_engine.writeConnectionsXML(ss, getConnectionId());
	return true;
}

// MonitorWriter member functions

MonitorWriter::MonitorWriter(pion::platform::ReactionEngine &reaction_engine, platform::VocabularyPtr& vptr,
					   const std::string& reactor_id, unsigned size, bool scroll)
	: MonitorHandler(reaction_engine, reactor_id),
	m_event_buffer(size), m_size(size), m_scroll(scroll), m_vocab_ptr(vptr), m_truncate(100), m_stopped(false),
	m_reaction_engine(reaction_engine)
{}

MonitorWriter::~MonitorWriter()
{
	PION_LOG_INFO(m_logger, "Closing output feed to " << getConnectionInfo()
				  << " (" << getConnectionId() << ')');
	stop();
}

void MonitorWriter::writeEvent(EventPtr& e)
{
	PION_LOG_DEBUG(m_logger, "Sending event to " << getConnectionInfo()
				   << " (" << getConnectionId() << ')');
	// lock the mutex to ensure that only one Event is sent at a time
	boost::mutex::scoped_lock send_lock(m_mutex);
	if (e.get() == NULL) {
		// Reactor is being removed -> close the connection
		// note that the ReactionEngine will remove the connection for us
		stop();
	} else {
		try {
			// Add latest event to end of circular buffer
			m_event_buffer.push_back(e);

			// If we're not scrolling, and buffer is full, then disconnect from the feed
			if (!m_scroll && m_event_buffer.full())
				stop();
		} catch (std::exception& ex) {
			// stop sending Events if we encounter an exception
			PION_LOG_WARN(m_logger, "Error sending event to " << getConnectionInfo()
						  << " (" << getConnectionId() << "):" << ex.what());
			stop();
		}
	}
}

void MonitorWriter::start(void)
{
	// lock the mutex to ensure that the HTTP response is sent first
	boost::mutex::scoped_lock send_lock(m_mutex);

	// tell the ReactionEngine to start sending us Events
	Reactor::EventHandler event_handler(boost::bind(&MonitorWriter::writeEvent,
													shared_from_this(), _1));
	m_reaction_engine.addTempConnectionOut(getReactorId(), getConnectionId(),
										   getConnectionInfo(),
										   event_handler);

	// send the HTTP response after the connection is successfully created
	if (! sendResponse())
		return;

	PION_LOG_INFO(m_logger, "Opened new output feed to " << getConnectionInfo()
				  << " (" << getConnectionId() << ')');
}

void MonitorWriter::SerializeXML(pion::platform::Vocabulary::TermRef tref,
	const pion::platform::Event::ParameterValue& value, std::ostream& xml, TermCol& cols) const
{
	if (tref > m_vocab_ptr->size())		// sanity check
		tref = Vocabulary::UNDEFINED_TERM_REF;
	const Vocabulary::Term& t((*m_vocab_ptr)[tref]);	// term corresponding with Event parameter
	// Have we seen this tref (column) yet?
	TermCol::iterator i = cols.find(tref);
	if (i == cols.end()) {
		cols[tref] = cols.size();
		i = cols.find(tref);
	}
	// Don't serialize the non-serializable
	if (t.term_type == Vocabulary::TYPE_NULL || t.term_type == Vocabulary::TYPE_OBJECT)
		xml << "<Term id=\"C" << i->second << "\"\\>";
	else {
		std::string tmp;		// tmp storage for values
		xml << "<Term id=\"C" << i->second << "\">"
			<< ConfigManager::xml_encode(Event::write(tmp, value, t).substr(0, m_truncate))
			<< "</Term>";
	}
}

std::string MonitorWriter::getStatus(void)
{
	// Map for termref -> Cnn index, we'll use it for building the guide
	TermCol col_map;

	// traverse through all events in buffer
	std::ostringstream xml;
	for (boost::circular_buffer<pion::platform::EventPtr>::const_iterator i = m_event_buffer.begin(); i != m_event_buffer.end(); i++) {
		// traverse through all terms in event
		xml << "<Event>";
		(*i)->for_each(boost::bind(&MonitorWriter::SerializeXML,
			this, _1, _2, boost::ref(xml), boost::ref(col_map)));
		xml << "</Event>";
	}
	std::ostringstream prefix;
	for (TermCol::const_iterator i = col_map.begin(); i != col_map.end(); i++) {
		const Vocabulary::Term& t((*m_vocab_ptr)[i->first]);
		prefix << "<Column id=\"C" << i->second << "\">" << t.term_id << "</Column>";
	}
	const std::string running(m_stopped ? "Stopped" : "Collecting");
	return "<Status><Running>" + running + "</Running><Columns>" + prefix.str() + "</Columns><Events>" + xml.str() + "</Events></Status>";
}

// MonitorService member functions

void MonitorService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
{
	// split out the path branches from the HTTP request
	PathBranches branches;
	splitPathBranches(branches, request->getResource());

	// make sure that there are two extra path branches in the request
	if (branches.size() < 2) {
		HTTPServer::handleNotFoundRequest(request, tcp_conn);
		return;
	}

	// get the start/stop verb
	const std::string verb(branches[0]);

	// check the request method to determine if we should read or write Events
	if (request->getMethod() == HTTPTypes::REQUEST_METHOD_GET) {

		HTTPResponseWriterPtr response_writer(HTTPResponseWriter::create(tcp_conn, *request,
										  boost::bind(&TCPConnection::finish, tcp_conn)));

		// request made to receive a stream of Events
		if (verb == "status") {
			// use local array to identify the reactor_id
			// possibly a secondary id, for multiple instances per reactor_id
			// get the status for this capture...
			unsigned slot = boost::lexical_cast<boost::uint32_t>(branches[1]);
			if (slot < m_writers.size() && m_writers[slot]) {
				std::string response = m_writers[slot]->getStatus();
				response_writer->write(dtd + response);
			} else {
				response_writer->write(dtd + "<Error>Invalid slot defined</Error>");
			}
		} else if (verb == "start") {
	// get the reactor_id from the first path branch
			const std::string reactor_id(branches[1]);
			if (reactor_id.empty() || !getConfig().getReactionEngine().hasPlugin(reactor_id)) {
				HTTPServer::handleNotFoundRequest(request, tcp_conn);
				return;
			}

			unsigned slot;
			// Try to find an empty slot
			for (slot = 0; slot < m_writers.size(); slot++)
				if (!m_writers[slot]) break;
			// If no empty slots, clear oldest
			if (slot == m_writers.size()) {
				// FIXME: find oldest, and wipe out
				slot = 0;
			}
			VocabularyPtr vocab_ptr(getConfig().getReactionEngine().getVocabulary());
			// create a MonitorWriter object that will be used to send Events
			m_writers[slot].reset(new MonitorWriter(getConfig().getReactionEngine(), vocab_ptr, reactor_id, 1000, true));
			m_writers[slot]->start();
			HTTPResponseWriterPtr response_writer(HTTPResponseWriter::create(tcp_conn, *request,
										  boost::bind(&TCPConnection::finish, tcp_conn)));
			std::ostringstream xml;
			xml << dtd << "<MonitorService>" << slot << "</MonitorService>";
			response_writer->write(xml);
		} else if (verb == "stop") {
			unsigned slot = boost::lexical_cast<boost::uint32_t>(branches[1]);
			if (slot < m_writers.size() && m_writers[slot])
				m_writers[slot]->stop();
		} else if (verb == "delete") {
			unsigned slot = boost::lexical_cast<boost::uint32_t>(branches[1]);
			if (slot < m_writers.size() && m_writers[slot]) {
				m_writers[slot]->stop();
				m_writers[slot].reset();
			}
		}

		response_writer->send();

	} else if (request->getMethod() == HTTPTypes::REQUEST_METHOD_PUT
			   || request->getMethod() == HTTPTypes::REQUEST_METHOD_POST)
	{

		// Error message? Not supported...

	} else if (request->getMethod() == HTTPTypes::REQUEST_METHOD_HEAD) {

		// request is just checking if the reactor is valid -> return OK
		HTTPResponseWriterPtr response_writer(HTTPResponseWriter::create(tcp_conn, *request,
											  boost::bind(&TCPConnection::finish, tcp_conn)));
		response_writer->send();
	}
}

}	// end namespace plugins
}	// end namespace pion

/// creates new MonitorService objects
extern "C" PION_PLUGIN_API pion::server::PlatformService *pion_create_MonitorService(void) {
	return new pion::plugins::MonitorService();
}

/// destroys MonitorService objects
extern "C" PION_PLUGIN_API void pion_destroy_MonitorService(pion::plugins::MonitorService *service_ptr) {
	delete service_ptr;
}
<commit_msg>MonitorService Changing the encoding of Object Type, into a pseudo-column, with the object URN term_id as the value<commit_after>// ------------------------------------------------------------------------
// Pion is a development platform for building Reactors that process Events
// ------------------------------------------------------------------------
// Copyright (C) 2007-2010 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Pion is free software: you can redistribute it and/or modify it under the
// terms of the GNU Affero General Public License as published by the Free
// Software Foundation, either version 3 of the License, or (at your option)
// any later version.
//
// Pion 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 Affero General Public License for
// more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with Pion.  If not, see <http://www.gnu.org/licenses/>.
//

#include <sstream>
#include <boost/bind.hpp>
#include <pion/PionId.hpp>
#include <pion/net/HTTPResponse.hpp>
#include <pion/net/HTTPResponseWriter.hpp>
#include "pion/platform/Event.hpp"
#include "PlatformConfig.hpp"
#include "MonitorService.hpp"

using namespace pion::net;
using namespace pion::server;
using namespace pion::platform;

namespace pion {		// begin namespace pion
namespace plugins {		// begin namespace plugins

const std::string dtd = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";

// MonitorHandler member functions

MonitorHandler::MonitorHandler(pion::platform::ReactionEngine &reaction_engine,
						 const std::string& reactor_id)
	: m_reaction_engine(reaction_engine),
	m_logger(PION_GET_LOGGER("pion.server.MonitorHandler")),
	m_connection_id(PionId().to_string()),
	m_reactor_id(reactor_id)
{}

bool MonitorHandler::sendResponse(void)
{
	// build some XML response content for the request
	std::stringstream ss;
	m_reaction_engine.writeConnectionsXML(ss, getConnectionId());
	return true;
}

// MonitorWriter member functions

MonitorWriter::MonitorWriter(pion::platform::ReactionEngine &reaction_engine, platform::VocabularyPtr& vptr,
					   const std::string& reactor_id, unsigned size, bool scroll)
	: MonitorHandler(reaction_engine, reactor_id),
	m_event_buffer(size), m_size(size), m_scroll(scroll), m_vocab_ptr(vptr), m_truncate(100), m_stopped(false),
	m_reaction_engine(reaction_engine)
{}

MonitorWriter::~MonitorWriter()
{
	PION_LOG_INFO(m_logger, "Closing output feed to " << getConnectionInfo()
				  << " (" << getConnectionId() << ')');
	stop();
}

void MonitorWriter::writeEvent(EventPtr& e)
{
	PION_LOG_DEBUG(m_logger, "Sending event to " << getConnectionInfo()
				   << " (" << getConnectionId() << ')');
	// lock the mutex to ensure that only one Event is sent at a time
	boost::mutex::scoped_lock send_lock(m_mutex);
	if (e.get() == NULL) {
		// Reactor is being removed -> close the connection
		// note that the ReactionEngine will remove the connection for us
		stop();
	} else {
		try {
			// Add latest event to end of circular buffer
			m_event_buffer.push_back(e);

			// If we're not scrolling, and buffer is full, then disconnect from the feed
			if (!m_scroll && m_event_buffer.full())
				stop();
		} catch (std::exception& ex) {
			// stop sending Events if we encounter an exception
			PION_LOG_WARN(m_logger, "Error sending event to " << getConnectionInfo()
						  << " (" << getConnectionId() << "):" << ex.what());
			stop();
		}
	}
}

void MonitorWriter::start(void)
{
	// lock the mutex to ensure that the HTTP response is sent first
	boost::mutex::scoped_lock send_lock(m_mutex);

	// tell the ReactionEngine to start sending us Events
	Reactor::EventHandler event_handler(boost::bind(&MonitorWriter::writeEvent,
													shared_from_this(), _1));
	m_reaction_engine.addTempConnectionOut(getReactorId(), getConnectionId(),
										   getConnectionInfo(),
										   event_handler);

	// send the HTTP response after the connection is successfully created
	if (! sendResponse())
		return;

	PION_LOG_INFO(m_logger, "Opened new output feed to " << getConnectionInfo()
				  << " (" << getConnectionId() << ')');
}

void MonitorWriter::SerializeXML(pion::platform::Vocabulary::TermRef tref,
	const pion::platform::Event::ParameterValue& value, std::ostream& xml, TermCol& cols) const
{
	if (tref > m_vocab_ptr->size())		// sanity check
		tref = Vocabulary::UNDEFINED_TERM_REF;
	const Vocabulary::Term& t((*m_vocab_ptr)[tref]);	// term corresponding with Event parameter
	// Have we seen this tref (column) yet?
	if (t.term_type == Vocabulary::TYPE_OBJECT)
		tref = Vocabulary::UNDEFINED_TERM_REF;			// Mask OBJECT to undef
	TermCol::iterator i = cols.find(tref);
	if (i == cols.end()) {
		cols[tref] = cols.size();
		i = cols.find(tref);
	}
	// Don't serialize the non-serializable
	if (t.term_type == Vocabulary::TYPE_NULL)
		xml << "<Term id=\"C" << i->second << "\"\\>";
	if (t.term_type == Vocabulary::TYPE_OBJECT)
		xml << "<Term id=\"C" << i->second << "\">" << t.term_id << "</Term>";
	else {
		std::string tmp;		// tmp storage for values
		xml << "<Term id=\"C" << i->second << "\">"
			<< ConfigManager::xml_encode(Event::write(tmp, value, t).substr(0, m_truncate))
			<< "</Term>";
	}
}

std::string MonitorWriter::getStatus(void)
{
	// Map for termref -> Cnn index, we'll use it for building the guide
	TermCol col_map;

	// traverse through all events in buffer
	std::ostringstream xml;
	for (boost::circular_buffer<pion::platform::EventPtr>::const_iterator i = m_event_buffer.begin(); i != m_event_buffer.end(); i++) {
		// traverse through all terms in event
		xml << "<Event>";
		(*i)->for_each(boost::bind(&MonitorWriter::SerializeXML,
			this, _1, _2, boost::ref(xml), boost::ref(col_map)));
		xml << "</Event>";
	}
	std::ostringstream prefix;
	for (TermCol::const_iterator i = col_map.begin(); i != col_map.end(); i++) {
		const Vocabulary::Term& t((*m_vocab_ptr)[i->first]);
		prefix << "<Column id=\"C" << i->second << "\">" << t.term_id << "</Column>";
	}
	const std::string running(m_stopped ? "Stopped" : "Collecting");
	return "<Status><Running>" + running + "</Running><Columns>" + prefix.str() + "</Columns><Events>" + xml.str() + "</Events></Status>";
}

// MonitorService member functions

void MonitorService::operator()(HTTPRequestPtr& request, TCPConnectionPtr& tcp_conn)
{
	// split out the path branches from the HTTP request
	PathBranches branches;
	splitPathBranches(branches, request->getResource());

	// make sure that there are two extra path branches in the request
	if (branches.size() < 2) {
		HTTPServer::handleNotFoundRequest(request, tcp_conn);
		return;
	}

	// get the start/stop verb
	const std::string verb(branches[0]);

	// check the request method to determine if we should read or write Events
	if (request->getMethod() == HTTPTypes::REQUEST_METHOD_GET) {

		HTTPResponseWriterPtr response_writer(HTTPResponseWriter::create(tcp_conn, *request,
										  boost::bind(&TCPConnection::finish, tcp_conn)));

		// request made to receive a stream of Events
		if (verb == "status") {
			// use local array to identify the reactor_id
			// possibly a secondary id, for multiple instances per reactor_id
			// get the status for this capture...
			unsigned slot = boost::lexical_cast<boost::uint32_t>(branches[1]);
			if (slot < m_writers.size() && m_writers[slot]) {
				std::string response = m_writers[slot]->getStatus();
				response_writer->write(dtd + response);
			} else {
				response_writer->write(dtd + "<Error>Invalid slot defined</Error>");
			}
		} else if (verb == "start") {
	// get the reactor_id from the first path branch
			const std::string reactor_id(branches[1]);
			if (reactor_id.empty() || !getConfig().getReactionEngine().hasPlugin(reactor_id)) {
				HTTPServer::handleNotFoundRequest(request, tcp_conn);
				return;
			}

			unsigned slot;
			// Try to find an empty slot
			for (slot = 0; slot < m_writers.size(); slot++)
				if (!m_writers[slot]) break;
			// If no empty slots, clear oldest
			if (slot == m_writers.size()) {
				// FIXME: find oldest, and wipe out
				slot = 0;
			}
			VocabularyPtr vocab_ptr(getConfig().getReactionEngine().getVocabulary());
			// create a MonitorWriter object that will be used to send Events
			m_writers[slot].reset(new MonitorWriter(getConfig().getReactionEngine(), vocab_ptr, reactor_id, 1000, true));
			m_writers[slot]->start();
			HTTPResponseWriterPtr response_writer(HTTPResponseWriter::create(tcp_conn, *request,
										  boost::bind(&TCPConnection::finish, tcp_conn)));
			std::ostringstream xml;
			xml << dtd << "<MonitorService>" << slot << "</MonitorService>";
			response_writer->write(xml);
		} else if (verb == "stop") {
			unsigned slot = boost::lexical_cast<boost::uint32_t>(branches[1]);
			if (slot < m_writers.size() && m_writers[slot])
				m_writers[slot]->stop();
		} else if (verb == "delete") {
			unsigned slot = boost::lexical_cast<boost::uint32_t>(branches[1]);
			if (slot < m_writers.size() && m_writers[slot]) {
				m_writers[slot]->stop();
				m_writers[slot].reset();
			}
		}

		response_writer->send();

	} else if (request->getMethod() == HTTPTypes::REQUEST_METHOD_PUT
			   || request->getMethod() == HTTPTypes::REQUEST_METHOD_POST)
	{

		// Error message? Not supported...

	} else if (request->getMethod() == HTTPTypes::REQUEST_METHOD_HEAD) {

		// request is just checking if the reactor is valid -> return OK
		HTTPResponseWriterPtr response_writer(HTTPResponseWriter::create(tcp_conn, *request,
											  boost::bind(&TCPConnection::finish, tcp_conn)));
		response_writer->send();
	}
}

}	// end namespace plugins
}	// end namespace pion

/// creates new MonitorService objects
extern "C" PION_PLUGIN_API pion::server::PlatformService *pion_create_MonitorService(void) {
	return new pion::plugins::MonitorService();
}

/// destroys MonitorService objects
extern "C" PION_PLUGIN_API void pion_destroy_MonitorService(pion::plugins::MonitorService *service_ptr) {
	delete service_ptr;
}
<|endoftext|>


<commit_before>#include "Side.h"

#include <ios>
#include <stdio.h>

#include "BoundingBox.h"
#include "KeyVal.h"
#include "Vector.h"

size_t Side::parseSpecial(std::istream & stream, std::string_view type)
{
	if (type == "dispinfo")
	{
		return disp.parse(stream);
	}

	return 0;
}

void Side::reID(unsigned int& sideID)
{
	id_ = ++sideID;
}

void Side::popuvars()
{
	if (keyvals.count("id") > 0)
	{
		this->id_ = atoi(keyvals["id"].c_str());
		keyvals.erase("id");
	}
	if (keyvals.count("plane") > 0)
	{
		this->polygon = Polygon(Plane(keyvals["plane"]));
		keyvals.erase("plane");
	}
	if (keyvals.count("uaxis") > 0)
	{
		this->uaxis.parsestr(keyvals["uaxis"]);
		keyvals.erase("uaxis");
	}
	if (keyvals.count("vaxis") > 0)
	{
		this->vaxis.parsestr(keyvals["vaxis"]);
		keyvals.erase("vaxis");
	}
}

void Side::rotate(const Vertex& point, const Matrix3d& rotmat)
{
	//mictimer rotatetimer("ms Side::rotate()", 1000.0);
	polygon.rotate(point, rotmat);
	uaxis.v = uaxis.v.rotate(rotmat);
	vaxis.v = vaxis.v.rotate(rotmat);

	disp.rotate(point, rotmat);
}

void Side::move(const Vector& vec)
{
	Vertex mov = vec.vec();
	polygon.move(mov);
	uaxis.translate(mov);
	vaxis.translate(mov);
}

Plane Side::plane() const
{
	if (polygon.points.size() <= 2)
		throw std::exception("Not enough data to construct plane from polygon");
	return Plane(polygon.points[0], polygon.points[1], polygon.points[2]);
}

BoundingBox Side::bbox() const
{
	Vertex min, max;

	min = max = polygon.points[0];

	for (size_t i = 1; i < polygon.points.size(); i++)
	{
		min = Vertex::allmin(min, polygon.points[i]);
		max = Vertex::allmax(max, polygon.points[i]);
	}

	return BoundingBox(min, max);
}

bool Side::testCollision(const Side& lhs, const Side& rhs)
{
	return false;
}

void Side::extraOutput(std::ostream& os) const
{
	os << std::setw(depth()) << "" << "\t\"Plane\" \"" << plane().toStr() << "\"\n";
	os << std::setw(depth()) << "" << "\t\"uaxis\" \"" << uaxis.toStr() << "\"\n";
	os << std::setw(depth()) << "" << "\t\"vaxis\" \"" << vaxis.toStr() << "\"\n";
	if (!disp.empty())
	{
		disp.depth(depth() + TABDEPTH);
		os << disp << "\n";
	}
}

std::string Side::getName() const
{
	return "side";
}

Side::Side()
{
}

Side::~Side()
{
}

<commit_msg>Made side emit lowercase plane keyval.<commit_after>#include "Side.h"

#include <ios>
#include <stdio.h>

#include "BoundingBox.h"
#include "KeyVal.h"
#include "Vector.h"

size_t Side::parseSpecial(std::istream & stream, std::string_view type)
{
	if (type == "dispinfo")
	{
		return disp.parse(stream);
	}

	return 0;
}

void Side::reID(unsigned int& sideID)
{
	id_ = ++sideID;
}

void Side::popuvars()
{
	if (keyvals.count("id") > 0)
	{
		this->id_ = atoi(keyvals["id"].c_str());
		keyvals.erase("id");
	}
	if (keyvals.count("plane") > 0)
	{
		this->polygon = Polygon(Plane(keyvals["plane"]));
		keyvals.erase("plane");
	}
	if (keyvals.count("uaxis") > 0)
	{
		this->uaxis.parsestr(keyvals["uaxis"]);
		keyvals.erase("uaxis");
	}
	if (keyvals.count("vaxis") > 0)
	{
		this->vaxis.parsestr(keyvals["vaxis"]);
		keyvals.erase("vaxis");
	}
}

void Side::rotate(const Vertex& point, const Matrix3d& rotmat)
{
	//mictimer rotatetimer("ms Side::rotate()", 1000.0);
	polygon.rotate(point, rotmat);
	uaxis.v = uaxis.v.rotate(rotmat);
	vaxis.v = vaxis.v.rotate(rotmat);

	disp.rotate(point, rotmat);
}

void Side::move(const Vector& vec)
{
	Vertex mov = vec.vec();
	polygon.move(mov);
	uaxis.translate(mov);
	vaxis.translate(mov);
}

Plane Side::plane() const
{
	if (polygon.points.size() <= 2)
		throw std::exception("Not enough data to construct plane from polygon");
	return Plane(polygon.points[0], polygon.points[1], polygon.points[2]);
}

BoundingBox Side::bbox() const
{
	Vertex min, max;

	min = max = polygon.points[0];

	for (size_t i = 1; i < polygon.points.size(); i++)
	{
		min = Vertex::allmin(min, polygon.points[i]);
		max = Vertex::allmax(max, polygon.points[i]);
	}

	return BoundingBox(min, max);
}

bool Side::testCollision(const Side& lhs, const Side& rhs)
{
	return false;
}

void Side::extraOutput(std::ostream& os) const
{
	os << std::setw(depth()) << "" << "\t\"plane\" \"" << plane().toStr() << "\"\n";
	os << std::setw(depth()) << "" << "\t\"uaxis\" \"" << uaxis.toStr() << "\"\n";
	os << std::setw(depth()) << "" << "\t\"vaxis\" \"" << vaxis.toStr() << "\"\n";
	if (!disp.empty())
	{
		disp.depth(depth() + TABDEPTH);
		os << disp << "\n";
	}
}

std::string Side::getName() const
{
	return "side";
}

Side::Side()
{
}

Side::~Side()
{
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QueryDesignFieldUndoAct.hxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 16:23:52 $
 *
 *  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 DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
#define DBAUI_QUERYDESIGNFIELDUNDOACT_HXX

#ifndef DBAUI_GENERALUNDO_HXX
#include "GeneralUndo.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
#include "SelectionBrowseBox.hxx"
#endif

namespace dbaui
{
    // ================================================================================================
    // OQueryDesignFieldUndoAct - Basisklasse fuer Undos in der Feldauflistung im Abfrageentwurf

    class OQueryDesignFieldUndoAct : public OCommentUndoAction
    {
    protected:
        OSelectionBrowseBox*    pOwner;
        USHORT                  m_nColumnPostion;

        virtual void    Undo() = 0;
        virtual void    Redo() = 0;

    public:
        OQueryDesignFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, USHORT nCommentID);
        virtual ~OQueryDesignFieldUndoAct();

        inline void SetColumnPosition(USHORT _nColumnPostion)
        {
            m_nColumnPostion = _nColumnPostion;
            OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
            OSL_ENSURE(m_nColumnPostion < pOwner->GetColumnCount(),"Position outside the column count!");
        }
    };

    // ================================================================================================
    // OTabFieldCellModifiedUndoAct - Undo-Klasse fuer Aendern einer Zelle einer Spaltenbeschreibung

    class OTabFieldCellModifiedUndoAct : public OQueryDesignFieldUndoAct
    {
    protected:
        String      m_strNextCellContents;
        sal_Int32   m_nCellIndex;

    public:
        OTabFieldCellModifiedUndoAct(OSelectionBrowseBox* pSelBrwBox)
            : OQueryDesignFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_MODIFY_CELL)
            ,m_nCellIndex(BROWSER_INVALIDID){ }

        inline void SetCellContents(const String& str)  { m_strNextCellContents = str; }
        inline void SetCellIndex(sal_Int32 nIndex)      { m_nCellIndex = nIndex; }

        virtual void Undo();
        virtual void Redo() { Undo(); }
    };

    // ================================================================================================
    // OTabFieldSizedUndoAct - Undo-Klasse fuer Aendern einer Spaltenbreite

    class OTabFieldSizedUndoAct : public OQueryDesignFieldUndoAct
    {
    protected:
        long        m_nNextWidth;

    public:
        OTabFieldSizedUndoAct(OSelectionBrowseBox* pSelBrwBox) : OQueryDesignFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_SIZE_COLUMN), m_nNextWidth(0) { }

        inline void SetOriginalWidth(long nWidth) { OSL_ENSURE(m_nNextWidth =! 0,"Width is 0!");m_nNextWidth = nWidth; }

        virtual void Undo();
        virtual void Redo() { Undo(); }
    };

    // ================================================================================================
    // OTabFieldUndoAct - Basisklasse fuer Undos in der Feldauflistung im Abfrageentwurf, die mit Veraendern einer kompletten Feldbeschreibung zu tun haben

    class OTabFieldUndoAct : public OQueryDesignFieldUndoAct
    {
    protected:
        OTableFieldDescRef      pDescr;     // geloeschte Spaltenbeschreibung

    public:
        OTabFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, USHORT nCommentID) : OQueryDesignFieldUndoAct(pSelBrwBox, nCommentID) { }

        void SetTabFieldDescr(OTableFieldDescRef pDescription) { pDescr = pDescription; }
    };

    // ================================================================================================
    // OTabFieldDelUndoAct - Undo-Klasse fuer Loeschen eines Feldes

    class OTabFieldDelUndoAct : public OTabFieldUndoAct
    {
    protected:
        virtual void Undo() { pOwner->InsertColumn(pDescr, m_nColumnPostion); }
        virtual void Redo() { pOwner->RemoveColumn(pDescr->GetColumnId()); }

    public:
        OTabFieldDelUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDDELETE) { }
    };

    // ================================================================================================
    // OTabFieldDelUndoAct - Undo-Klasse fuer Anlegen eines Feldes

    class OTabFieldCreateUndoAct : public OTabFieldUndoAct
    {
    protected:
        virtual void Undo() { pOwner->RemoveColumn(pDescr->GetColumnId());}
        virtual void Redo() { pOwner->InsertColumn(pDescr, m_nColumnPostion);}

    public:
        OTabFieldCreateUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDCREATE) { }
    };

    // ================================================================================================
    // OTabFieldMovedUndoAct - Undo-class when a field was moved inside the selection

    class OTabFieldMovedUndoAct : public OTabFieldUndoAct
    {
    protected:
        virtual void Undo();
        virtual void Redo()
        {
            Undo();
        }

    public:
        OTabFieldMovedUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDMOVED) { }
    };
}
#endif // DBAUI_QUERYDESIGNFIELDUNDOACT_HXX

<commit_msg>INTEGRATION: CWS dba201b (1.6.376); FILE MERGED 2005/09/21 10:08:16 oj 1.6.376.2: RESYNC: (1.6-1.7); FILE MERGED 2005/07/06 10:36:26 oj 1.6.376.1: #123168# check if we are in undo mode<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: QueryDesignFieldUndoAct.hxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: hr $ $Date: 2005-09-23 12:42:49 $
 *
 *  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 DBAUI_QUERYDESIGNFIELDUNDOACT_HXX
#define DBAUI_QUERYDESIGNFIELDUNDOACT_HXX

#ifndef DBAUI_GENERALUNDO_HXX
#include "GeneralUndo.hxx"
#endif
#ifndef _DBU_QRY_HRC_
#include "dbu_qry.hrc"
#endif
#ifndef DBAUI_QUERYDESIGN_OSELECTIONBROWSEBOX_HXX
#include "SelectionBrowseBox.hxx"
#endif

namespace dbaui
{
    // ================================================================================================
    // OQueryDesignFieldUndoAct - Basisklasse fuer Undos in der Feldauflistung im Abfrageentwurf

    class OQueryDesignFieldUndoAct : public OCommentUndoAction
    {
    protected:
        OSelectionBrowseBox*    pOwner;
        USHORT                  m_nColumnPostion;

        virtual void    Undo() = 0;
        virtual void    Redo() = 0;

    public:
        OQueryDesignFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, USHORT nCommentID);
        virtual ~OQueryDesignFieldUndoAct();

        inline void SetColumnPosition(USHORT _nColumnPostion)
        {
            m_nColumnPostion = _nColumnPostion;
            OSL_ENSURE(m_nColumnPostion != BROWSER_INVALIDID,"Column position was not set add the undo action!");
            OSL_ENSURE(m_nColumnPostion < pOwner->GetColumnCount(),"Position outside the column count!");
        }
    };

    // ================================================================================================
    // OTabFieldCellModifiedUndoAct - Undo-Klasse fuer Aendern einer Zelle einer Spaltenbeschreibung

    class OTabFieldCellModifiedUndoAct : public OQueryDesignFieldUndoAct
    {
    protected:
        String      m_strNextCellContents;
        sal_Int32   m_nCellIndex;

    public:
        OTabFieldCellModifiedUndoAct(OSelectionBrowseBox* pSelBrwBox)
            : OQueryDesignFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_MODIFY_CELL)
            ,m_nCellIndex(BROWSER_INVALIDID){ }

        inline void SetCellContents(const String& str)  { m_strNextCellContents = str; }
        inline void SetCellIndex(sal_Int32 nIndex)      { m_nCellIndex = nIndex; }

        virtual void Undo();
        virtual void Redo() { Undo(); }
    };

    // ================================================================================================
    // OTabFieldSizedUndoAct - Undo-Klasse fuer Aendern einer Spaltenbreite

    class OTabFieldSizedUndoAct : public OQueryDesignFieldUndoAct
    {
    protected:
        long        m_nNextWidth;

    public:
        OTabFieldSizedUndoAct(OSelectionBrowseBox* pSelBrwBox) : OQueryDesignFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_SIZE_COLUMN), m_nNextWidth(0) { }

        inline void SetOriginalWidth(long nWidth) { OSL_ENSURE(m_nNextWidth =! 0,"Width is 0!");m_nNextWidth = nWidth; }

        virtual void Undo();
        virtual void Redo() { Undo(); }
    };

    // ================================================================================================
    // OTabFieldUndoAct - Basisklasse fuer Undos in der Feldauflistung im Abfrageentwurf, die mit Veraendern einer kompletten Feldbeschreibung zu tun haben

    class OTabFieldUndoAct : public OQueryDesignFieldUndoAct
    {
    protected:
        OTableFieldDescRef      pDescr;     // geloeschte Spaltenbeschreibung

    public:
        OTabFieldUndoAct(OSelectionBrowseBox* pSelBrwBox, USHORT nCommentID) : OQueryDesignFieldUndoAct(pSelBrwBox, nCommentID) { }

        void SetTabFieldDescr(OTableFieldDescRef pDescription) { pDescr = pDescription; }
    };

    // ================================================================================================
    // OTabFieldDelUndoAct - Undo-Klasse fuer Loeschen eines Feldes

    class OTabFieldDelUndoAct : public OTabFieldUndoAct
    {
    protected:
        virtual void Undo() { pOwner->EnterUndoMode();pOwner->InsertColumn(pDescr, m_nColumnPostion);pOwner->LeaveUndoMode(); }
        virtual void Redo() { pOwner->EnterUndoMode();pOwner->RemoveColumn(pDescr->GetColumnId());pOwner->LeaveUndoMode(); }

    public:
        OTabFieldDelUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDDELETE) { }
    };

    // ================================================================================================
    // OTabFieldDelUndoAct - Undo-Klasse fuer Anlegen eines Feldes

    class OTabFieldCreateUndoAct : public OTabFieldUndoAct
    {
    protected:
        virtual void Undo() { pOwner->EnterUndoMode();pOwner->RemoveColumn(pDescr->GetColumnId());pOwner->LeaveUndoMode();}
        virtual void Redo() { pOwner->EnterUndoMode();pOwner->InsertColumn(pDescr, m_nColumnPostion);pOwner->LeaveUndoMode();}

    public:
        OTabFieldCreateUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDCREATE) { }
    };

    // ================================================================================================
    // OTabFieldMovedUndoAct - Undo-class when a field was moved inside the selection

    class OTabFieldMovedUndoAct : public OTabFieldUndoAct
    {
    protected:
        virtual void Undo();
        virtual void Redo()
        {
            Undo();
        }

    public:
        OTabFieldMovedUndoAct(OSelectionBrowseBox* pSelBrwBox) : OTabFieldUndoAct(pSelBrwBox, STR_QUERY_UNDO_TABFIELDMOVED) { }
    };
}
#endif // DBAUI_QUERYDESIGNFIELDUNDOACT_HXX

<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2016                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_ddr_phy_reset.C
/// @brief Reset the DDR PHY
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <stdint.h>
#include <string.h>

#include <fapi2.H>
#include <mss.H>

#include <p9_mss_ddr_phy_reset.H>
#include <lib/utils/count_dimm.H>
#include <lib/phy/adr32s.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/fir/check.H>
#include <lib/fir/unmask.H>

using fapi2::TARGET_TYPE_MCBIST;

extern "C"
{

///
/// @brief Perform a phy reset on all the PHY related to this half-chip (mcbist)
/// @param[in] the mcbist representing the PHY
/// @return FAPI2_RC_SUCCESS iff OK
///
    fapi2::ReturnCode p9_mss_ddr_phy_reset(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target)
    {

        // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
        // attributes for the PHY, etc.
        if (mss::count_dimm(i_target) == 0)
        {
            FAPI_INF("... skipping ddr_phy_reset %s - no DIMM ...", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        FAPI_TRY(mss::change_force_mclk_low(i_target, mss::LOW),
                 "force_mclk_low (set high) Failed rc = 0x%08X", uint64_t(fapi2::current_err) );

        // New for Nimbus - perform duty cycle clock distortion calibration
#ifdef RUN_DCD
        FAPI_TRY( mss::adr32s::duty_cycle_distortion_calibration(i_target) );
#endif

        // 1. Drive all control signals to the PHY to their inactive state, idle state, or inactive value.
        FAPI_TRY( mss::dp16::reset_sysclk(i_target) );

        //    (Note: The chip should already be in this state.)
        FAPI_DBG("All control signals to the PHYs should be set to their inactive state, idle state, or inactive values");

        // 2. Assert reset to PHY for 32 memory clocks
        FAPI_TRY( mss::change_resetn(i_target, mss::HIGH), "change_resetn for %s failed", mss::c_str(i_target) );
        fapi2::delay(mss::cycles_to_ns(i_target, 32), mss::cycles_to_simcycles(32));

        // 3. Deassert reset_n
        FAPI_TRY( mss::change_resetn(i_target, mss::LOW), "change_resetn for %s failed", mss::c_str(i_target) );

        //
        // Flush output drivers
        //

        // 8. Set FLUSH=1 and INIT_IO=1 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL and DDRPHY_DP16_DATA_BIT_DIR1 register
        // 9. Wait at least 32 dphy_gckn clock cycles.
        // 10. Set FLUSH=0 and INIT_IO=0 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL register
        FAPI_TRY( mss::flush_output_drivers(i_target), "unable to flush output drivers for %s", mss::c_str(i_target) );

        //
        // ZCTL Enable
        //

        // 11. Assert the ZCNTL enable to the internal impedance controller in DDRPHY_PC_RESETS register
        // 12. Wait at least 1024 dphy_gckn cycles
        // 13. Deassert the ZCNTL impedance controller enable, Check for DONE in DDRPHY_PC_DLL_ZCAL
        FAPI_TRY( mss::enable_zctl(i_target), "enable_zctl for %s failed", mss::c_str(i_target) );

        //
        // DLL calibration
        //

        // 14. Begin DLL calibrations by setting INIT_RXDLL_CAL_RESET=0 in the DDRPHY_DP16_DLL_CNTL{0:1} registers
        // and DDRPHY_ADR_DLL_CNTL registers
        // 15. Monitor the DDRPHY_PC_DLL_ZCAL_CAL_STATUS register to determine when calibration is
        // complete. One of the 3 bits will be asserted for ADR and DP16.
        FAPI_INF( "starting DLL calibration %s", mss::c_str(i_target) );
        FAPI_TRY( mss::dll_calibration(i_target) );

        //
        // Start bang-bang-lock
        //

        // 16. Take dphy_nclk/SysClk alignment circuits out of reset and put into continuous update mode,
        FAPI_INF("set up of phase rotator controls %s", mss::c_str(i_target) );
        FAPI_TRY( mss::setup_phase_rotator_control_registers(i_target, mss::ON) );

        // 17. Wait at least 5932 dphy_nclk clock cycles to allow the dphy_nclk/SysClk alignment circuit to
        // perform initial alignment.
        FAPI_INF("Wait at least 5932 memory clock cycles for clock alignment circuit to perform initial alignment %s",
                 mss::c_str(i_target));
        FAPI_TRY( fapi2::delay(mss::cycles_to_ns(i_target, 5932), 2000) );

        // 18. Check for LOCK in DDRPHY_DP16_SYSCLK_PR_VALUE registers and DDRPHY_ADR_SYSCLK_PR_VALUE
        FAPI_INF("Checking for bang-bang lock %s ...", mss::c_str(i_target));
        FAPI_TRY( mss::check_bang_bang_lock(i_target) );

        // 19. Write 0b0 into the DDRPHY_PC_RESETS register bit 1. This write de-asserts the SYSCLK_RESET.
        FAPI_INF("deassert sysclk reset %s", mss::c_str(i_target));
        FAPI_TRY( mss::deassert_sysclk_reset(i_target), "deassert_sysclk_reset failed for %s", mss::c_str(i_target) );

        // 20. Write 8020h into the DDRPHY_ADR_SYSCLK_CNTL_PR Registers and
        // DDRPHY_DP16_SYSCLK_PR0/1 registers This write takes the dphy_nclk/
        // SysClk alignment circuit out of the Continuous Update mode.
        FAPI_INF("take sysclk alignment out of cont update mode %s", mss::c_str(i_target));
        FAPI_TRY( mss::setup_phase_rotator_control_registers(i_target, mss::OFF),
                  "set up of phase rotator controls failed (out of cont update) %s", mss::c_str(i_target) );

        // 21. Wait at least 32 dphy_nclk clock cycles.
        FAPI_DBG("Wait at least 32 memory clock cycles %s", mss::c_str(i_target));
        FAPI_TRY( fapi2::delay(mss::cycles_to_ns(i_target, 32), mss::cycles_to_simcycles(32)) );

        //
        // Done bang-bang-lock
        //

        // Per J. Bialas, force_mclk_low can be dasserted.
        FAPI_TRY(mss::change_force_mclk_low(i_target, mss::HIGH),
                 "force_mclk_low (set low) Failed rc = 0x%08X", uint64_t(fapi2::current_err) );

        // Workarounds
        FAPI_TRY( mss::workarounds::dp16::after_phy_reset(i_target) );

        // Unmask the FIR we want unmasked after phy reset is complete. Note this is the "good path."
        // The algorithm is 'good path do after_phy_reset, all paths (error or not) perform the checks
        // which are defined in during_phy_reset'. We won't run after_phy_reset (unmask of FIR) unless
        // we're done with a success.
        FAPI_TRY( mss::unmask::after_phy_reset(i_target) );

    fapi_try_exit:

        // mss::check::during_phy_reset handles the error/no error case internally. All we need to do is
        // return the ReturnCode it hands us - it's taken care of commiting anything it needed to.
        return mss::check::during_phy_reset(i_target);

    }

}
<commit_msg>Reflow ddr phy FIR checking/unmasking to not unmask if FIR are set<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_ddr_phy_reset.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2017                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_ddr_phy_reset.C
/// @brief Reset the DDR PHY
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 2
// *HWP Consumed by: FSP:HB

#include <stdint.h>
#include <string.h>

#include <fapi2.H>
#include <mss.H>

#include <p9_mss_ddr_phy_reset.H>
#include <lib/utils/count_dimm.H>
#include <lib/phy/adr32s.H>
#include <lib/workarounds/dp16_workarounds.H>
#include <lib/fir/check.H>
#include <lib/fir/unmask.H>

using fapi2::TARGET_TYPE_MCBIST;

extern "C"
{

///
/// @brief Perform a phy reset on all the PHY related to this half-chip (mcbist)
/// @param[in] the mcbist representing the PHY
/// @return FAPI2_RC_SUCCESS iff OK
///
    fapi2::ReturnCode p9_mss_ddr_phy_reset(const fapi2::Target<fapi2::TARGET_TYPE_MCBIST>& i_target)
    {

        // If there are no DIMM we don't need to bother. In fact, we can't as we didn't setup
        // attributes for the PHY, etc.
        if (mss::count_dimm(i_target) == 0)
        {
            FAPI_INF("... skipping ddr_phy_reset %s - no DIMM ...", mss::c_str(i_target));
            return fapi2::FAPI2_RC_SUCCESS;
        }

        FAPI_TRY(mss::change_force_mclk_low(i_target, mss::LOW),
                 "force_mclk_low (set high) Failed rc = 0x%08X", uint64_t(fapi2::current_err) );

        // New for Nimbus - perform duty cycle clock distortion calibration
#ifdef RUN_DCD
        FAPI_TRY( mss::adr32s::duty_cycle_distortion_calibration(i_target) );
#endif

        // 1. Drive all control signals to the PHY to their inactive state, idle state, or inactive value.
        FAPI_TRY( mss::dp16::reset_sysclk(i_target) );

        //    (Note: The chip should already be in this state.)
        FAPI_DBG("All control signals to the PHYs should be set to their inactive state, idle state, or inactive values");

        // 2. Assert reset to PHY for 32 memory clocks
        FAPI_TRY( mss::change_resetn(i_target, mss::HIGH), "change_resetn for %s failed", mss::c_str(i_target) );
        fapi2::delay(mss::cycles_to_ns(i_target, 32), mss::cycles_to_simcycles(32));

        // 3. Deassert reset_n
        FAPI_TRY( mss::change_resetn(i_target, mss::LOW), "change_resetn for %s failed", mss::c_str(i_target) );

        //
        // Flush output drivers
        //

        // 8. Set FLUSH=1 and INIT_IO=1 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL and DDRPHY_DP16_DATA_BIT_DIR1 register
        // 9. Wait at least 32 dphy_gckn clock cycles.
        // 10. Set FLUSH=0 and INIT_IO=0 in the DDRPHY_ADR_OUTPUT_FORCE_ATEST_CNTL register
        FAPI_TRY( mss::flush_output_drivers(i_target), "unable to flush output drivers for %s", mss::c_str(i_target) );

        //
        // ZCTL Enable
        //

        // 11. Assert the ZCNTL enable to the internal impedance controller in DDRPHY_PC_RESETS register
        // 12. Wait at least 1024 dphy_gckn cycles
        // 13. Deassert the ZCNTL impedance controller enable, Check for DONE in DDRPHY_PC_DLL_ZCAL
        FAPI_TRY( mss::enable_zctl(i_target), "enable_zctl for %s failed", mss::c_str(i_target) );

        //
        // DLL calibration
        //

        // 14. Begin DLL calibrations by setting INIT_RXDLL_CAL_RESET=0 in the DDRPHY_DP16_DLL_CNTL{0:1} registers
        // and DDRPHY_ADR_DLL_CNTL registers
        // 15. Monitor the DDRPHY_PC_DLL_ZCAL_CAL_STATUS register to determine when calibration is
        // complete. One of the 3 bits will be asserted for ADR and DP16.
        FAPI_INF( "starting DLL calibration %s", mss::c_str(i_target) );
        FAPI_TRY( mss::dll_calibration(i_target) );

        //
        // Start bang-bang-lock
        //

        // 16. Take dphy_nclk/SysClk alignment circuits out of reset and put into continuous update mode,
        FAPI_INF("set up of phase rotator controls %s", mss::c_str(i_target) );
        FAPI_TRY( mss::setup_phase_rotator_control_registers(i_target, mss::ON) );

        // 17. Wait at least 5932 dphy_nclk clock cycles to allow the dphy_nclk/SysClk alignment circuit to
        // perform initial alignment.
        FAPI_INF("Wait at least 5932 memory clock cycles for clock alignment circuit to perform initial alignment %s",
                 mss::c_str(i_target));
        FAPI_TRY( fapi2::delay(mss::cycles_to_ns(i_target, 5932), 2000) );

        // 18. Check for LOCK in DDRPHY_DP16_SYSCLK_PR_VALUE registers and DDRPHY_ADR_SYSCLK_PR_VALUE
        FAPI_INF("Checking for bang-bang lock %s ...", mss::c_str(i_target));
        FAPI_TRY( mss::check_bang_bang_lock(i_target) );

        // 19. Write 0b0 into the DDRPHY_PC_RESETS register bit 1. This write de-asserts the SYSCLK_RESET.
        FAPI_INF("deassert sysclk reset %s", mss::c_str(i_target));
        FAPI_TRY( mss::deassert_sysclk_reset(i_target), "deassert_sysclk_reset failed for %s", mss::c_str(i_target) );

        // 20. Write 8020h into the DDRPHY_ADR_SYSCLK_CNTL_PR Registers and
        // DDRPHY_DP16_SYSCLK_PR0/1 registers This write takes the dphy_nclk/
        // SysClk alignment circuit out of the Continuous Update mode.
        FAPI_INF("take sysclk alignment out of cont update mode %s", mss::c_str(i_target));
        FAPI_TRY( mss::setup_phase_rotator_control_registers(i_target, mss::OFF),
                  "set up of phase rotator controls failed (out of cont update) %s", mss::c_str(i_target) );

        // 21. Wait at least 32 dphy_nclk clock cycles.
        FAPI_DBG("Wait at least 32 memory clock cycles %s", mss::c_str(i_target));
        FAPI_TRY( fapi2::delay(mss::cycles_to_ns(i_target, 32), mss::cycles_to_simcycles(32)) );

        //
        // Done bang-bang-lock
        //

        // Per J. Bialas, force_mclk_low can be dasserted.
        FAPI_TRY(mss::change_force_mclk_low(i_target, mss::HIGH),
                 "force_mclk_low (set low) Failed rc = 0x%08X", uint64_t(fapi2::current_err) );

        // Workarounds
        FAPI_TRY( mss::workarounds::dp16::after_phy_reset(i_target) );

        // mss::check::during_phy_reset checks to see if there are any FIR. We do this 'twice' once here
        // (as part of the good-path) and once if we jump to the fapi_try label.
        if ((fapi2::current_err = mss::check::during_phy_reset(i_target)) != fapi2::FAPI2_RC_SUCCESS)
        {
            goto leave_for_real;
        }

        // Unmask the FIR we want unmasked after phy reset is complete. Note this is the "good path."
        // The algorithm is 'good path do after_phy_reset, all paths (error or not) perform the checks
        // which are defined in during_phy_reset'. We won't run after_phy_reset (unmask of FIR) unless
        // we're done with a success.
        FAPI_TRY( mss::unmask::after_phy_reset(i_target) );

        // Leave as we're all good and checked the FIR already ...
        return fapi2::current_err;

        // ... here on a bad-path, check FIR and leave ...
    fapi_try_exit:

        // mss::check::during_phy_reset handles the error/no error case internally. All we need to do is
        // return the ReturnCode it hands us - it's taken care of commiting anything it needed to.
        return mss::check::during_phy_reset(i_target);

        // ... here if the good-path FIR check found an error. We jumped over the unmasking and are
        // returning an error to the caller.
    leave_for_real:
        return fapi2::current_err;

    }

}
<|endoftext|>