<commit_before>
// Copyright (c) 2013-2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <assert.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#include "portal.h"
#include "sock_utils.h"

static struct {
    unsigned char *buffer;
    uint32_t buffer_len;
    int size_accum;
} dma_info[32];

extern "C" {
  void write_pareff32(uint32_t pref, uint32_t offset, unsigned int data){
    *(unsigned int *)&dma_info[pref].buffer[offset] = data;
  }

  unsigned int read_pareff32(uint32_t pref, uint32_t offset){
    return *(unsigned int *)&dma_info[pref].buffer[offset];
  }

  void write_pareff64(uint32_t pref, uint32_t offset, uint64_t data){
    *(uint64_t *)&dma_info[pref].buffer[offset] = data;
  }

  uint64_t read_pareff64(uint32_t pref, uint32_t offset){
    return *(uint64_t *)&dma_info[pref].buffer[offset];
  }

  void pareff(uint32_t apref, uint32_t size){
    uint32_t pref = apref >> 8;
    //fprintf(stderr, "BsimDma::pareff pref=%ld, size=%08x size_accum=%08x\n", pref, size, dma_info[pref].size_accum);
    assert(pref < 32);
    dma_info[pref].size_accum += size;
    if(size == 0){
      int fd;
      pareff_fd(&fd);
      dma_info[pref].buffer = (unsigned char *)mmap(0,
          dma_info[pref].size_accum, PROT_WRITE|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0);
      dma_info[pref].buffer_len = dma_info[pref].size_accum;
    }
  }
}
<commit_msg>added error message when mmap fails in bluesim<commit_after>
// Copyright (c) 2013-2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <assert.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>

#include "portal.h"
#include "sock_utils.h"

static struct {
    unsigned char *buffer;
    uint32_t buffer_len;
    int size_accum;
} dma_info[32];

extern "C" {
  void write_pareff32(uint32_t pref, uint32_t offset, unsigned int data){
    *(unsigned int *)&dma_info[pref].buffer[offset] = data;
  }

  unsigned int read_pareff32(uint32_t pref, uint32_t offset){
    return *(unsigned int *)&dma_info[pref].buffer[offset];
  }

  void write_pareff64(uint32_t pref, uint32_t offset, uint64_t data){
    *(uint64_t *)&dma_info[pref].buffer[offset] = data;
  }

  uint64_t read_pareff64(uint32_t pref, uint32_t offset){
    return *(uint64_t *)&dma_info[pref].buffer[offset];
  }

  void pareff(uint32_t apref, uint32_t size){
    uint32_t pref = apref >> 8;
    //fprintf(stderr, "BsimDma::pareff pref=%ld, size=%08x size_accum=%08x\n", pref, size, dma_info[pref].size_accum);
    assert(pref < 32);
    dma_info[pref].size_accum += size;
    if(size == 0){
      int fd;
      pareff_fd(&fd);
      dma_info[pref].buffer = (unsigned char *)mmap(0,
          dma_info[pref].size_accum, PROT_WRITE|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0);
      if (dma_info[pref].buffer == MAP_FAILED) {
          printf("%s: mmap failed fd %x buffer %p size %x errno %d\n", __FUNCTION__, fd, dma_info[pref].buffer, size, errno);
          exit(-1);
      }
      dma_info[pref].buffer_len = dma_info[pref].size_accum;
    }
  }
}
<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013-2015, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

#include <iostream>
#include <vector>
#include <algorithm>    // std::generate
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand
#include <cmath> 	// pow

#include "nupic/algorithms/SpatialPooler.hpp"
#include "nupic/algorithms/Cells4.hpp"

using namespace std;
using namespace nupic;
using nupic::algorithms::spatial_pooler::SpatialPooler;
using nupic::algorithms::Cells4::Cells4;

// function generator:
int RandomNumber01 () { return (rand()%2); } // returns random (binary) numbers from {0,1}

int main(int argc, const char * argv[])
{
const UInt DIM = 2048; // number of columns in SP, TP
const UInt DIM_INPUT = 10000;
const UInt TP_CELLS_PER_COL = 10; // cells per column in TP
const UInt EPOCHS = pow(10, 4); // number of iterations (calls to SP/TP compute() )

  vector<UInt> inputDim = {DIM_INPUT};
  vector<UInt> colDim = {DIM};

  // generate random input
  vector<UInt> input(DIM_INPUT);
  vector<UInt> outSP(DIM); // active array, output of SP/TP
  const int _CELLS = DIM * TP_CELLS_PER_COL;
  vector<UInt> outTP(_CELLS);
  Real rIn[DIM] = {}; // input for TP (must be Reals)
  Real rOut[_CELLS] = {};

  // initialize SP, TP
  SpatialPooler sp(inputDim, colDim);
  Cells4 tp(DIM, TP_CELLS_PER_COL, 12, 8, 15, 5, .5, .8, 1.0, .1, .1, 0.0, false, 42, true, false);

  //run
  for (UInt e=0; e< EPOCHS; e++) {
    generate(input.begin(), input.end(), RandomNumber01);
    fill(outSP.begin(), outSP.end(), 0);
    sp.compute(input.data(), true, outSP.data());

    for (UInt i=0; i< DIM; i++) {
      rIn[i] = (Real)(outSP[i]);
    }

    tp.compute(rIn, rOut, true, true);

    for (UInt i=0; i< _CELLS; i++) {
      outTP[i] = (UInt)rOut[i];
    }

    // print
    if (e == EPOCHS-1) {
      cout << "Epoch = " << e << endl;
      cout << "SP=" << outSP << endl;
      cout << "TP=" << outTP << endl;
    }
  }
  return 0;
}
<commit_msg>add nupic::Timer functionality<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013-2015, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

#include <iostream>
#include <vector>
#include <algorithm>    // std::generate
#include <ctime>        // std::time
#include <cstdlib>      // std::rand, std::srand
#include <cmath> 	// pow

#include "nupic/algorithms/SpatialPooler.hpp"
#include "nupic/algorithms/Cells4.hpp"
#include "nupic/os/Timer.hpp"

using namespace std;
using namespace nupic;
using nupic::algorithms::spatial_pooler::SpatialPooler;
using nupic::algorithms::Cells4::Cells4;

// function generator:
int RandomNumber01 () { return (rand()%2); } // returns random (binary) numbers from {0,1}

int main(int argc, const char * argv[])
{
const UInt DIM = 2048; // number of columns in SP, TP
const UInt DIM_INPUT = 10000;
const UInt TP_CELLS_PER_COL = 10; // cells per column in TP
const UInt EPOCHS = pow(10, 4); // number of iterations (calls to SP/TP compute() )

  vector<UInt> inputDim = {DIM_INPUT};
  vector<UInt> colDim = {DIM};

  // generate random input
  vector<UInt> input(DIM_INPUT);
  vector<UInt> outSP(DIM); // active array, output of SP/TP
  const int _CELLS = DIM * TP_CELLS_PER_COL;
  vector<UInt> outTP(_CELLS);
  Real rIn[DIM] = {}; // input for TP (must be Reals)
  Real rOut[_CELLS] = {};

  // initialize SP, TP
  SpatialPooler sp(inputDim, colDim);
  Cells4 tp(DIM, TP_CELLS_PER_COL, 12, 8, 15, 5, .5, .8, 1.0, .1, .1, 0.0, false, 42, true, false);

  // Start a stopwatch timer
  Timer stopwatch(true);

  //run
  for (UInt e=0; e< EPOCHS; e++) {
    generate(input.begin(), input.end(), RandomNumber01);
    fill(outSP.begin(), outSP.end(), 0);
    sp.compute(input.data(), true, outSP.data());

    for (UInt i=0; i< DIM; i++) {
      rIn[i] = (Real)(outSP[i]);
    }

    tp.compute(rIn, rOut, true, true);

    for (UInt i=0; i< _CELLS; i++) {
      outTP[i] = (UInt)rOut[i];
    }

    // print
    if (e == EPOCHS-1) {
      cout << "Epoch = " << e << endl;
      cout << "SP=" << outSP << endl;
      cout << "TP=" << outTP << endl;
    }

  stopwatch.stop();
  cout << "Total elapsed time = " << stopwatch.getElapsed() << " seconds" << endl;
  }
  return 0;
}
<|endoftext|>


<commit_before>#include "stdafx.h"

const static InputElement elements[] = {
	CInputElement("POSITION", SF_R32G32B32_FLOAT, 0),
	CInputElement("COLOR", SF_R32G32B32_FLOAT, 12),
};

struct Vertex {
	Vec3 pos;
	Vec3 color;
};

struct PickingUBO {
	Mat matVP;
};

class Picking {
	VBOID vbo2d, vbo3d;
	AFRenderStates renderStates;
public:
	Picking();
	~Picking();
	void Update();
	void Draw2D();
	void Draw3D();
};

#define CLASSNAME "Picking"
#define GET_PICKING \
	Picking* p = (Picking*)luaL_checkudata(L, 1, CLASSNAME);	\
	if (!p) {	\
		return 0;	\
	}

class PickingBinder {
public:
	PickingBinder() {
		GetLuaBindFuncContainer().push_back([](lua_State* L) {
			static luaL_Reg methods[] = {
				{ "Update", [](lua_State* L) { GET_PICKING p->Update(); return 0; } },
				{ "Draw2D", [](lua_State* L) { GET_PICKING p->Draw2D(); return 0; } },
				{ "Draw3D", [](lua_State* L) { GET_PICKING p->Draw3D(); return 0; } },
				{ "__gc", [](lua_State* L) { GET_PICKING p->~Picking(); return 0; } },
				{ nullptr, nullptr },
			};
			aflBindClass(L, CLASSNAME, methods, [](lua_State* L) { void* u = lua_newuserdata(L, sizeof(Picking)); new (u) Picking(); return 1; });
		});
	}
} static binder;

Picking::Picking()
{
	vbo2d = afCreateDynamicVertexBuffer(sizeof(Vertex) * 3);
	vbo3d = afCreateDynamicVertexBuffer(sizeof(Vertex) * 3);
	renderStates.Create("solid", dimof(elements), elements, BM_NONE, DSM_DEPTH_ENABLE, CM_DISABLE);
	Update();
}

Picking::~Picking()
{
	afSafeDeleteBuffer(vbo2d);
	afSafeDeleteBuffer(vbo3d);
}

