<commit_before>#include "ParamsSM30.h"
#include <ShaderMeta/SM30ShaderMeta.h>
#include <Utils.h>
#include <Logging.h>
#include <iostream>

//???!!!TODO:
//???skip loading shader metadata when creating effect in DEM? all relevant metadata is already copied to the effect.

struct CSM30EffectMeta
{
	// Param ID -> shader type mask + metadata
	//std::map<CStrID, std::pair<uint8_t, CSM30BufferMeta>> Buffers;
	//std::map<CStrID, std::pair<uint8_t, CSM30StructMeta>> Structs;
	std::vector<CSM30BufferMeta> Buffers;
	std::vector<CSM30StructMeta> Structs;
	std::map<CStrID, std::pair<uint8_t, CSM30ConstMeta>> Consts;
	std::map<CStrID, std::pair<uint8_t, CSM30RsrcMeta>> Resources;
	std::map<CStrID, std::pair<uint8_t, CSM30SamplerMeta>> Samplers;

	// Cache for faster search
	std::set<uint32_t> UsedFloat4;
	std::set<uint32_t> UsedInt4;
	std::set<uint32_t> UsedBool;
	std::set<uint32_t> UsedResources;
	std::set<uint32_t> UsedSamplers;

	// For logging
	std::string PrintableName;
};

static bool CheckConstRegisterOverlapping(const CSM30ConstMeta& Param, CSM30EffectMeta& Meta, const CSM30EffectMeta& Other)
{
	auto& Regs =
		(Param.RegisterSet == RS_Float4) ? Meta.UsedFloat4 :
		(Param.RegisterSet == RS_Int4) ? Meta.UsedInt4 :
		Meta.UsedBool;

	const auto& OtherRegs =
		(Param.RegisterSet == RS_Float4) ? Other.UsedFloat4 :
		(Param.RegisterSet == RS_Int4) ? Other.UsedInt4 :
		Other.UsedBool;

	for (uint32_t r = Param.RegisterStart; r < Param.RegisterStart + Param.RegisterCount; ++r)
	{
		// Fail if overlapping detected. Overlapping data can't be correctly set from effects.
		if (OtherRegs.find(r) != OtherRegs.cend()) return false;

		// Remember our own registers to check overlapping with other objects
		Regs.insert(r);
	}

	return true;
}

static bool ProcessNewConstant(uint8_t ShaderType, CSM30ConstMeta& Param, const CSM30ShaderMeta& SrcMeta, CSM30EffectMeta& TargetMeta, const CSM30EffectMeta& OtherMeta1, const CSM30EffectMeta& OtherMeta2, const CContext& Ctx)
{
	CStrID ID(Param.Name.c_str());

	// Check if this param was already added from another shader
	auto ItPrev = TargetMeta.Consts.find(ID);
	if (ItPrev == TargetMeta.Consts.cend())
	{
		// New param, check register overlapping and add to meta

		if (!CheckConstRegisterOverlapping(Param, TargetMeta, OtherMeta1))
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " param '" << ID.CStr() << "' uses a register used by " << OtherMeta1.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		if (!CheckConstRegisterOverlapping(Param, TargetMeta, OtherMeta2))
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " param '" << ID.CStr() << "' uses a register used by " << OtherMeta2.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		TargetMeta.Consts.emplace(ID, std::make_pair(ShaderType, std::move(Param)));

		// Copy related struct and buffer metadata

		// TODO: copy necessary struct and buffer meta!
		//!!!fix buffer indexing! check if this buffer already exists!
		//???check by name, by == or both? can be problems with multiple shaders?
	}
	else
	{
		// The same param found, check compatibility

		const auto& ExistingMeta = ItPrev->second.second;
		if (ExistingMeta != Param)
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " param '" << ID.CStr() << "' is not compatible across all tech shaders" << Ctx.LineEnd;
			return false;
		}

		// Compare containing constant buffers

		//!!!for SM30 we must not compare constantbuffers because they are fictional. If constants itselves
		// are the same, registers are compatible, so we can use this constants even from different buffers.
		// We just throw away the second buffer.
		//!!!that's why operator == for SM30 buffers always returns true!

		//???must be equal or compatible?
		if (TargetMeta.Buffers[ExistingMeta.BufferIndex] != SrcMeta.Buffers[Param.BufferIndex])
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " param '" << ID.CStr() << "' containing constant buffer is not compatible across all tech shaders" << Ctx.LineEnd;
			return false;
		}

		// Extend shader mask
		ItPrev->second.first |= ShaderType;
	}

	return true;
}

bool WriteParameterTablesForDX9C(std::ostream& Stream, const std::vector<CTechnique>& Techs, const CContext& Ctx)
{
	CSM30EffectMeta GlobalMeta, MaterialMeta, TechMeta;
	GlobalMeta.PrintableName = "Global";
	MaterialMeta.PrintableName = "Material";
	TechMeta.PrintableName = "Tech";

	for (const auto& Tech : Techs)
	{
		for (CStrID PassID : Tech.Passes)
		{
			const CRenderState& RS = Ctx.RSCache.at(PassID);

			CStrID ShaderIDs[] = { RS.VertexShader, RS.PixelShader, RS.GeometryShader, RS.HullShader, RS.DomainShader };

			for (uint8_t ShaderType = ShaderType_Vertex; ShaderType < ShaderType_COUNT; ++ShaderType)
			{
				const CStrID ShaderID = ShaderIDs[ShaderType];
				if (!ShaderID) continue;

				CSM30ShaderMeta ShaderMeta;
				{
					const CShaderData& ShaderData = Ctx.ShaderCache.at(ShaderID);
					membuf MetaBuffer(ShaderData.MetaBytes.get(), ShaderData.MetaBytes.get() + ShaderData.MetaByteCount);
					std::istream MetaStream(&MetaBuffer);
					MetaStream >> ShaderMeta;
				}

				for (auto& Const : ShaderMeta.Consts)
				{
					if (Ctx.LogVerbosity >= EVerbosity::Debug)
						std::cout << "Shader '" << ShaderID.CStr() << "' constant " << Const.Name << Ctx.LineEnd;

					CStrID ID(Const.Name.c_str());
					if (Ctx.GlobalParams.find(ID) != Ctx.GlobalParams.cend())
					{
						ProcessNewConstant(ShaderType, Const, ShaderMeta, GlobalMeta, MaterialMeta, TechMeta, Ctx);
					}
					else
					{
						auto ItMtl = Ctx.MaterialParams.find(ID);
						if (ItMtl != Ctx.MaterialParams.cend())
						{
							ProcessNewConstant(ShaderType, Const, ShaderMeta, MaterialMeta, GlobalMeta, TechMeta, Ctx);

							// process defaults
						}
						else
						{
							ProcessNewConstant(ShaderType, Const, ShaderMeta, TechMeta, GlobalMeta, MaterialMeta, Ctx);
						}
					}
				}

				for (auto& Rsrc : ShaderMeta.Resources)
				{
					if (Ctx.LogVerbosity >= EVerbosity::Debug)
						std::cout << "Shader '" << ShaderID.CStr() << "' resource " << Rsrc.Name << Ctx.LineEnd;

					CStrID ID(Rsrc.Name.c_str());
					if (Ctx.GlobalParams.find(ID) != Ctx.GlobalParams.cend())
					{
						//!!! check that registers don't overlap !
						//GlobalMeta.Resources.push_back(std::move(Rsrc));
					}
					else
					{
						auto ItMtl = Ctx.MaterialParams.find(ID);
						if (ItMtl != Ctx.MaterialParams.cend())
						{
							//!!! check that registers don't overlap !
							//MaterialMeta.Resources.push_back(std::move(Rsrc));

							// process defaults
						}
						else
						{
							////!!! check that registers don't overlap !
							//TechMeta.Resources.push_back(std::move(Rsrc));
						}
					}

					//in all cases check that registers don't overlap
				}

				for (auto& Sampler : ShaderMeta.Samplers)
				{
					if (Ctx.LogVerbosity >= EVerbosity::Debug)
						std::cout << "Shader '" << ShaderID.CStr() << "' sampler " << Sampler.Name << Ctx.LineEnd;

					CStrID ID(Sampler.Name.c_str());
					if (Ctx.GlobalParams.find(ID) != Ctx.GlobalParams.cend())
					{
						//!!! check that registers don't overlap !
						//GlobalMeta.Samplers.push_back(std::move(Sampler));
					}
					else
					{
						auto ItMtl = Ctx.MaterialParams.find(ID);
						if (ItMtl != Ctx.MaterialParams.cend())
						{
							//!!! check that registers don't overlap !
							//MaterialMeta.Samplers.push_back(std::move(Sampler));

							// process defaults
						}
						else
						{
							//!!! check that registers don't overlap !
							//TechMeta.Samplers.push_back(std::move(Sampler));
						}
					}
				}
			}
		}
	}

	return false;
}
<commit_msg>sm3.0 all types of meta are gathered to param tables, except buffers and structs<commit_after>#include "ParamsSM30.h"
#include <ShaderMeta/SM30ShaderMeta.h>
#include <Utils.h>
#include <Logging.h>
#include <iostream>

//???!!!TODO:
//???skip loading shader metadata when creating effect in DEM? all relevant metadata is already copied to the effect.

struct CSM30EffectMeta
{
	// Param ID -> shader type mask + metadata
	//std::map<CStrID, std::pair<uint8_t, CSM30BufferMeta>> Buffers;
	//std::map<CStrID, std::pair<uint8_t, CSM30StructMeta>> Structs;
	std::vector<CSM30BufferMeta> Buffers;
	std::vector<CSM30StructMeta> Structs;
	std::map<CStrID, std::pair<uint8_t, CSM30ConstMeta>> Consts;
	std::map<CStrID, std::pair<uint8_t, CSM30RsrcMeta>> Resources;
	std::map<CStrID, std::pair<uint8_t, CSM30SamplerMeta>> Samplers;

	// Cache for faster search
	std::set<uint32_t> UsedFloat4;
	std::set<uint32_t> UsedInt4;
	std::set<uint32_t> UsedBool;
	std::set<uint32_t> UsedResources;
	std::set<uint32_t> UsedSamplers;

	// For logging
	std::string PrintableName;
};

static bool CheckConstRegisterOverlapping(const CSM30ConstMeta& Param, const CSM30EffectMeta& Other)
{
	const auto& OtherRegs =
		(Param.RegisterSet == RS_Float4) ? Other.UsedFloat4 :
		(Param.RegisterSet == RS_Int4) ? Other.UsedInt4 :
		Other.UsedBool;

	// Fail if overlapping detected. Overlapping data can't be correctly set from effects.
	for (uint32_t r = Param.RegisterStart; r < Param.RegisterStart + Param.RegisterCount; ++r)
		if (OtherRegs.find(r) != OtherRegs.cend())
			return false;

	return true;
}
//---------------------------------------------------------------------

static bool CheckSamplerRegisterOverlapping(const CSM30SamplerMeta& Param, const CSM30EffectMeta& Other)
{
	// Fail if overlapping detected. Overlapping data can't be correctly set from effects.
	for (uint32_t r = Param.RegisterStart; r < Param.RegisterStart + Param.RegisterCount; ++r)
		if (Other.UsedSamplers.find(r) != Other.UsedSamplers.cend())
			return false;

	return true;
}
//---------------------------------------------------------------------

