<commit_before>#include <qpiekey.h>
#include <QSizePolicy>
#include <QPainter>
#include <QPaintEvent>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include "term_logging.h"

using namespace std;

QPieKey::QPieKey(QWidget *parent) : QWidget(parent)
{
    sections = 0;
    size = 0;

    hide();
}

QPieKey::~QPieKey()
{
}

QChar QPieKey::toChar(Qt::Key key)
{
    if( key >= Qt::Key_A && key <= Qt::Key_Z ) {
        return key - Qt::Key_A + 'a';
    }
}

void QPieKey::paintEvent(QPaintEvent *event)
{
    int inSelection = 0, selectedChar;
    int i, j,k;
    double charangle;
    QPainter painter(this);
    Qt::Key character;

    painter.setBrush(QColor(128, 128, 128));
    painter.drawRect(event->rect());

    if( sections ) {
        painter.setBrush(QColor(180, 180, 180));
        if( highlighted_section != -1 ) {
            painter.drawPie(0, 0, size*2, size*2, (90-(angle*(highlighted_section+0.5))*180/M_PI)*16, angle*180/M_PI*16);
        }
        painter.setBrush(QColor(0, 0, 0));
        for( i = 0; i < sections; i ++ ) {
            for( j = 0; j < letters_per_section; j ++ ) {
                // The angle of the section extends from angle*(i-0.5) to
                // angle*(i+0.5). We want to center 'sections' characters
                // with equal angular spacing in this area. Add a full width
                // on each side to separate a section from its neighbour
                character = keylist[i][j];
                charangle = angle*((j+1.0)/(sections+1.0)+i-0.5);
                selectedChar = (highlighted_section == -1 || highlighted_section == i);
                if( selectedChar ) {
                    for(map<int, const vector<Qt::Key> *>::const_iterator k = selections.begin(); k != selections.end(); k ++ ) {
                        if( k->second == NULL ) continue;
                        if( std::find(k->second->begin(), k->second->end(), selectedChar) == k->second->end() ) {
                            selectedChar = false;
                            break;
                        }
                    }
                }
                if( selectedChar != inSelection ) {
                    QFont font;
                    inSelection = selectedChar;
                    font.setBold(inSelection);
                    if( inSelection ) {
                        if( font.pixelSize() != -1 ) {
                            font.setPixelSize(font.pixelSize() + 3);
                        }
                        if( font.pointSize() != -1 ) {
                            font.setPointSize(font.pointSize() + 3);
                        }
                    }
                    painter.setFont(font);
                }

                switch( character ) {
                    case Qt::Key_Tab:
                        {
                            QPixmap img("app/native/tab.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4+img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Escape:
                        {
                            QPixmap img("app/native/escape.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4+img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Up:
                        {
                            QPixmap img("app/native/up.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4+img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Down:
                        {
                            QPixmap img("app/native/down.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4+img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Right:
                        {
                            QPixmap img("app/native/right.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4+img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Left:
                        {
                            QPixmap img("app/native/left.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4+img.height()/2, img);
                        }
                        break;
                    default:
                        painter.drawText(size+size*sin(charangle)*3/4-painter.fontMetrics().width(character)/2, size-size*cos(charangle)*3/4+painter.fontMetrics().height()/2, toChar(character));
                        break;
                }
            }
        }
        for( i = 0; i < sections; i ++ ) {
            if( highlighted_section == -1 || (i != highlighted_section && i != (highlighted_section + 1) % sections)) {
                painter.drawLine(size, size, size+size*sin(angle*(i-0.5)), size-size*cos(angle*(i-0.5)));
            }
        }
    }
}

void QPieKey::mouseMoveEvent(QMouseEvent *event)
{
    moveTouch(event->x(), event->y());
}

void QPieKey::moveTouch(int x, int y)
{
    int section;
    double distance;
    double mouseangle;
    // Find whether we are in the wheel
    distance = sqrt((x-size)*(x-size)+(y-size)*(y-size));

    if( distance * 2 < size ) {
        section = -1;
    } else {
        mouseangle = atan2(((double)size - x), ((double)y - size)) + M_PI;
        section = ((int)((mouseangle + 0.5) / angle)) % sections;
    }

    if( section != highlighted_section ) {
        if( section == -1 ) {
            // We're losing our selection, send the signal now
            for(int i = 0; i < letters_per_section; i ++ ) {
                std::map<int, const std::vector<Qt::Key> *>::const_iterator j;
                for(j = selections.begin(); j != selections.end(); j ++ ) {
                    if( std::find(j->second->begin(), j->second->end(), keylist[highlighted_section][i]) == j->second->end() ) {
                        break;
                    }
                }
                if( j == selections.end() ) {
                    emit(keypress(keylist[highlighted_section][i]));
                }
            }
            emit selectionChanged(NULL);
        } else {
            // We're gaining a selection, notify our parent
            emit selectionChanged(&keylist[ section ]);
        }
        highlighted_section = section;
        update(0,0, size*2, size*2);
    }
}

void QPieKey::mouseReleaseEvent(QMouseEvent *event)
{
    releaseMouse();
    emit released();
}

void QPieKey::initialize(int sections, const vector<Qt::Key> &keylist)
{
    int i, j;

    this->selections.clear();
    letters_per_section = keylist.size() / sections;
    this->sections = sections;
    this->keylist.clear();
    for( i = 0; i < sections; i ++ ) {
        this->keylist.push_back(vector<Qt::Key>());
        for( j = 0; j < letters_per_section; j ++ ) {
            this->keylist.back().push_back(keylist[i*letters_per_section+j]);
        }
    }

    angle = 2*M_PI / sections;
    highlighted_section = -1;
    size_ring();
}

void QPieKey::activate(int x, int y)
{
    // Center the widget on the mouse coordinates
    highlighted_section = -1;
    selections.clear();
    setGeometry(x - width() / 2, y - height() / 2, width(), height());
    show();
    grabMouse();
}

void QPieKey::select(int key, const vector<Qt::Key> *selection)
{
    this->selections[key] = selection;
    update(0,0, size*2, size*2);
}

void QPieKey::size_ring()
{
    // TODO Figure out how big the largest section has to be so letters don't overlap
    size = 200;

    // Update the mask of the widget appropriately
    bitmap = new QBitmap(size*2,size*2);
    QPainter painter(bitmap);

    setFixedSize(size*2, size*2);

    bitmap->clear();
    painter.setBrush(Qt::color1);
    painter.drawEllipse(1, 1, size*2-2, size*2-2);
    painter.setBrush(Qt::color0);
    painter.drawEllipse(size/2, size/2, size, size);
    setMask(*bitmap);
}
<commit_msg>Fix centering of letters/images in piekey<commit_after>#include <qpiekey.h>
#include <QSizePolicy>
#include <QPainter>
#include <QPaintEvent>
#include <math.h>
#include <stdio.h>
#include <unistd.h>
#include "term_logging.h"

using namespace std;

QPieKey::QPieKey(QWidget *parent) : QWidget(parent)
{
    sections = 0;
    size = 0;

    hide();
}

QPieKey::~QPieKey()
{
}

QChar QPieKey::toChar(Qt::Key key)
{
    if( key >= Qt::Key_A && key <= Qt::Key_Z ) {
        return key - Qt::Key_A + 'a';
    }
}

void QPieKey::paintEvent(QPaintEvent *event)
{
    int inSelection = 0, selectedChar;
    int i, j,k;
    double charangle;
    QPainter painter(this);
    Qt::Key character;

    painter.setBrush(QColor(128, 128, 128));
    painter.drawRect(event->rect());

    if( sections ) {
        painter.setBrush(QColor(180, 180, 180));
        if( highlighted_section != -1 ) {
            painter.drawPie(0, 0, size*2, size*2, (90-(angle*(highlighted_section+0.5))*180/M_PI)*16, angle*180/M_PI*16);
        }
        painter.setBrush(QColor(0, 0, 0));
        for( i = 0; i < sections; i ++ ) {
            for( j = 0; j < letters_per_section; j ++ ) {
                // The angle of the section extends from angle*(i-0.5) to
                // angle*(i+0.5). We want to center 'sections' characters
                // with equal angular spacing in this area. Add a full width
                // on each side to separate a section from its neighbour
                character = keylist[i][j];
                charangle = angle*(j/letters_per_section + i);
                selectedChar = (highlighted_section == -1 || highlighted_section == i);
                if( selectedChar ) {
                    for(map<int, const vector<Qt::Key> *>::const_iterator k = selections.begin(); k != selections.end(); k ++ ) {
                        if( k->second == NULL ) continue;
                        if( std::find(k->second->begin(), k->second->end(), selectedChar) == k->second->end() ) {
                            selectedChar = false;
                            break;
                        }
                    }
                }
                if( selectedChar != inSelection ) {
                    QFont font;
                    inSelection = selectedChar;
                    font.setBold(inSelection);
                    if( inSelection ) {
                        if( font.pixelSize() != -1 ) {
                            font.setPixelSize(font.pixelSize() + 3);
                        }
                        if( font.pointSize() != -1 ) {
                            font.setPointSize(font.pointSize() + 3);
                        }
                    }
                    painter.setFont(font);
                }

                switch( character ) {
                    case Qt::Key_Tab:
                        {
                            QPixmap img("app/native/tab.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4-img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Escape:
                        {
                            QPixmap img("app/native/escape.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4-img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Up:
                        {
                            QPixmap img("app/native/up.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4-img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Down:
                        {
                            QPixmap img("app/native/down.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4-img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Right:
                        {
                            QPixmap img("app/native/right.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4-img.height()/2, img);
                        }
                        break;
                    case Qt::Key_Left:
                        {
                            QPixmap img("app/native/left.png");
                            painter.drawPixmap(size+size*sin(charangle)*3/4-img.width()/2, size-size*cos(charangle)*3/4-img.height()/2, img);
                        }
                        break;
                    default:
                        painter.drawText(size+size*sin(charangle)*3/4-painter.fontMetrics().width(character)/2, size-size*cos(charangle)*3/4+painter.fontMetrics().height()/2, toChar(character));
                        break;
                }
            }
        }
        for( i = 0; i < sections; i ++ ) {
            if( highlighted_section == -1 || (i != highlighted_section && i != (highlighted_section + 1) % sections)) {
                painter.drawLine(size, size, size+size*sin(angle*(i-0.5)), size-size*cos(angle*(i-0.5)));
            }
        }
    }
}

void QPieKey::mouseMoveEvent(QMouseEvent *event)
{
    moveTouch(event->x(), event->y());
}

void QPieKey::moveTouch(int x, int y)
{
    int section;
    double distance;
    double mouseangle;
    // Find whether we are in the wheel
    distance = sqrt((x-size)*(x-size)+(y-size)*(y-size));

    if( distance * 2 < size ) {
        section = -1;
    } else {
        mouseangle = atan2(((double)size - x), ((double)y - size)) + M_PI;
        section = ((int)((mouseangle + 0.5) / angle)) % sections;
    }

    if( section != highlighted_section ) {
        if( section == -1 ) {
            // We're losing our selection, send the signal now
            for(int i = 0; i < letters_per_section; i ++ ) {
                std::map<int, const std::vector<Qt::Key> *>::const_iterator j;
                for(j = selections.begin(); j != selections.end(); j ++ ) {
                    if( std::find(j->second->begin(), j->second->end(), keylist[highlighted_section][i]) == j->second->end() ) {
                        break;
                    }
                }
                if( j == selections.end() ) {
                    emit(keypress(keylist[highlighted_section][i]));
                }
            }
            emit selectionChanged(NULL);
        } else {
            // We're gaining a selection, notify our parent
            emit selectionChanged(&keylist[ section ]);
        }
        highlighted_section = section;
        update(0,0, size*2, size*2);
    }
}

void QPieKey::mouseReleaseEvent(QMouseEvent *event)
{
    releaseMouse();
    emit released();
}

void QPieKey::initialize(int sections, const vector<Qt::Key> &keylist)
{
    int i, j;

    this->selections.clear();
    letters_per_section = keylist.size() / sections;
    this->sections = sections;
    this->keylist.clear();
    for( i = 0; i < sections; i ++ ) {
        this->keylist.push_back(vector<Qt::Key>());
        for( j = 0; j < letters_per_section; j ++ ) {
            this->keylist.back().push_back(keylist[i*letters_per_section+j]);
        }
    }

    angle = 2*M_PI / sections;
    highlighted_section = -1;
    size_ring();
}

void QPieKey::activate(int x, int y)
{
    // Center the widget on the mouse coordinates
    highlighted_section = -1;
    selections.clear();
    setGeometry(x - width() / 2, y - height() / 2, width(), height());
    show();
    grabMouse();
}

void QPieKey::select(int key, const vector<Qt::Key> *selection)
{
    this->selections[key] = selection;
    update(0,0, size*2, size*2);
}

void QPieKey::size_ring()
{
    // TODO Figure out how big the largest section has to be so letters don't overlap
    size = 200;

    // Update the mask of the widget appropriately
    bitmap = new QBitmap(size*2,size*2);
    QPainter painter(bitmap);

    setFixedSize(size*2, size*2);

    bitmap->clear();
    painter.setBrush(Qt::color1);
    painter.drawEllipse(1, 1, size*2-2, size*2-2);
    painter.setBrush(Qt::color0);
    painter.drawEllipse(size/2, size/2, size, size);
    setMask(*bitmap);
}
<|endoftext|>


<commit_before>
#include <memory>
#include <string>
#include <map>
#include <algorithm>

#pragma warning (disable : 4005)
#include "Effekseer.h"
#include "EffekseerRendererDX9.h"
#include "EffekseerRendererDX11.h"

#include "../common/IUnityGraphics.h"
#include "../common/EffekseerPluginLoader.h"

using namespace Effekseer;

extern UnityGfxRenderer				g_RendererType;
extern IDirect3DDevice9*				g_D3d9Device;
extern ID3D11Device*					g_D3d11Device;
extern ID3D11DeviceContext*			g_D3d11Context;
extern EffekseerRenderer::Renderer*		g_EffekseerRenderer;

namespace EffekseerPlugin
{
	class TextureLoaderWin : public TextureLoader
	{
		struct TextureResource {
			int referenceCount = 1;
			void* texture = nullptr;
		};
		std::map<std::u16string, TextureResource> resources;
	public:
		TextureLoaderWin(
			TextureLoaderLoad load,
			TextureLoaderUnload unload)
			: TextureLoader(load, unload) {}
		virtual ~TextureLoaderWin() {}
		virtual void* Load( const EFK_CHAR* path, Effekseer::TextureType textureType ){
			auto it = resources.find((const char16_t*)path);
			if (it != resources.end()) {
				it->second.referenceCount++;
				return it->second.texture;
			} else {
				TextureResource res;
				res.texture = load( (const char16_t*)path );
				if (g_RendererType == kUnityGfxRendererD3D11)
				{
					// Unity[ĥID3D11Texture2DȂ̂ŁA
					// ID3D11ShaderResourceViewɕϊ
					HRESULT hr;
					ID3D11Texture2D* textureDX11 = (ID3D11Texture2D*)res.texture;

					D3D11_TEXTURE2D_DESC texDesc;
					textureDX11->GetDesc(&texDesc);

					ID3D11ShaderResourceView* resView = nullptr;
					D3D11_SHADER_RESOURCE_VIEW_DESC desc;
					ZeroMemory(&desc, sizeof(desc));
					desc.Format = texDesc.Format;
					desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
					desc.Texture2D.MostDetailedMip = 0;
					desc.Texture2D.MipLevels = texDesc.MipLevels;
					hr = g_D3d11Device->CreateShaderResourceView(textureDX11, &desc, &resView);
					if (FAILED(hr))
					{
						return nullptr;
					}

					res.texture = resView;
				}
				resources.insert( std::make_pair(
					(const char16_t*)path, res ) );
				return res.texture;
			}
			return nullptr;
		}
		virtual void Unload( void* source ){
			for (auto it = resources.begin(); it != resources.end(); it++) {
				if (it->second.texture == source) {
					it->second.referenceCount--;
					if (it->second.referenceCount <= 0) {
						if (g_RendererType == kUnityGfxRendererD3D11)
						{
							// ID3D11Texture2Dɖ߂UnityɃA[hĂ炤
							ID3D11Resource* resourceDX11 = nullptr;
							ID3D11ShaderResourceView* resView = (ID3D11ShaderResourceView*)source;
							resView->GetResource(&resourceDX11);
							resView->Release();
						}
						unload( it->first.c_str() );
						resources.erase(it);
					}
				}
			}
		}
	};

	TextureLoader* TextureLoader::Create(
		TextureLoaderLoad load,
		TextureLoaderUnload unload)
	{
		return new TextureLoaderWin( load, unload );
	}

	class ModelLoaderWin : public ModelLoader
	{
		ModelLoaderLoad load;
		ModelLoaderUnload unload;

		struct ModelResource {
			int referenceCount = 1;
			void* internalData;
		};
		std::map<std::u16string, ModelResource> resources;

		class MemoryFileReader : public Effekseer::FileReader {
			uint8_t* data;
			size_t length;
			int position;
		public:
			MemoryFileReader(uint8_t* data, size_t length): data(data), length(length) {}
			size_t Read( void* buffer, size_t size ) {
				if (size >= length - position) {
					size = length - position;
				}
				memcpy(buffer, &data[position], size);
				position += size;
				return size;
			}
			void Seek(int position) {
				this->position = position;
			}
			int GetPosition() {
				return position;
			}
			size_t GetLength() {
				return length;
			}
		};
		class MemoryFile : public Effekseer::FileInterface {
		public:
			std::vector<uint8_t> loadbuffer;
			size_t loadsize;
			FileReader* OpenRead( const EFK_CHAR* path ) {
				return new MemoryFileReader(&loadbuffer[0], loadsize);
			}
			FileWriter* OpenWrite( const EFK_CHAR* path ) {
				return nullptr;
			}
		};

		MemoryFile memoryFile;
		std::unique_ptr<Effekseer::ModelLoader> internalLoader;

	public:
		ModelLoaderWin(
			ModelLoaderLoad load,
			ModelLoaderUnload unload )
			: ModelLoader( load, unload )
			, internalLoader( g_EffekseerRenderer->CreateModelLoader( &memoryFile ) ) {}
		virtual ~ModelLoaderWin() {}
		virtual void* Load( const EFK_CHAR* path ){
			auto it = resources.find((const char16_t*)path);
			if (it != resources.end()) {
				it->second.referenceCount++;
				return it->second.internalData;
			} else {
				ModelResource res;
				int size = load( (const char16_t*)path,
					&memoryFile.loadbuffer[0], (int)memoryFile.loadbuffer.size() );
				if (size <= 0) {
					return nullptr;
				}
				memoryFile.loadsize = (size_t)size;
				res.internalData = internalLoader->Load( path );
				resources.insert( std::make_pair(
					(const char16_t*)path, res ) );
				return res.internalData;
			}
			return nullptr;
		}
		virtual void Unload( void* source ){
			for (auto it = resources.begin(); it != resources.end(); it++) {
				if (it->second.internalData == source) {
					it->second.referenceCount--;
					if (it->second.referenceCount <= 0) {
						unload( it->first.c_str() );
						resources.erase(it);
					}
				}
			}
		}
	};

	ModelLoader* ModelLoader::Create(
		ModelLoaderLoad load,
		ModelLoaderUnload unload)
	{
		return new ModelLoaderWin( load, unload );
	}
};<commit_msg>[UnityPlugin] テクスチャロード時のnullチェックを追加<commit_after>
#include <memory>
#include <string>
#include <map>
#include <algorithm>

#pragma warning (disable : 4005)
#include "Effekseer.h"
#include "EffekseerRendererDX9.h"
#include "EffekseerRendererDX11.h"

#include "../common/IUnityGraphics.h"
#include "../common/EffekseerPluginLoader.h"

using namespace Effekseer;

extern UnityGfxRenderer				g_RendererType;
extern IDirect3DDevice9*				g_D3d9Device;
extern ID3D11Device*					g_D3d11Device;
extern ID3D11DeviceContext*			g_D3d11Context;
extern EffekseerRenderer::Renderer*		g_EffekseerRenderer;

namespace EffekseerPlugin
{
	class TextureLoaderWin : public TextureLoader
	{
		struct TextureResource {
			int referenceCount = 1;
			void* texture = nullptr;
		};
		std::map<std::u16string, TextureResource> resources;
	public:
		TextureLoaderWin(
			TextureLoaderLoad load,
			TextureLoaderUnload unload)
			: TextureLoader(load, unload) {}
		virtual ~TextureLoaderWin() {}
		virtual void* Load( const EFK_CHAR* path, Effekseer::TextureType textureType ){
			auto it = resources.find((const char16_t*)path);
			if (it != resources.end()) {
				it->second.referenceCount++;
				return it->second.texture;
			} else {
				TextureResource res;
				res.texture = load( (const char16_t*)path );
				if (res.texture == nullptr)
				{
					return nullptr;
				}
				if (g_RendererType == kUnityGfxRendererD3D11)
				{
					// Unity[ĥID3D11Texture2DȂ̂ŁA
					// ID3D11ShaderResourceViewɕϊ
					HRESULT hr;
					ID3D11Texture2D* textureDX11 = (ID3D11Texture2D*)res.texture;

					D3D11_TEXTURE2D_DESC texDesc;
					textureDX11->GetDesc(&texDesc);

					ID3D11ShaderResourceView* resView = nullptr;
					D3D11_SHADER_RESOURCE_VIEW_DESC desc;
					ZeroMemory(&desc, sizeof(desc));
					desc.Format = texDesc.Format;
					desc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
					desc.Texture2D.MostDetailedMip = 0;
					desc.Texture2D.MipLevels = texDesc.MipLevels;
					hr = g_D3d11Device->CreateShaderResourceView(textureDX11, &desc, &resView);
					if (FAILED(hr))
					{
						return nullptr;
					}

					res.texture = resView;
				}
				resources.insert( std::make_pair(
					(const char16_t*)path, res ) );
				return res.texture;
			}
			return nullptr;
		}
		virtual void Unload( void* source ){
			for (auto it = resources.begin(); it != resources.end(); it++) {
				if (it->second.texture == source) {
					it->second.referenceCount--;
					if (it->second.referenceCount <= 0) {
						if (g_RendererType == kUnityGfxRendererD3D11)
						{
							// ID3D11Texture2Dɖ߂UnityɃA[hĂ炤
							ID3D11Resource* resourceDX11 = nullptr;
							ID3D11ShaderResourceView* resView = (ID3D11ShaderResourceView*)source;
							resView->GetResource(&resourceDX11);
							resView->Release();
						}
						unload( it->first.c_str() );
						resources.erase(it);
					}
				}
			}
		}
	};

	TextureLoader* TextureLoader::Create(
		TextureLoaderLoad load,
		TextureLoaderUnload unload)
	{
		return new TextureLoaderWin( load, unload );
	}

	class ModelLoaderWin : public ModelLoader
	{
		ModelLoaderLoad load;
		ModelLoaderUnload unload;

		struct ModelResource {
			int referenceCount = 1;
			void* internalData;
		};
		std::map<std::u16string, ModelResource> resources;

		class MemoryFileReader : public Effekseer::FileReader {
			uint8_t* data;
			size_t length;
			int position;
		public:
			MemoryFileReader(uint8_t* data, size_t length): data(data), length(length) {}
			size_t Read( void* buffer, size_t size ) {
				if (size >= length - position) {
					size = length - position;
				}
				memcpy(buffer, &data[position], size);
				position += (int)size;
				return size;
			}
			void Seek(int position) {
				this->position = position;
			}
			int GetPosition() {
				return position;
			}
			size_t GetLength() {
				return length;
			}
		};
		class MemoryFile : public Effekseer::FileInterface {
		public:
			std::vector<uint8_t> loadbuffer;
			size_t loadsize;
			FileReader* OpenRead( const EFK_CHAR* path ) {
				return new MemoryFileReader(&loadbuffer[0], loadsize);
			}
			FileWriter* OpenWrite( const EFK_CHAR* path ) {
				return nullptr;
			}
		};

		MemoryFile memoryFile;
		std::unique_ptr<Effekseer::ModelLoader> internalLoader;

	public:
		ModelLoaderWin(
			ModelLoaderLoad load,
			ModelLoaderUnload unload )
			: ModelLoader( load, unload )
			, internalLoader( g_EffekseerRenderer->CreateModelLoader( &memoryFile ) ) {}
		virtual ~ModelLoaderWin() {}
		virtual void* Load( const EFK_CHAR* path ){
			auto it = resources.find((const char16_t*)path);
			if (it != resources.end()) {
				it->second.referenceCount++;
				return it->second.internalData;
			} else {
				ModelResource res;
				int size = load( (const char16_t*)path,
					&memoryFile.loadbuffer[0], (int)memoryFile.loadbuffer.size() );
				if (size <= 0) {
					return nullptr;
				}
				memoryFile.loadsize = (size_t)size;
				res.internalData = internalLoader->Load( path );
				resources.insert( std::make_pair(
					(const char16_t*)path, res ) );
				return res.internalData;
			}
			return nullptr;
		}
		virtual void Unload( void* source ){
			for (auto it = resources.begin(); it != resources.end(); it++) {
				if (it->second.internalData == source) {
					it->second.referenceCount--;
					if (it->second.referenceCount <= 0) {
						unload( it->first.c_str() );
						resources.erase(it);
					}
				}
			}
		}
	};

	ModelLoader* ModelLoader::Create(
		ModelLoaderLoad load,
		ModelLoaderUnload unload)
	{
		return new ModelLoaderWin( load, unload );
	}
};<|endoftext|>


<commit_before>#include <string>
#include <vector>

#include <ros/ros.h>
#include <moveit/move_group_interface/move_group.h>
#include <moveit/robot_trajectory/robot_trajectory.h>
#include <moveit/trajectory_processing/iterative_time_parameterization.h>
#include <tf2_ros/transform_listener.h>

#include <geometry_msgs/Pose.h>
#include <geometry_msgs/Point.h>
#include <geometry_msgs/TransformStamped.h>
#include <moveit_msgs/RobotTrajectory.h>

class MoveGroupInterface {
  moveit::planning_interface::MoveGroup move_group_;

  tf2_ros::Buffer buffer_;
  tf2_ros::TransformListener listener_;

  geometry_msgs::Pose tomapo_;
  std::vector<geometry_msgs::Pose> waypoints_;

  static constexpr double eef_length_ {0.3}; // TODO
  static constexpr double eef_step_ {0.10};

  static constexpr double abs_rail_length_ {5.0};
  double sign_;

public:
  MoveGroupInterface(const std::string& group_name, const double& joint_tolerance)
    : move_group_ {group_name},
      buffer_ {},
      listener_ {buffer_},
      tomapo_ {},
      waypoints_ {},
      sign_ {1.0}
  {
    move_group_.allowReplanning(true);
    move_group_.setGoalJointTolerance(joint_tolerance);
    move_group_.setPlanningTime(5.0);
  }

  bool queryTargetExistence()
  {
    try {
      geometry_msgs::TransformStamped transform_stamped_ {buffer_.lookupTransform("rail", "tomato", ros::Time(0), ros::Duration(1.0))};
      tomapo_.position.x = transform_stamped_.transform.translation.x;
      tomapo_.position.y = transform_stamped_.transform.translation.y;
      tomapo_.position.z = transform_stamped_.transform.translation.z;
      tomapo_.orientation.x = 0;
      tomapo_.orientation.y = 0;
      tomapo_.orientation.z = 0;
      tomapo_.orientation.w = 1.0;
      return true;
    } catch (const tf2::TransformException& ex) {
      ROS_INFO_STREAM(ex.what());
      return false;
    }
  }

  bool startSequence()
  {
    waypoints_.clear();

    geometry_msgs::Pose pose1 {tomapo_};
    pose1.position.x -= eef_length_;
    // waypoints_.push_back(pose1);
    move_group_.setPoseTarget(pose1);

    moveit::planning_interface::MoveGroup::Plan plan;
    move_group_.plan(plan);
    if (!move_group_.execute(plan)) return false;

    geometry_msgs::Pose pose2 {tomapo_};
    waypoints_.push_back(pose2);

    geometry_msgs::Pose pose3 {tomapo_};
    pose3.orientation = tf::createQuaternionMsgFromRollPitchYaw(1.0, 0, 0);
    waypoints_.push_back(pose3);

    geometry_msgs::Pose pose4 {tomapo_};
    pose4.position.x -= eef_length_;
    waypoints_.push_back(pose4);

    moveit_msgs::RobotTrajectory trajectory_msgs_;
    move_group_.computeCartesianPath(waypoints_, eef_step_, 0.0, trajectory_msgs_);

    robot_trajectory::RobotTrajectory robot_trajectory_ {move_group_.getCurrentState()->getRobotModel(), move_group_.getName()};
    robot_trajectory_.setRobotTrajectoryMsg(*move_group_.getCurrentState(), trajectory_msgs_);

    trajectory_processing::IterativeParabolicTimeParameterization iptp;
    iptp.computeTimeStamps(robot_trajectory_);

    robot_trajectory_.getRobotTrajectoryMsg(trajectory_msgs_);

    moveit::planning_interface::MoveGroup::Plan motion_plan_;
    motion_plan_.trajectory_ = trajectory_msgs_;

    return move_group_.execute(motion_plan_);
  }

  bool baseShift()
  {
    double tmp;

    try {
      geometry_msgs::TransformStamped transform_stamped {buffer_.lookupTransform("rail", "shaft", ros::Time(0), ros::Duration(1.0))};
      tmp = transform_stamped.transform.translation.y;
      if (tmp > (abs_rail_length_ - 1.0)) sign_ = -1.0;
      else if (tmp < -(abs_rail_length_ - 1.0)) sign_ = 1.0;
    } catch (const tf2::TransformException& ex) {
      ROS_INFO_STREAM(ex.what());
      return false;
    }

    // auto named_target_values = move_group_.getNamedTargetValues("init");
    // named_target_values["rail_to_shaft_joint"] += (sign_ * 1.0);
    // move_group_.setJointValueTarget(named_target_values);

    move_group_.setNamedTarget("init");

    std::vector<double> joint_values;
    auto joint_model_group = move_group_.getCurrentState()->getRobotModel()->getJointModelGroup(move_group_.getName());
    move_group_.getCurrentState()->copyJointGroupPositions(joint_model_group, joint_values);

    // joint_values[0] += sign_ * 1.0;
    // joint_values[1] = -0.3927;
    joint_values[1] =  0;
    joint_values[2] = -0.7854;
    joint_values[3] =  1.5707;
    joint_values[4] = -0.7854;
    joint_values[5] =  0;

    move_group_.setJointValueTarget(joint_values);
    moveit::planning_interface::MoveGroup::Plan plan;
    move_group_.plan(plan);

    move_group_.execute(plan);

    joint_values[0] += sign_ * 1.0;
    // joint_values[1] = -0.3927;
    joint_values[1] =  0;
    joint_values[2] = -0.7854;
    joint_values[3] =  1.5707;
    joint_values[4] = -0.7854;
    joint_values[5] =  0;

    move_group_.setJointValueTarget(joint_values);
    // moveit::planning_interface::MoveGroup::Plan plan;
    move_group_.plan(plan);

    return move_group_.execute(plan);
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "arcsys2_move_group_interface_node");
  ros::NodeHandle node_handle {"~"};

  ros::AsyncSpinner spinner {1};
  spinner.start();

  MoveGroupInterface interface {"arcsys2", node_handle.param("joint_tolerance", 0.1)};

  while (ros::ok()) {
    while (!interface.queryTargetExistence()) interface.baseShift();
    interface.startSequence();
  }

  spinner.stop();

  return 0;
}
<commit_msg>Change to getCurrentJointValues()<commit_after>#include <string>
#include <vector>

#include <ros/ros.h>
#include <moveit/move_group_interface/move_group.h>
#include <moveit/robot_trajectory/robot_trajectory.h>
#include <moveit/trajectory_processing/iterative_time_parameterization.h>
#include <tf2_ros/transform_listener.h>

#include <geometry_msgs/Pose.h>
#include <geometry_msgs/Point.h>
#include <geometry_msgs/TransformStamped.h>
#include <moveit_msgs/RobotTrajectory.h>

class MoveGroupInterface {
  moveit::planning_interface::MoveGroup move_group_;

  tf2_ros::Buffer buffer_;
  tf2_ros::TransformListener listener_;

  geometry_msgs::Pose tomapo_;
  std::vector<geometry_msgs::Pose> waypoints_;

  static constexpr double eef_length_ {0.3}; // TODO
  static constexpr double eef_step_ {0.10};

  static constexpr double abs_rail_length_ {5.0};
  double sign_;

public:
  MoveGroupInterface(const std::string& group_name, const double& joint_tolerance)
    : move_group_ {group_name},
      buffer_ {},
      listener_ {buffer_},
      tomapo_ {},
      waypoints_ {},
      sign_ {1.0}
  {
    move_group_.allowReplanning(true);
    move_group_.setGoalJointTolerance(joint_tolerance);
    move_group_.setPlanningTime(5.0);
  }

  bool queryTargetExistence()
  {
    try {
      geometry_msgs::TransformStamped transform_stamped_ {buffer_.lookupTransform("rail", "tomato", ros::Time(0), ros::Duration(1.0))};
      tomapo_.position.x = transform_stamped_.transform.translation.x;
      tomapo_.position.y = transform_stamped_.transform.translation.y;
      tomapo_.position.z = transform_stamped_.transform.translation.z;
      tomapo_.orientation.x = 0;
      tomapo_.orientation.y = 0;
      tomapo_.orientation.z = 0;
      tomapo_.orientation.w = 1.0;
      return true;
    } catch (const tf2::TransformException& ex) {
      ROS_INFO_STREAM(ex.what());
      return false;
    }
  }

  bool startSequence()
  {
    waypoints_.clear();

    geometry_msgs::Pose pose1 {tomapo_};
    pose1.position.x -= eef_length_;
    // waypoints_.push_back(pose1);
    move_group_.setPoseTarget(pose1);

    moveit::planning_interface::MoveGroup::Plan plan;
    move_group_.plan(plan);
    if (!move_group_.execute(plan)) return false;

    geometry_msgs::Pose pose2 {tomapo_};
    waypoints_.push_back(pose2);

    geometry_msgs::Pose pose3 {tomapo_};
    pose3.orientation = tf::createQuaternionMsgFromRollPitchYaw(1.0, 0, 0);
    waypoints_.push_back(pose3);

    geometry_msgs::Pose pose4 {tomapo_};
    pose4.position.x -= eef_length_;
    waypoints_.push_back(pose4);

    moveit_msgs::RobotTrajectory trajectory_msgs_;
    move_group_.computeCartesianPath(waypoints_, eef_step_, 0.0, trajectory_msgs_);

    robot_trajectory::RobotTrajectory robot_trajectory_ {move_group_.getCurrentState()->getRobotModel(), move_group_.getName()};
    robot_trajectory_.setRobotTrajectoryMsg(*move_group_.getCurrentState(), trajectory_msgs_);

    trajectory_processing::IterativeParabolicTimeParameterization iptp;
    iptp.computeTimeStamps(robot_trajectory_);

    robot_trajectory_.getRobotTrajectoryMsg(trajectory_msgs_);

    moveit::planning_interface::MoveGroup::Plan motion_plan_;
    motion_plan_.trajectory_ = trajectory_msgs_;

    return move_group_.execute(motion_plan_);
  }

  bool baseShift()
  {
    double tmp;

    try {
      geometry_msgs::TransformStamped transform_stamped {buffer_.lookupTransform("rail", "shaft", ros::Time(0), ros::Duration(1.0))};
      tmp = transform_stamped.transform.translation.y;
      if (tmp > (abs_rail_length_ - 1.0)) sign_ = -1.0;
      else if (tmp < -(abs_rail_length_ - 1.0)) sign_ = 1.0;
    } catch (const tf2::TransformException& ex) {
      ROS_INFO_STREAM(ex.what());
      return false;
    }

    // auto named_target_values = move_group_.getNamedTargetValues("init");
    // named_target_values["rail_to_shaft_joint"] += (sign_ * 1.0);
    // move_group_.setJointValueTarget(named_target_values);

    // move_group_.setNamedTarget("init");

    std::vector<double> joint_values = move_group_.getCurrentJointValues();
    // auto joint_model_group = move_group_.getCurrentState()->getRobotModel()->getJointModelGroup(move_group_.getName());
    // move_group_.getCurrentState()->copyJointGroupPositions(joint_model_group, joint_values);

    // joint_values[0] += sign_ * 1.0;
    // joint_values[1] = -0.3927;
    joint_values[1] =  0;
    joint_values[2] = -0.7854;
    joint_values[3] =  1.5707;
    joint_values[4] = -0.7854;
    joint_values[5] =  0;

    move_group_.setJointValueTarget(joint_values);
    moveit::planning_interface::MoveGroup::Plan plan;
    move_group_.plan(plan);

    move_group_.execute(plan);

    joint_values[0] += sign_ * 1.0;
    // joint_values[1] = -0.3927;
    joint_values[1] =  0;
    joint_values[2] = -0.7854;
    joint_values[3] =  1.5707;
    joint_values[4] = -0.7854;
    joint_values[5] =  0;

    move_group_.setJointValueTarget(joint_values);
    // moveit::planning_interface::MoveGroup::Plan plan;
    move_group_.plan(plan);

    return move_group_.execute(plan);
  }
};

int main(int argc, char** argv)
{
  ros::init(argc, argv, "arcsys2_move_group_interface_node");
  ros::NodeHandle node_handle {"~"};

  ros::AsyncSpinner spinner {1};
  spinner.start();

  MoveGroupInterface interface {"arcsys2", node_handle.param("joint_tolerance", 0.1)};

  while (ros::ok()) {
    while (!interface.queryTargetExistence()) interface.baseShift();
    interface.startSequence();
  }

  spinner.stop();

  return 0;
}
<|endoftext|>


<commit_before>/*
 *
 *    Copyright (c) 2019 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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.
 */

/**
 *    @file
 *          Contains non-inline method definitions for the
 *          GenericThreadStackManagerImpl_FreeRTOS<> template.
 */

#ifndef GENERIC_THREAD_STACK_MANAGER_IMPL_FREERTOS_IPP
#define GENERIC_THREAD_STACK_MANAGER_IMPL_FREERTOS_IPP

#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/ThreadStackManager.h>
#include <Weave/DeviceLayer/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.h>

namespace nl {
namespace Weave {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericThreadStackManagerImpl_FreeRTOS<ThreadStackManagerImpl>;

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::DoInit(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    mThreadStackLock = xSemaphoreCreateMutex();
    if (mThreadStackLock == NULL)
    {
        WeaveLogError(DeviceLayer, "Failed to create Thread stack lock");
        ExitNow(err = WEAVE_ERROR_NO_MEMORY);
    }

    mThreadTask = NULL;

exit:
    return err;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_StartThreadTask(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    BaseType_t res;

    VerifyOrExit(mThreadTask == NULL, err = WEAVE_ERROR_INCORRECT_STATE);

    res = xTaskCreate(ThreadTaskMain,
                WEAVE_DEVICE_CONFIG_THREAD_TASK_NAME,
                WEAVE_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE / sizeof(StackType_t),
                this,
                WEAVE_DEVICE_CONFIG_THREAD_TASK_PRIORITY,
                NULL);
    VerifyOrExit(res == pdPASS, err = WEAVE_ERROR_NO_MEMORY);

exit:
    return err;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_LockThreadStack(void)
{
    xSemaphoreTake(mThreadStackLock, portMAX_DELAY);
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_TryLockThreadStack(void)
{
    return xSemaphoreTake(mThreadStackLock, 0) == pdTRUE;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_UnlockThreadStack(void)
{
    xSemaphoreGive(mThreadStackLock);
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::SignalThreadActivityPending()
{
    if (mThreadTask != NULL)
    {
        xTaskNotifyGive(mThreadTask);
    }
}

template<class ImplClass>
BaseType_t GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::SignalThreadActivityPendingFromISR()
{
    BaseType_t yieldRequired = pdFALSE;

    if (mThreadTask != NULL)
    {
        vTaskNotifyGiveFromISR(mThreadTask, &yieldRequired);
    }

    return yieldRequired;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::ThreadTaskMain(void * arg)
{
    GenericThreadStackManagerImpl_FreeRTOS<ImplClass> * self =
            static_cast<GenericThreadStackManagerImpl_FreeRTOS<ImplClass>*>(arg);

    VerifyOrDie(self->mThreadTask == NULL);

    WeaveLogDetail(DeviceLayer, "Thread task running");

    // Capture the Thread task handle.
    self->mThreadTask = xTaskGetCurrentTaskHandle();

    while (true)
    {
        // Lock the Thread stack.
        self->Impl()->LockThreadStack();

        // Process any pending Thread activity.
        self->Impl()->ProcessThreadActivity();

        // Unlock the Thread stack.
        self->Impl()->UnlockThreadStack();

        // Wait for a signal that more activity is pending.
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    }
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace Weave
} // namespace nl

#endif // GENERIC_THREAD_STACK_MANAGER_IMPL_FREERTOS_IPP
<commit_msg>Update GenericThreadStackManagerImpl_FreeRTOS<commit_after>/*
 *
 *    Copyright (c) 2019 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    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.
 */

/**
 *    @file
 *          Contains non-inline method definitions for the
 *          GenericThreadStackManagerImpl_FreeRTOS<> template.
 */

#ifndef GENERIC_THREAD_STACK_MANAGER_IMPL_FREERTOS_IPP
#define GENERIC_THREAD_STACK_MANAGER_IMPL_FREERTOS_IPP

#include <Weave/DeviceLayer/internal/WeaveDeviceLayerInternal.h>
#include <Weave/DeviceLayer/ThreadStackManager.h>
#include <Weave/DeviceLayer/FreeRTOS/GenericThreadStackManagerImpl_FreeRTOS.h>

namespace nl {
namespace Weave {
namespace DeviceLayer {
namespace Internal {

// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
template class GenericThreadStackManagerImpl_FreeRTOS<ThreadStackManagerImpl>;

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::DoInit(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;

    mThreadStackLock = xSemaphoreCreateRecursiveMutex();
    if (mThreadStackLock == NULL)
    {
        WeaveLogError(DeviceLayer, "Failed to create Thread stack lock");
        ExitNow(err = WEAVE_ERROR_NO_MEMORY);
    }

    mThreadTask = NULL;

exit:
    return err;
}

template<class ImplClass>
WEAVE_ERROR GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_StartThreadTask(void)
{
    WEAVE_ERROR err = WEAVE_NO_ERROR;
    BaseType_t res;

    VerifyOrExit(mThreadTask == NULL, err = WEAVE_ERROR_INCORRECT_STATE);

    res = xTaskCreate(ThreadTaskMain,
                WEAVE_DEVICE_CONFIG_THREAD_TASK_NAME,
                WEAVE_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE / sizeof(StackType_t),
                this,
                WEAVE_DEVICE_CONFIG_THREAD_TASK_PRIORITY,
                NULL);
    VerifyOrExit(res == pdPASS, err = WEAVE_ERROR_NO_MEMORY);

exit:
    return err;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_LockThreadStack(void)
{
    xSemaphoreTakeRecursive(mThreadStackLock, portMAX_DELAY);
}

template<class ImplClass>
bool GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_TryLockThreadStack(void)
{
    return xSemaphoreTakeRecursive(mThreadStackLock, 0) == pdTRUE;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::_UnlockThreadStack(void)
{
    xSemaphoreGiveRecursive(mThreadStackLock);
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::SignalThreadActivityPending()
{
    if (mThreadTask != NULL)
    {
        xTaskNotifyGive(mThreadTask);
    }
}

template<class ImplClass>
BaseType_t GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::SignalThreadActivityPendingFromISR()
{
    BaseType_t yieldRequired = pdFALSE;

    if (mThreadTask != NULL)
    {
        vTaskNotifyGiveFromISR(mThreadTask, &yieldRequired);
    }

    return yieldRequired;
}

template<class ImplClass>
void GenericThreadStackManagerImpl_FreeRTOS<ImplClass>::ThreadTaskMain(void * arg)
{
    GenericThreadStackManagerImpl_FreeRTOS<ImplClass> * self =
            static_cast<GenericThreadStackManagerImpl_FreeRTOS<ImplClass>*>(arg);

    VerifyOrDie(self->mThreadTask == NULL);

    WeaveLogDetail(DeviceLayer, "Thread task running");

    // Capture the Thread task handle.
    self->mThreadTask = xTaskGetCurrentTaskHandle();

    while (true)
    {
        // Lock the Thread stack.
        self->Impl()->LockThreadStack();

        // Process any pending Thread activity.
        self->Impl()->ProcessThreadActivity();

        // Unlock the Thread stack.
        self->Impl()->UnlockThreadStack();

        // Wait for a signal that more activity is pending.
        ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
    }
}

} // namespace Internal
} // namespace DeviceLayer
} // namespace Weave
} // namespace nl

#endif // GENERIC_THREAD_STACK_MANAGER_IMPL_FREERTOS_IPP
<|endoftext|>


<commit_before>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: kill.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

#include <tchar.h>

#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef SIGNULL
#define SIGNULL 0
#endif

#ifndef SIGKILL
#define SIGKILL 9
#endif

#include <signal.h>

#define MAX_MODULES 1024

/////////////////////////////////////////////////////////////////////////////
// Determines if a returned handle value is valid
/////////////////////////////////////////////////////////////////////////////

static inline bool IsValidHandle( HANDLE handle )
{
    return INVALID_HANDLE_VALUE != handle && NULL != handle;
}

#define elementsof( a ) (sizeof(a) / sizeof( (a)[0] ))

/////////////////////////////////////////////////////////////////////////////
// Retrieves function adress in another process
/////////////////////////////////////////////////////////////////////////////

#if 1
#define GetProcAddressEx( hProcess, hModule, lpProcName ) GetProcAddress( hModule, lpProcName )
#else
FARPROC WINAPI GetProcAddressEx( HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName )
{
    FARPROC lpfnProcAddress = GetProcAddress( hModule, lpProcName );

    if ( lpfnProcAddress )
    {
        DWORD   dwProcessId = GetProcessId( hProcess );

        if ( GetCurrentProcessId() != dwProcessId )
        {
            FARPROC lpfnRemoteProcAddress = NULL;
            TCHAR   szBaseName[MAX_PATH];

            if ( GetModuleBaseName( GetCurrentProcess(), hModule, szBaseName, elementsof(szBaseName) ) )
            {
                HMODULE ahModules[MAX_MODULES];
                DWORD   cbNeeded = 0;

                if ( EnumProcessModules( hProcess, ahModules, sizeof(ahModules), &cbNeeded ) )
                {
                    ULONG   nModules = cbNeeded / sizeof(ahModules[0]);

                    for ( ULONG n = 0; n < nModules; n++ )
                    {
                        TCHAR   szRemoteBaseName[MAX_PATH];

                        if ( GetModuleBaseName(
                            hProcess, ahModules[n], szRemoteBaseName, elementsof(szRemoteBaseName) ) &&
                            0 == lstrcmpi( szRemoteBaseName, szBaseName )
                            )
                        {
                            lpfnRemoteProcAddress = lpfnProcAddress;

                            if ( ahModules[n] != hModule )
                                *(LPBYTE*)&lpfnRemoteProcAddress += (LPBYTE)ahModules[n] - (LPBYTE)hModule;
                            break;
                        }
                    }
                }
            }

            lpfnProcAddress = lpfnRemoteProcAddress;
        }
    }

    return lpfnProcAddress;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// Raises a signal in an other process
/////////////////////////////////////////////////////////////////////////////

static DWORD SignalToExceptionCode( int signal )
{
    switch ( signal )
    {
    case SIGSEGV:
        return EXCEPTION_ACCESS_VIOLATION;
    case SIGFPE:
        return EXCEPTION_FLT_INVALID_OPERATION;
    case SIGILL:
        return EXCEPTION_ILLEGAL_INSTRUCTION;
    case SIGINT:
        return CONTROL_C_EXIT;
    case SIGBREAK:
        return CONTROL_C_EXIT;
    default:
        return 0;
    }
}

static void RaiseSignalEx( HANDLE hProcess, int sig )
{
    DWORD   dwProcessId = GetProcessId( hProcess );

    HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
    HANDLE  hThread = 0;

    if ( IsValidHandle(hSnapshot) )
    {
        THREADENTRY32   te;

        te.dwSize = sizeof(te);
        BOOL fSuccess = Thread32First( hSnapshot, &te );
        while ( fSuccess )
        {
            if ( te.th32OwnerProcessID == dwProcessId )
            {
                hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, te.th32ThreadID );
                break;
            }

            fSuccess = Thread32Next( hSnapshot, &te );
        }

        CloseHandle( hSnapshot );
    }

    CONTEXT aContext;

    SuspendThread( hThread );
    ZeroMemory( &aContext, sizeof(aContext) );
    aContext.ContextFlags = CONTEXT_FULL;
    GetThreadContext( hThread, &aContext );

    if ( sig )
    {
        DWORD   dwStackBuffer[] =
        {
            aContext.Eip,
            SignalToExceptionCode( sig ),
            EXCEPTION_NONCONTINUABLE,
            0,
            0
        };

        aContext.Esp -= sizeof(dwStackBuffer);
        WriteProcessMemory( hProcess, (LPVOID)aContext.Esp, dwStackBuffer, sizeof(dwStackBuffer), NULL );
        aContext.Eip = (DWORD)GetProcAddressEx( hProcess, GetModuleHandleA("KERNEL32"), "RaiseException" );
    }
    else
    {
        aContext.Ecx = aContext.Eax = aContext.Ebx = aContext.Edx = aContext.Esi = aContext.Edi = 0;
    }

    SetThreadContext( hThread, &aContext );
    ResumeThread( hThread );
}
/////////////////////////////////////////////////////////////////////////////
// Command line parameter parsing
/////////////////////////////////////////////////////////////////////////////

static void ParseCommandArgs( LPDWORD lpProcesses, LPDWORD lpdwNumProcesses, int *pSig )
{
    typedef struct _SignalEntry
    {
        LPCTSTR lpSignalName;
        int iSignalValue;
    } SignalEntry;

    #define SIG_ENTRY( signal ) { TEXT(#signal), SIG##signal }

    static SignalEntry SupportedSignals[] =
    {
        SIG_ENTRY( NULL ),
        SIG_ENTRY( SEGV ),
        SIG_ENTRY( ILL ),
        SIG_ENTRY( FPE ),
        SIG_ENTRY( INT ),
        SIG_ENTRY( BREAK ),
        SIG_ENTRY( TERM ),
        SIG_ENTRY( ABRT ),
        SIG_ENTRY( KILL )
    };

    const int NumSupportedSignals = elementsof(SupportedSignals);

    DWORD   dwMaxProcesses = *lpdwNumProcesses;
    int     argc = __argc;
    TCHAR   **argv = __targv;

    *lpdwNumProcesses = 0;

    for ( int argn = 1; argn < argc; argn++ )
    {
        if ( 0 == lstrcmpi( argv[argn], TEXT("-l") ) ||
             0 == lstrcmpi( argv[argn], TEXT("/l") ) )

        {
            for ( int n = 0; n < NumSupportedSignals; n++ )
            {
                _tprintf( _T("%s "), SupportedSignals[n] );
            }
            _tprintf( _T("\n") );
            ExitProcess( 0 );
        }
        else if ( 0 == lstrcmpi( argv[argn], TEXT("-?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("-h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("--help") ) )
        {
            _tprintf(
                _T("Terminates a process by sending a signal.\n\n")
                _T("Usage: kill [ -l ] [ -signal ] pid ...\n\n")
                _T("-l        Lists supported signals\n")
                _T("-signal   Sends the specified signal to the given processes.\n")
                _T("          signal can be a numeric value specifying the signal number\n")
                _T("          or a string listed by the -l parameter. If no signal is\n")
                _T("          given SIGTERM (-TERM) is used.\n")
                _T("pid       Process id(s) or executables names(s) of processes to \n")
                _T("          signal or terminate.\n\n")
                );
            ExitProcess( 0 );
        }
        else if ( argv[argn] && ( *argv[argn] == '-' || *argv[argn] == '/' ) )
        {
            LPCTSTR argsig = CharNext( argv[argn] );

            int n;
            for ( n = 0; n < NumSupportedSignals; n++ )
            {
                _TCHAR *endptr = NULL;

                if ( 0 == lstrcmpi( SupportedSignals[n].lpSignalName, argsig ) ||
                     _tcstoul( argsig, &endptr, 0 ) == static_cast< unsigned >(SupportedSignals[n].iSignalValue) && (!endptr || !*endptr) )
                {
                    *pSig = SupportedSignals[n].iSignalValue;
                    break;
                }
            }

            if ( n >= NumSupportedSignals )
            {
                _ftprintf( stderr,
                    _T("kill: Illegal argument %s\n")
                    _T("Type 'kill --help' to show allowed syntax.\n")
                    _T("Type 'kill -l' to show supported signals.\n"),
                    argv[argn] );
                ExitProcess( 0 );
            }
        }
        else
        {
            unsigned long value = 0;
            _TCHAR  *endptr = NULL;

            value = _tcstoul( argv[argn], &endptr, 0 );

            if ( !endptr || !*endptr )
            {
                if ( *lpdwNumProcesses < dwMaxProcesses )
                {
                    *(lpProcesses++) = value;
                    (*lpdwNumProcesses)++;
                }
            }
            else
            {
                HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

                if ( IsValidHandle( hSnapshot ) )
                {
                    PROCESSENTRY32  pe;

                    pe.dwSize = sizeof(pe);
                    BOOL fSuccess = Process32First( hSnapshot, &pe );

                    while ( fSuccess )
                    {
                        if ( 0 == lstrcmpi( argv[argn], pe.szExeFile ) )
                        {
                            if ( *lpdwNumProcesses < dwMaxProcesses )
                            {
                                *(lpProcesses++) = pe.th32ProcessID;
                                (*lpdwNumProcesses)++;
                            }
                        }
                        fSuccess = Process32Next( hSnapshot, &pe );
                    }

                    CloseHandle( hSnapshot );
                }
            }
        }
    }

    if ( !*lpdwNumProcesses )
    {
        _ftprintf( stderr,
            _T("kill: No process specified.\n")
            _T("Use kill --help to show allowed syntax.\n")
            );
        ExitProcess( 0 );
    }

}

int _tmain()
{
    DWORD   dwProcessIds[1024];
    DWORD   nProcesses = elementsof(dwProcessIds);
    int     sig = SIGTERM;

    ParseCommandArgs( dwProcessIds, &nProcesses, &sig );

    for ( ULONG n = 0; n < nProcesses; n++ )
    {
        HANDLE  hProcess;

        _tprintf( _T("Sending signal to process id %d..."), dwProcessIds[n] );
        hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_CREATE_THREAD | SYNCHRONIZE |
            PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
            FALSE, dwProcessIds[n] );

        if ( IsValidHandle( hProcess ) )
        {
            RaiseSignalEx( hProcess, sig );
            _tprintf( _T("Done\n") );

            CloseHandle( hProcess );
        }
        else
            _ftprintf( stderr, _T("No such process\n") );
    }

    return 0;
}

<commit_msg>INTEGRATION: CWS qadev32 (1.7.2); FILE MERGED 2008/04/18 14:11:32 hro 1.7.2.1: #i86802# Support kill -9<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: kill.cxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sal.hxx"

#include <tchar.h>

#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tlhelp32.h>
#include <psapi.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

#ifndef SIGNULL
#define SIGNULL 0
#endif

#ifndef SIGKILL
#define SIGKILL 9
#endif

#include <signal.h>

#define MAX_MODULES 1024

/////////////////////////////////////////////////////////////////////////////
// Determines if a returned handle value is valid
/////////////////////////////////////////////////////////////////////////////

static inline bool IsValidHandle( HANDLE handle )
{
    return INVALID_HANDLE_VALUE != handle && NULL != handle;
}

#define elementsof( a ) (sizeof(a) / sizeof( (a)[0] ))

/////////////////////////////////////////////////////////////////////////////
// Retrieves function adress in another process
/////////////////////////////////////////////////////////////////////////////

#if 1
#define GetProcAddressEx( hProcess, hModule, lpProcName ) GetProcAddress( hModule, lpProcName )
#else
FARPROC WINAPI GetProcAddressEx( HANDLE hProcess, HMODULE hModule, LPCSTR lpProcName )
{
    FARPROC lpfnProcAddress = GetProcAddress( hModule, lpProcName );

    if ( lpfnProcAddress )
    {
        DWORD   dwProcessId = GetProcessId( hProcess );

        if ( GetCurrentProcessId() != dwProcessId )
        {
            FARPROC lpfnRemoteProcAddress = NULL;
            TCHAR   szBaseName[MAX_PATH];

            if ( GetModuleBaseName( GetCurrentProcess(), hModule, szBaseName, elementsof(szBaseName) ) )
            {
                HMODULE ahModules[MAX_MODULES];
                DWORD   cbNeeded = 0;

                if ( EnumProcessModules( hProcess, ahModules, sizeof(ahModules), &cbNeeded ) )
                {
                    ULONG   nModules = cbNeeded / sizeof(ahModules[0]);

                    for ( ULONG n = 0; n < nModules; n++ )
                    {
                        TCHAR   szRemoteBaseName[MAX_PATH];

                        if ( GetModuleBaseName(
                            hProcess, ahModules[n], szRemoteBaseName, elementsof(szRemoteBaseName) ) &&
                            0 == lstrcmpi( szRemoteBaseName, szBaseName )
                            )
                        {
                            lpfnRemoteProcAddress = lpfnProcAddress;

                            if ( ahModules[n] != hModule )
                                *(LPBYTE*)&lpfnRemoteProcAddress += (LPBYTE)ahModules[n] - (LPBYTE)hModule;
                            break;
                        }
                    }
                }
            }

            lpfnProcAddress = lpfnRemoteProcAddress;
        }
    }

    return lpfnProcAddress;
}
#endif

/////////////////////////////////////////////////////////////////////////////
// Raises a signal in an other process
/////////////////////////////////////////////////////////////////////////////

static DWORD SignalToExceptionCode( int signal )
{
    switch ( signal )
    {
    case SIGSEGV:
        return EXCEPTION_ACCESS_VIOLATION;
    case SIGFPE:
        return EXCEPTION_FLT_INVALID_OPERATION;
    case SIGILL:
        return EXCEPTION_ILLEGAL_INSTRUCTION;
    case SIGINT:
        return CONTROL_C_EXIT;
    case SIGBREAK:
        return CONTROL_C_EXIT;
    default:
        return 0;
    }
}

static void RaiseSignalEx( HANDLE hProcess, int sig )
{
    DWORD   dwProcessId = GetProcessId( hProcess );

    HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 );
    HANDLE  hThread = 0;

    if ( IsValidHandle(hSnapshot) )
    {
        THREADENTRY32   te;

        te.dwSize = sizeof(te);
        BOOL fSuccess = Thread32First( hSnapshot, &te );
        while ( fSuccess )
        {
            if ( te.th32OwnerProcessID == dwProcessId )
            {
                hThread = OpenThread( THREAD_ALL_ACCESS, FALSE, te.th32ThreadID );
                break;
            }

            fSuccess = Thread32Next( hSnapshot, &te );
        }

        CloseHandle( hSnapshot );
    }

    CONTEXT aContext;

    SuspendThread( hThread );
    ZeroMemory( &aContext, sizeof(aContext) );
    aContext.ContextFlags = CONTEXT_FULL;
    GetThreadContext( hThread, &aContext );

    if ( sig )
    {
        DWORD   dwStackBuffer[] =
        {
            aContext.Eip,
            SignalToExceptionCode( sig ),
            EXCEPTION_NONCONTINUABLE,
            0,
            0
        };

        aContext.Esp -= sizeof(dwStackBuffer);
        WriteProcessMemory( hProcess, (LPVOID)aContext.Esp, dwStackBuffer, sizeof(dwStackBuffer), NULL );
        aContext.Eip = (DWORD)GetProcAddressEx( hProcess, GetModuleHandleA("KERNEL32"), "RaiseException" );
    }
    else
    {
        aContext.Ecx = aContext.Eax = aContext.Ebx = aContext.Edx = aContext.Esi = aContext.Edi = 0;
    }

    SetThreadContext( hThread, &aContext );
    ResumeThread( hThread );
}
/////////////////////////////////////////////////////////////////////////////
// Command line parameter parsing
/////////////////////////////////////////////////////////////////////////////

static void ParseCommandArgs( LPDWORD lpProcesses, LPDWORD lpdwNumProcesses, int *pSig )
{
    typedef struct _SignalEntry
    {
        LPCTSTR lpSignalName;
        int iSignalValue;
    } SignalEntry;

    #define SIG_ENTRY( signal ) { TEXT(#signal), SIG##signal }

    static SignalEntry SupportedSignals[] =
    {
        SIG_ENTRY( NULL ),
        SIG_ENTRY( SEGV ),
        SIG_ENTRY( ILL ),
        SIG_ENTRY( FPE ),
        SIG_ENTRY( INT ),
        SIG_ENTRY( BREAK ),
        SIG_ENTRY( TERM ),
        SIG_ENTRY( ABRT ),
        SIG_ENTRY( KILL )
    };

    const int NumSupportedSignals = elementsof(SupportedSignals);

    DWORD   dwMaxProcesses = *lpdwNumProcesses;
    int     argc = __argc;
    TCHAR   **argv = __targv;

    *lpdwNumProcesses = 0;

    for ( int argn = 1; argn < argc; argn++ )
    {
        if ( 0 == lstrcmpi( argv[argn], TEXT("-l") ) ||
             0 == lstrcmpi( argv[argn], TEXT("/l") ) )

        {
            for ( int n = 0; n < NumSupportedSignals; n++ )
            {
                _tprintf( _T("%s "), SupportedSignals[n] );
            }
            _tprintf( _T("\n") );
            ExitProcess( 0 );
        }
        else if ( 0 == lstrcmpi( argv[argn], TEXT("-?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/?") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("-h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("/h") ) ||
                  0 == lstrcmpi( argv[argn], TEXT("--help") ) )
        {
            _tprintf(
                _T("Terminates a process by sending a signal.\n\n")
                _T("Usage: kill [ -l ] [ -signal ] pid ...\n\n")
                _T("-l        Lists supported signals\n")
                _T("-signal   Sends the specified signal to the given processes.\n")
                _T("          signal can be a numeric value specifying the signal number\n")
                _T("          or a string listed by the -l parameter. If no signal is\n")
                _T("          given SIGTERM (-TERM) is used.\n")
                _T("pid       Process id(s) or executables names(s) of processes to \n")
                _T("          signal or terminate.\n\n")
                );
            ExitProcess( 0 );
        }
        else if ( argv[argn] && ( *argv[argn] == '-' || *argv[argn] == '/' ) )
        {
            LPCTSTR argsig = CharNext( argv[argn] );

            int n;
            for ( n = 0; n < NumSupportedSignals; n++ )
            {
                _TCHAR *endptr = NULL;

                if ( 0 == lstrcmpi( SupportedSignals[n].lpSignalName, argsig ) ||
                     _tcstoul( argsig, &endptr, 0 ) == static_cast< unsigned >(SupportedSignals[n].iSignalValue) && (!endptr || !*endptr) )
                {
                    *pSig = SupportedSignals[n].iSignalValue;
                    break;
                }
            }

            if ( n >= NumSupportedSignals )
            {
                _ftprintf( stderr,
                    _T("kill: Illegal argument %s\n")
                    _T("Type 'kill --help' to show allowed syntax.\n")
                    _T("Type 'kill -l' to show supported signals.\n"),
                    argv[argn] );
                ExitProcess( 0 );
            }
        }
        else
        {
            unsigned long value = 0;
            _TCHAR  *endptr = NULL;

            value = _tcstoul( argv[argn], &endptr, 0 );

            if ( !endptr || !*endptr )
            {
                if ( *lpdwNumProcesses < dwMaxProcesses )
                {
                    *(lpProcesses++) = value;
                    (*lpdwNumProcesses)++;
                }
            }
            else
            {
                HANDLE  hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );

                if ( IsValidHandle( hSnapshot ) )
                {
                    PROCESSENTRY32  pe;

                    pe.dwSize = sizeof(pe);
                    BOOL fSuccess = Process32First( hSnapshot, &pe );

                    while ( fSuccess )
                    {
                        if ( 0 == lstrcmpi( argv[argn], pe.szExeFile ) )
                        {
                            if ( *lpdwNumProcesses < dwMaxProcesses )
                            {
                                *(lpProcesses++) = pe.th32ProcessID;
                                (*lpdwNumProcesses)++;
                            }
                        }
                        fSuccess = Process32Next( hSnapshot, &pe );
                    }

                    CloseHandle( hSnapshot );
                }
            }
        }
    }

    if ( !*lpdwNumProcesses )
    {
        _ftprintf( stderr,
            _T("kill: No process specified.\n")
            _T("Use kill --help to show allowed syntax.\n")
            );
        ExitProcess( 0 );
    }

}

int _tmain()
{
    DWORD   dwProcessIds[1024];
    DWORD   nProcesses = elementsof(dwProcessIds);
    int     sig = SIGTERM;

    ParseCommandArgs( dwProcessIds, &nProcesses, &sig );

    for ( ULONG n = 0; n < nProcesses; n++ )
    {
        HANDLE  hProcess;

        _tprintf( _T("Sending signal to process id %d..."), dwProcessIds[n] );
        hProcess = OpenProcess( PROCESS_TERMINATE | PROCESS_CREATE_THREAD | SYNCHRONIZE |
            PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
            FALSE, dwProcessIds[n] );

        if ( IsValidHandle( hProcess ) )
        {
            if ( SIGKILL == sig )
                TerminateProcess( hProcess, 255 );
            else
                RaiseSignalEx( hProcess, sig );
            _tprintf( _T("Done\n") );

            CloseHandle( hProcess );
        }
        else
            _ftprintf( stderr, _T("No such process\n") );
    }

    return 0;
}

<|endoftext|>


<commit_before>/*
 * matching_test.cpp
 *
 *  Created on: Oct 17, 2010
 *      Author: ethan
 */
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <iostream>

using namespace cv;

using std::cout;
using std::cerr;
using std::endl;
using std::vector;

void help(char **av)
{
	   cerr << "usage: " << av[0] << " im1.jpg im2.jpg"
			   << "\n"
			   << "This program shows how to use BRIEF descriptor to match points in features2d\n"
			   << "It takes in two images, finds keypoints and matches them displaying matches and final homography warped results\n"
			   << endl;
}

//Copy (x,y) location of descriptor matches found from KeyPoint data structures into Point2f vectors
void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train,
                    const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query)
{
  pts_train.clear();
  pts_query.clear();
  pts_train.reserve(matches.size());
  pts_query.reserve(matches.size());
  for (size_t i = 0; i < matches.size(); i++)
  {
    const DMatch& match = matches[i];
    pts_query.push_back(kpts_query[match.queryIdx].pt);
    pts_train.push_back(kpts_train[match.trainIdx].pt);
  }

}

double match(const vector<KeyPoint>& /*kpts_train*/, const vector<KeyPoint>& /*kpts_query*/, DescriptorMatcher& matcher,
            const Mat& train, const Mat& query, vector<DMatch>& matches)
{

  double t = (double)getTickCount();
  matcher.match(query, train, matches); //Using features2d
  return ((double)getTickCount() - t) / getTickFrequency();
}

int main(int ac, char ** av)
{
  if (ac != 3)
  {
	help(av);
    return 1;
  }
  string im1_name, im2_name;
  im1_name = av[1];
  im2_name = av[2];

  Mat im1 = imread(im1_name, CV_LOAD_IMAGE_GRAYSCALE);
  Mat im2 = imread(im2_name, CV_LOAD_IMAGE_GRAYSCALE);

  if (im1.empty() || im2.empty())
  {
    cerr << "could not open one of the images..." << endl;
    return 1;
  }

  double t = (double)getTickCount();

  FastFeatureDetector detector(50);
  BriefDescriptorExtractor extractor(32); //this is really 32 x 8 matches since they are binary matches packed into bytes

  vector<KeyPoint> kpts_1, kpts_2;
  detector.detect(im1, kpts_1);
  detector.detect(im2, kpts_2);

  t = ((double)getTickCount() - t) / getTickFrequency();

  cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size()
      << " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl;

  Mat desc_1, desc_2;

  cout << "computing descriptors..." << endl;

  t = (double)getTickCount();

  extractor.compute(im1, kpts_1, desc_1);
  extractor.compute(im2, kpts_2, desc_2);

  t = ((double)getTickCount() - t) / getTickFrequency();

  cout << "done computing descriptors... took " << t << " seconds" << endl;

  //Do matching with 2 methods using features2d
  cout << "matching with BruteForceMatcher<HammingLUT>" << endl;
  BruteForceMatcher<HammingLUT> matcher;
  vector<DMatch> matches_lut;
  float lut_time = (float)match(kpts_1, kpts_2, matcher, desc_1, desc_2, matches_lut);
  cout << "done BruteForceMatcher<HammingLUT> matching. took " << lut_time << " seconds" << endl;

  cout << "matching with BruteForceMatcher<Hamming>" << endl;
  BruteForceMatcher<Hamming> matcher_popcount;
  vector<DMatch> matches_popcount;
  double pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
  cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;

  vector<Point2f> mpts_1, mpts_2;
  matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2); //Extract a list of the (x,y) location of the matches
  vector<uchar> outlier_mask;
  Mat H = findHomography(mpts_2, mpts_1, RANSAC, 1, outlier_mask);

  Mat outimg;
  drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1),
              reinterpret_cast<const vector<char>&> (outlier_mask));
  imshow("matches - popcount - outliers removed", outimg);

  Mat warped;
  warpPerspective(im2, warped, H, im1.size());
  imshow("warped", warped);
  imshow("diff", im1 - warped);
  waitKey();
  return 0;
}
<commit_msg>Fix a litte bug on matrix subtraction<commit_after>/*
 * matching_test.cpp
 *
 *  Created on: Oct 17, 2010
 *      Author: ethan
 */
#include <opencv2/calib3d/calib3d.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
#include <iostream>

using namespace cv;

using std::cout;
using std::cerr;
using std::endl;
using std::vector;

void help(char **av)
{
	   cerr << "usage: " << av[0] << " im1.jpg im2.jpg"
			   << "\n"
			   << "This program shows how to use BRIEF descriptor to match points in features2d\n"
			   << "It takes in two images, finds keypoints and matches them displaying matches and final homography warped results\n"
			   << endl;
}

//Copy (x,y) location of descriptor matches found from KeyPoint data structures into Point2f vectors
void matches2points(const vector<DMatch>& matches, const vector<KeyPoint>& kpts_train,
                    const vector<KeyPoint>& kpts_query, vector<Point2f>& pts_train, vector<Point2f>& pts_query)
{
  pts_train.clear();
  pts_query.clear();
  pts_train.reserve(matches.size());
  pts_query.reserve(matches.size());
  for (size_t i = 0; i < matches.size(); i++)
  {
    const DMatch& match = matches[i];
    pts_query.push_back(kpts_query[match.queryIdx].pt);
    pts_train.push_back(kpts_train[match.trainIdx].pt);
  }

}

double match(const vector<KeyPoint>& /*kpts_train*/, const vector<KeyPoint>& /*kpts_query*/, DescriptorMatcher& matcher,
            const Mat& train, const Mat& query, vector<DMatch>& matches)
{

  double t = (double)getTickCount();
  matcher.match(query, train, matches); //Using features2d
  return ((double)getTickCount() - t) / getTickFrequency();
}

int main(int ac, char ** av)
{
  if (ac != 3)
  {
	help(av);
    return 1;
  }
  string im1_name, im2_name;
  im1_name = av[1];
  im2_name = av[2];

  Mat im1 = imread(im1_name, CV_LOAD_IMAGE_GRAYSCALE);
  Mat im2 = imread(im2_name, CV_LOAD_IMAGE_GRAYSCALE);

  if (im1.empty() || im2.empty())
  {
    cerr << "could not open one of the images..." << endl;
    return 1;
  }

  double t = (double)getTickCount();

  FastFeatureDetector detector(50);
  BriefDescriptorExtractor extractor(32); //this is really 32 x 8 matches since they are binary matches packed into bytes

  vector<KeyPoint> kpts_1, kpts_2;
  detector.detect(im1, kpts_1);
  detector.detect(im2, kpts_2);

  t = ((double)getTickCount() - t) / getTickFrequency();

  cout << "found " << kpts_1.size() << " keypoints in " << im1_name << endl << "fount " << kpts_2.size()
      << " keypoints in " << im2_name << endl << "took " << t << " seconds." << endl;

  Mat desc_1, desc_2;

  cout << "computing descriptors..." << endl;

  t = (double)getTickCount();

  extractor.compute(im1, kpts_1, desc_1);
  extractor.compute(im2, kpts_2, desc_2);

  t = ((double)getTickCount() - t) / getTickFrequency();

  cout << "done computing descriptors... took " << t << " seconds" << endl;

  //Do matching with 2 methods using features2d
  cout << "matching with BruteForceMatcher<HammingLUT>" << endl;
  BruteForceMatcher<HammingLUT> matcher;
  vector<DMatch> matches_lut;
  float lut_time = (float)match(kpts_1, kpts_2, matcher, desc_1, desc_2, matches_lut);
  cout << "done BruteForceMatcher<HammingLUT> matching. took " << lut_time << " seconds" << endl;

  cout << "matching with BruteForceMatcher<Hamming>" << endl;
  BruteForceMatcher<Hamming> matcher_popcount;
  vector<DMatch> matches_popcount;
  double pop_time = match(kpts_1, kpts_2, matcher_popcount, desc_1, desc_2, matches_popcount);
  cout << "done BruteForceMatcher<Hamming> matching. took " << pop_time << " seconds" << endl;

  vector<Point2f> mpts_1, mpts_2;
  matches2points(matches_popcount, kpts_1, kpts_2, mpts_1, mpts_2); //Extract a list of the (x,y) location of the matches
  vector<uchar> outlier_mask;
  Mat H = findHomography(mpts_2, mpts_1, RANSAC, 1, outlier_mask);

  Mat outimg;
  drawMatches(im2, kpts_2, im1, kpts_1, matches_popcount, outimg, Scalar::all(-1), Scalar::all(-1),
              reinterpret_cast<const vector<char>&> (outlier_mask));
  imshow("matches - popcount - outliers removed", outimg);

  Mat warped;
  Mat diff;
  warpPerspective(im2, warped, H, im1.size());
  imshow("warped", warped);
  absdiff(im1,warped,diff);
  imshow("diff", diff);
  waitKey();
  return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: lotus.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 12:28:56 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "lotimpop.hxx"

#include <sfx2/docfile.hxx>
#include <tools/urlobj.hxx>

#include "scerrors.hxx"
#include "root.hxx"
#include "filtopt.hxx"

//------------------------------------------------------------------------

extern FltError ScImportLotus123old( SvStream&, ScDocument*, CharSet eSrc );
        // alter Krempel in filter.cxx!

FltError ScImportLotus123( SfxMedium& rMedium, ScDocument* pDocument, CharSet eSrc )
{
        ScFilterOptions aFilterOpt;
    BOOL bWithWK3 = aFilterOpt.GetWK3Flag();

    SvStream*           pStream = rMedium.GetInStream();

    if( !pStream )
        return eERR_OPEN;

    FltError            eRet;

    pStream->Seek( 0UL );

    pStream->SetBufferSize( 32768 );

    ImportLotus         aLotusImport( *pStream, pDocument, eSrc );

    if( bWithWK3 )
        eRet = aLotusImport.Read();
    else
        eRet = 0xFFFFFFFF;  // WK1 /WKS erzwingen

    // ACHTUNG: QUICK-HACK fuer WK1 / WKS  <->  WK3 / WK4
    if( eRet == 0xFFFFFFFF )
    {
        SvStream*       pStream = rMedium.GetInStream();

        if( !pStream )
            return eERR_OPEN;

        pStream->Seek( 0UL );

        pStream->SetBufferSize( 32768 );

        eRet = ScImportLotus123old( *pStream, pDocument, eSrc );

        pStream->SetBufferSize( 0 );

        return eRet;
    }

    if( eRet != eERR_OK )
        return eRet;

    if( pLotusRoot->eFirstType == Lotus_WK3 )
    {// versuchen *.FM3-File zu laden
        INetURLObject aURL( rMedium.GetURLObject() );
        aURL.setExtension( CREATE_STRING( "FM3" ) );
        SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_STD_READ, TRUE );
        SvStream* pStream = aMedium.GetInStream();
        if ( pStream )
        {
            if( aLotusImport.Read( *pStream ) != eERR_OK )
                eRet = SCWARN_IMPORT_WRONG_FM3;
        }
        else
            eRet = SCWARN_IMPORT_OPEN_FM3;
    }

    return eRet;
}

<commit_msg>INTEGRATION: CWS calcwarnings (1.8.110); FILE MERGED 2006/12/12 16:42:51 dr 1.8.110.1: #i69284# remove compiler warnings for unxlngi6<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: lotus.cxx,v $
 *
 *  $Revision: 1.9 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 12:39:05 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"
#include "lotimpop.hxx"

#include <sfx2/docfile.hxx>
#include <tools/urlobj.hxx>

#include "scerrors.hxx"
#include "root.hxx"
#include "filtopt.hxx"

//------------------------------------------------------------------------

extern FltError ScImportLotus123old( SvStream&, ScDocument*, CharSet eSrc );
        // alter Krempel in filter.cxx!

FltError ScImportLotus123( SfxMedium& rMedium, ScDocument* pDocument, CharSet eSrc )
{
        ScFilterOptions aFilterOpt;
    BOOL bWithWK3 = aFilterOpt.GetWK3Flag();

    SvStream*           pStream = rMedium.GetInStream();

    if( !pStream )
        return eERR_OPEN;

    FltError            eRet;

    pStream->Seek( 0UL );

    pStream->SetBufferSize( 32768 );

    ImportLotus         aLotusImport( *pStream, pDocument, eSrc );

    if( bWithWK3 )
        eRet = aLotusImport.Read();
    else
        eRet = 0xFFFFFFFF;  // WK1 /WKS erzwingen

    // ACHTUNG: QUICK-HACK fuer WK1 / WKS  <->  WK3 / WK4
    if( eRet == 0xFFFFFFFF )
    {
        pStream->Seek( 0UL );

        pStream->SetBufferSize( 32768 );

        eRet = ScImportLotus123old( *pStream, pDocument, eSrc );

        pStream->SetBufferSize( 0 );

        return eRet;
    }

    if( eRet != eERR_OK )
        return eRet;

    if( pLotusRoot->eFirstType == Lotus_WK3 )
    {// versuchen *.FM3-File zu laden
        INetURLObject aURL( rMedium.GetURLObject() );
        aURL.setExtension( CREATE_STRING( "FM3" ) );
        SfxMedium aMedium( aURL.GetMainURL(INetURLObject::NO_DECODE), STREAM_STD_READ, TRUE );
        pStream = aMedium.GetInStream();
        if ( pStream )
        {
            if( aLotusImport.Read( *pStream ) != eERR_OK )
                eRet = SCWARN_IMPORT_WRONG_FM3;
        }
        else
            eRet = SCWARN_IMPORT_OPEN_FM3;
    }

    return eRet;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docsh7.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 20:47:22 $
 *
 *  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
 *
 ************************************************************************/

#ifdef PCH
#include "ui_pch.hxx"
#endif

#pragma hdrstop

// INCLUDE ---------------------------------------------------------

#include "docsh.hxx"

//------------------------------------------------------------------

void ScDocShell::GetDrawObjState( SfxItemSet &rSet )
{
    //  SID_SC_ACTIVEOBJECT (SelectedObject) - removed (old Basic)
}

<commit_msg>INTEGRATION: CWS pchfix01 (1.2.216); FILE MERGED 2006/07/12 10:02:33 kaib 1.2.216.1: #i67080# Converted cxx files in sc, added initial project level pch and stripped old PCH definitions.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: docsh7.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 13:41:31 $
 *
 *  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
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// INCLUDE ---------------------------------------------------------

#include "docsh.hxx"

//------------------------------------------------------------------

void ScDocShell::GetDrawObjState( SfxItemSet &rSet )
{
    //  SID_SC_ACTIVEOBJECT (SelectedObject) - removed (old Basic)
}

<|endoftext|>


<commit_before>#ifndef GNR_INVOKE_HPP
# define GNR_INVOKE_HPP
# pragma once

#include <tuple>

namespace gnr
{

namespace detail::invoke
{

constexpr bool is_nothrow_invocable(auto&& f, auto&& t) noexcept
{
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept
  {
    return noexcept(
      std::invoke(
        std::forward<decltype(f)>(f),
        std::get<I>(std::forward<decltype(t)>(t))...
      )
    );
  }(std::make_index_sequence<
      std::tuple_size_v<std::remove_reference_t<decltype(t)>>
    >()
  );
}

template <std::size_t N>
constexpr auto split(auto&& t) noexcept requires(bool(N))
{
  constexpr auto n(std::tuple_size_v<std::remove_cvref_t<decltype(t)>>);
  static_assert(n && !(n % N));
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept
  {
    return std::make_tuple(
      [&]<auto ...J>(std::index_sequence<J...>) noexcept
      {
        constexpr auto K(N * I);
        return std::forward_as_tuple(std::get<K + J>(t)...);
      }(std::make_index_sequence<N + I - I>())...
    );
  }(std::make_index_sequence<n / N>());
}

}

constexpr decltype(auto) apply(auto&& f, auto&& t) noexcept(
  noexcept(
    detail::invoke::is_nothrow_invocable(
      std::forward<decltype(f)>(f),
      std::forward<decltype(t)>(t)
    )
  )
)
{
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept(
    noexcept(
      std::invoke(
        std::forward<decltype(f)>(f),
        std::get<I>(std::forward<decltype(t)>(t))...
      )
    )
  )
  {
    return std::invoke(
      std::forward<decltype(f)>(f),
      std::get<I>(std::forward<decltype(t)>(t))...
    );
  }(std::make_index_sequence<
      std::tuple_size_v<std::remove_reference_t<decltype(t)>>
    >()
  );
}

constexpr auto invoke_all(auto f, auto&& ...a) noexcept(noexcept(
  (f(std::forward<decltype(a)>(a)), ...)))
{
  (f(std::forward<decltype(a)>(a)), ...);
}

constexpr auto invoke_cond(auto f, auto&& ...a) noexcept(noexcept(
  (f(std::forward<decltype(a)>(a)), ...)))
{
  return (f(std::forward<decltype(a)>(a)) || ...);
}

namespace detail::invoke
{

template <std::size_t N>
constexpr bool is_nothrow_split_invocable(auto f, auto&& ...a) noexcept
{
  return noexcept(
    ::gnr::apply([&](auto&& ...t) noexcept(noexcept(
      (::gnr::apply(f, std::forward<decltype(t)>(t)), ...)))
      {
        (::gnr::apply(f, std::forward<decltype(t)>(t)), ...);
      },
      detail::invoke::split<N>(std::forward_as_tuple(a...))
    )
  );
}

}

template <std::size_t N>
constexpr void invoke_split(auto f, auto&& ...a) noexcept(
  noexcept(
    detail::invoke::is_nothrow_split_invocable<N>(
      f,
      std::forward<decltype(a)>(a)...
    )
  )
)
{
  ::gnr::apply([&](auto&& ...t) noexcept(noexcept(
    (::gnr::apply(f, std::forward<decltype(t)>(t)), ...)))
    {
      (::gnr::apply(f, std::forward<decltype(t)>(t)), ...);
    },
    detail::invoke::split<N>(std::forward_as_tuple(a...))
  );
}

}

#endif // GNR_INVOKE_HPP
<commit_msg>some fixes<commit_after>#ifndef GNR_INVOKE_HPP
# define GNR_INVOKE_HPP
# pragma once

#include <functional>

#include <tuple>

namespace gnr
{

namespace detail::invoke
{

constexpr bool is_nothrow_invocable(auto&& f, auto&& t) noexcept
{
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept
  {
    return noexcept(
      std::invoke(
        std::forward<decltype(f)>(f),
        std::get<I>(std::forward<decltype(t)>(t))...
      )
    );
  }(std::make_index_sequence<
      std::tuple_size_v<std::remove_reference_t<decltype(t)>>
    >()
  );
}

template <std::size_t N>
constexpr auto split(auto&& t) noexcept requires(bool(N))
{
  constexpr auto n(std::tuple_size_v<std::remove_cvref_t<decltype(t)>>);
  static_assert(n && !(n % N));
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept
  {
    return std::tuple(
      [&]<auto ...J>(std::index_sequence<J...>) noexcept
      {
        constexpr auto K(N * I);
        return std::forward_as_tuple(std::get<K + J>(t)...);
      }(std::make_index_sequence<N + I - I>())...
    );
  }(std::make_index_sequence<n / N>());
}

}

constexpr decltype(auto) apply(auto&& f, auto&& t) noexcept(
  noexcept(
    detail::invoke::is_nothrow_invocable(
      std::forward<decltype(f)>(f),
      std::forward<decltype(t)>(t)
    )
  )
)
{
  return [&]<auto ...I>(std::index_sequence<I...>) noexcept(
    noexcept(
      std::invoke(
        std::forward<decltype(f)>(f),
        std::get<I>(std::forward<decltype(t)>(t))...
      )
    )
  )
  {
    return std::invoke(
      std::forward<decltype(f)>(f),
      std::get<I>(std::forward<decltype(t)>(t))...
    );
  }(std::make_index_sequence<
      std::tuple_size_v<std::remove_reference_t<decltype(t)>>
    >()
  );
}

constexpr auto invoke_all(auto f, auto&& ...a) noexcept(noexcept(
  (f(std::forward<decltype(a)>(a)), ...)))
{
  (f(std::forward<decltype(a)>(a)), ...);
}

constexpr auto invoke_cond(auto f, auto&& ...a) noexcept(noexcept(
  (f(std::forward<decltype(a)>(a)), ...)))
{
  return (f(std::forward<decltype(a)>(a)) || ...);
}

namespace detail::invoke
{

template <std::size_t N>
constexpr bool is_nothrow_split_invocable(auto f, auto&& ...a) noexcept
{
  return noexcept(
    ::gnr::apply([&](auto&& ...t) noexcept(noexcept(
      (::gnr::apply(f, std::forward<decltype(t)>(t)), ...)))
      {
        (::gnr::apply(f, std::forward<decltype(t)>(t)), ...);
      },
      detail::invoke::split<N>(std::forward_as_tuple(a...))
    )
  );
}

}

template <std::size_t N>
constexpr void invoke_split(auto f, auto&& ...a) noexcept(
  noexcept(
    detail::invoke::is_nothrow_split_invocable<N>(
      f,
      std::forward<decltype(a)>(a)...
    )
  )
)
{
  ::gnr::apply([&](auto&& ...t) noexcept(noexcept(
    (::gnr::apply(f, std::forward<decltype(t)>(t)), ...)))
    {
      (::gnr::apply(f, std::forward<decltype(t)>(t)), ...);
    },
    detail::invoke::split<N>(std::forward_as_tuple(a...))
  );
}

}

#endif // GNR_INVOKE_HPP
<|endoftext|>