void ScreenPosToRay(const Vec2& scrPos, Vec3& nearPos, Vec3& farPos)
{
	Mat v, p;
	matrixMan.Get(MatrixMan::VIEW, v);
	matrixMan.Get(MatrixMan::PROJ, p);
	Mat vp = makeViewportMatrix(systemMisc.GetScreenSize());
	Mat mInv = inv(v * p * vp);
	Vec4 nearPos4 = transform(Vec4(scrPos.x, scrPos.y, NDC_SPACE_NEAR, 1), mInv);
	Vec4 farPos4 = transform(Vec4(scrPos.x, scrPos.y, NDC_SPACE_FAR, 1), mInv);
	nearPos = Vec3(nearPos4.x, nearPos4.y, nearPos4.z) / nearPos4.w;
	farPos = Vec3(farPos4.x, farPos4.y, farPos4.z) / farPos4.w;
}

bool RayVsTriangle(const Vec3& ray1, const Vec3& ray2, const Vec3 triangle[])
{
	Vec3 rayDir = ray2 - ray1;
	float inner[3];
	for (int i = 0; i < 3; i++) {
		const Vec3& a = triangle[i];
		const Vec3& b = triangle[(i + 1) % 3];
		inner[i] = dot(cross(ray1 - a, a - b), rayDir);
	}
	return (inner[0] < 0 && inner[1] < 0 && inner[2] < 0) || (inner[0] > 0 && inner[1] > 0 && inner[2] > 0);
}

void Picking::Update()
{
	Vertex v[3];
	float radian = (float)(std::fmod(GetTime(), 3) * M_PI * 2 / 3);
	float radius = 0.5f;
	float aspect = (float)systemMisc.GetScreenSize().x / systemMisc.GetScreenSize().y;
	for (int i = 0; i < 3; i++) {
		static Vec3 center(-0.7f, 0.7f, 0.f);
		radian += (float)M_PI * 2 / 3;
		v[i].pos = Vec3(std::sin(radian) / aspect, std::cos(radian), 0) * radius + center;
	}

	bool hit = true;

	Vec2 scrPos = systemMisc.GetScreenSize();
	Vec2 curPos = systemMisc.GetMousePos();

	Vec2 curPosInNDC = curPos / scrPos * Vec2(2, -2) + Vec2(-1, 1);

	// test
	Mat vp = makeViewportMatrix(scrPos);
	Vec3 transformed = transform(Vec3(curPos.x, curPos.y, 1), inv(vp));
	assert(std::abs(transformed.x - curPosInNDC.x) < 0.001f);
	assert(std::abs(transformed.y - curPosInNDC.y) < 0.001f);

	for (int i = 0; i < 3; i++) {
		Vec3 dir = v[(i + 1) % 3].pos - v[i].pos;
		Vec3 cursorDir = Vec3(curPosInNDC.x, curPosInNDC.y, 0) - v[i].pos;
		if (cross(dir, cursorDir).z > 0) {
			hit = false;
		}
	}

	for (int i = 0; i < 3; i++) {
		v[i].color = hit ? Vec3(i == 0, i == 1, i == 2) : Vec3(0.5, 0.5, 0.5);
	}

	afWriteBuffer(vbo2d, v, sizeof(v));

	radian = (float)(std::fmod(GetTime(), 10) * M_PI * 2 / 10);
	radius = 50.f;
	Vec3 triangle[3];
	for (int i = 0; i < 3; i++) {
		radian += (float)M_PI * 2 / 3;
		triangle[i] = v[i].pos = Vec3(std::sin(radian) * radius, std::cos(radian) * radius, 50.f);
		v[i].color = Vec3(0.5, 0.5, 0.5);
	}

	Vec3 n, f;
	ScreenPosToRay(systemMisc.GetMousePos(), n, f);
	hit = RayVsTriangle(n, f, triangle);
	for (int i = 0; i < 3; i++) {
		v[i].color = hit ? Vec3(i == 0, i == 1, i == 2) : Vec3(0.5, 0.5, 0.5);
	}

	afWriteBuffer(vbo3d, v, sizeof(v));
}

void Picking::Draw3D()
{
	renderStates.Apply();
	VBOID vbos[] = {vbo3d};
	int strides[] = {sizeof(Vertex)};
#ifdef GL_TRUE
	afSetVertexAttributes(elements, dimof(elements), 1, vbos, strides);
#endif
#ifdef __d3d11_h__
	ID3D11Buffer* d11Bufs[] = { vbo3d.Get() };
	UINT uStrides[] = { sizeof(Vertex) };
	UINT offsets[] = {0};
	deviceMan11.GetContext()->IASetVertexBuffers(0, dimof(d11Bufs), d11Bufs, uStrides, offsets);
#endif
	Mat mView, mProj;
	matrixMan.Get(MatrixMan::VIEW, mView);
	matrixMan.Get(MatrixMan::PROJ, mProj);
	Mat mVP = mView * mProj;
	UBOID ubo = afBindCbv0(&mVP, sizeof(Mat));
	afDraw(PT_TRIANGLESTRIP, 3);
	afSafeDeleteBuffer(ubo);
}

void Picking::Draw2D()
{
	renderStates.Apply();
	VBOID vbos[] = {vbo2d};
	int strides[] = {sizeof(Vertex)};
#ifdef GL_TRUE
	afSetVertexAttributes(elements, dimof(elements), 1, vbos, strides);
#endif
#ifdef __d3d11_h__
	ID3D11Buffer* d11Bufs[] = { vbo2d.Get() };
	UINT uStrides[] = { sizeof(Vertex) };
	UINT offsets[] = { 0 };
	deviceMan11.GetContext()->IASetVertexBuffers(0, dimof(d11Bufs), d11Bufs, uStrides, offsets);
#endif
	Mat mView, mProj;
	matrixMan.Get(MatrixMan::VIEW, mView);
	matrixMan.Get(MatrixMan::PROJ, mProj);
	Mat mVP = mView * mProj;
	UBOID ubo = afBindCbv0(&mVP, sizeof(Mat));
	afDraw(PT_TRIANGLESTRIP, 3);
	afSafeDeleteBuffer(ubo);
}
<commit_msg>Apply VAO to picking.cpp.<commit_after>#include "stdafx.h"

const static InputElement elements[] = {
	CInputElement("POSITION", SF_R32G32B32_FLOAT, 0),
	CInputElement("COLOR", SF_R32G32B32_FLOAT, 12),
};

struct Vertex {
	Vec3 pos;
	Vec3 color;
};

class Picking {
	VBOID vbo2d, vbo3d;
	VAOID vao2d, vao3d;
	AFRenderStates renderStates;
public:
	Picking();
	~Picking();
	void Update();
	void Draw2D();
	void Draw3D();
};

#define CLASSNAME "Picking"
#define GET_PICKING \
	Picking* p = (Picking*)luaL_checkudata(L, 1, CLASSNAME);	\
	if (!p) {	\
		return 0;	\
	}

class PickingBinder {
public:
	PickingBinder() {
		GetLuaBindFuncContainer().push_back([](lua_State* L) {
			static luaL_Reg methods[] = {
				{ "Update", [](lua_State* L) { GET_PICKING p->Update(); return 0; } },
				{ "Draw2D", [](lua_State* L) { GET_PICKING p->Draw2D(); return 0; } },
				{ "Draw3D", [](lua_State* L) { GET_PICKING p->Draw3D(); return 0; } },
				{ "__gc", [](lua_State* L) { GET_PICKING p->~Picking(); return 0; } },
				{ nullptr, nullptr },
			};
			aflBindClass(L, CLASSNAME, methods, [](lua_State* L) { void* u = lua_newuserdata(L, sizeof(Picking)); new (u) Picking(); return 1; });
		});
	}
} static binder;

Picking::Picking()
{
	vbo2d = afCreateDynamicVertexBuffer(sizeof(Vertex) * 3);
	int strides = sizeof(Vertex);
	VBOID vboIds2d[] = { vbo2d };
	vao2d = afCreateVAO(elements, dimof(elements), 1, vboIds2d, &strides, IBOID());
	vbo3d = afCreateDynamicVertexBuffer(sizeof(Vertex) * 3);
	VBOID vboIds3d[] = { vbo3d };
	vao3d = afCreateVAO(elements, dimof(elements), 1, vboIds3d, &strides, IBOID());
	renderStates.Create("solid", dimof(elements), elements, BM_NONE, DSM_DEPTH_ENABLE, CM_DISABLE);
	Update();
}

Picking::~Picking()
{
	afSafeDeleteVAO(vao2d);
	afSafeDeleteVAO(vao3d);
	afSafeDeleteBuffer(vbo2d);
	afSafeDeleteBuffer(vbo3d);
}

void ScreenPosToRay(const Vec2& scrPos, Vec3& nearPos, Vec3& farPos)
{
	Mat v, p;
	matrixMan.Get(MatrixMan::VIEW, v);
	matrixMan.Get(MatrixMan::PROJ, p);
	Mat vp = makeViewportMatrix(systemMisc.GetScreenSize());
	Mat mInv = inv(v * p * vp);
	Vec4 nearPos4 = transform(Vec4(scrPos.x, scrPos.y, NDC_SPACE_NEAR, 1), mInv);
	Vec4 farPos4 = transform(Vec4(scrPos.x, scrPos.y, NDC_SPACE_FAR, 1), mInv);
	nearPos = Vec3(nearPos4.x, nearPos4.y, nearPos4.z) / nearPos4.w;
	farPos = Vec3(farPos4.x, farPos4.y, farPos4.z) / farPos4.w;
}

bool RayVsTriangle(const Vec3& ray1, const Vec3& ray2, const Vec3 triangle[])
{
	Vec3 rayDir = ray2 - ray1;
	float inner[3];
	for (int i = 0; i < 3; i++) {
		const Vec3& a = triangle[i];
		const Vec3& b = triangle[(i + 1) % 3];
		inner[i] = dot(cross(ray1 - a, a - b), rayDir);
	}
	return (inner[0] < 0 && inner[1] < 0 && inner[2] < 0) || (inner[0] > 0 && inner[1] > 0 && inner[2] > 0);
}