static bool ProcessNewConstant(uint8_t ShaderType, CSM30ConstMeta& Param, const CSM30ShaderMeta& SrcMeta, CSM30EffectMeta& TargetMeta, const CSM30EffectMeta& OtherMeta1, const CSM30EffectMeta& OtherMeta2, const CContext& Ctx)
{
	CStrID ID(Param.Name.c_str());

	// Check if this param was already added from another shader
	auto ItPrev = TargetMeta.Consts.find(ID);
	if (ItPrev == TargetMeta.Consts.cend())
	{
		// Check register overlapping, because it prevents correct param setup from effects

		if (!CheckConstRegisterOverlapping(Param, OtherMeta1))
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " constant '" << ID.CStr() << "' uses a register used by " << OtherMeta1.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		if (!CheckConstRegisterOverlapping(Param, OtherMeta2))
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " constant '" << ID.CStr() << "' uses a register used by " << OtherMeta2.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		// Remember used registers for future overlap checks

		auto& Regs =
			(Param.RegisterSet == RS_Float4) ? TargetMeta.UsedFloat4 :
			(Param.RegisterSet == RS_Int4) ? TargetMeta.UsedInt4 :
			TargetMeta.UsedBool;

		for (uint32_t r = Param.RegisterStart; r < Param.RegisterStart + Param.RegisterCount; ++r)
			Regs.insert(r);

		// Copy necessary metadata

		TargetMeta.Consts.emplace(ID, std::make_pair(ShaderType, std::move(Param)));

		// TODO: copy necessary struct and buffer meta!
		//!!!fix buffer indexing! check if this buffer already exists!
		//???check by name, by == or both? can be problems with multiple shaders?
	}
	else
	{
		// The same param found, check compatibility

		const auto& ExistingMeta = ItPrev->second.second;
		if (ExistingMeta != Param)
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " constant '" << ID.CStr() << "' is not compatible across all tech shaders" << Ctx.LineEnd;
			return false;
		}

		// Compare containing constant buffers

		//!!!for SM30 we must not compare constantbuffers because they are fictional. If constants itselves
		// are the same, registers are compatible, so we can use this constants even from different buffers.
		// We just throw away the second buffer.
		//!!!that's why operator == for SM30 buffers always returns true!

		//???must be equal or compatible?
		if (TargetMeta.Buffers[ExistingMeta.BufferIndex] != SrcMeta.Buffers[Param.BufferIndex])
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " param '" << ID.CStr() << "' containing constant buffer is not compatible across all tech shaders" << Ctx.LineEnd;
			return false;
		}

		// Extend shader mask
		ItPrev->second.first |= ShaderType;
	}

	return true;
}
//---------------------------------------------------------------------

static bool ProcessNewResource(uint8_t ShaderType, CSM30RsrcMeta& Param, CSM30EffectMeta& TargetMeta, const CSM30EffectMeta& OtherMeta1, const CSM30EffectMeta& OtherMeta2, const CContext& Ctx)
{
	CStrID ID(Param.Name.c_str());

	// Check if this param was already added from another shader
	auto ItPrev = TargetMeta.Resources.find(ID);
	if (ItPrev == TargetMeta.Resources.cend())
	{
		if (OtherMeta1.UsedResources.find(Param.Register) != OtherMeta1.UsedResources.cend())
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " resource '" << ID.CStr() << "' uses a register used by " << OtherMeta1.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		if (OtherMeta2.UsedResources.find(Param.Register) != OtherMeta2.UsedResources.cend())
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " resource '" << ID.CStr() << "' uses a register used by " << OtherMeta2.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		TargetMeta.UsedResources.insert(Param.Register);

		TargetMeta.Resources.emplace(ID, std::make_pair(ShaderType, std::move(Param)));
	}
	else
	{
		// The same param found, check compatibility
		const auto& ExistingMeta = ItPrev->second.second;
		if (ExistingMeta != Param)
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " resource '" << ID.CStr() << "' is not compatible across all tech shaders" << Ctx.LineEnd;
			return false;
		}

		// Extend shader mask
		ItPrev->second.first |= ShaderType;
	}

	return true;
}
//---------------------------------------------------------------------

static bool ProcessNewSampler(uint8_t ShaderType, CSM30SamplerMeta& Param, CSM30EffectMeta& TargetMeta, const CSM30EffectMeta& OtherMeta1, const CSM30EffectMeta& OtherMeta2, const CContext& Ctx)
{
	CStrID ID(Param.Name.c_str());

	// Check if this param was already added from another shader
	auto ItPrev = TargetMeta.Samplers.find(ID);
	if (ItPrev == TargetMeta.Samplers.cend())
	{
		if (!CheckSamplerRegisterOverlapping(Param, OtherMeta1))
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " sampler '" << ID.CStr() << "' uses a register used by " << OtherMeta1.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		if (!CheckSamplerRegisterOverlapping(Param, OtherMeta2))
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " sampler '" << ID.CStr() << "' uses a register used by " << OtherMeta2.PrintableName << " params" << Ctx.LineEnd;
			return false;
		}

		for (uint32_t r = Param.RegisterStart; r < Param.RegisterStart + Param.RegisterCount; ++r)
			TargetMeta.UsedSamplers.insert(r);

		TargetMeta.Samplers.emplace(ID, std::make_pair(ShaderType, std::move(Param)));
	}
	else
	{
		// The same param found, check compatibility
		const auto& ExistingMeta = ItPrev->second.second;
		if (ExistingMeta != Param)
		{
			if (Ctx.LogVerbosity >= EVerbosity::Errors)
				std::cout << TargetMeta.PrintableName << " sampler '" << ID.CStr() << "' is not compatible across all tech shaders" << Ctx.LineEnd;
			return false;
		}

		// Extend shader mask
		ItPrev->second.first |= ShaderType;
	}

	return true;
}
//---------------------------------------------------------------------

bool WriteParameterTablesForDX9C(std::ostream& Stream, const std::vector<CTechnique>& Techs, const CContext& Ctx)
{
	CSM30EffectMeta GlobalMeta, MaterialMeta, TechMeta;
	GlobalMeta.PrintableName = "Global";
	MaterialMeta.PrintableName = "Material";
	TechMeta.PrintableName = "Tech";

	for (const auto& Tech : Techs)
	{
		for (CStrID PassID : Tech.Passes)
		{
			const CRenderState& RS = Ctx.RSCache.at(PassID);

			CStrID ShaderIDs[] = { RS.VertexShader, RS.PixelShader, RS.GeometryShader, RS.HullShader, RS.DomainShader };

			for (uint8_t ShaderType = ShaderType_Vertex; ShaderType < ShaderType_COUNT; ++ShaderType)
			{
				const CStrID ShaderID = ShaderIDs[ShaderType];
				if (!ShaderID) continue;

				CSM30ShaderMeta ShaderMeta;
				{
					const CShaderData& ShaderData = Ctx.ShaderCache.at(ShaderID);
					membuf MetaBuffer(ShaderData.MetaBytes.get(), ShaderData.MetaBytes.get() + ShaderData.MetaByteCount);
					std::istream MetaStream(&MetaBuffer);
					MetaStream >> ShaderMeta;
				}

				for (auto& Const : ShaderMeta.Consts)
				{
					if (Ctx.LogVerbosity >= EVerbosity::Debug)
						std::cout << "Shader '" << ShaderID.CStr() << "' constant " << Const.Name << Ctx.LineEnd;

					CStrID ID(Const.Name.c_str());
					if (Ctx.GlobalParams.find(ID) != Ctx.GlobalParams.cend())
					{
						ProcessNewConstant(ShaderType, Const, ShaderMeta, GlobalMeta, MaterialMeta, TechMeta, Ctx);
					}
					else
					{
						auto ItMtl = Ctx.MaterialParams.find(ID);
						if (ItMtl != Ctx.MaterialParams.cend())
						{
							ProcessNewConstant(ShaderType, Const, ShaderMeta, MaterialMeta, GlobalMeta, TechMeta, Ctx);

							// process defaults - null or depends on const type
							//???!!!support defaults for structs? CParams with fields!
						}
						else
						{
							ProcessNewConstant(ShaderType, Const, ShaderMeta, TechMeta, GlobalMeta, MaterialMeta, Ctx);
						}
					}
				}

				for (auto& Rsrc : ShaderMeta.Resources)
				{
					if (Ctx.LogVerbosity >= EVerbosity::Debug)
						std::cout << "Shader '" << ShaderID.CStr() << "' resource " << Rsrc.Name << Ctx.LineEnd;

					CStrID ID(Rsrc.Name.c_str());
					if (Ctx.GlobalParams.find(ID) != Ctx.GlobalParams.cend())
					{
						ProcessNewResource(ShaderType, Rsrc, GlobalMeta, MaterialMeta, TechMeta, Ctx);
					}
					else
					{
						auto ItMtl = Ctx.MaterialParams.find(ID);
						if (ItMtl != Ctx.MaterialParams.cend())
						{
							ProcessNewResource(ShaderType, Rsrc, MaterialMeta, GlobalMeta, TechMeta, Ctx);

							// process defaults - null, string, CStrID
						}
						else
						{
							ProcessNewResource(ShaderType, Rsrc, TechMeta, GlobalMeta, MaterialMeta, Ctx);
						}
					}
				}

				for (auto& Sampler : ShaderMeta.Samplers)
				{
					if (Ctx.LogVerbosity >= EVerbosity::Debug)
						std::cout << "Shader '" << ShaderID.CStr() << "' sampler " << Sampler.Name << Ctx.LineEnd;

					CStrID ID(Sampler.Name.c_str());
					if (Ctx.GlobalParams.find(ID) != Ctx.GlobalParams.cend())
					{
						ProcessNewSampler(ShaderType, Sampler, GlobalMeta, MaterialMeta, TechMeta, Ctx);
					}
					else
					{
						auto ItMtl = Ctx.MaterialParams.find(ID);
						if (ItMtl != Ctx.MaterialParams.cend())
						{
							ProcessNewSampler(ShaderType, Sampler, MaterialMeta, GlobalMeta, TechMeta, Ctx);

							// process defaults - null or CParams
						}
						else
						{
							ProcessNewSampler(ShaderType, Sampler, TechMeta, GlobalMeta, MaterialMeta, Ctx);
						}
					}
				}
			}
		}
	}

	return false;
}
//---------------------------------------------------------------------
<|endoftext|>


<commit_before>#ifndef _SV_CTRL_HXX
#include <vcl/ctrl.hxx>
#endif

#include <vector>

class ToolbarMenuEntry;
typedef std::vector< ToolbarMenuEntry * > ToolbarMenuEntryVector;

class ToolbarMenu : public Control
{
private:
    ToolbarMenuEntryVector  maEntryVector;

    int mnCheckPos;
    int mnImagePos;
    int mnTextPos;

    int mnHighlightedEntry;
    int mnSelectedEntry;

    Size maSize;

    Link            maHighlightHdl;
    Link            maSelectHdl;

    void            StateChanged( StateChangedType nType );
    void            DataChanged( const DataChangedEvent& rDCEvt );