void Picking::Update()
{
	Vertex v[3];
	float radian = (float)(std::fmod(GetTime(), 3) * M_PI * 2 / 3);
	float radius = 0.5f;
	float aspect = (float)systemMisc.GetScreenSize().x / systemMisc.GetScreenSize().y;
	for (int i = 0; i < 3; i++) {
		static Vec3 center(-0.7f, 0.7f, 0.f);
		radian += (float)M_PI * 2 / 3;
		v[i].pos = Vec3(std::sin(radian) / aspect, std::cos(radian), 0) * radius + center;
	}

	bool hit = true;

	Vec2 scrPos = systemMisc.GetScreenSize();
	Vec2 curPos = systemMisc.GetMousePos();

	Vec2 curPosInNDC = curPos / scrPos * Vec2(2, -2) + Vec2(-1, 1);

	// test
	Mat vp = makeViewportMatrix(scrPos);
	Vec3 transformed = transform(Vec3(curPos.x, curPos.y, 1), inv(vp));
	assert(std::abs(transformed.x - curPosInNDC.x) < 0.001f);
	assert(std::abs(transformed.y - curPosInNDC.y) < 0.001f);

	for (int i = 0; i < 3; i++) {
		Vec3 dir = v[(i + 1) % 3].pos - v[i].pos;
		Vec3 cursorDir = Vec3(curPosInNDC.x, curPosInNDC.y, 0) - v[i].pos;
		if (cross(dir, cursorDir).z > 0) {
			hit = false;
		}
	}

	for (int i = 0; i < 3; i++) {
		v[i].color = hit ? Vec3(i == 0, i == 1, i == 2) : Vec3(0.5, 0.5, 0.5);
	}

	afWriteBuffer(vbo2d, v, sizeof(v));

	radian = (float)(std::fmod(GetTime(), 10) * M_PI * 2 / 10);
	radius = 50.f;
	Vec3 triangle[3];
	for (int i = 0; i < 3; i++) {
		radian += (float)M_PI * 2 / 3;
		triangle[i] = v[i].pos = Vec3(std::sin(radian) * radius, std::cos(radian) * radius, 50.f);
		v[i].color = Vec3(0.5, 0.5, 0.5);
	}

	Vec3 n, f;
	ScreenPosToRay(systemMisc.GetMousePos(), n, f);
	hit = RayVsTriangle(n, f, triangle);
	for (int i = 0; i < 3; i++) {
		v[i].color = hit ? Vec3(i == 0, i == 1, i == 2) : Vec3(0.5, 0.5, 0.5);
	}

	afWriteBuffer(vbo3d, v, sizeof(v));
}

void Picking::Draw3D()
{
	renderStates.Apply();
	afBindVAO(vao3d);
	Mat mView, mProj;
	matrixMan.Get(MatrixMan::VIEW, mView);
	matrixMan.Get(MatrixMan::PROJ, mProj);
	Mat mVP = mView * mProj;
	UBOID ubo = afBindCbv0(&mVP, sizeof(Mat));
	afDraw(PT_TRIANGLESTRIP, 3);
	afSafeDeleteBuffer(ubo);
	afBindVAO(0);
}

void Picking::Draw2D()
{
	renderStates.Apply();
	afBindVAO(vao2d);
	Mat matIdentity;
	UBOID ubo = afBindCbv0(&matIdentity, sizeof(Mat));
	afDraw(PT_TRIANGLESTRIP, 3);
	afSafeDeleteBuffer(ubo);
	afBindVAO(0);
}
<|endoftext|>


<commit_before>#include "stdafx.h"

TexMan texMan;

#ifndef _MSC_VER
static GLuint LoadTextureViaOS(const char* name, ivec2& size)
{
	jclass myview = jniEnv->FindClass(boundJavaClass);
	jmethodID method = method = jniEnv->GetStaticMethodID(myview, "loadTexture", "(Ljava/lang/String;)I");
	if (method == 0) {
		return 0;
	}
	GLuint id = jniEnv->CallStaticIntMethod(myview, method, jniEnv->NewStringUTF(name));

	glBindTexture(GL_TEXTURE_2D, id);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &size.x);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &size.y);
	glBindTexture(GL_TEXTURE_2D, 0);
}
#endif

#ifdef _MSC_VER
namespace Gdiplus {
	using std::min;
	using std::max;
}
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

static GLuint LoadTextureViaOS(const char* name, ivec2& size)
{
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
	WCHAR wc[MAX_PATH];
	MultiByteToWideChar(CP_ACP, 0, name, -1, wc, dimof(wc));
	Gdiplus::Bitmap* image = new Gdiplus::Bitmap(wc);

	int w = (int)image->GetWidth();
	int h = (int)image->GetHeight();
	size.x = w;
	size.y = h;
	Gdiplus::Rect rc(0, 0, w, h);

	Gdiplus::BitmapData* bitmapData = new Gdiplus::BitmapData;
	image->LockBits(&rc, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, bitmapData);

	std::vector<uint32_t> col;
	col.resize(w * h);
	for (int y = 0; y < h; y++) {
		memcpy(&col[y * w], (char*)bitmapData->Scan0 + bitmapData->Stride * y, w * 4);
		for (int x = 0; x < w; x++) {
			uint32_t& c = col[y * w + x];
			c = (c & 0xff00ff00) | ((c & 0xff) << 16) | ((c & 0xff0000) >> 16);
		}
	}
	image->UnlockBits(bitmapData);
	delete bitmapData;
	delete image;
	Gdiplus::GdiplusShutdown(gdiplusToken);

	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, &col[0]);
	glGenerateMipmap(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, 0);
	return texture;
}
#endif

struct DDSHeader {
	uint32_t h3[3];
	int h, w;
	uint32_t h2[2];
	int mipCnt;
	uint32_t h13[13];
	uint32_t fourcc, bitsPerPixel, rMask, gMask, bMask, aMask, caps1, caps2;
	bool IsCubeMap() const { return caps2 == 0xFE00; }
	int GetArraySize() const { return IsCubeMap() ? 6 : 1; }
	int GetMipCnt() const { return std::max(mipCnt, 1); }
};

static void bitScanForward(uint32_t* result, uint32_t mask)
{
	//	DWORD dwd;
	//	_BitScanForward(&dwd, mask);
	//	*result = dwd;

	for (int i = 0; i < 32; i++) {
		if (mask & (1 << i)) {
			*result = i;
			return;
		}
	}
	*result = 0;
}

static void ArrangeRawDDS(void* img, int size)
{
	const DDSHeader* hdr = (DDSHeader*)img;
	uint32_t rShift, gShift, bShift, aShift;
	bitScanForward(&rShift, hdr->rMask);
	bitScanForward(&gShift, hdr->gMask);
	bitScanForward(&bShift, hdr->bMask);
	bitScanForward(&aShift, hdr->aMask);
	std::for_each((uint32_t*)img + 128 / 4, (uint32_t*)img + size / 4, [&](uint32_t& im) {
		im = ((hdr->aMask & im) >> aShift << 24) + ((hdr->bMask & im) >> bShift << 16) + ((hdr->gMask & im) >> gShift << 8) + ((hdr->rMask & im) >> rShift);
	});
}

static GLuint LoadDDSTexture(const char* name, ivec2& texSize)
{
	int size;
	GLuint texture = 0;
	void* img = LoadFile(name, &size);
	if (!img) {
		aflog("LoadDDSTexture failed! %s", name);
		return 0;
	}
	const DDSHeader* hdr = (DDSHeader*)img;

	GLenum format;
	int(*pitchCalcurator)(int, int) = nullptr;
	switch (hdr->fourcc) {
	case 0x31545844: //'1TXD':
		format = 0x83F1;	// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
		pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 8; };
		break;
	case 0x33545844: //'3TXD':
		format = 0x83F2;	// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
		pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 16; };
		break;
	case 0x35545844: //'5TXD':
		format = 0x83F3;	// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
		pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 16; };
		break;
	default:
		ArrangeRawDDS(img, size);
		format = GL_RGBA;
		pitchCalcurator = [](int w, int h) { return w * h * 4; };
		break;
	}
	texSize.x = hdr->w;
	texSize.y = hdr->h;

	GLenum target = hdr->IsCubeMap() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
	GLenum targetFace = hdr->IsCubeMap() ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : GL_TEXTURE_2D;

	glGenTextures(1, &texture);
	glBindTexture(target, texture);
	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);

	int arraySize = hdr->GetArraySize();
	int mipCnt = hdr->GetMipCnt();
	int offset = 128;
	for (int a = 0; a < arraySize; a++) {
		for (int m = 0; m < mipCnt; m++) {
			int w = std::max(1, hdr->w >> m);
			int h = std::max(1, hdr->h >> m);
			if (format == GL_RGBA) {
				afHandleGLError(glTexImage2D(targetFace + a, m, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (char*)img + offset));
			} else {
				int texSize = pitchCalcurator(w, h);
				afHandleGLError(glCompressedTexImage2D(targetFace + a, m, format, w, h, 0, texSize, (char*)img + offset));
			}
			offset += pitchCalcurator(w, h);
		}
	}
	if (mipCnt == 1) {
		if (format == GL_RGBA) {
			afHandleGLError(glGenerateMipmap(target));
		} else {
			glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	// temporary disable mipmap
		}
	}

	glBindTexture(target, 0);
	free(img);
	return texture;
}

static GLuint LoadTexture(const char* name, ivec2& size)
{
	size = ivec2();
	int len = strlen(name);
	if (len > 4 && !stricmp(name + len - 4, ".dds")) {
		return LoadDDSTexture(name, size);
	} else {
		return LoadTextureViaOS(name, size);
	}
}

TexMan::TMID TexMan::CreateDynamicTexture(const char* name, int w, int h)
{
	auto it = nameToId.find(name);
	if (it != nameToId.end())
	{
		return it->second;
	}
	TMID id = nameToId[name] = afCreateDynamicTexture(w, h, AFDT_R8G8B8A8_UINT);
	ivec2 size(w, h);
	StoreTexState(id, size);
	return id;
}

TexMan::TMID TexMan::Create(const char *name)
{
	NameToId::iterator it = nameToId.find(name);
	if (it != nameToId.end())
	{
		return it->second;
	}
	ivec2 size;
	TMID id = nameToId[name] = LoadTexture(name, size);
	StoreTexState(id, size);
	return id;
}

TexMan::TMID TexMan::CreateWhiteTexture()
{
	const std::string name = "$WHITE";
	NameToId::iterator it = nameToId.find(name);
	if (it != nameToId.end())
	{
		return it->second;
	}
	TMID id = nameToId[name] = afCreateWhiteTexture();
	ivec2 size(1, 1);
	StoreTexState(id, size);
	return id;
}

void TexMan::Destroy()
{
	for (NameToId::iterator it = nameToId.begin(); it != nameToId.end(); ++it)
	{
		GLuint id[1] = { it->second };
		glDeleteTextures(1, id);
	}
	nameToId.clear();
}

void TexMan::StoreTexState(TMID id, const ivec2& v2)
{
	if (id >= texStates.size() ) {
		texStates.resize(id + 1);
	}
	texStates[id] = v2;
}

ivec2 TexMan::GetSize(TMID id)
{
	if (id >= texStates.size()) {
		return ivec2();
	}
	return texStates[id];
}

void TexMan::Write(TMID id, const void* buf)
{
	ivec2 v = GetSize(id);
	glBindTexture(GL_TEXTURE_2D, id);
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v.x, v.y, GL_RGBA, GL_UNSIGNED_BYTE, buf);
	glBindTexture(GL_TEXTURE_2D, 0);
}
<commit_msg>Fix the black texture bug<commit_after>#include "stdafx.h"

TexMan texMan;

#ifndef _MSC_VER
static GLuint LoadTextureViaOS(const char* name, ivec2& size)
{
	jclass myview = jniEnv->FindClass(boundJavaClass);
	jmethodID method = method = jniEnv->GetStaticMethodID(myview, "loadTexture", "(Ljava/lang/String;)I");
	if (method == 0) {
		return 0;
	}
	GLuint id = jniEnv->CallStaticIntMethod(myview, method, jniEnv->NewStringUTF(name));

	glBindTexture(GL_TEXTURE_2D, id);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &size.x);
	glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &size.y);
	glBindTexture(GL_TEXTURE_2D, 0);

	return id;
}
#endif

#ifdef _MSC_VER
namespace Gdiplus {
	using std::min;
	using std::max;
}
#include <gdiplus.h>
#pragma comment(lib, "gdiplus.lib")

static GLuint LoadTextureViaOS(const char* name, ivec2& size)
{
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
	ULONG_PTR gdiplusToken;
	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, nullptr);
	WCHAR wc[MAX_PATH];
	MultiByteToWideChar(CP_ACP, 0, name, -1, wc, dimof(wc));
	Gdiplus::Bitmap* image = new Gdiplus::Bitmap(wc);

	int w = (int)image->GetWidth();
	int h = (int)image->GetHeight();
	size.x = w;
	size.y = h;
	Gdiplus::Rect rc(0, 0, w, h);

	Gdiplus::BitmapData* bitmapData = new Gdiplus::BitmapData;
	image->LockBits(&rc, Gdiplus::ImageLockModeRead, PixelFormat32bppARGB, bitmapData);

	std::vector<uint32_t> col;
	col.resize(w * h);
	for (int y = 0; y < h; y++) {
		memcpy(&col[y * w], (char*)bitmapData->Scan0 + bitmapData->Stride * y, w * 4);
		for (int x = 0; x < w; x++) {
			uint32_t& c = col[y * w + x];
			c = (c & 0xff00ff00) | ((c & 0xff) << 16) | ((c & 0xff0000) >> 16);
		}
	}
	image->UnlockBits(bitmapData);
	delete bitmapData;
	delete image;
	Gdiplus::GdiplusShutdown(gdiplusToken);

	GLuint texture;
	glGenTextures(1, &texture);
	glBindTexture(GL_TEXTURE_2D, texture);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, &col[0]);
	glGenerateMipmap(GL_TEXTURE_2D);
	glBindTexture(GL_TEXTURE_2D, 0);
	return texture;
}
#endif

struct DDSHeader {
	uint32_t h3[3];
	int h, w;
	uint32_t h2[2];
	int mipCnt;
	uint32_t h13[13];
	uint32_t fourcc, bitsPerPixel, rMask, gMask, bMask, aMask, caps1, caps2;
	bool IsCubeMap() const { return caps2 == 0xFE00; }
	int GetArraySize() const { return IsCubeMap() ? 6 : 1; }
	int GetMipCnt() const { return std::max(mipCnt, 1); }
};

static void bitScanForward(uint32_t* result, uint32_t mask)
{
	//	DWORD dwd;
	//	_BitScanForward(&dwd, mask);
	//	*result = dwd;

	for (int i = 0; i < 32; i++) {
		if (mask & (1 << i)) {
			*result = i;
			return;
		}
	}
	*result = 0;
}

static void ArrangeRawDDS(void* img, int size)
{
	const DDSHeader* hdr = (DDSHeader*)img;
	uint32_t rShift, gShift, bShift, aShift;
	bitScanForward(&rShift, hdr->rMask);
	bitScanForward(&gShift, hdr->gMask);
	bitScanForward(&bShift, hdr->bMask);
	bitScanForward(&aShift, hdr->aMask);
	std::for_each((uint32_t*)img + 128 / 4, (uint32_t*)img + size / 4, [&](uint32_t& im) {
		im = ((hdr->aMask & im) >> aShift << 24) + ((hdr->bMask & im) >> bShift << 16) + ((hdr->gMask & im) >> gShift << 8) + ((hdr->rMask & im) >> rShift);
	});
}

static GLuint LoadDDSTexture(const char* name, ivec2& texSize)
{
	int size;
	GLuint texture = 0;
	void* img = LoadFile(name, &size);
	if (!img) {
		aflog("LoadDDSTexture failed! %s", name);
		return 0;
	}
	const DDSHeader* hdr = (DDSHeader*)img;

	GLenum format;
	int(*pitchCalcurator)(int, int) = nullptr;
	switch (hdr->fourcc) {
	case 0x31545844: //'1TXD':
		format = 0x83F1;	// GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
		pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 8; };
		break;
	case 0x33545844: //'3TXD':
		format = 0x83F2;	// GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
		pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 16; };
		break;
	case 0x35545844: //'5TXD':
		format = 0x83F3;	// GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
		pitchCalcurator = [](int w, int h) { return ((w + 3) / 4) * ((h + 3) / 4) * 16; };
		break;
	default:
		ArrangeRawDDS(img, size);
		format = GL_RGBA;
		pitchCalcurator = [](int w, int h) { return w * h * 4; };
		break;
	}
	texSize.x = hdr->w;
	texSize.y = hdr->h;

	GLenum target = hdr->IsCubeMap() ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
	GLenum targetFace = hdr->IsCubeMap() ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : GL_TEXTURE_2D;

	glGenTextures(1, &texture);
	glBindTexture(target, texture);
	glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
	glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_REPEAT);

	int arraySize = hdr->GetArraySize();
	int mipCnt = hdr->GetMipCnt();
	int offset = 128;
	for (int a = 0; a < arraySize; a++) {
		for (int m = 0; m < mipCnt; m++) {
			int w = std::max(1, hdr->w >> m);
			int h = std::max(1, hdr->h >> m);
			if (format == GL_RGBA) {
				afHandleGLError(glTexImage2D(targetFace + a, m, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, (char*)img + offset));
			} else {
				int texSize = pitchCalcurator(w, h);
				afHandleGLError(glCompressedTexImage2D(targetFace + a, m, format, w, h, 0, texSize, (char*)img + offset));
			}
			offset += pitchCalcurator(w, h);
		}
	}
	if (mipCnt == 1) {
		if (format == GL_RGBA) {
			afHandleGLError(glGenerateMipmap(target));
		} else {
			glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);	// temporary disable mipmap
		}
	}

	glBindTexture(target, 0);
	free(img);
	return texture;
}

static GLuint LoadTexture(const char* name, ivec2& size)
{
	size = ivec2();
	int len = strlen(name);
	if (len > 4 && !stricmp(name + len - 4, ".dds")) {
		return LoadDDSTexture(name, size);
	} else {
		return LoadTextureViaOS(name, size);
	}
}

TexMan::TMID TexMan::CreateDynamicTexture(const char* name, int w, int h)
{
	auto it = nameToId.find(name);
	if (it != nameToId.end())
	{
		return it->second;
	}
	TMID id = nameToId[name] = afCreateDynamicTexture(w, h, AFDT_R8G8B8A8_UINT);
	ivec2 size(w, h);
	StoreTexState(id, size);
	return id;
}

TexMan::TMID TexMan::Create(const char *name)
{
	NameToId::iterator it = nameToId.find(name);
	if (it != nameToId.end())
	{
		return it->second;
	}
	ivec2 size;
	TMID id = nameToId[name] = LoadTexture(name, size);
	StoreTexState(id, size);
	return id;
}

TexMan::TMID TexMan::CreateWhiteTexture()
{
	const std::string name = "$WHITE";
	NameToId::iterator it = nameToId.find(name);
	if (it != nameToId.end())
	{
		return it->second;
	}
	TMID id = nameToId[name] = afCreateWhiteTexture();
	ivec2 size(1, 1);
	StoreTexState(id, size);
	return id;
}

void TexMan::Destroy()
{
	for (NameToId::iterator it = nameToId.begin(); it != nameToId.end(); ++it)
	{
		GLuint id[1] = { it->second };
		glDeleteTextures(1, id);
	}
	nameToId.clear();
}

void TexMan::StoreTexState(TMID id, const ivec2& v2)
{
	if (id >= texStates.size() ) {
		texStates.resize(id + 1);
	}
	texStates[id] = v2;
}

ivec2 TexMan::GetSize(TMID id)
{
	if (id >= texStates.size()) {
		return ivec2();
	}
	return texStates[id];
}

void TexMan::Write(TMID id, const void* buf)
{
	ivec2 v = GetSize(id);
	glBindTexture(GL_TEXTURE_2D, id);
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, v.x, v.y, GL_RGBA, GL_UNSIGNED_BYTE, buf);
	glBindTexture(GL_TEXTURE_2D, 0);
}
<|endoftext|>


<commit_before>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_EITHER_HPP
#define CPPA_EITHER_HPP

#include <new>
#include <utility>
#include <type_traits>
#include "cppa/config.hpp"

namespace cppa {

/**
 * @brief Represents either a @p Left or a @p Right.
 */
template<class Left, class Right>
class either {

    static_assert(   std::is_convertible<Left, Right>::value == false
                  && std::is_convertible<Right, Left>::value == false,
                  "Left is not allowed to be convertible to Right");

 public:

    typedef Left left_type;
    typedef Right right_type;

    /**
     * @brief Default constructor, creates a @p Left.
     */
    either() : m_is_left(true) { new (&m_left) left_type (); }

    /**
     * @brief Creates a @p Left from @p value.
     */
    either(const left_type& value) : m_is_left(true) { cr_left(value); }

    /**
     * @brief Creates a @p Left from @p value.
     */
    either(Left&& value) : m_is_left(true) { cr_left(std::move(value)); }

    /**
     * @brief Creates a @p Right from @p value.
     */
    either(const right_type& value) : m_is_left(false) { cr_right(value); }

    /**
     * @brief Creates a @p Right from @p value.
     */
    either(Right&& value) : m_is_left(false) { cr_right(std::move(value)); }

    either(const either& other) : m_is_left(other.m_is_left) {
        if (other.m_is_left) cr_left(other.m_left);
        else cr_right(other.m_right);
    }

    either(either&& other) : m_is_left(other.m_is_left) {
        if (other.m_is_left) cr_left(std::move(other.m_left));
        else cr_right(std::move(other.m_right));
    }

    ~either() { destroy(); }