    void            initWindow();

    Size            implCalcSize();

    void            appendEntry( ToolbarMenuEntry* pEntry );

    void            implPaint( ToolbarMenuEntry* pThisOnly = NULL, bool bHighlight = false );

    void            implHighlightEntry( int nHighlightEntry, bool bHighlight );
    void            implHighlightEntry( const MouseEvent& rMEvt, bool bMBDown );

    void            implChangeHighlightEntry( int nEntry );
    void            implSelectEntry( int nSelectedEntry );

    ToolbarMenuEntry*   implCursorUpDown( bool bUp, bool bHomeEnd );
    ToolbarMenuEntry*   implGetEntry( int nEntry ) const;
    ToolbarMenuEntry*   implSearchEntry( int nEntryId ) const;

public:
                    ToolbarMenu( Window* pParent, WinBits nStyle );
                    ~ToolbarMenu();

    virtual void    MouseMove( const MouseEvent& rMEvt );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt );
    virtual void    MouseButtonUp( const MouseEvent& rMEvt );
    virtual void    KeyInput( const KeyEvent& rKEvent );
    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    Paint( const Rectangle& rRect );
    virtual void    RequestHelp( const HelpEvent& rHEvt );
    virtual void    Resize();
    virtual void    GetFocus();
    virtual void    LoseFocus();

    void            appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, const Image& rImage, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, const String& rStr, Control* pControl, MenuItemBits nItemBits = 0 );
    void            appendSeparator();

    void            checkEntry( int nEntryId, bool bCheck = true );
    bool            isEntryChecked( int nEntryId ) const;

    void            enableEntry( int nEntryId, bool bEnable = true );
    bool            isEntryEnabled( int nEntryId ) const;

    void            setEntryText( int nEntryId, const String& rStr );
    const String&   getEntryText( int nEntryId ) const;

    void            setEntryImage( int nEntryId, const Image& rImage );
    const Image&    getEntryImage( int nEntryId ) const;

    const Size&     getMenuSize() const { return maSize; }

    void            SetHighlightHdl( const Link& rLink )    { maHighlightHdl = rLink; }
    const Link&     GetHighlightHdl() const                 { return maHighlightHdl; }

    void            SetSelectHdl( const Link& rLink )       { maSelectHdl = rLink; }
    const Link&     GetSelectHdl() const                    { return maSelectHdl; }

    int             getSelectedEntryId() const;
    int             getHighlightedEntryId() const;
};
<commit_msg>INTEGRATION: CWS changefileheader (1.2.2172); FILE MERGED 2008/04/01 15:51:49 thb 1.2.2172.1: #i85898# Stripping all external header guards<commit_after>#include <vcl/ctrl.hxx>

#include <vector>

class ToolbarMenuEntry;
typedef std::vector< ToolbarMenuEntry * > ToolbarMenuEntryVector;

class ToolbarMenu : public Control
{
private:
    ToolbarMenuEntryVector  maEntryVector;

    int mnCheckPos;
    int mnImagePos;
    int mnTextPos;

    int mnHighlightedEntry;
    int mnSelectedEntry;

    Size maSize;

    Link            maHighlightHdl;
    Link            maSelectHdl;

    void            StateChanged( StateChangedType nType );
    void            DataChanged( const DataChangedEvent& rDCEvt );

    void            initWindow();

    Size            implCalcSize();

    void            appendEntry( ToolbarMenuEntry* pEntry );

    void            implPaint( ToolbarMenuEntry* pThisOnly = NULL, bool bHighlight = false );

    void            implHighlightEntry( int nHighlightEntry, bool bHighlight );
    void            implHighlightEntry( const MouseEvent& rMEvt, bool bMBDown );

    void            implChangeHighlightEntry( int nEntry );
    void            implSelectEntry( int nSelectedEntry );

    ToolbarMenuEntry*   implCursorUpDown( bool bUp, bool bHomeEnd );
    ToolbarMenuEntry*   implGetEntry( int nEntry ) const;
    ToolbarMenuEntry*   implSearchEntry( int nEntryId ) const;

public:
                    ToolbarMenu( Window* pParent, WinBits nStyle );
                    ~ToolbarMenu();

    virtual void    MouseMove( const MouseEvent& rMEvt );
    virtual void    MouseButtonDown( const MouseEvent& rMEvt );
    virtual void    MouseButtonUp( const MouseEvent& rMEvt );
    virtual void    KeyInput( const KeyEvent& rKEvent );
    virtual void    Command( const CommandEvent& rCEvt );
    virtual void    Paint( const Rectangle& rRect );
    virtual void    RequestHelp( const HelpEvent& rHEvt );
    virtual void    Resize();
    virtual void    GetFocus();
    virtual void    LoseFocus();

    void            appendEntry( int nEntryId, const String& rStr, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, const Image& rImage, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, const String& rStr, const Image& rImage, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, Control* pControl, MenuItemBits nItemBits = 0 );
    void            appendEntry( int nEntryId, const String& rStr, Control* pControl, MenuItemBits nItemBits = 0 );
    void            appendSeparator();

    void            checkEntry( int nEntryId, bool bCheck = true );
    bool            isEntryChecked( int nEntryId ) const;

    void            enableEntry( int nEntryId, bool bEnable = true );
    bool            isEntryEnabled( int nEntryId ) const;

    void            setEntryText( int nEntryId, const String& rStr );
    const String&   getEntryText( int nEntryId ) const;

    void            setEntryImage( int nEntryId, const Image& rImage );
    const Image&    getEntryImage( int nEntryId ) const;

    const Size&     getMenuSize() const { return maSize; }

    void            SetHighlightHdl( const Link& rLink )    { maHighlightHdl = rLink; }
    const Link&     GetHighlightHdl() const                 { return maHighlightHdl; }

    void            SetSelectHdl( const Link& rLink )       { maSelectHdl = rLink; }
    const Link&     GetSelectHdl() const                    { return maSelectHdl; }

    int             getSelectedEntryId() const;
    int             getHighlightedEntryId() const;
};
<|endoftext|>


<commit_before>#include "ImGuiEntityEditorSystem.hpp"
#include "EntityManager.hpp"

#include "data/ImGuiComponent.hpp"
#include "data/ImGuiToolComponent.hpp"
#include "data/SelectedComponent.hpp"
#include "data/NameComponent.hpp"

#include "helpers/typeHelper.hpp"
#include "helpers/imGuiHelper.hpp"
#include "imgui.h"

namespace kengine {
	EntityCreatorFunctor<64> ImGuiEntityEditorSystem(EntityManager & em) {
		return [&](Entity & e) {
			e += NameComponent{ "Entity editor" };
			auto & tool = e.attach<ImGuiToolComponent>();
			tool.enabled = true;

			e += ImGuiComponent([&] {
				if (!tool.enabled)
					return;

				for (auto & [selected, _] : em.getEntities<SelectedComponent>()) {
					bool open = true;

					ImGui::SetNextWindowSize({ 200.f, 200.f }, ImGuiCond_FirstUseEver);

					const auto beginWindow = [&] {
						if (selected.has<NameComponent>())
							return ImGui::Begin(putils::string<64>("%s##[%d]", selected.get<NameComponent>().name.c_str(), selected.id), &open, ImGuiWindowFlags_NoSavedSettings);
						else
							return ImGui::Begin(putils::string<64>("[%d] Entity editor", selected.id), nullptr, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar);
					};

					if (beginWindow()) {
						if (!selected.has<NameComponent>()) // no title bar
							if (ImGui::Button("x"))
								selected.detach<SelectedComponent>();

						ImGui::Separator();

						ImGui::BeginChild("##child");
						imguiHelper::editEntity(em, selected);
						ImGui::EndChild();
					}
					ImGui::End();

					if (!open)
						selected.detach<SelectedComponent>();
				}
			});
		};
	}
}
<commit_msg>imgui editor - take imgui scale into account for new editor windows<commit_after>#include "ImGuiEntityEditorSystem.hpp"
#include "EntityManager.hpp"

#include "data/ImGuiComponent.hpp"
#include "data/ImGuiToolComponent.hpp"
#include "data/SelectedComponent.hpp"
#include "data/NameComponent.hpp"

#include "functions/GetImGuiScale.hpp"

#include "helpers/typeHelper.hpp"
#include "helpers/imGuiHelper.hpp"
#include "imgui.h"

namespace kengine {
	EntityCreatorFunctor<64> ImGuiEntityEditorSystem(EntityManager & em) {
		return [&](Entity & e) {
			e += NameComponent{ "Entity editor" };
			auto & tool = e.attach<ImGuiToolComponent>();
			tool.enabled = true;

			e += ImGuiComponent([&] {
				if (!tool.enabled)
					return;

				float scale = 1.f;
				for (const auto & [e, getScale] : em.getEntities<functions::GetImGuiScale>())
					scale = getScale();

				for (auto & [selected, _] : em.getEntities<SelectedComponent>()) {
					bool open = true;

					ImGui::SetNextWindowSize({ 200.f * scale, 200.f * scale}, ImGuiCond_FirstUseEver);

					const auto beginWindow = [&] {
						if (selected.has<NameComponent>())
							return ImGui::Begin(putils::string<64>("%s##[%d]", selected.get<NameComponent>().name.c_str(), selected.id), &open, ImGuiWindowFlags_NoSavedSettings);
						else
							return ImGui::Begin(putils::string<64>("[%d] Entity editor", selected.id), nullptr, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoTitleBar);
					};

					if (beginWindow()) {
						if (!selected.has<NameComponent>()) // no title bar
							if (ImGui::Button("x"))
								selected.detach<SelectedComponent>();

						ImGui::Separator();

						ImGui::BeginChild("##child");
						imguiHelper::editEntity(em, selected);
						ImGui::EndChild();
					}
					ImGui::End();

					if (!open)
						selected.detach<SelectedComponent>();
				}
			});
		};
	}
}
<|endoftext|>