    either& operator=(const either& other) {
        if (m_is_left == other.m_is_left) {
            if (m_is_left) m_left = other.m_left;
            else m_right = other.m_right;
        }
        else {
            destroy();
            m_is_left = other.m_is_left;
            if (other.m_is_left) cr_left(other.m_left);
            else cr_right(other.m_right);
        }
        return *this;
    }

    either& operator=(either&& other) {
        if (m_is_left == other.m_is_left) {
            if (m_is_left) m_left = std::move(other.m_left);
            else m_right = std::move(other.m_right);
        }
        else {
            destroy();
            m_is_left = other.m_is_left;
            if (other.m_is_left) cr_left(std::move(other.m_left));
            else cr_right(std::move(other.m_right));
        }
        return *this;
    }

    /**
     * @brief Returns @p true if this is a @p Left; otherwise @p false.
     */
    inline bool is_left() const { return m_is_left; }

    /**
     * @brief Returns @p true if this is a @p Left; otherwise @p false.
     */
    inline bool is_right() const { return !m_is_left; }

    /**
     * @brief Returns this @p either as a @p Left.
     */
    inline Left& left() {
        CPPA_REQUIRE(m_is_left);
        return m_left;
    }

    /**
     * @brief Returns this @p either as a @p Left.
     */
    inline const left_type& left() const {
        CPPA_REQUIRE(m_is_left);
        return m_left;
    }

    /**
     * @brief Returns this @p either as a @p Right.
     */
    inline Right& right() {
        CPPA_REQUIRE(!m_is_left);
        return m_right;
    }

    /**
     * @brief Returns this @p either as a @p Right.
     */
    inline const right_type& right() const {
        CPPA_REQUIRE(!m_is_left);
        return m_right;
    }

 private:

    bool m_is_left;

    union {
        left_type m_left;
        right_type m_right;
    };

    void destroy() {
        if (m_is_left) m_left.~Left();
        else m_right.~Right();
    }

    template<typename L>
    void cr_left(L&& value) {
        new (&m_left) left_type (std::forward<L>(value));
    }