<commit_before>/*
* Copyright 2013 Baxter, Lovell, Mangsingkha, Saeedi
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
#include <iostream>

#include "State.h"
#include "utils.h"
#include "constants.h"

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

typedef boost::numeric::ublas::matrix<double> matrixD;
using namespace std;

int main(int argc, char** argv) {
  cout << endl << "test_state: Hello World!" << endl;

  // load some data
  matrixD data;
  string filename = "SynData2.csv";
  // string filename = "analyze_2d/ring_data.csv";
  LoadData(filename, data);
  cout << "data is: " << data << endl;
  int num_rows = data.size1();
  int num_cols = data.size2();

  // create the objects to test
  vector<int> global_row_indices = create_sequence(data.size1());
  vector<int> global_column_indices = create_sequence(data.size2());
  vector<string> global_col_types;
  vector<int> global_col_multinomial_counts;
  for(int i=0; i<global_column_indices.size(); i++) {
    global_col_types.push_back(CONTINUOUS_DATATYPE);
    global_col_multinomial_counts.push_back(0);
  }
  State s = State(data, global_col_types,
		  global_col_multinomial_counts,
		  global_row_indices,
		  global_column_indices);

  cout << "start X_D" << endl << s.get_X_D() << endl;
  int num_views = s.get_num_views();
  cout << "s.num_views: " << num_views << endl;
  for(int view_idx=0; view_idx<num_views; view_idx++) {
    View &v = s.get_view(view_idx);
    cout << "view idx " << view_idx << ": ";
    v.print();
  }

  for(int i=0;i<200;i++) {
    cout << "transition #: " << i << endl;
    s.transition(data);
    cout << "s.num_views: " << s.get_num_views() << endl;
    for(int j=0;j<s.get_num_views(); j++) {
      cout << "view " << j << " row_paritition_model_counts: " << s.get_row_partition_model_counts_i(j) << endl;
    }
    cout << "s.column_crp_score: " << s.get_column_crp_score();
    cout << "; s.data_score: " << s.get_data_score();
    cout << "; s.score: " << s.get_marginal_logp();
    cout << endl;
  }

  num_views = s.get_num_views();
  for(int view_idx=0; view_idx<num_views; view_idx++) {
    View &v = s.get_view(view_idx);
    cout << "view_idx " << view_idx << ": " << endl;
    v.print();
  }

  cout << "FINAL STATE" << endl;
  cout << s << endl;

  cout << "end X_D" << endl << s.get_X_D() << endl;
  cout << endl << "test_state: Goodbye World!" << endl;
}
<commit_msg>change filename read<commit_after>/*
* Copyright 2013 Baxter, Lovell, Mangsingkha, Saeedi
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*/
#include <iostream>

#include "State.h"
#include "utils.h"
#include "constants.h"

#include <boost/numeric/ublas/matrix.hpp>
#include <boost/numeric/ublas/io.hpp>

typedef boost::numeric::ublas::matrix<double> matrixD;
using namespace std;

int main(int argc, char** argv) {
  cout << endl << "test_state: Hello World!" << endl;

  // load some data
  matrixD data;
  // tail -n +2 ../../www/data/dha_small_cont.csv > dha_small_cont_no_header.csv
  // string filename = "SynData2.csv";
  string filename = "dha_small_cont_no_header.csv";
  // string filename = "analyze_2d/ring_data.csv";
  LoadData(filename, data);
  cout << "data is: " << data << endl;
  int num_rows = data.size1();
  int num_cols = data.size2();

  // create the objects to test
  vector<int> global_row_indices = create_sequence(data.size1());
  vector<int> global_column_indices = create_sequence(data.size2());
  vector<string> global_col_types;
  vector<int> global_col_multinomial_counts;
  for(int i=0; i<global_column_indices.size(); i++) {
    global_col_types.push_back(CONTINUOUS_DATATYPE);
    global_col_multinomial_counts.push_back(0);
  }
  State s = State(data, global_col_types,
		  global_col_multinomial_counts,
		  global_row_indices,
		  global_column_indices);

  cout << "start X_D" << endl << s.get_X_D() << endl;
  int num_views = s.get_num_views();
  cout << "s.num_views: " << num_views << endl;
  for(int view_idx=0; view_idx<num_views; view_idx++) {
    View &v = s.get_view(view_idx);
    cout << "view idx " << view_idx << ": ";
    v.print();
  }

  for(int i=0;i<200;i++) {
    cout << "transition #: " << i << endl;
    s.transition(data);
    cout << "s.num_views: " << s.get_num_views() << endl;
    for(int j=0;j<s.get_num_views(); j++) {
      cout << "view " << j << " row_paritition_model_counts: " << s.get_row_partition_model_counts_i(j) << endl;
    }
    cout << "s.column_crp_score: " << s.get_column_crp_score();
    cout << "; s.data_score: " << s.get_data_score();
    cout << "; s.score: " << s.get_marginal_logp();
    cout << endl;
  }

  num_views = s.get_num_views();
  for(int view_idx=0; view_idx<num_views; view_idx++) {
    View &v = s.get_view(view_idx);
    cout << "view_idx " << view_idx << ": " << endl;
    v.print();
  }

  cout << "FINAL STATE" << endl;
  cout << s << endl;

  cout << "end X_D" << endl << s.get_X_D() << endl;
  cout << endl << "test_state: Goodbye World!" << endl;
}
<|endoftext|>


<commit_before><commit_msg>Part: Geometry GeomTrim Geomline segment type<commit_after><|endoftext|>


<commit_before>#include "QZXingFilterVideoSink.h"
#include <QDebug>
#include <QtConcurrent/QtConcurrent>
#include "QZXingImageProvider.h"

QZXingFilter::QZXingFilter(QObject *parent)
    : QObject(parent)
    , decoder(QZXing::DecoderFormat_QR_CODE)
    , decoding(false)
{
    /// Connecting signals to handlers that will send signals to QML
    connect(&decoder, &QZXing::decodingStarted,
            this, &QZXingFilter::handleDecodingStarted);
    connect(&decoder, &QZXing::decodingFinished,
            this, &QZXingFilter::handleDecodingFinished);
}

QZXingFilter::~QZXingFilter()
{
    if(!processThread.isFinished()) {
        processThread.cancel();
        processThread.waitForFinished();
    }
}

void QZXingFilter::handleDecodingStarted()
{
    decoding = true;
    emit decodingStarted();
    emit isDecodingChanged();
}

void QZXingFilter::handleDecodingFinished(bool succeeded)
{
    decoding = false;
    emit decodingFinished(succeeded, decoder.getProcessTimeOfLastDecoding());
    emit isDecodingChanged();
}

void QZXingFilter::setVideoSink(QObject *videoSink){
    m_videoSink = qobject_cast<QVideoSink*>(videoSink);

    connect(m_videoSink, &QVideoSink::videoFrameChanged, this, &QZXingFilter::processFrame);
}

void QZXingFilter::processFrame(const QVideoFrame &frame) {
    if(isDecoding() || !processThread.isFinished()) return;

    decoding = true;
    QImage image = frame.toImage();
    processThread = QtConcurrent::run([=](){
        if(image.isNull())
        {
            qDebug() << "QZXingFilter error: Cant create image file to process.";
            decoding = false;
            return;
        }

        QImage frameToProcess(image);
        const QRect& rect = captureRect.toRect();

        if (captureRect.isValid() && frameToProcess.size() != rect.size()) {
            frameToProcess = image.copy(rect);
        }

        static int i=0;
        qDebug() << "image.size()" << frameToProcess.size();
        qDebug() << "image.format()" << frameToProcess.format();
        const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i++ % 100) + ".png";
        qDebug() << "saving image" << i << "at:" << path << frameToProcess.save(path);

        decoder.decodeImage(frameToProcess, frameToProcess.width(), frameToProcess.height());
    });
}
<commit_msg>Applied fix suggested by @kiibimees when QZXingFilter is used on Android<commit_after>#include "QZXingFilterVideoSink.h"
#include <QDebug>
#include <QtConcurrent/QtConcurrent>
#include "QZXingImageProvider.h"

QZXingFilter::QZXingFilter(QObject *parent)
    : QObject(parent)
    , decoder(QZXing::DecoderFormat_QR_CODE)
    , decoding(false)
{
    /// Connecting signals to handlers that will send signals to QML
    connect(&decoder, &QZXing::decodingStarted,
            this, &QZXingFilter::handleDecodingStarted);
    connect(&decoder, &QZXing::decodingFinished,
            this, &QZXingFilter::handleDecodingFinished);
}

QZXingFilter::~QZXingFilter()
{
    if(!processThread.isFinished()) {
        processThread.cancel();
        processThread.waitForFinished();
    }
}

void QZXingFilter::handleDecodingStarted()
{
    decoding = true;
    emit decodingStarted();
    emit isDecodingChanged();
}

void QZXingFilter::handleDecodingFinished(bool succeeded)
{
    decoding = false;
    emit decodingFinished(succeeded, decoder.getProcessTimeOfLastDecoding());
    emit isDecodingChanged();
}

void QZXingFilter::setVideoSink(QObject *videoSink){
    m_videoSink = qobject_cast<QVideoSink*>(videoSink);

    connect(m_videoSink, &QVideoSink::videoFrameChanged, this, &QZXingFilter::processFrame);
}

void QZXingFilter::processFrame(const QVideoFrame &frame) {
    if(isDecoding() || !processThread.isFinished()) return;

    decoding = true;

#ifdef Q_OS_ANDROID
        m_videoSink->setRhi(nullptr); // https://bugreports.qt.io/browse/QTBUG-97789
        QVideoFrame f(frame);
        f.map(QVideoFrame::ReadOnly);
#else
        const QVideoFrame &f = frame;
#endif // Q_OS_ANDROID

    QImage image = f.toImage();
    processThread = QtConcurrent::run([=](){
        if(image.isNull())
        {
            qDebug() << "QZXingFilter error: Cant create image file to process.";
            decoding = false;
            return;
        }

        QImage frameToProcess(image);
        const QRect& rect = captureRect.toRect();

        if (captureRect.isValid() && frameToProcess.size() != rect.size()) {
            frameToProcess = image.copy(rect);
        }

        static int i=0;
        qDebug() << "image.size()" << frameToProcess.size();
        qDebug() << "image.format()" << frameToProcess.format();
        const QString path = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation) + "/qrtest/test_" + QString::number(i++ % 100) + ".png";
        qDebug() << "saving image" << i << "at:" << path << frameToProcess.save(path);

        decoder.decodeImage(frameToProcess, frameToProcess.width(), frameToProcess.height());
    });
}
<|endoftext|>


<commit_before>// $Id: quadrature_gauss_3D.C 2892 2008-06-25 21:57:54Z jwpeterson $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2007  Benjamin S. Kirk, John W. Peterson

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "quadrature_gm.h"

void QGrundmann_Moller::init_3D(const ElemType _type,
				unsigned int p)
{
  // Nearly all GM rules contain negative weights, so if you are not
  // allowing rules with negative weights, we cannot continue!
  if (!allow_rules_with_negative_weights)
    {
      std::cerr << "You requested a Grundmann-Moller rule but\n"
		<< "are not allowing rules with negative weights!\n"
		<< "Either select a different quadrature class or\n"
		<< "set allow_rules_with_negative_weights==true."
		<< std::endl;

      libmesh_error();
    }

  switch (_type)
    {
    case TET4:
    case TET10:
      {
	gm_rule( (_order + 2*p)/2 );
	return;

// 	switch(_order + 2*p)
// 	  {
// 	  case CONSTANT:
// 	  case FIRST:
// 	    {
// 	      gm_rule(0);
// 	      return;
// 	    }
// 	  case SECOND:
// 	  case THIRD:
// 	    {
// 	      gm_rule(1);
// 	      return;
// 	    }
// 	  case FOURTH:
// 	  case FIFTH:
// 	    {
// 	      gm_rule(2);
// 	      return;
// 	    }
// 	  case SIXTH:
// 	  case SEVENTH:
// 	    {
// 	      gm_rule(3);
// 	      return;
// 	    }
// 	  case EIGHTH:
// 	  case NINTH:
// 	    {
// 	      gm_rule(4);
// 	      return;
// 	    }
// 	  case TENTH:
// 	  case ELEVENTH:
// 	    {
// 	      gm_rule(5);
// 	      return;
// 	    }
// 	  case TWELFTH:
// 	  case THIRTEENTH:
// 	    {
// 	      gm_rule(6);
// 	      return;
// 	    }
// 	  case FOURTEENTH:
// 	  case FIFTEENTH:
// 	    {
// 	      gm_rule(7);
// 	      return;
// 	    }
// 	  case SIXTEENTH:
// 	  case SEVENTEENTH:
// 	    {
// 	      gm_rule(8);
// 	      return;
// 	    }
// 	  case EIGHTTEENTH:
// 	  case NINTEENTH:
// 	    {
// 	      gm_rule(9);
// 	      return;
// 	    }
// 	  case TWENTIETH:
// 	  case TWENTYFIRST:
// 	    {
// 	      gm_rule(10);
// 	      return;
// 	    }
// 	  case TWENTYSECOND:
// 	  case TWENTYTHIRD:
// 	    {
// 	      gm_rule(11);
// 	      return;
// 	    }
// 	  default:
// 	    {
// 	      std::cout << "Quadrature rule not supported!" << std::endl;

// 	      libmesh_error();
// 	    }
//	  }
      } // end case TET4, TET10

      //---------------------------------------------
      // Unsupported element type
    default:
      {
	std::cerr << "ERROR: Unsupported element type: " << _type << std::endl;
	libmesh_error();
      }
    } // end switch (_type)

  // We must have returned or errored-out by this point.  If not,
  // throw an error now.
  libmesh_error();
  return;
}
<commit_msg>Removed big commented-out case statement.  This isn't needed for the GM rules...<commit_after>// $Id: quadrature_gauss_3D.C 2892 2008-06-25 21:57:54Z jwpeterson $

// The libMesh Finite Element Library.
// Copyright (C) 2002-2007  Benjamin S. Kirk, John W. Peterson

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

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.

// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

// Local includes
#include "quadrature_gm.h"

void QGrundmann_Moller::init_3D(const ElemType _type,
				unsigned int p)
{
  // Nearly all GM rules contain negative weights, so if you are not
  // allowing rules with negative weights, we cannot continue!
  if (!allow_rules_with_negative_weights)
    {
      std::cerr << "You requested a Grundmann-Moller rule but\n"
		<< "are not allowing rules with negative weights!\n"
		<< "Either select a different quadrature class or\n"
		<< "set allow_rules_with_negative_weights==true."
		<< std::endl;

      libmesh_error();
    }

  switch (_type)
    {
    case TET4:
    case TET10:
      {
	// Untested above _order=23 but should work...
	gm_rule( (_order + 2*p)/2 );
	return;

      } // end case TET4, TET10

      //---------------------------------------------
      // Unsupported element type
    default:
      {
	std::cerr << "ERROR: Unsupported element type: " << _type << std::endl;
	libmesh_error();
      }
    } // end switch (_type)

  // We must have returned or errored-out by this point.  If not,
  // throw an error now.
  libmesh_error();
  return;
}
<|endoftext|>


<commit_before>// Halide tutorial lesson 10: AOT compilation part 1

// This lesson demonstrates how to use Halide as an more traditional
// ahead-of-time (AOT) compiler.

// This lesson is split across two files. The first (this one), builds
// a Halide pipeline and compiles it to an object file and header. The
// second (lesson_10_aot_compilation_run.cpp), uses that object file
// to actually run the pipeline. This means that compiling this code
// is a multi-step process.

// On linux, you can compile and run it like so:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate
// LD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.o -lpthread -ldl -o lesson_10_run
// ./lesson_10_run

// On os x:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -o lesson_10_generate
// DYLD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.o -o lesson_10_run
// ./lesson_10_run

// The benefits of this approach are that the final program:
// - Doesn't do any jit compilation at runtime, so it's fast.
// - Doesn't depend on libHalide at all, so it's a small, easy-to-deploy binary.

// If you have the entire Halide source tree, you can also build it by
// running:
//    make tutorial_lesson_10_aot_compilation_run
// in a shell with the current directory at the top of the halide
// source tree.

#include "Halide.h"
#include <stdio.h>
using namespace Halide;

int main(int argc, char **argv) {

    // We'll define a simple one-stage pipeline:
    Func brighter;
    Var x, y;

    // The pipeline will depend on one scalar parameter.
    Param<uint8_t> offset;

    // And take one grayscale 8-bit input buffer. The first
    // constructor argument gives the type of a pixel, and the second
    // specifies the number of dimensions (not the number of
    // channels!). For a grayscale image this is two; for a color
    // image it's three. Currently, four dimensions is the maximum for
    // inputs and outputs.
    ImageParam input(type_of<uint8_t>(), 2);

    // If we were jit-compiling, these would just be an int and an
    // Image, but because we want to compile the pipeline once and
    // have it work for any value of the parameter, we need to make a
    // Param object, which can be used like an Expr, and an ImageParam
    // object, which can be used like an Image.

    // Define the Func.
    brighter(x, y) = input(x, y) + offset;

    // Schedule it.
    brighter.vectorize(x, 16).parallel(y);

    // This time, instead of calling brighter.realize(...), which
    // would compile and run the pipeline immediately, we'll call a
    // method that compiles the pipeline to a static library and header.
    //
    // For AOT-compiled code, we need to explicitly declare the
    // arguments to the routine. This routine takes two. Arguments are
    // usually Params or ImageParams.
    std::vector<Argument> args = {input, offset};
    brighter.compile_to_static_library("lesson_10_halide", args, "brighter");

    // If you're using C++11, you can just say:
    // brighter.compile_to_static_library("lesson_10_halide", {input, offset}, "brighter");

    printf("Halide pipeline compiled, but not yet run.\n");

    // To continue this lesson, look in the file lesson_10_aot_compilation_run.cpp

    return 0;
}
<commit_msg>Fix lesson 10 comments<commit_after>
// Halide tutorial lesson 10: AOT compilation part 1

// This lesson demonstrates how to use Halide as an more traditional
// ahead-of-time (AOT) compiler.

// This lesson is split across two files. The first (this one), builds
// a Halide pipeline and compiles it to a static library and
// header. The second (lesson_10_aot_compilation_run.cpp), uses that
// static library to actually run the pipeline. This means that
// compiling this code is a multi-step process.

// On linux, you can compile and run it like so:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -lpthread -ldl -o lesson_10_generate
// LD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.a -lpthread -ldl -o lesson_10_run
// ./lesson_10_run

// On os x:
// g++ lesson_10*generate.cpp -g -std=c++11 -I ../include -L ../bin -lHalide -o lesson_10_generate
// DYLD_LIBRARY_PATH=../bin ./lesson_10_generate
// g++ lesson_10*run.cpp lesson_10_halide.a -o lesson_10_run
// ./lesson_10_run

// The benefits of this approach are that the final program:
// - Doesn't do any jit compilation at runtime, so it's fast.
// - Doesn't depend on libHalide at all, so it's a small, easy-to-deploy binary.

// If you have the entire Halide source tree, you can also build it by
// running:
//    make tutorial_lesson_10_aot_compilation_run
// in a shell with the current directory at the top of the halide
// source tree.

#include "Halide.h"
#include <stdio.h>
using namespace Halide;

int main(int argc, char **argv) {

    // We'll define a simple one-stage pipeline:
    Func brighter;
    Var x, y;

    // The pipeline will depend on one scalar parameter.
    Param<uint8_t> offset;

    // And take one grayscale 8-bit input buffer. The first
    // constructor argument gives the type of a pixel, and the second
    // specifies the number of dimensions (not the number of
    // channels!). For a grayscale image this is two; for a color
    // image it's three. Currently, four dimensions is the maximum for
    // inputs and outputs.
    ImageParam input(type_of<uint8_t>(), 2);

    // If we were jit-compiling, these would just be an int and an
    // Image, but because we want to compile the pipeline once and
    // have it work for any value of the parameter, we need to make a
    // Param object, which can be used like an Expr, and an ImageParam
    // object, which can be used like an Image.

    // Define the Func.
    brighter(x, y) = input(x, y) + offset;

    // Schedule it.
    brighter.vectorize(x, 16).parallel(y);

    // This time, instead of calling brighter.realize(...), which
    // would compile and run the pipeline immediately, we'll call a
    // method that compiles the pipeline to a static library and header.
    //
    // For AOT-compiled code, we need to explicitly declare the
    // arguments to the routine. This routine takes two. Arguments are
    // usually Params or ImageParams.
    std::vector<Argument> args = {input, offset};
    brighter.compile_to_static_library("lesson_10_halide", args, "brighter");

    // If you're using C++11, you can just say:
    // brighter.compile_to_static_library("lesson_10_halide", {input, offset}, "brighter");

    printf("Halide pipeline compiled, but not yet run.\n");

    // To continue this lesson, look in the file lesson_10_aot_compilation_run.cpp

    return 0;
}
<|endoftext|>


<commit_before>#include <limits> // for std::numeric_limits<unsigned int>::max()

#include "utility/memory.hpp"
#include "TimeWarpOutputManager.hpp"

namespace warped {

void TimeWarpOutputManager::initialize(unsigned int num_local_objects) {
    output_queue_ = make_unique<std::vector<std::shared_ptr<Event>> []>(num_local_objects);
    output_queue_lock_ = make_unique<std::mutex []>(num_local_objects);
}

void TimeWarpOutputManager::insertEvent(std::shared_ptr<Event> event,
    unsigned int local_object_id) {
    output_queue_lock_[local_object_id].lock();
    output_queue_[local_object_id].push_back(event);
    output_queue_lock_[local_object_id].unlock();
}

unsigned int TimeWarpOutputManager::fossilCollect(unsigned int gvt, unsigned int local_object_id) {

    unsigned int retval = std::numeric_limits<unsigned int>::max();

    if (output_queue_[local_object_id].empty())
        return retval;

    output_queue_lock_[local_object_id].lock();

    auto min = output_queue_[local_object_id].begin();
    while ((min != output_queue_[local_object_id].end()) && (min->get()->timestamp() < gvt)) {
        min = output_queue_[local_object_id].erase(min);
    }

    if (min != output_queue_[local_object_id].end()) {
        retval = min->get()->timestamp();
    }

    output_queue_lock_[local_object_id].unlock();

    return retval;
}

void TimeWarpOutputManager::fossilCollectAll(unsigned int gvt) {
    for (unsigned int i = 0; i < output_queue_.get()->size(); i++) {
        fossilCollect(gvt, i);
    }
}

std::unique_ptr<std::vector<std::shared_ptr<Event>>>
TimeWarpOutputManager::removeEventsSentAtOrAfter(unsigned int rollback_time,
    unsigned int local_object_id) {

    auto events_to_cancel = make_unique<std::vector<std::shared_ptr<Event>>>();

    output_queue_lock_[local_object_id].lock();

    auto max = std::prev(output_queue_[local_object_id].end());
    while ((max != output_queue_[local_object_id].begin()) &&
                    (max->get()->timestamp() >= rollback_time)) {
        events_to_cancel->push_back(*max);
        output_queue_[local_object_id].erase(max);
        max = std::prev(output_queue_[local_object_id].end());
    }

    if ((max != output_queue_[local_object_id].begin())
        && (max->get()->timestamp() >= rollback_time)) {
        events_to_cancel->push_back(*max);
        output_queue_[local_object_id].erase(max);
    }

    output_queue_lock_[local_object_id].unlock();

    return std::move(events_to_cancel);
}

std::size_t TimeWarpOutputManager::size(unsigned int local_object_id) {
    return output_queue_[local_object_id].size();
}

} // namespace warped