    template<typename R>
    void cr_right(R&& value) {
        new (&m_right) right_type (std::forward<R>(value));
    }

};

/** @relates either */
template<typename Left, typename Right>
bool operator==(const either<Left, Right>& lhs, const either<Left, Right>& rhs) {
    if (lhs.is_left() == rhs.is_left()) {
        if (lhs.is_left()) return lhs.left() == rhs.left();
        else return lhs.right() == rhs.right();
    }
    return false;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const either<Left, Right>& lhs, const Left& rhs) {
    return lhs.is_left() && lhs.left() == rhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const Left& lhs, const either<Left, Right>& rhs) {
    return rhs == lhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const either<Left, Right>& lhs, const Right& rhs) {
    return lhs.is_right() && lhs.right() == rhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const Right& lhs, const either<Left, Right>& rhs) {
    return rhs == lhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const either<Left, Right>& lhs, const either<Left, Right>& rhs) {
    return !(lhs == rhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const either<Left, Right>& lhs, const Left& rhs) {
    return !(lhs == rhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const Left& lhs, const either<Left, Right>& rhs) {
    return !(rhs == lhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const either<Left, Right>& lhs, const Right& rhs) {
    return !(lhs == rhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const Right& lhs, const either<Left, Right>& rhs) {
    return !(rhs == lhs);
}

} // namespace cppa

#endif // CPPA_EITHER_HPP
<commit_msg>be less restrictive on either's template parameters and added two inspection functions<commit_after>/******************************************************************************\
 *           ___        __                                                    *
 *          /\_ \    __/\ \                                                   *
 *          \//\ \  /\_\ \ \____    ___   _____   _____      __               *
 *            \ \ \ \/\ \ \ '__`\  /'___\/\ '__`\/\ '__`\  /'__`\             *
 *             \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_           *
 *             /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\          *
 *             \/____/ \/_/\/___/  \/____/ \ \ \/  \ \ \/  \/__/\/_/          *
 *                                          \ \_\   \ \_\                     *
 *                                           \/_/    \/_/                     *
 *                                                                            *
 * Copyright (C) 2011, 2012                                                   *
 * Dominik Charousset <dominik.charousset@haw-hamburg.de>                     *
 *                                                                            *
 * This file is part of libcppa.                                              *
 * libcppa is free software: you can redistribute it and/or modify it under   *
 * the terms of the GNU Lesser General Public License as published by the     *
 * Free Software Foundation, either version 3 of the License                  *
 * or (at your option) any later version.                                     *
 *                                                                            *
 * libcppa 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 libcppa. If not, see <http://www.gnu.org/licenses/>.            *
\******************************************************************************/

#ifndef CPPA_EITHER_HPP
#define CPPA_EITHER_HPP

#include <new>
#include <utility>
#include <type_traits>
#include "cppa/config.hpp"

namespace cppa {

/**
 * @brief Represents either a @p Left or a @p Right.
 */
template<class Left, class Right>
class either {

    //static_assert(   std::is_convertible<Left, Right>::value == false
    //              && std::is_convertible<Right, Left>::value == false,
    //              "Left is not allowed to be convertible to Right");

 public:

    typedef Left left_type;
    typedef Right right_type;

    /**
     * @brief Default constructor, creates a @p Left.
     */
    either() : m_is_left(true) { new (&m_left) left_type (); }

    /**
     * @brief Creates a @p Left from @p value.
     */
    either(const left_type& value) : m_is_left(true) { cr_left(value); }

    /**
     * @brief Creates a @p Left from @p value.
     */
    either(Left&& value) : m_is_left(true) { cr_left(std::move(value)); }

    /**
     * @brief Creates a @p Right from @p value.
     */
    either(const right_type& value) : m_is_left(false) { cr_right(value); }

    /**
     * @brief Creates a @p Right from @p value.
     */
    either(Right&& value) : m_is_left(false) { cr_right(std::move(value)); }

    either(const either& other) : m_is_left(other.m_is_left) {
        if (other.m_is_left) cr_left(other.m_left);
        else cr_right(other.m_right);
    }

    either(either&& other) : m_is_left(other.m_is_left) {
        if (other.m_is_left) cr_left(std::move(other.m_left));
        else cr_right(std::move(other.m_right));
    }

    ~either() { destroy(); }

    either& operator=(const either& other) {
        if (m_is_left == other.m_is_left) {
            if (m_is_left) m_left = other.m_left;
            else m_right = other.m_right;
        }
        else {
            destroy();
            m_is_left = other.m_is_left;
            if (other.m_is_left) cr_left(other.m_left);
            else cr_right(other.m_right);
        }
        return *this;
    }

    either& operator=(either&& other) {
        if (m_is_left == other.m_is_left) {
            if (m_is_left) m_left = std::move(other.m_left);
            else m_right = std::move(other.m_right);
        }
        else {
            destroy();
            m_is_left = other.m_is_left;
            if (other.m_is_left) cr_left(std::move(other.m_left));
            else cr_right(std::move(other.m_right));
        }
        return *this;
    }

    /**
     * @brief Returns @p true if this is a @p Left; otherwise @p false.
     */
    inline bool is_left() const { return m_is_left; }

    /**
     * @brief Returns @p true if this is a @p Left; otherwise @p false.
     */
    inline bool is_right() const { return !m_is_left; }

    /**
     * @brief Returns this @p either as a @p Left.
     */
    inline Left& left() {
        CPPA_REQUIRE(m_is_left);
        return m_left;
    }

    /**
     * @brief Returns this @p either as a @p Left.
     */
    inline const left_type& left() const {
        CPPA_REQUIRE(m_is_left);
        return m_left;
    }

    /**
     * @brief Returns this @p either as a @p Right.
     */
    inline Right& right() {
        CPPA_REQUIRE(!m_is_left);
        return m_right;
    }

    /**
     * @brief Returns this @p either as a @p Right.
     */
    inline const right_type& right() const {
        CPPA_REQUIRE(!m_is_left);
        return m_right;
    }

    template<typename F>
    void apply(const F& fun) {
        if (is_left()) fun(left());
        else fun(right());
    }

    template<typename F>
    void apply(const F& fun) const {
        if (is_left()) fun(left());
        else fun(right());
    }

    template<typename Result, typename F>
    Result inspect(const F& fun) {
        if (is_left()) return fun(left());
        else return fun(right());
    }

    template<typename Result, typename F>
    Result inspect(const F& fun) const {
        if (is_left()) return fun(left());
        else return fun(right());
    }

 private:

    bool m_is_left;

    union {
        left_type m_left;
        right_type m_right;
    };

    void destroy() {
        if (m_is_left) m_left.~Left();
        else m_right.~Right();
    }

    template<typename L>
    void cr_left(L&& value) {
        new (&m_left) left_type (std::forward<L>(value));
    }

    template<typename R>
    void cr_right(R&& value) {
        new (&m_right) right_type (std::forward<R>(value));
    }

};

/** @relates either */
template<typename Left, typename Right>
bool operator==(const either<Left, Right>& lhs, const either<Left, Right>& rhs) {
    if (lhs.is_left() == rhs.is_left()) {
        if (lhs.is_left()) return lhs.left() == rhs.left();
        else return lhs.right() == rhs.right();
    }
    return false;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const either<Left, Right>& lhs, const Left& rhs) {
    return lhs.is_left() && lhs.left() == rhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const Left& lhs, const either<Left, Right>& rhs) {
    return rhs == lhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const either<Left, Right>& lhs, const Right& rhs) {
    return lhs.is_right() && lhs.right() == rhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator==(const Right& lhs, const either<Left, Right>& rhs) {
    return rhs == lhs;
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const either<Left, Right>& lhs, const either<Left, Right>& rhs) {
    return !(lhs == rhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const either<Left, Right>& lhs, const Left& rhs) {
    return !(lhs == rhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const Left& lhs, const either<Left, Right>& rhs) {
    return !(rhs == lhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const either<Left, Right>& lhs, const Right& rhs) {
    return !(lhs == rhs);
}

/** @relates either */
template<typename Left, typename Right>
bool operator!=(const Right& lhs, const either<Left, Right>& rhs) {
    return !(rhs == lhs);
}

} // namespace cppa

#endif // CPPA_EITHER_HPP
<|endoftext|>


<commit_before>#include "TextRenderer.hpp"
#include "utility/Log.h"
#include <Windows.h>

using namespace ojgl;

TextRenderer& TextRenderer::instance()
{
    static TextRenderer instance;
    return instance;
}

void TextRenderer::setHDC(void* hdc)
{
    _hdcBackend = hdc;
}

ojstd::shared_ptr<Texture> TextRenderer::get(const ojstd::string& text)
{
    int fontSize = 96;
    HDC vhdc = CreateCompatibleDC((HDC)_hdcBackend);
    auto hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
        CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Segoe Script"));

    SelectObject(vhdc, hFont);

    int totalWidth = 3;
    for (size_t i = 0; i < text.length(); i++) {
        const char* ptr = text.c_str();
        int res[1];
        GetCharWidth32A(vhdc, ptr[i], ptr[i], res);
        totalWidth += res[0];
    }

    int w = totalWidth;
    int h = fontSize;

    RECT rect { 0, 0, w, h };

    if (!vhdc)
        throw "error with vhdc";
    HBITMAP hbmp = CreateCompatibleBitmap((HDC)_hdcBackend, w, h);
    BITMAPINFO bmpi = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32, BI_RGB, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 } };

    SelectObject(vhdc, hbmp);
    ExtFloodFill(vhdc, 0, 0, 0x00FFFFFF, FLOODFILLBORDER);

    //SetTextAlign(vhdc, TA_CENTER);
    DrawText(vhdc, text.c_str(), text.length(), &rect, DT_CENTER);

    GetDIBits(vhdc, hbmp, 0, h, nullptr, &bmpi, BI_RGB);

    BYTE* buf = new BYTE[bmpi.bmiHeader.biSizeImage];
    GetDIBits(vhdc, hbmp, 0, h, buf, &bmpi, BI_RGB);

    auto result = Texture::construct(w, h, 4, buf);

    delete[] buf;

    return result;
}
<commit_msg>Replace throw with assert<commit_after>#include "TextRenderer.hpp"
#include "utility/Log.h"
#include <Windows.h>

using namespace ojgl;

TextRenderer& TextRenderer::instance()
{
    static TextRenderer instance;
    return instance;
}

void TextRenderer::setHDC(void* hdc)
{
    _hdcBackend = hdc;
}

ojstd::shared_ptr<Texture> TextRenderer::get(const ojstd::string& text)
{
    int fontSize = 96;
    HDC vhdc = CreateCompatibleDC((HDC)_hdcBackend);
    auto hFont = CreateFont(fontSize, 0, 0, 0, FW_BOLD, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS,
        CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, VARIABLE_PITCH, TEXT("Segoe Script"));

    SelectObject(vhdc, hFont);

    int totalWidth = 3;
    for (size_t i = 0; i < text.length(); i++) {
        const char* ptr = text.c_str();
        int res[1];
        GetCharWidth32A(vhdc, ptr[i], ptr[i], res);
        totalWidth += res[0];
    }

    int w = totalWidth;
    int h = fontSize;

    RECT rect { 0, 0, w, h };

    _ASSERT_EXPR(vhdc, "error with vhdc");

    HBITMAP hbmp = CreateCompatibleBitmap((HDC)_hdcBackend, w, h);
    BITMAPINFO bmpi = { { sizeof(BITMAPINFOHEADER), w, h, 1, 32, BI_RGB, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0 } };

    SelectObject(vhdc, hbmp);
    ExtFloodFill(vhdc, 0, 0, 0x00FFFFFF, FLOODFILLBORDER);

    //SetTextAlign(vhdc, TA_CENTER);
    DrawText(vhdc, text.c_str(), text.length(), &rect, DT_CENTER);

    GetDIBits(vhdc, hbmp, 0, h, nullptr, &bmpi, BI_RGB);

    BYTE* buf = new BYTE[bmpi.bmiHeader.biSizeImage];
    GetDIBits(vhdc, hbmp, 0, h, buf, &bmpi, BI_RGB);

    auto result = Texture::construct(w, h, 4, buf);

    delete[] buf;

    return result;
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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.
 *
 ************************************************************************/

#include "oox/xls/excelfilter.hxx"

#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include "oox/dump/biffdumper.hxx"
#include "oox/dump/xlsbdumper.hxx"
#include "oox/helper/binaryinputstream.hxx"
#include "oox/xls/biffdetector.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/excelchartconverter.hxx"
#include "oox/xls/excelvbaproject.hxx"
#include "oox/xls/stylesbuffer.hxx"
#include "oox/xls/themebuffer.hxx"
#include "oox/xls/workbookfragment.hxx"

namespace oox {
namespace xls {

// ============================================================================

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::oox::core;

using ::rtl::OUString;
using ::oox::drawingml::table::TableStyleListPtr;

// ============================================================================

ExcelFilterBase::ExcelFilterBase() :
    mpData( 0 )
{
}

ExcelFilterBase::~ExcelFilterBase()
{
    OSL_ENSURE( !mpData, "ExcelFilterBase::~ExcelFilterBase - workbook data not cleared" );
}

void ExcelFilterBase::registerWorkbookData( WorkbookData& rData )
{
    mpData = &rData;
}

WorkbookData& ExcelFilterBase::getWorkbookData() const
{
    OSL_ENSURE( mpData, "ExcelFilterBase::getWorkbookData - missing workbook data" );
    return *mpData;
}

void ExcelFilterBase::unregisterWorkbookData()
{
    mpData = 0;
}

// ============================================================================

OUString SAL_CALL ExcelFilter_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelFilter" );
}

Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw()
{
    Sequence< OUString > aSeq( 2 );
    aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
    aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
    return aSeq;
}

Reference< XInterface > SAL_CALL ExcelFilter_createInstance(
        const Reference< XComponentContext >& rxContext ) throw( Exception )
{
    return static_cast< ::cppu::OWeakObject* >( new ExcelFilter( rxContext ) );
}

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

ExcelFilter::ExcelFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
    XmlFilterBase( rxContext )
{
}

ExcelFilter::~ExcelFilter()
{
}

bool ExcelFilter::importDocument() throw()
{
    /*  To activate the XLSX/XLSB dumper, insert the full path to the file
        file:///<path-to-oox-module>/source/dump/xlsbdumper.ini
        into the environment variable OOO_XLSBDUMPER and start the office with
        this variable (nonpro only). */
    OOX_DUMP_FILE( ::oox::dump::xlsb::Dumper );

    OUString aWorkbookPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "officeDocument" ) );
    if( aWorkbookPath.getLength() == 0 )
        return false;

    WorkbookHelperRoot aHelper( *this );
    return aHelper.isValid() && importFragment( new WorkbookFragment( aHelper, aWorkbookPath ) );
}

bool ExcelFilter::exportDocument() throw()
{
    return false;
}

const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const
{
    return &WorkbookHelper( getWorkbookData() ).getTheme();
}

::oox::vml::Drawing* ExcelFilter::getVmlDrawing()
{
    return 0;
}

const TableStyleListPtr ExcelFilter::getTableStyles()
{
    return TableStyleListPtr();
}

::oox::drawingml::chart::ChartConverter& ExcelFilter::getChartConverter()
{
    return WorkbookHelper( getWorkbookData() ).getChartConverter();
}

GraphicHelper* ExcelFilter::implCreateGraphicHelper() const
{
    return new ExcelGraphicHelper( getWorkbookData() );
}

::oox::ole::VbaProject* ExcelFilter::implCreateVbaProject() const
{
    return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
}

sal_Bool SAL_CALL ExcelFilter::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
{
    if ( XmlFilterBase::filter( rDescriptor ) )
        return true;

    if ( isExportFilter() )
    {
        Reference< XExporter > xExporter( getServiceFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilterExport" ) ), UNO_QUERY );

        if ( xExporter.is() )
        {
            Reference< XComponent > xDocument( getModel(), UNO_QUERY );
            Reference< XFilter > xFilter( xExporter, UNO_QUERY );

            if ( xFilter.is() )
            {
                xExporter->setSourceDocument( xDocument );
                if ( xFilter->filter( rDescriptor ) )
                    return true;
            }
        }
    }

    return false;
}

OUString ExcelFilter::implGetImplementationName() const
{
    return ExcelFilter_getImplementationName();
}

// ============================================================================

OUString SAL_CALL ExcelBiffFilter_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelBiffFilter" );
}

Sequence< OUString > SAL_CALL ExcelBiffFilter_getSupportedServiceNames() throw()
{
    Sequence< OUString > aSeq( 2 );
    aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
    aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
    return aSeq;
}

Reference< XInterface > SAL_CALL ExcelBiffFilter_createInstance(
        const Reference< XComponentContext >& rxContext ) throw( Exception )
{
    return static_cast< ::cppu::OWeakObject* >( new ExcelBiffFilter( rxContext ) );
}

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

ExcelBiffFilter::ExcelBiffFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
    BinaryFilterBase( rxContext )
{
}

ExcelBiffFilter::~ExcelBiffFilter()
{
}

bool ExcelBiffFilter::importDocument() throw()
{
    /*  To activate the BIFF dumper, insert the full path to the file
        file:///<path-to-oox-module>/source/dump/biffdumper.ini
        into the environment variable OOO_BIFFDUMPER and start the office with
        this variable (nonpro only). */
    OOX_DUMP_FILE( ::oox::dump::biff::Dumper );

    /*  The boolean argument "UseBiffFilter" passed through XInitialisation
        decides whether to import/export the document with this filter (true),
        or to only use the BIFF file dumper implemented in this filter (false
        or missing) */
    Any aUseBiffFilter = getArgument( CREATE_OUSTRING( "UseBiffFilter" ) );
    bool bUseBiffFilter = false;
    if( !(aUseBiffFilter >>= bUseBiffFilter) || !bUseBiffFilter )
        return true;

    // detect BIFF version and workbook stream name
    OUString aWorkbookName;
    BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
    OSL_ENSURE( eBiff != BIFF_UNKNOWN, "ExcelBiffFilter::ExcelBiffFilter - invalid file format" );
    if( eBiff == BIFF_UNKNOWN )
        return false;

    WorkbookHelperRoot aHelper( *this, eBiff );
    return aHelper.isValid() && BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment();
}

bool ExcelBiffFilter::exportDocument() throw()
{
    return false;
}

GraphicHelper* ExcelBiffFilter::implCreateGraphicHelper() const
{
    return new ExcelGraphicHelper( getWorkbookData() );
}

::oox::ole::VbaProject* ExcelBiffFilter::implCreateVbaProject() const
{
    return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
}

OUString ExcelBiffFilter::implGetImplementationName() const
{
    return ExcelBiffFilter_getImplementationName();
}

// ============================================================================

OUString SAL_CALL ExcelVbaProjectFilter_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelVbaProjectFilter" );
}

Sequence< OUString > SAL_CALL ExcelVbaProjectFilter_getSupportedServiceNames() throw()
{
    Sequence< OUString > aSeq( 1 );
    aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
    return aSeq;
}

Reference< XInterface > SAL_CALL ExcelVbaProjectFilter_createInstance(
        const Reference< XComponentContext >& rxContext ) throw( Exception )
{
    return static_cast< ::cppu::OWeakObject* >( new ExcelVbaProjectFilter( rxContext ) );
}

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

ExcelVbaProjectFilter::ExcelVbaProjectFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
    ExcelBiffFilter( rxContext )
{
}

bool ExcelVbaProjectFilter::importDocument() throw()
{
    // detect BIFF version and workbook stream name
    OUString aWorkbookName;
    BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
    OSL_ENSURE( eBiff == BIFF8, "ExcelVbaProjectFilter::ExcelVbaProjectFilter - invalid file format" );
    if( eBiff != BIFF8 )
        return false;

    StorageRef xVbaPrjStrg = openSubStorage( CREATE_OUSTRING( "_VBA_PROJECT_CUR" ), false );
    if( !xVbaPrjStrg || !xVbaPrjStrg->isStorage() )
        return false;

    WorkbookHelperRoot aHelper( *this, eBiff );
    // set palette colors passed in service constructor
    Any aPalette = getArgument( CREATE_OUSTRING( "ColorPalette" ) );
    aHelper.getStyles().importPalette( aPalette );
    // import the VBA project
    getVbaProject().importVbaProject( *xVbaPrjStrg, getGraphicHelper() );
    return true;
}

bool ExcelVbaProjectFilter::exportDocument() throw()
{
    return false;
}

OUString ExcelVbaProjectFilter::implGetImplementationName() const
{
    return ExcelVbaProjectFilter_getImplementationName();
}

// ============================================================================

} // namespace xls
} // namespace oox

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Again merge-fix with importDocumentProperties()<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * 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.
 *
 ************************************************************************/

#include "oox/xls/excelfilter.hxx"

#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include "oox/dump/biffdumper.hxx"
#include "oox/dump/xlsbdumper.hxx"
#include "oox/helper/binaryinputstream.hxx"
#include "oox/xls/biffdetector.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/excelchartconverter.hxx"
#include "oox/xls/excelvbaproject.hxx"
#include "oox/xls/stylesbuffer.hxx"
#include "oox/xls/themebuffer.hxx"
#include "oox/xls/workbookfragment.hxx"

namespace oox {
namespace xls {

// ============================================================================

using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sheet;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::xml::sax;
using namespace ::oox::core;

using ::rtl::OUString;
using ::oox::drawingml::table::TableStyleListPtr;

// ============================================================================

ExcelFilterBase::ExcelFilterBase() :
    mpData( 0 )
{
}

ExcelFilterBase::~ExcelFilterBase()
{
    OSL_ENSURE( !mpData, "ExcelFilterBase::~ExcelFilterBase - workbook data not cleared" );
}

void ExcelFilterBase::registerWorkbookData( WorkbookData& rData )
{
    mpData = &rData;
}

WorkbookData& ExcelFilterBase::getWorkbookData() const
{
    OSL_ENSURE( mpData, "ExcelFilterBase::getWorkbookData - missing workbook data" );
    return *mpData;
}

void ExcelFilterBase::unregisterWorkbookData()
{
    mpData = 0;
}

// ============================================================================

OUString SAL_CALL ExcelFilter_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelFilter" );
}

Sequence< OUString > SAL_CALL ExcelFilter_getSupportedServiceNames() throw()
{
    Sequence< OUString > aSeq( 2 );
    aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
    aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
    return aSeq;
}

Reference< XInterface > SAL_CALL ExcelFilter_createInstance(
        const Reference< XComponentContext >& rxContext ) throw( Exception )
{
    return static_cast< ::cppu::OWeakObject* >( new ExcelFilter( rxContext ) );
}

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

ExcelFilter::ExcelFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
    XmlFilterBase( rxContext )
{
}

ExcelFilter::~ExcelFilter()
{
}

bool ExcelFilter::importDocument() throw()
{
    /*  To activate the XLSX/XLSB dumper, insert the full path to the file
        file:///<path-to-oox-module>/source/dump/xlsbdumper.ini
        into the environment variable OOO_XLSBDUMPER and start the office with
        this variable (nonpro only). */
    OOX_DUMP_FILE( ::oox::dump::xlsb::Dumper );

    OUString aWorkbookPath = getFragmentPathFromFirstType( CREATE_OFFICEDOC_RELATION_TYPE( "officeDocument" ) );
    if( aWorkbookPath.getLength() == 0 )
        return false;

    WorkbookHelperRoot aHelper( *this );
    if( aHelper.isValid() && importFragment( new WorkbookFragment( aHelper, aWorkbookPath ) ) )
    {
        importDocumentProperties();
        return true;
    }
    return false;
}

bool ExcelFilter::exportDocument() throw()
{
    return false;
}

const ::oox::drawingml::Theme* ExcelFilter::getCurrentTheme() const
{
    return &WorkbookHelper( getWorkbookData() ).getTheme();
}

::oox::vml::Drawing* ExcelFilter::getVmlDrawing()
{
    return 0;
}

const TableStyleListPtr ExcelFilter::getTableStyles()
{
    return TableStyleListPtr();
}

::oox::drawingml::chart::ChartConverter& ExcelFilter::getChartConverter()
{
    return WorkbookHelper( getWorkbookData() ).getChartConverter();
}

GraphicHelper* ExcelFilter::implCreateGraphicHelper() const
{
    return new ExcelGraphicHelper( getWorkbookData() );
}

::oox::ole::VbaProject* ExcelFilter::implCreateVbaProject() const
{
    return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
}

sal_Bool SAL_CALL ExcelFilter::filter( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& rDescriptor ) throw( ::com::sun::star::uno::RuntimeException )
{
    if ( XmlFilterBase::filter( rDescriptor ) )
        return true;

    if ( isExportFilter() )
    {
        Reference< XExporter > xExporter( getServiceFactory()->createInstance( CREATE_OUSTRING( "com.sun.star.comp.oox.ExcelFilterExport" ) ), UNO_QUERY );

        if ( xExporter.is() )
        {
            Reference< XComponent > xDocument( getModel(), UNO_QUERY );
            Reference< XFilter > xFilter( xExporter, UNO_QUERY );

            if ( xFilter.is() )
            {
                xExporter->setSourceDocument( xDocument );
                if ( xFilter->filter( rDescriptor ) )
                    return true;
            }
        }
    }

    return false;
}

OUString ExcelFilter::implGetImplementationName() const
{
    return ExcelFilter_getImplementationName();
}

// ============================================================================

OUString SAL_CALL ExcelBiffFilter_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelBiffFilter" );
}

Sequence< OUString > SAL_CALL ExcelBiffFilter_getSupportedServiceNames() throw()
{
    Sequence< OUString > aSeq( 2 );
    aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
    aSeq[ 1 ] = CREATE_OUSTRING( "com.sun.star.document.ExportFilter" );
    return aSeq;
}

Reference< XInterface > SAL_CALL ExcelBiffFilter_createInstance(
        const Reference< XComponentContext >& rxContext ) throw( Exception )
{
    return static_cast< ::cppu::OWeakObject* >( new ExcelBiffFilter( rxContext ) );
}

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

ExcelBiffFilter::ExcelBiffFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
    BinaryFilterBase( rxContext )
{
}

ExcelBiffFilter::~ExcelBiffFilter()
{
}

bool ExcelBiffFilter::importDocument() throw()
{
    /*  To activate the BIFF dumper, insert the full path to the file
        file:///<path-to-oox-module>/source/dump/biffdumper.ini
        into the environment variable OOO_BIFFDUMPER and start the office with
        this variable (nonpro only). */
    OOX_DUMP_FILE( ::oox::dump::biff::Dumper );

    /*  The boolean argument "UseBiffFilter" passed through XInitialisation
        decides whether to import/export the document with this filter (true),
        or to only use the BIFF file dumper implemented in this filter (false
        or missing) */
    Any aUseBiffFilter = getArgument( CREATE_OUSTRING( "UseBiffFilter" ) );
    bool bUseBiffFilter = false;
    if( !(aUseBiffFilter >>= bUseBiffFilter) || !bUseBiffFilter )
        return true;

    // detect BIFF version and workbook stream name
    OUString aWorkbookName;
    BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
    OSL_ENSURE( eBiff != BIFF_UNKNOWN, "ExcelBiffFilter::ExcelBiffFilter - invalid file format" );
    if( eBiff == BIFF_UNKNOWN )
        return false;

    WorkbookHelperRoot aHelper( *this, eBiff );
    return aHelper.isValid() && BiffWorkbookFragment( aHelper, aWorkbookName ).importFragment();
}

bool ExcelBiffFilter::exportDocument() throw()
{
    return false;
}

GraphicHelper* ExcelBiffFilter::implCreateGraphicHelper() const
{
    return new ExcelGraphicHelper( getWorkbookData() );
}

::oox::ole::VbaProject* ExcelBiffFilter::implCreateVbaProject() const
{
    return new ExcelVbaProject( getComponentContext(), Reference< XSpreadsheetDocument >( getModel(), UNO_QUERY ) );
}

OUString ExcelBiffFilter::implGetImplementationName() const
{
    return ExcelBiffFilter_getImplementationName();
}

// ============================================================================

OUString SAL_CALL ExcelVbaProjectFilter_getImplementationName() throw()
{
    return CREATE_OUSTRING( "com.sun.star.comp.oox.xls.ExcelVbaProjectFilter" );
}

Sequence< OUString > SAL_CALL ExcelVbaProjectFilter_getSupportedServiceNames() throw()
{
    Sequence< OUString > aSeq( 1 );
    aSeq[ 0 ] = CREATE_OUSTRING( "com.sun.star.document.ImportFilter" );
    return aSeq;
}

Reference< XInterface > SAL_CALL ExcelVbaProjectFilter_createInstance(
        const Reference< XComponentContext >& rxContext ) throw( Exception )
{
    return static_cast< ::cppu::OWeakObject* >( new ExcelVbaProjectFilter( rxContext ) );
}

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

ExcelVbaProjectFilter::ExcelVbaProjectFilter( const Reference< XComponentContext >& rxContext ) throw( RuntimeException ) :
    ExcelBiffFilter( rxContext )
{
}

bool ExcelVbaProjectFilter::importDocument() throw()
{
    // detect BIFF version and workbook stream name
    OUString aWorkbookName;
    BiffType eBiff = BiffDetector::detectStorageBiffVersion( aWorkbookName, getStorage() );
    OSL_ENSURE( eBiff == BIFF8, "ExcelVbaProjectFilter::ExcelVbaProjectFilter - invalid file format" );
    if( eBiff != BIFF8 )
        return false;

    StorageRef xVbaPrjStrg = openSubStorage( CREATE_OUSTRING( "_VBA_PROJECT_CUR" ), false );
    if( !xVbaPrjStrg || !xVbaPrjStrg->isStorage() )
        return false;

    WorkbookHelperRoot aHelper( *this, eBiff );
    // set palette colors passed in service constructor
    Any aPalette = getArgument( CREATE_OUSTRING( "ColorPalette" ) );
    aHelper.getStyles().importPalette( aPalette );
    // import the VBA project
    getVbaProject().importVbaProject( *xVbaPrjStrg, getGraphicHelper() );
    return true;
}

bool ExcelVbaProjectFilter::exportDocument() throw()
{
    return false;
}

OUString ExcelVbaProjectFilter::implGetImplementationName() const
{
    return ExcelVbaProjectFilter_getImplementationName();
}

// ============================================================================

} // namespace xls
} // namespace oox

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/**
 * GLib - General C++ Library
 *
 * Copyright (C) 2014 Jozef Stefan Institute
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 * thread.cpp
 *
 *  Created on: May 24, 2010
 *      Author: tadej
 */
#include "thread_win.h"

////////////////////////////////////////////
// Mutex
TMutex::TMutex(const bool& LockOnStartP) {
    MutexHandle = CreateMutex(NULL, LockOnStartP ? TRUE : FALSE, NULL);
}

TMutex::~TMutex() {
    CloseHandle(MutexHandle);
}

bool TMutex::Wait(const int& MxMSecs) {
    DWORD dwMilliSeconds = (MxMSecs == -1) ? INFINITE : ((DWORD)MxMSecs);
    const DWORD Res = WaitForSingleObject(MutexHandle, dwMilliSeconds);
    return (Res == WAIT_ABANDONED) || (Res == WAIT_OBJECT_0);
}

void TMutex::GetLock() {
	while (!Wait(1000)) { }
}

bool TMutex::Release() {
    return ReleaseMutex(MutexHandle) != 0;
}

////////////////////////////////////////////
// Critical Section
TCriticalSection::TCriticalSection(const TCriticalSectionType& _Type) {
	InitializeCriticalSection(&Cs);
}
TCriticalSection::~TCriticalSection() {
	DeleteCriticalSection(&Cs);
}
void TCriticalSection::Enter() {
	EnterCriticalSection(&Cs);
}
bool TCriticalSection::TryEnter() {
	return TryEnterCriticalSection(&Cs) != 0;
}
void TCriticalSection::Leave() {
	LeaveCriticalSection(&Cs);
}

////////////////////////////////////////////
// Blocker
TBlocker::TBlocker() {
	Event = CreateEvent(
        NULL,	// default security attributes
        false,  // auto-reset event
        false,  // initial state is nonsignaled
        NULL);	// object name
	IAssert(Event != NULL);
}

TBlocker::~TBlocker() {
	if (Event != NULL) {
		CloseHandle(Event);
	}
}

void TBlocker::Block(int MxMSecs) {
	if (Event != NULL) {
	    DWORD dwMilliSeconds = (MxMSecs == -1) ? INFINITE : ((DWORD)MxMSecs);
		switch (WaitForSingleObject(Event, dwMilliSeconds))
		{
			// Event object was signaled
			case WAIT_OBJECT_0:
				ResetEvent(Event);
				break;
			// An error occurred
			default:
				EFailR(TStr::Fmt("Thread wait error: %d\n", GetLastError()));
		}
	}
}

void TBlocker::Release() {
	SetEvent(Event);
}

////////////////////////////////////////////
// Thread
DWORD WINAPI TThread::EntryPoint(LPVOID pArg) {
    TThread* pThis = (TThread*)pArg;
    pThis->Run();
    return 0;
}

TThread::TThread(): ThreadHandle(NULL), ThreadId(0) { }

TThread::~TThread() {
    if (ThreadHandle != NULL) {
        CloseHandle(ThreadHandle);
    }
}

TThread &TThread::operator =(const TThread& Other) {
	ThreadHandle = Other.ThreadHandle;
	ThreadId = Other.ThreadId;
	return *this;
}

void TThread::Start() {
    // create new thread
    ThreadHandle = CreateThread(
        NULL,                   // default security attributes
        0,                      // use default stack size
        EntryPoint,             // thread function
        this,                   // argument to thread function
        0,                      // use default creation flags
        &ThreadId);             // returns the thread identifier

    // make sure all ok so far...
    EAssert(ThreadHandle != NULL);
}

int TThread::Join() {
	return ThreadWait<TThread>(*this);
}

void TThread::Sleep(const int& MSecs) {
	TSysProc::Sleep(MSecs);
}

int TThread::GetCoreCount() {
	int NumCpu;
	//Blaz: we know it's widnows, since it's in thread_win.cpp :-)
	SYSTEM_INFO sysinfo;
	GetSystemInfo( &sysinfo );
	NumCpu = sysinfo.dwNumberOfProcessors;
	return NumCpu;
}

////////////////////////////////////////////
// Conditional variable lock
TCondVarLock::TCondVarLock():
	Mutex(TMutexType::mtRecursive) {}

TCondVarLock::~TCondVarLock() {
	// pthread_cond_destroy should be called to free a condition variable that is no longer needed
//	pthread_cond_destroy(&CondVar);
}

void TCondVarLock::Lock() {
	Mutex.GetLock();
}

bool TCondVarLock::Release() {
	return Mutex.Release();
}

void TCondVarLock::WaitForSignal() {
//	pthread_cond_wait(&CondVar, &Mutex.MutexHandle);
}

void TCondVarLock::Signal() {
//	pthread_cond_signal(&CondVar);
}

void TCondVarLock::Broadcast() {
//	pthread_cond_broadcast(&CondVar);
}
<commit_msg>critical sections<commit_after>/**
 * GLib - General C++ Library
 *
 * Copyright (C) 2014 Jozef Stefan Institute
 *
 * This library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License, version 3,
 * 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 *
 */

/*
 * thread.cpp
 *
 *  Created on: May 24, 2010
 *      Author: tadej
 */
#include "thread_win.h"

////////////////////////////////////////////
// Mutex
TMutex::TMutex(const bool& LockOnStartP) {
    MutexHandle = CreateMutex(NULL, LockOnStartP ? TRUE : FALSE, NULL);
}

TMutex::~TMutex() {
    CloseHandle(MutexHandle);
}

bool TMutex::Wait(const int& MxMSecs) {
    DWORD dwMilliSeconds = (MxMSecs == -1) ? INFINITE : ((DWORD)MxMSecs);
    const DWORD Res = WaitForSingleObject(MutexHandle, dwMilliSeconds);
    return (Res == WAIT_ABANDONED) || (Res == WAIT_OBJECT_0);
}

void TMutex::GetLock() {
	while (!Wait(1000)) { }
}

bool TMutex::Release() {
    return ReleaseMutex(MutexHandle) != 0;
}

////////////////////////////////////////////
// Critical Section
TCriticalSection::TCriticalSection() {
	InitializeCriticalSection(&Cs);
}
TCriticalSection::~TCriticalSection() {
	DeleteCriticalSection(&Cs);
}
void TCriticalSection::Enter() {
	EnterCriticalSection(&Cs);
}
bool TCriticalSection::TryEnter() {
	return TryEnterCriticalSection(&Cs) != 0;
}
void TCriticalSection::Leave() {
	LeaveCriticalSection(&Cs);
}

////////////////////////////////////////////
// Blocker
TBlocker::TBlocker() {
	Event = CreateEvent(
        NULL,	// default security attributes
        false,  // auto-reset event
        false,  // initial state is nonsignaled
        NULL);	// object name
	IAssert(Event != NULL);
}

TBlocker::~TBlocker() {
	if (Event != NULL) {
		CloseHandle(Event);
	}
}

void TBlocker::Block(int MxMSecs) {
	if (Event != NULL) {
	    DWORD dwMilliSeconds = (MxMSecs == -1) ? INFINITE : ((DWORD)MxMSecs);
		switch (WaitForSingleObject(Event, dwMilliSeconds))
		{
			// Event object was signaled
			case WAIT_OBJECT_0:
				ResetEvent(Event);
				break;
			// An error occurred
			default:
				EFailR(TStr::Fmt("Thread wait error: %d\n", GetLastError()));
		}
	}
}

void TBlocker::Release() {
	SetEvent(Event);
}

////////////////////////////////////////////
// Thread
DWORD WINAPI TThread::EntryPoint(LPVOID pArg) {
    TThread* pThis = (TThread*)pArg;
    pThis->Run();
    return 0;
}

TThread::TThread(): ThreadHandle(NULL), ThreadId(0) { }

TThread::~TThread() {
    if (ThreadHandle != NULL) {
        CloseHandle(ThreadHandle);
    }
}

TThread &TThread::operator =(const TThread& Other) {
	ThreadHandle = Other.ThreadHandle;
	ThreadId = Other.ThreadId;
	return *this;
}

void TThread::Start() {
    // create new thread
    ThreadHandle = CreateThread(
        NULL,                   // default security attributes
        0,                      // use default stack size
        EntryPoint,             // thread function
        this,                   // argument to thread function
        0,                      // use default creation flags
        &ThreadId);             // returns the thread identifier

    // make sure all ok so far...
    EAssert(ThreadHandle != NULL);
}

int TThread::Join() {
	return ThreadWait<TThread>(*this);
}

void TThread::Sleep(const int& MSecs) {
	TSysProc::Sleep(MSecs);
}

int TThread::GetCoreCount() {
	int NumCpu;
	//Blaz: we know it's widnows, since it's in thread_win.cpp :-)
	SYSTEM_INFO sysinfo;
	GetSystemInfo( &sysinfo );
	NumCpu = sysinfo.dwNumberOfProcessors;
	return NumCpu;
}

////////////////////////////////////////////
// Conditional variable lock
TCondVarLock::TCondVarLock():
	Mutex(TMutexType::mtRecursive) {}

TCondVarLock::~TCondVarLock() {
	// pthread_cond_destroy should be called to free a condition variable that is no longer needed
//	pthread_cond_destroy(&CondVar);
}

void TCondVarLock::Lock() {
	Mutex.GetLock();
}

bool TCondVarLock::Release() {
	return Mutex.Release();
}

void TCondVarLock::WaitForSignal() {
//	pthread_cond_wait(&CondVar, &Mutex.MutexHandle);
}

void TCondVarLock::Signal() {
//	pthread_cond_signal(&CondVar);
}

void TCondVarLock::Broadcast() {
//	pthread_cond_broadcast(&CondVar);
}
<|endoftext|>