<commit_msg>Added check for empty output queue<commit_after>#include <limits> // for std::numeric_limits<unsigned int>::max()

#include "utility/memory.hpp"
#include "TimeWarpOutputManager.hpp"

namespace warped {

void TimeWarpOutputManager::initialize(unsigned int num_local_objects) {
    output_queue_ = make_unique<std::vector<std::shared_ptr<Event>> []>(num_local_objects);
    output_queue_lock_ = make_unique<std::mutex []>(num_local_objects);
}

void TimeWarpOutputManager::insertEvent(std::shared_ptr<Event> event,
    unsigned int local_object_id) {
    output_queue_lock_[local_object_id].lock();
    output_queue_[local_object_id].push_back(event);
    output_queue_lock_[local_object_id].unlock();
}

unsigned int TimeWarpOutputManager::fossilCollect(unsigned int gvt, unsigned int local_object_id) {

    unsigned int retval = std::numeric_limits<unsigned int>::max();

    if (output_queue_[local_object_id].empty())
        return retval;

    output_queue_lock_[local_object_id].lock();

    auto min = output_queue_[local_object_id].begin();
    while ((min != output_queue_[local_object_id].end()) && (min->get()->timestamp() < gvt)) {
        min = output_queue_[local_object_id].erase(min);
    }

    if (min != output_queue_[local_object_id].end()) {
        retval = min->get()->timestamp();
    }

    output_queue_lock_[local_object_id].unlock();

    return retval;
}

void TimeWarpOutputManager::fossilCollectAll(unsigned int gvt) {
    for (unsigned int i = 0; i < output_queue_.get()->size(); i++) {
        fossilCollect(gvt, i);
    }
}

std::unique_ptr<std::vector<std::shared_ptr<Event>>>
TimeWarpOutputManager::removeEventsSentAtOrAfter(unsigned int rollback_time,
    unsigned int local_object_id) {

    auto events_to_cancel = make_unique<std::vector<std::shared_ptr<Event>>>();

    output_queue_lock_[local_object_id].lock();
    if (output_queue_[local_object_id].empty()) {
        output_queue_lock_[local_object_id].unlock();
        return std::move(events_to_cancel);
    }

    auto max = std::prev(output_queue_[local_object_id].end());
    while ((max != output_queue_[local_object_id].begin()) &&
           (max->get()->timestamp() >= rollback_time)) {
        events_to_cancel->push_back(*max);
        output_queue_[local_object_id].erase(max);
        max = std::prev(output_queue_[local_object_id].end());
    }

    if ((max != output_queue_[local_object_id].begin())
        && (max->get()->timestamp() >= rollback_time)) {
        events_to_cancel->push_back(*max);
        output_queue_[local_object_id].erase(max);
    }

    output_queue_lock_[local_object_id].unlock();

    return std::move(events_to_cancel);
}

std::size_t TimeWarpOutputManager::size(unsigned int local_object_id) {
    return output_queue_[local_object_id].size();
}

} // namespace warped

<|endoftext|>


<commit_before>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Pavel Strakhov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "ToolWindowManagerArea.h"
#include "ToolWindowManagerTabBar.h"
#include "ToolWindowManagerWrapper.h"
#include "ToolWindowManager.h"
#include <QApplication>
#include <QMouseEvent>
#include <algorithm>

static void showCloseButton(QTabBar *bar, int index, bool show) {
  QWidget *button = bar->tabButton(index, QTabBar::RightSide);
  if(button == NULL)
    button = bar->tabButton(index, QTabBar::LeftSide);

  if(button)
    button->resize(show ? QSize(16, 16) : QSize(0, 0));
}

ToolWindowManagerArea::ToolWindowManagerArea(ToolWindowManager *manager, QWidget *parent) :
  QTabWidget(parent)
, m_manager(manager)
{
  m_tabBar = new ToolWindowManagerTabBar(this);
  setTabBar(m_tabBar);

  m_tabBar->setTabsClosable(true);

  m_dragCanStart = false;
  m_tabDragCanStart = false;
  m_inTabMoved = false;
  m_userCanDrop = true;
  setMovable(true);
  setDocumentMode(true);
  tabBar()->installEventFilter(this);
  m_manager->m_areas << this;

  QObject::connect(tabBar(), &QTabBar::tabMoved, this, &ToolWindowManagerArea::tabMoved);
  QObject::connect(tabBar(), &QTabBar::tabCloseRequested, this, &ToolWindowManagerArea::tabClosing);
  QObject::connect(tabBar(), &QTabBar::tabCloseRequested, this, &QTabWidget::tabCloseRequested);
  QObject::connect(this, &QTabWidget::currentChanged, this, &ToolWindowManagerArea::tabSelected);
}

ToolWindowManagerArea::~ToolWindowManagerArea() {
  m_manager->m_areas.removeOne(this);
}

void ToolWindowManagerArea::addToolWindow(QWidget *toolWindow, int insertIndex) {
  addToolWindows(QList<QWidget*>() << toolWindow, insertIndex);
}

void ToolWindowManagerArea::addToolWindows(const QList<QWidget *> &toolWindows, int insertIndex) {
  int index = 0;
  foreach(QWidget* toolWindow, toolWindows) {
    index = insertTab(insertIndex, toolWindow, toolWindow->windowIcon(), toolWindow->windowTitle());
    insertIndex = index+1;
    if(m_manager->toolWindowProperties(toolWindow) & ToolWindowManager::HideCloseButton) {
      showCloseButton(tabBar(), index, false);
    }
  }
  setCurrentIndex(index);
  m_manager->m_lastUsedArea = this;
}

QList<QWidget *> ToolWindowManagerArea::toolWindows() {
  QList<QWidget *> result;
  for(int i = 0; i < count(); i++) {
    result << widget(i);
  }
  return result;
}

void ToolWindowManagerArea::updateToolWindow(QWidget* toolWindow) {
  int index = indexOf(toolWindow);
  if(index >= 0) {
    if(m_manager->toolWindowProperties(toolWindow) & ToolWindowManager::HideCloseButton) {
      showCloseButton(tabBar(), index, false);
    } else {
      showCloseButton(tabBar(), index, true);
    }
    tabBar()->setTabText(index, toolWindow->windowTitle());
  }
}

void ToolWindowManagerArea::mouseMoveEvent(QMouseEvent *) {
  check_mouse_move();
}

bool ToolWindowManagerArea::eventFilter(QObject *object, QEvent *event) {
  if (object == tabBar()) {
    if (event->type() == QEvent::MouseButtonPress &&
        qApp->mouseButtons() == Qt::LeftButton) {

      QPoint pos = static_cast<QMouseEvent*>(event)->pos();

      int tabIndex = tabBar()->tabAt(pos);

      // can start tab drag only if mouse is at some tab, not at empty tabbar space
      if (tabIndex >= 0) {
        m_tabDragCanStart = true;

        if (m_manager->toolWindowProperties(widget(tabIndex)) & ToolWindowManager::DisableDraggableTab) {
          setMovable(false);
        } else {
          setMovable(true);
        }
      } else if (m_tabBar == NULL || !m_tabBar->inButton(pos)) {
        m_dragCanStart = true;
        m_dragCanStartPos = QCursor::pos();
      }
    } else if (event->type() == QEvent::MouseButtonPress &&
        qApp->mouseButtons() == Qt::MiddleButton) {

      int tabIndex = tabBar()->tabAt(static_cast<QMouseEvent*>(event)->pos());

      if(tabIndex >= 0) {
        QWidget *w = widget(tabIndex);

        if(!(m_manager->toolWindowProperties(w) & ToolWindowManager::HideCloseButton)) {
          m_manager->removeToolWindow(w);
        }
      }
    } else if (event->type() == QEvent::MouseButtonRelease) {
      m_tabDragCanStart = false;
      m_dragCanStart = false;
      m_manager->updateDragPosition();
    } else if (event->type() == QEvent::MouseMove) {
      m_manager->updateDragPosition();
      if (m_tabDragCanStart) {
        if (tabBar()->rect().contains(static_cast<QMouseEvent*>(event)->pos())) {
          return false;
        }
        if (qApp->mouseButtons() != Qt::LeftButton) {
          return false;
        }
        QWidget* toolWindow = currentWidget();
        if (!toolWindow || !m_manager->m_toolWindows.contains(toolWindow)) {
          return false;
        }
        m_tabDragCanStart = false;
        //stop internal tab drag in QTabBar
        QMouseEvent* releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease,
                                                    static_cast<QMouseEvent*>(event)->pos(),
                                                    Qt::LeftButton, Qt::LeftButton, 0);
        qApp->sendEvent(tabBar(), releaseEvent);
        m_manager->startDrag(QList<QWidget*>() << toolWindow, NULL);
      } else if (m_dragCanStart) {
        check_mouse_move();
      }
    }
  }
  return QTabWidget::eventFilter(object, event);
}

void ToolWindowManagerArea::tabInserted(int index) {
  // update the select order. Increment any existing index after the insertion point to keep the
  // indices in the list up to date.
  for (int &idx : m_tabSelectOrder) {
    if (idx >= index)
      idx++;
  }

  // if the tab inserted is the current index (most likely) then add it at the end, otherwise
  // add it next-to-end (to keep the most recent tab the same).
  if (currentIndex() == index || m_tabSelectOrder.isEmpty())
    m_tabSelectOrder.append(index);
  else
    m_tabSelectOrder.insert(m_tabSelectOrder.count()-1, index);

  QTabWidget::tabInserted(index);
}

void ToolWindowManagerArea::tabRemoved(int index) {
  // update the select order. Remove the index that just got deleted, and decrement any index
  // greater than it to remap to their new indices
  m_tabSelectOrder.removeOne(index);

  for (int &idx : m_tabSelectOrder) {
    if (idx > index)
      idx--;
  }

  QTabWidget::tabRemoved(index);
}

void ToolWindowManagerArea::tabSelected(int index) {
  // move this tab to the end of the select order, as long as we have it - if it's a new index then
  // ignore and leave it to be handled in tabInserted()
  if (m_tabSelectOrder.contains(index)) {
    m_tabSelectOrder.removeOne(index);
    m_tabSelectOrder.append(index);
  }

  ToolWindowManagerWrapper* wrapper = m_manager->wrapperOf(this);
  if (wrapper)
    wrapper->updateTitle();
}

void ToolWindowManagerArea::tabClosing(int index) {
  // before closing this index, switch the current index to the next tab in succession.

  // should never get here but let's check this
  if (m_tabSelectOrder.isEmpty())
    return;

  // when closing the last tab there's nothing to do
  if (m_tabSelectOrder.count() == 1)
    return;

  // if the last in the select order is being closed, switch to the next most selected tab
  if (m_tabSelectOrder.last() == index)
    setCurrentIndex(m_tabSelectOrder.at(m_tabSelectOrder.count()-2));
}

QVariantMap ToolWindowManagerArea::saveState() {
  QVariantMap result;
  result[QStringLiteral("type")] = QStringLiteral("area");
  result[QStringLiteral("currentIndex")] = currentIndex();
  QVariantList objects;
  objects.reserve(count());
  for(int i = 0; i < count(); i++) {
    QWidget *w = widget(i);
    QString name = w->objectName();
    if (name.isEmpty()) {
      qWarning("cannot save state of tool window without object name");
    } else {
      QVariantMap objectData;
      objectData[QStringLiteral("name")] = name;
      objectData[QStringLiteral("data")] = w->property("persistData");
      objects.push_back(objectData);
    }
  }
  result[QStringLiteral("objects")] = objects;
  return result;
}

void ToolWindowManagerArea::restoreState(const QVariantMap &savedData) {
  for(QVariant object : savedData[QStringLiteral("objects")].toList()) {
    QVariantMap objectData = object.toMap();
    if (objectData.isEmpty()) { continue; }
    QString objectName = objectData[QStringLiteral("name")].toString();
    if (objectName.isEmpty()) { continue; }
    QWidget *t = NULL;
    for(QWidget* toolWindow : m_manager->m_toolWindows) {
      if (toolWindow->objectName() == objectName) {
        t = toolWindow;
        break;
      }
    }
    if (t == NULL) t = m_manager->createToolWindow(objectName);
    if (t) {
        t->setProperty("persistData", objectData[QStringLiteral("data")]);
        addToolWindow(t);
    } else {
      qWarning("tool window with name '%s' not found or created", objectName.toLocal8Bit().constData());
    }
  }
  setCurrentIndex(savedData[QStringLiteral("currentIndex")].toInt());
}

void ToolWindowManagerArea::check_mouse_move() {
  if (qApp->mouseButtons() != Qt::LeftButton && m_dragCanStart) {
    m_dragCanStart = false;
  }
  m_manager->updateDragPosition();
  if (m_dragCanStart &&
      (QCursor::pos() - m_dragCanStartPos).manhattanLength() > 10) {
    m_dragCanStart = false;
    QList<QWidget*> toolWindows;
    for(int i = 0; i < count(); i++) {
      QWidget* toolWindow = widget(i);
      if (!m_manager->m_toolWindows.contains(toolWindow)) {
        qWarning("tab widget contains unmanaged widget");
      } else {
        toolWindows << toolWindow;
      }
    }
    m_manager->startDrag(toolWindows, NULL);
  }
}

bool ToolWindowManagerArea::useMinimalTabBar() {
  QWidget *w = widget(0);
  if (w == NULL)
    return false;

  return (m_manager->toolWindowProperties(w) & ToolWindowManager::AlwaysDisplayFullTabs) == 0;
}

void ToolWindowManagerArea::tabMoved(int from, int to) {
  if(m_inTabMoved) return;

  // update the select order.
  // This amounts to just a swap - any indices other than the pair in question are unaffected since
  // one tab is removed (above/below) and added (below/above) so the indices themselves remain the
  // same.
  for (int &idx : m_tabSelectOrder) {
    if (idx == from)
      idx = to;
    else if (idx == to)
      idx = from;
  }

  QWidget *a = widget(from);
  QWidget *b = widget(to);

  if(!a || !b) return;

  if(m_manager->toolWindowProperties(a) & ToolWindowManager::DisableDraggableTab ||
     m_manager->toolWindowProperties(b) & ToolWindowManager::DisableDraggableTab)
  {
    m_inTabMoved = true;
    tabBar()->moveTab(to, from);
    m_inTabMoved = false;
  }
}
<commit_msg>Update all windows when tabs are added to ensure close buttons go away<commit_after>/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Pavel Strakhov
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "ToolWindowManagerArea.h"
#include "ToolWindowManagerTabBar.h"
#include "ToolWindowManagerWrapper.h"
#include "ToolWindowManager.h"
#include <QApplication>
#include <QMouseEvent>
#include <algorithm>

static void showCloseButton(QTabBar *bar, int index, bool show) {
  QWidget *button = bar->tabButton(index, QTabBar::RightSide);
  if(button == NULL)
    button = bar->tabButton(index, QTabBar::LeftSide);

  if(button)
    button->resize(show ? QSize(16, 16) : QSize(0, 0));
}

ToolWindowManagerArea::ToolWindowManagerArea(ToolWindowManager *manager, QWidget *parent) :
  QTabWidget(parent)
, m_manager(manager)
{
  m_tabBar = new ToolWindowManagerTabBar(this);
  setTabBar(m_tabBar);

  m_tabBar->setTabsClosable(true);

  m_dragCanStart = false;
  m_tabDragCanStart = false;
  m_inTabMoved = false;
  m_userCanDrop = true;
  setMovable(true);
  setDocumentMode(true);
  tabBar()->installEventFilter(this);
  m_manager->m_areas << this;

  QObject::connect(tabBar(), &QTabBar::tabMoved, this, &ToolWindowManagerArea::tabMoved);
  QObject::connect(tabBar(), &QTabBar::tabCloseRequested, this, &ToolWindowManagerArea::tabClosing);
  QObject::connect(tabBar(), &QTabBar::tabCloseRequested, this, &QTabWidget::tabCloseRequested);
  QObject::connect(this, &QTabWidget::currentChanged, this, &ToolWindowManagerArea::tabSelected);
}

ToolWindowManagerArea::~ToolWindowManagerArea() {
  m_manager->m_areas.removeOne(this);
}

void ToolWindowManagerArea::addToolWindow(QWidget *toolWindow, int insertIndex) {
  addToolWindows(QList<QWidget*>() << toolWindow, insertIndex);
}

void ToolWindowManagerArea::addToolWindows(const QList<QWidget *> &toolWindows, int insertIndex) {
  int index = 0;
  foreach(QWidget* toolWindow, toolWindows) {
    index = insertTab(insertIndex, toolWindow, toolWindow->windowIcon(), toolWindow->windowTitle());
    insertIndex = index+1;
  }
  setCurrentIndex(index);
  for (int i=0; i < count(); i++) {
    updateToolWindow(widget(i));
  }
  m_manager->m_lastUsedArea = this;
}

QList<QWidget *> ToolWindowManagerArea::toolWindows() {
  QList<QWidget *> result;
  for(int i = 0; i < count(); i++) {
    result << widget(i);
  }
  return result;
}

void ToolWindowManagerArea::updateToolWindow(QWidget* toolWindow) {
  int index = indexOf(toolWindow);
  if(index >= 0) {
    if(m_manager->toolWindowProperties(toolWindow) & ToolWindowManager::HideCloseButton) {
      showCloseButton(tabBar(), index, false);
    } else {
      showCloseButton(tabBar(), index, true);
    }
    tabBar()->setTabText(index, toolWindow->windowTitle());
  }
}

void ToolWindowManagerArea::mouseMoveEvent(QMouseEvent *) {
  check_mouse_move();
}

bool ToolWindowManagerArea::eventFilter(QObject *object, QEvent *event) {
  if (object == tabBar()) {
    if (event->type() == QEvent::MouseButtonPress &&
        qApp->mouseButtons() == Qt::LeftButton) {

      QPoint pos = static_cast<QMouseEvent*>(event)->pos();

      int tabIndex = tabBar()->tabAt(pos);

      // can start tab drag only if mouse is at some tab, not at empty tabbar space
      if (tabIndex >= 0) {
        m_tabDragCanStart = true;

        if (m_manager->toolWindowProperties(widget(tabIndex)) & ToolWindowManager::DisableDraggableTab) {
          setMovable(false);
        } else {
          setMovable(true);
        }
      } else if (m_tabBar == NULL || !m_tabBar->inButton(pos)) {
        m_dragCanStart = true;
        m_dragCanStartPos = QCursor::pos();
      }
    } else if (event->type() == QEvent::MouseButtonPress &&
        qApp->mouseButtons() == Qt::MiddleButton) {

      int tabIndex = tabBar()->tabAt(static_cast<QMouseEvent*>(event)->pos());

      if(tabIndex >= 0) {
        QWidget *w = widget(tabIndex);

        if(!(m_manager->toolWindowProperties(w) & ToolWindowManager::HideCloseButton)) {
          m_manager->removeToolWindow(w);
        }
      }
    } else if (event->type() == QEvent::MouseButtonRelease) {
      m_tabDragCanStart = false;
      m_dragCanStart = false;
      m_manager->updateDragPosition();
    } else if (event->type() == QEvent::MouseMove) {
      m_manager->updateDragPosition();
      if (m_tabDragCanStart) {
        if (tabBar()->rect().contains(static_cast<QMouseEvent*>(event)->pos())) {
          return false;
        }
        if (qApp->mouseButtons() != Qt::LeftButton) {
          return false;
        }
        QWidget* toolWindow = currentWidget();
        if (!toolWindow || !m_manager->m_toolWindows.contains(toolWindow)) {
          return false;
        }
        m_tabDragCanStart = false;
        //stop internal tab drag in QTabBar
        QMouseEvent* releaseEvent = new QMouseEvent(QEvent::MouseButtonRelease,
                                                    static_cast<QMouseEvent*>(event)->pos(),
                                                    Qt::LeftButton, Qt::LeftButton, 0);
        qApp->sendEvent(tabBar(), releaseEvent);
        m_manager->startDrag(QList<QWidget*>() << toolWindow, NULL);
      } else if (m_dragCanStart) {
        check_mouse_move();
      }
    }
  }
  return QTabWidget::eventFilter(object, event);
}

void ToolWindowManagerArea::tabInserted(int index) {
  // update the select order. Increment any existing index after the insertion point to keep the
  // indices in the list up to date.
  for (int &idx : m_tabSelectOrder) {
    if (idx >= index)
      idx++;
  }

  // if the tab inserted is the current index (most likely) then add it at the end, otherwise
  // add it next-to-end (to keep the most recent tab the same).
  if (currentIndex() == index || m_tabSelectOrder.isEmpty())
    m_tabSelectOrder.append(index);
  else
    m_tabSelectOrder.insert(m_tabSelectOrder.count()-1, index);

  QTabWidget::tabInserted(index);
}

void ToolWindowManagerArea::tabRemoved(int index) {
  // update the select order. Remove the index that just got deleted, and decrement any index
  // greater than it to remap to their new indices
  m_tabSelectOrder.removeOne(index);

  for (int &idx : m_tabSelectOrder) {
    if (idx > index)
      idx--;
  }

  QTabWidget::tabRemoved(index);
}

void ToolWindowManagerArea::tabSelected(int index) {
  // move this tab to the end of the select order, as long as we have it - if it's a new index then
  // ignore and leave it to be handled in tabInserted()
  if (m_tabSelectOrder.contains(index)) {
    m_tabSelectOrder.removeOne(index);
    m_tabSelectOrder.append(index);
  }

  ToolWindowManagerWrapper* wrapper = m_manager->wrapperOf(this);
  if (wrapper)
    wrapper->updateTitle();
}

void ToolWindowManagerArea::tabClosing(int index) {
  // before closing this index, switch the current index to the next tab in succession.

  // should never get here but let's check this
  if (m_tabSelectOrder.isEmpty())
    return;

  // when closing the last tab there's nothing to do
  if (m_tabSelectOrder.count() == 1)
    return;

  // if the last in the select order is being closed, switch to the next most selected tab
  if (m_tabSelectOrder.last() == index)
    setCurrentIndex(m_tabSelectOrder.at(m_tabSelectOrder.count()-2));
}

QVariantMap ToolWindowManagerArea::saveState() {
  QVariantMap result;
  result[QStringLiteral("type")] = QStringLiteral("area");
  result[QStringLiteral("currentIndex")] = currentIndex();
  QVariantList objects;
  objects.reserve(count());
  for(int i = 0; i < count(); i++) {
    QWidget *w = widget(i);
    QString name = w->objectName();
    if (name.isEmpty()) {
      qWarning("cannot save state of tool window without object name");
    } else {
      QVariantMap objectData;
      objectData[QStringLiteral("name")] = name;
      objectData[QStringLiteral("data")] = w->property("persistData");
      objects.push_back(objectData);
    }
  }
  result[QStringLiteral("objects")] = objects;
  return result;
}

void ToolWindowManagerArea::restoreState(const QVariantMap &savedData) {
  for(QVariant object : savedData[QStringLiteral("objects")].toList()) {
    QVariantMap objectData = object.toMap();
    if (objectData.isEmpty()) { continue; }
    QString objectName = objectData[QStringLiteral("name")].toString();
    if (objectName.isEmpty()) { continue; }
    QWidget *t = NULL;
    for(QWidget* toolWindow : m_manager->m_toolWindows) {
      if (toolWindow->objectName() == objectName) {
        t = toolWindow;
        break;
      }
    }
    if (t == NULL) t = m_manager->createToolWindow(objectName);
    if (t) {
        t->setProperty("persistData", objectData[QStringLiteral("data")]);
        addToolWindow(t);
    } else {
      qWarning("tool window with name '%s' not found or created", objectName.toLocal8Bit().constData());
    }
  }
  setCurrentIndex(savedData[QStringLiteral("currentIndex")].toInt());
}

void ToolWindowManagerArea::check_mouse_move() {
  if (qApp->mouseButtons() != Qt::LeftButton && m_dragCanStart) {
    m_dragCanStart = false;
  }
  m_manager->updateDragPosition();
  if (m_dragCanStart &&
      (QCursor::pos() - m_dragCanStartPos).manhattanLength() > 10) {
    m_dragCanStart = false;
    QList<QWidget*> toolWindows;
    for(int i = 0; i < count(); i++) {
      QWidget* toolWindow = widget(i);
      if (!m_manager->m_toolWindows.contains(toolWindow)) {
        qWarning("tab widget contains unmanaged widget");
      } else {
        toolWindows << toolWindow;
      }
    }
    m_manager->startDrag(toolWindows, NULL);
  }
}

bool ToolWindowManagerArea::useMinimalTabBar() {
  QWidget *w = widget(0);
  if (w == NULL)
    return false;

  return (m_manager->toolWindowProperties(w) & ToolWindowManager::AlwaysDisplayFullTabs) == 0;
}

void ToolWindowManagerArea::tabMoved(int from, int to) {
  if(m_inTabMoved) return;

  // update the select order.
  // This amounts to just a swap - any indices other than the pair in question are unaffected since
  // one tab is removed (above/below) and added (below/above) so the indices themselves remain the
  // same.
  for (int &idx : m_tabSelectOrder) {
    if (idx == from)
      idx = to;
    else if (idx == to)
      idx = from;
  }

  QWidget *a = widget(from);
  QWidget *b = widget(to);

  if(!a || !b) return;

  if(m_manager->toolWindowProperties(a) & ToolWindowManager::DisableDraggableTab ||
     m_manager->toolWindowProperties(b) & ToolWindowManager::DisableDraggableTab)
  {
    m_inTabMoved = true;
    tabBar()->moveTab(to, from);
    m_inTabMoved = false;
  }
}
<|endoftext|>


<commit_before>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2013
Raffaello D. Di Napoli

This file is part of Application-Building Components (henceforth referred to as ABC).

ABC 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.

ABC 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 General Public
License for more details.

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

#include <abc/testing/core.hxx>
#include <abc/testing/test_case.hxx>
#include <abc/trace.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::testing::test_case

namespace abc {

namespace testing {

test_case::test_case() {
}

/*virtual*/ test_case::~test_case() {
}

void test_case::init(runner * prunner) {
   ABC_TRACE_FN((this, prunner));

   m_prunner = prunner;
}

void test_case::assert_does_not_throw(
   source_location const & srcloc, std::function<void ()> fnExpr, istr const & sExpr
) {
   ABC_TRACE_FN((this, srcloc, /*fnExpr, */sExpr));

   istr sCaughtWhat;
   try {
      fnExpr();
   } catch (::std::exception const & x) {
      sCaughtWhat = istr(SL("throws {}")).format(x.what());
   } catch (...) {
      sCaughtWhat = SL("unknown type");
   }
   m_prunner->log_assertion(srcloc, !sCaughtWhat, sExpr, istr(), SL("does not throw"), sCaughtWhat);
}

void test_case::assert_false(source_location const & srcloc, bool bActual, istr const & sExpr) {
   ABC_TRACE_FN((this, srcloc, bActual, sExpr));

   m_prunner->log_assertion(
      srcloc, !bActual, sExpr, istr(), !bActual ? istr() : SL("false"), SL("true")
   );
}

void test_case::assert_true(source_location const & srcloc, bool bActual, istr const & sExpr) {
   ABC_TRACE_FN((this, srcloc, bActual, sExpr));

   m_prunner->log_assertion(
      srcloc, bActual, sExpr, istr(), bActual ? istr() : SL("true"), SL("false")
   );
}

void test_case::assert_throws(
   source_location const & srcloc, std::function<void ()> fnExpr, istr const & sExpr,
   std::function<bool (std::exception const &)> fnMatchType, char const * pszExpectedWhat
) {
   bool bPass(false);
   istr sCaughtWhat;
   try {
      fnExpr();
      sCaughtWhat = SL("does not throw");
   } catch (::std::exception const & x) {
      if (fnMatchType(x)) {
         bPass = true;
      } else {
         sCaughtWhat = istr(SL("throws {}")).format(x.what());
      }
   } catch (...) {
      sCaughtWhat = SL("unknown type");
   }
   this->m_prunner->log_assertion(
      srcloc, bPass, sExpr, istr(), istr(SL("throws {}")).format(pszExpectedWhat), sCaughtWhat
   );
}

} //namespace testing

} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::testing::test_case_factory_impl

namespace abc {

namespace testing {

/*static*/ test_case_factory_impl::list_item * test_case_factory_impl::sm_pliHead(nullptr);
// MSC16 BUG: for some reason, this will be parsed as a function declaration if written as a
// constructor call.
/*static*/ test_case_factory_impl::list_item ** test_case_factory_impl::sm_ppliTailNext = nullptr;

test_case_factory_impl::test_case_factory_impl(list_item * pli) {
   if (sm_pliHead) {
      // We have a head and therefore a tail as well: add *pli as the new tail.
      *sm_ppliTailNext = pli;
   } else {
      // We don’t have a head yet: set it up now.
      sm_pliHead = pli;
   }
   // Save the “next” pointer of *pli for the next call.
   sm_ppliTailNext = &pli->pliNext;
}

} //namespace testing

} //namespace abc

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

<commit_msg>Add missing ABC_TRACE_FN<commit_after>/* -*- coding: utf-8; mode: c++; tab-width: 3; indent-tabs-mode: nil -*-

Copyright 2013
Raffaello D. Di Napoli

This file is part of Application-Building Components (henceforth referred to as ABC).

ABC 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.

ABC 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 General Public
License for more details.

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

#include <abc/testing/core.hxx>
#include <abc/testing/test_case.hxx>
#include <abc/trace.hxx>

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::testing::test_case

namespace abc {

namespace testing {

test_case::test_case() {
}

/*virtual*/ test_case::~test_case() {
}

void test_case::init(runner * prunner) {
   ABC_TRACE_FN((this, prunner));

   m_prunner = prunner;
}

void test_case::assert_does_not_throw(
   source_location const & srcloc, std::function<void ()> fnExpr, istr const & sExpr
) {
   ABC_TRACE_FN((this, srcloc, /*fnExpr, */sExpr));

   istr sCaughtWhat;
   try {
      fnExpr();
   } catch (::std::exception const & x) {
      sCaughtWhat = istr(SL("throws {}")).format(x.what());
   } catch (...) {
      sCaughtWhat = SL("unknown type");
   }
   m_prunner->log_assertion(srcloc, !sCaughtWhat, sExpr, istr(), SL("does not throw"), sCaughtWhat);
}

void test_case::assert_false(source_location const & srcloc, bool bActual, istr const & sExpr) {
   ABC_TRACE_FN((this, srcloc, bActual, sExpr));

   m_prunner->log_assertion(
      srcloc, !bActual, sExpr, istr(), !bActual ? istr() : SL("false"), SL("true")
   );
}

void test_case::assert_true(source_location const & srcloc, bool bActual, istr const & sExpr) {
   ABC_TRACE_FN((this, srcloc, bActual, sExpr));

   m_prunner->log_assertion(
      srcloc, bActual, sExpr, istr(), bActual ? istr() : SL("true"), SL("false")
   );
}

void test_case::assert_throws(
   source_location const & srcloc, std::function<void ()> fnExpr, istr const & sExpr,
   std::function<bool (std::exception const &)> fnMatchType, char const * pszExpectedWhat
) {
   ABC_TRACE_FN((this, srcloc, /*fnExpr, */sExpr, /*fnMatchType, */pszExpectedWhat));

   bool bPass(false);
   istr sCaughtWhat;
   try {
      fnExpr();
      sCaughtWhat = SL("does not throw");
   } catch (::std::exception const & x) {
      if (fnMatchType(x)) {
         bPass = true;
      } else {
         sCaughtWhat = istr(SL("throws {}")).format(x.what());
      }
   } catch (...) {
      sCaughtWhat = SL("unknown type");
   }
   this->m_prunner->log_assertion(
      srcloc, bPass, sExpr, istr(), istr(SL("throws {}")).format(pszExpectedWhat), sCaughtWhat
   );
}

} //namespace testing

} //namespace abc

////////////////////////////////////////////////////////////////////////////////////////////////////
// abc::testing::test_case_factory_impl

namespace abc {

namespace testing {

/*static*/ test_case_factory_impl::list_item * test_case_factory_impl::sm_pliHead(nullptr);
// MSC16 BUG: for some reason, this will be parsed as a function declaration if written as a
// constructor call.
/*static*/ test_case_factory_impl::list_item ** test_case_factory_impl::sm_ppliTailNext = nullptr;

test_case_factory_impl::test_case_factory_impl(list_item * pli) {
   if (sm_pliHead) {
      // We have a head and therefore a tail as well: add *pli as the new tail.
      *sm_ppliTailNext = pli;
   } else {
      // We don’t have a head yet: set it up now.
      sm_pliHead = pli;
   }
   // Save the “next” pointer of *pli for the next call.
   sm_ppliTailNext = &pli->pliNext;
}

} //namespace testing

} //namespace abc

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

<|endoftext|>