<commit_before>#if !defined(DOUBLETAKE_SEMAPHORE_H)
#define DOUBLETAKE_SEMAPHORE_H

/*
 * @file   semaphore.h
 * @brief  Semaphore used to reproduce the order of synchronization.
 * @author Tongping Liu <http://www.cs.umass.edu/~tonyliu>
 */

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>

#include "log.hh"
#include "real.hh"

typedef union semun {
  int val;
  struct semid_ds* buf;
  ushort* array;
} semaArg;

class semaphore {
public:
  semaphore() {}

  ~semaphore() { destroy(); }

#ifdef X86_32BIT
  int createSemaKey(unsigned long key) { return key; }
#else
  int createSemaKey(unsigned long key) {
    int key1 = (int)key;
    int key2 = (int)((key >> 16) & 0xFFFFFFFF);

    return key1 + key2;
  }
#endif

  void init(unsigned long key, int nsemas, int initValue) {
    int id;

    // We are trying to check whether a key is existing. If yes, then we
    // must pickup another key.
    _semaKey = createSemaKey(key);
    while(true) {
      /* Create the semaphore with external key KEY if it doesn't already
       exists. Give permissions to the world. */
      id = Real::semget(_semaKey, 1, 0666);
      /* Always check system returns. */
      if(id < 0) {
        break;
      }
      _semaKey++;
    }

    // Now we are guaranteed that the key is not exisiting.
    semaArg arg;

    // Initialize semaphore to the desired number.
    arg.val = initValue;
    _semaId = Real::semget(_semaKey, nsemas, 0666 | IPC_CREAT);
    // PRINF("Semaphore %p _semaId %d semaphore creation\n", &_semaKey, _semaId);
    if(_semaId == -1) {
      PRWRN("semaphore creates failure %s\n", strerror(errno));
      abort();
    } else {
      Real::semctl(_semaId, 0, SETVAL, arg);
    }
  }

  void wait(int val) {
    int minusVal = 0 - val;
    set(minusVal);
  }

  // Put and get are only used for simple increment and decrement operation.
  void get() { set(-1); }

  void put() { set(1); }

  void destroy() {
    semaArg argument;
    argument.val = 0;

    if(_semaId == 0) {
      return;
    }

    // PRWRN("Semaphore %p _semaId %d semaphore destory\n", &_semaKey, _semaId);
    if(Real::semctl(_semaId, 0, IPC_RMID, argument) < 0) {
      PRWRN("Cannot detroy semaphore.\n");
      abort();
    }
  }

private:
  void set(int val) {
    // PRINF("Semaphore %p _semaId %d semop value %d\n", &_semaKey, _semaId, val);
    // Now increment the semaphore by the desired value.
    struct sembuf sops;
    sops.sem_num = 0;
    sops.sem_op = val;
    sops.sem_flg = 0;
    /* int retval = */ Real::semop(_semaId, &sops, 1); // FIXME? throwing away return value.
  }

  int _semaKey;
  int _semaId;
};

#endif
<commit_msg>Temporarily disabling semaphore logic.<commit_after>#if !defined(DOUBLETAKE_SEMAPHORE_H)
#define DOUBLETAKE_SEMAPHORE_H

/*
 * @file   semaphore.h
 * @brief  Semaphore used to reproduce the order of synchronization.
 * @author Tongping Liu <http://www.cs.umass.edu/~tonyliu>
 */

#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/types.h>

#include "log.hh"
#include "real.hh"

typedef union semun {
  int val;
  struct semid_ds* buf;
  ushort* array;
} semaArg;

class semaphore {
public:
  semaphore() {}

  ~semaphore() { destroy(); }

#ifdef X86_32BIT
  int createSemaKey(unsigned long key) { return key; }
#else
  int createSemaKey(unsigned long key) {
    int key1 = (int)key;
    int key2 = (int)((key >> 16) & 0xFFFFFFFF);

    return key1 + key2;
  }
#endif

  void init(unsigned long key, int nsemas, int initValue) {
    int id;

    // We are trying to check whether a key is existing. If yes, then we
    // must pickup another key.
    _semaKey = createSemaKey(key);
    while(true) {
      /* Create the semaphore with external key KEY if it doesn't already
	 exist. Give permissions to the world. */
      id = Real::semget(_semaKey, 1, 0666);
      /* Always check system returns. */
      if(id < 0) {
        break;
      }
      _semaKey++;
    }

    // Now we are guaranteed that the key is not exisiting.
    semaArg arg;

    // Initialize semaphore to the desired number.
    arg.val = initValue;
    _semaId = Real::semget(_semaKey, nsemas, 0666 | IPC_CREAT);
    if(_semaId == -1) {
      PRWRN("semaphore creation failure %s\n", strerror(errno));
      // EDB FIXME: for now, do nothing.
      // abort();
    } else {
      Real::semctl(_semaId, 0, SETVAL, arg);
    }
  }

  void wait(int val) {
    int minusVal = 0 - val;
    set(minusVal);
  }

  // Put and get are only used for simple increment and decrement operation.
  void get() { set(-1); }

  void put() { set(1); }

  void destroy() {
    semaArg argument;
    argument.val = 0;

    if(_semaId == 0) {
      return;
    }

    // PRWRN("Semaphore %p _semaId %d semaphore destory\n", &_semaKey, _semaId);
    if(Real::semctl(_semaId, 0, IPC_RMID, argument) < 0) {
      PRWRN("Cannot detroy semaphore.\n");
      abort();
    }
  }

private:
  void set(int val) {
    // PRINF("Semaphore %p _semaId %d semop value %d\n", &_semaKey, _semaId, val);
    // Now increment the semaphore by the desired value.
    struct sembuf sops;
    sops.sem_num = 0;
    sops.sem_op = val;
    sops.sem_flg = 0;
    /* int retval = */ Real::semop(_semaId, &sops, 1); // FIXME? throwing away return value.
  }

  int _semaKey;
  int _semaId;
};

#endif
<|endoftext|>


<commit_before>#ifndef UTILJSON_HH
#define UTILJSON_HH

/**
  * @short A few utilities for better work with input JSON files.
  */

#include <string>
#include <memory>
#include <stdexcept>
#include <vector>

#include <json/reader.h>

namespace g4
{
    namespace util
    {
        /**
          * @short Create a JSON value from a file-
          */
        std::shared_ptr<Json::Value> parseJsonFile(const std::string& path);

        /**
          * @short Template-based JSON value parsing (for use in other templates).
          */
        template<typename T> T readJsonValue(const Json::Value& value);

        template<> inline double readJsonValue<double>(const Json::Value& value)
        {
            return value.asDouble();
        }

        template<> inline std::string readJsonValue<std::string>(const Json::Value& value)
        {
            return value.asString();
        }

        template<> inline int readJsonValue<int>(const Json::Value& value)
        {
            return value.asInt();
        }

        template<typename T> std::vector<T> readJsonArray(const Json::Value& value)
        {
            if (!value.isArray())
            {
                throw std::runtime_error("Cannot make vector from JSON non-array.");
            }
            std::vector<T> result;
            for (int i = 0; i < value.size(); i++)
            {
                T val = readJsonValue<T>(value[i]);
                result.push_back(val);
            }
            return result;
        }
    }
}

#endif
<commit_msg>Change JSON include to enable amalgamated version<commit_after>#ifndef UTILJSON_HH
#define UTILJSON_HH

/**
  * @short A few utilities for better work with input JSON files.
  */

#include <string>
#include <memory>
#include <stdexcept>
#include <vector>

#include <json/json.h>

namespace g4
{
    namespace util
    {
        /**
          * @short Create a JSON value from a file-
          */
        std::shared_ptr<Json::Value> parseJsonFile(const std::string& path);

        /**
          * @short Template-based JSON value parsing (for use in other templates).
          */
        template<typename T> T readJsonValue(const Json::Value& value);

        template<> inline double readJsonValue<double>(const Json::Value& value)
        {
            return value.asDouble();
        }

        template<> inline std::string readJsonValue<std::string>(const Json::Value& value)
        {
            return value.asString();
        }

        template<> inline int readJsonValue<int>(const Json::Value& value)
        {
            return value.asInt();
        }

        template<typename T> std::vector<T> readJsonArray(const Json::Value& value)
        {
            if (!value.isArray())
            {
                throw std::runtime_error("Cannot make vector from JSON non-array.");
            }
            std::vector<T> result;
            for (int i = 0; i < value.size(); i++)
            {
                T val = readJsonValue<T>(value[i]);
                result.push_back(val);
            }
            return result;
        }
    }
}

#endif
<|endoftext|>


<commit_before>//============================================================================
// Name        : DeferredRenderer.h
// Author      : Duarte Peixinho
// Version     :
// Copyright   : ;)
// Description : Deferred Renderer
//============================================================================

#include "DeferredRenderer.h"
#include <Pyros3D/Other/PyrosGL.h>

namespace p3d {

	f32 f(f32 r)
	{
		return r * (2.f * (tanf(PI / 4)));
	}
	f32 g(f32 a)
	{
		return a / (2.f*sinf(PI / 4));
	}

    DeferredRenderer::DeferredRenderer(const uint32 Width, const uint32 Height, FrameBuffer* fbo) : IRenderer(Width,Height)
    {

        echo("SUCCESS: Deferred Renderer Created");

        ActivateCulling(CullingMode::FrustumCulling);

        shadowMaterial = new GenericShaderMaterial(ShaderUsage::CastShadows);
        shadowMaterial->SetCullFace(CullFace::DoubleSided);
        shadowSkinnedMaterial = new GenericShaderMaterial(ShaderUsage::CastShadows | ShaderUsage::Skinning);
        shadowSkinnedMaterial->SetCullFace(CullFace::DoubleSided);

        // Default View Port Init Values
        viewPortStartX = viewPortStartY = 0;

        // Save FrameBuffer
        FBO = fbo;

        // Create Second Pass Specifics
        deferredMaterialDirectional = new CustomShaderMaterial("../../../../examples/DeferredRendering/assets/shaders/secondpassDirectional.glsl");
		deferredMaterialPoint = new CustomShaderMaterial("../../../../examples/DeferredRendering/assets/shaders/secondpassPoint.glsl");
		deferredMaterialSpot = new CustomShaderMaterial("../../../../examples/DeferredRendering/assets/shaders/secondpassSpot.glsl");

		uint32 texID = 0;
        deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tDepth", Uniforms::DataType::Int, &texID));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("tDepth", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tDepth", Uniforms::DataType::Int, &texID));
        texID = 1;
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
        deferredMaterialPoint->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
        texID = 2;
        deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tSpecular", Uniforms::DataType::Int, &texID));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
		texID = 3;
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tNormal", Uniforms::DataType::Int, &texID));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("tNormal", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tNormal", Uniforms::DataType::Int, &texID));

		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uScreenDimensions", Uniforms::DataUsage::ScreenDimensions));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uLightDirection", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uLightColor", Uniforms::DataUsage::Other, Uniforms::DataType::Vec4));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uMatProj", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uNearFar", Uniforms::DataUsage::NearFarPlane));
		deferredMaterialDirectional->DisableDepthTest();
		deferredMaterialDirectional->DisableDepthWrite();
		deferredMaterialDirectional->EnableBlending();
		deferredMaterialDirectional->BlendingEquation(BlendEq::Add);
		deferredMaterialDirectional->BlendingFunction(BlendFunc::One, BlendFunc::One);

		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uScreenDimensions", Uniforms::DataUsage::ScreenDimensions));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uLightPosition", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightDirection", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uLightRadius", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uLightColor", Uniforms::DataUsage::Other, Uniforms::DataType::Vec4));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uModelMatrix", Uniforms::DataUsage::ModelMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uViewMatrix", Uniforms::DataUsage::ViewMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uProjectionMatrix", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uMatProj", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uNearFar", Uniforms::DataUsage::NearFarPlane));
		deferredMaterialPoint->SetCullFace(CullFace::FrontFace);
		deferredMaterialPoint->DisableDepthTest();
		deferredMaterialPoint->DisableDepthWrite();
		deferredMaterialPoint->EnableBlending();
		deferredMaterialPoint->BlendingEquation(BlendEq::Add);
		deferredMaterialPoint->BlendingFunction(BlendFunc::One, BlendFunc::One);

		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uScreenDimensions", Uniforms::DataUsage::ScreenDimensions));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightPosition", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightRadius", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uOutterCone", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uInnerCone", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightColor", Uniforms::DataUsage::Other, Uniforms::DataType::Vec4));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uModelMatrix", Uniforms::DataUsage::ModelMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uViewMatrix", Uniforms::DataUsage::ViewMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uProjectionMatrix", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uMatProj", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uNearFar", Uniforms::DataUsage::NearFarPlane));
		deferredMaterialSpot->SetCullFace(CullFace::FrontFace);
		deferredMaterialSpot->DisableDepthTest();
		deferredMaterialSpot->DisableDepthWrite();
		deferredMaterialSpot->EnableBlending();
		deferredMaterialSpot->BlendingEquation(BlendEq::Add);
		deferredMaterialSpot->BlendingFunction(BlendFunc::One, BlendFunc::One);

        // Light Volume
		quadHandle = new Plane(1, 1);
		directionalLight = new RenderingComponent(quadHandle);

        sphereHandle = new Sphere(1,6,4);
        pointLight = new RenderingComponent(sphereHandle);
		pointLight->GetMeshes()[0]->Material->SetCullFace(CullFace::FrontFace);
    }

    void DeferredRenderer::Resize(const uint32 Width, const uint32 Height)
    {
        IRenderer::Resize(Width,Height);
    }

    DeferredRenderer::~DeferredRenderer()
    {
        if (IsCulling)
        {
            delete culling;
        }

        delete shadowMaterial;
        delete sphereHandle;
    }

    std::vector<RenderingMesh*> DeferredRenderer::GroupAndSortAssets(SceneGraph* Scene, GameObject* Camera, const uint32 Tag)
    {

        // Sort and Group Objects From Scene
        std::vector<RenderingMesh*> _OpaqueMeshes;
        std::map<f32,RenderingMesh*> _TranslucidMeshes;

        std::vector<RenderingMesh*> rmeshes = RenderingComponent::GetRenderingMeshes(Scene);

        for (std::vector<RenderingMesh*>::iterator k=rmeshes.begin();k!=rmeshes.end();k++)
        {
            if ((*k)->Material->IsTransparent())
            {
                f32 index = Camera->GetPosition().distanceSQR((*k)->renderingComponent->GetOwner()->GetWorldPosition());
                while(_TranslucidMeshes.find(index)!=_TranslucidMeshes.end()) index+=1.f;
                _TranslucidMeshes[index] = (*k);
            }
            else _OpaqueMeshes.push_back((*k));
        }

        for (std::map<f32,RenderingMesh*>::iterator i=_TranslucidMeshes.begin();i!=_TranslucidMeshes.end();i++)
        {
            _OpaqueMeshes.push_back((*i).second);
        }

        return _OpaqueMeshes;

    }

    void DeferredRenderer::RenderScene(const p3d::Projection& projection, GameObject* Camera, SceneGraph* Scene, const uint32 BufferOptions)
    {

        // Initialize Renderer
        InitRender();

        // Group and Sort Meshes
        std::vector<RenderingMesh*> rmesh = GroupAndSortAssets(Scene, Camera);

        // Get Lights List
        std::vector<IComponent*> lcomps = ILightComponent::GetLightsOnScene(Scene);

        // Save Time
        Timer = Scene->GetTime();

        // First Pass

            // Save Values for Cache
            // Saves Scene
            this->Scene = Scene;

            // Saves Camera
            this->Camera = Camera;
            this->CameraPosition = this->Camera->GetWorldPosition();

            // Saves Projection
            this->projection = projection;

            // Universal Cache
            ProjectionMatrix = projection.m;
            NearFarPlane = Vec2(projection.Near, projection.Far);

            // View Matrix and Position
            ViewMatrix = Camera->GetWorldTransformation().Inverse();
            CameraPosition = Camera->GetWorldPosition();

            // Update Culling
            UpdateCulling(ProjectionMatrix*ViewMatrix);

            // Flags
            ViewMatrixInverseIsDirty = true;
            ProjectionMatrixInverseIsDirty = true;
            ViewProjectionMatrixIsDirty = true;

            // Bind Frame Buffer
            FBO->Bind();

            // Set ViewPort
            viewPortEndX = Width;
            viewPortEndY = Height;
            // Set Viewport
            _SetViewPort(viewPortStartX,viewPortStartY,viewPortEndX,viewPortEndY);
            ClearBufferBit(Buffer_Bit::Color | Buffer_Bit::Depth);
            ClearDepthBuffer();
            ClearScreen();

            // Draw Background
            DrawBackground();

            // Render Scene with Objects Material
            for (std::vector<RenderingMesh*>::iterator i=rmesh.begin();i!=rmesh.end();i++)
            {

                if ((*i)->renderingComponent->GetOwner()!=NULL)
                {
                    // Culling Test
                    bool cullingTest = false;
                    switch((*i)->CullingGeometry)
                    {
                        case CullingGeometry::Box:
                            cullingTest = CullingBoxTest((*i),(*i)->renderingComponent->GetOwner());
                            break;
                        case CullingGeometry::Sphere:
                        default:
                            cullingTest = CullingSphereTest((*i), (*i)->renderingComponent->GetOwner());
                            break;
                    }
                    if (cullingTest && (*i)->renderingComponent->IsActive() && (*i)->Active == true)
                        RenderObject((*i),(*i)->renderingComponent->GetOwner(),(*i)->Material);
                }
            }

            // End Rendering
            EndRender();

            // Unbind FrameBuffer
            FBO->UnBind();

			// Initialize Rendering
			InitRender();

			ClearBufferBit(Buffer_Bit::Color | Buffer_Bit::Depth);
			ClearScreen();

            // Bind FBO Textures
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Depth_Attachment]->TexturePTR->Bind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment0]->TexturePTR->Bind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment1]->TexturePTR->Bind();
			FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment2]->TexturePTR->Bind();

            // Render Point Lights
            for (std::vector<IComponent*>::iterator i=lcomps.begin();i!=lcomps.end();i++)
            {

                if ((*i)->GetOwner()!=NULL)
                {
                    if (PointLight* p = dynamic_cast<PointLight*>((*i))) {
                        // Point Lights
						Vec3 pos = (ViewMatrix * Vec4(p->GetOwner()->GetWorldPosition(),1.0)).xyz();
                        Vec4 color = p->GetLightColor();
                        deferredMaterialPoint->SetUniformValue("uLightPosition", &pos);
                        deferredMaterialPoint->SetUniformValue("uLightRadius", p->GetLightRadius());
                        deferredMaterialPoint->SetUniformValue("uLightColor", &color);
						// Set Scale
						f32 sc = g(f(p->GetLightRadius()));
						Matrix m; m.Scale(sc, sc, sc);
                        pointLight->GetMeshes()[0]->Pivot = m;
                        RenderObject(pointLight->GetMeshes()[0],p->GetOwner(),deferredMaterialPoint);
                    }
                    else if (SpotLight* s = dynamic_cast<SpotLight*>((*i))) {
                        // Spot Lights
						Vec3 pos = (ViewMatrix * Vec4(s->GetOwner()->GetWorldPosition(), 1.0)).xyz();
						Vec4 color = s->GetLightColor();
						Vec3 dir = (ViewMatrix * Vec4(s->GetLightDirection(), 0.0)).xyz();
						deferredMaterialSpot->SetUniformValue("uLightPosition", &pos);
						deferredMaterialSpot->SetUniformValue("uLightDirection", &dir);
						deferredMaterialSpot->SetUniformValue("uLightRadius", s->GetLightRadius());
						deferredMaterialSpot->SetUniformValue("uOutterCone", s->GetLightCosOutterCone());
						deferredMaterialSpot->SetUniformValue("uInnerCone", s->GetLightCosInnerCone());
						deferredMaterialSpot->SetUniformValue("uLightColor", &color);
						// Set Scale
						f32 sc = g(f(s->GetLightRadius()));
						Matrix m; m.Scale(sc,sc,sc);
						pointLight->GetMeshes()[0]->Pivot = m;
						RenderObject(pointLight->GetMeshes()[0], s->GetOwner(), deferredMaterialSpot);
                    }
                    else if (DirectionalLight* d = dynamic_cast<DirectionalLight*>((*i))) {
                        // Directional Lights
						Vec3 dir = (ViewMatrix * Vec4(d->GetLightDirection(),0.0)).xyz();
						Vec4 color = d->GetLightColor();
						deferredMaterialDirectional->SetUniformValue("uLightDirection", &dir);
						deferredMaterialDirectional->SetUniformValue("uLightColor", &color);
						RenderObject(directionalLight->GetMeshes()[0], d->GetOwner(), deferredMaterialDirectional);
                    }
                }
            }

			FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment2]->TexturePTR->Unbind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment1]->TexturePTR->Unbind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment0]->TexturePTR->Unbind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Depth_Attachment]->TexturePTR->Unbind();

            // End Render
            EndRender();
    }

    void DeferredRenderer::SetFBO(FrameBuffer* fbo)
    {
        // Save FBO
        FBO = fbo;
    }

};
<commit_msg>Reordered a line<commit_after>//============================================================================
// Name        : DeferredRenderer.h
// Author      : Duarte Peixinho
// Version     :
// Copyright   : ;)
// Description : Deferred Renderer
//============================================================================

#include "DeferredRenderer.h"
#include <Pyros3D/Other/PyrosGL.h>

namespace p3d {

	f32 f(f32 r)
	{
		return r * (2.f * (tanf(PI / 4)));
	}
	f32 g(f32 a)
	{
		return a / (2.f*sinf(PI / 4));
	}

    DeferredRenderer::DeferredRenderer(const uint32 Width, const uint32 Height, FrameBuffer* fbo) : IRenderer(Width,Height)
    {

        echo("SUCCESS: Deferred Renderer Created");

        ActivateCulling(CullingMode::FrustumCulling);

        shadowMaterial = new GenericShaderMaterial(ShaderUsage::CastShadows);
        shadowMaterial->SetCullFace(CullFace::DoubleSided);
        shadowSkinnedMaterial = new GenericShaderMaterial(ShaderUsage::CastShadows | ShaderUsage::Skinning);
        shadowSkinnedMaterial->SetCullFace(CullFace::DoubleSided);

        // Default View Port Init Values
        viewPortStartX = viewPortStartY = 0;

        // Save FrameBuffer
        FBO = fbo;

        // Create Second Pass Specifics
        deferredMaterialDirectional = new CustomShaderMaterial("../../../../examples/DeferredRendering/assets/shaders/secondpassDirectional.glsl");
		deferredMaterialPoint = new CustomShaderMaterial("../../../../examples/DeferredRendering/assets/shaders/secondpassPoint.glsl");
		deferredMaterialSpot = new CustomShaderMaterial("../../../../examples/DeferredRendering/assets/shaders/secondpassSpot.glsl");

		uint32 texID = 0;
        deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tDepth", Uniforms::DataType::Int, &texID));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("tDepth", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tDepth", Uniforms::DataType::Int, &texID));
        texID = 1;
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
        deferredMaterialPoint->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
        texID = 2;
        deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tSpecular", Uniforms::DataType::Int, &texID));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tDiffuse", Uniforms::DataType::Int, &texID));
		texID = 3;
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("tNormal", Uniforms::DataType::Int, &texID));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("tNormal", Uniforms::DataType::Int, &texID));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("tNormal", Uniforms::DataType::Int, &texID));

		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uScreenDimensions", Uniforms::DataUsage::ScreenDimensions));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uLightDirection", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uLightColor", Uniforms::DataUsage::Other, Uniforms::DataType::Vec4));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uMatProj", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialDirectional->AddUniform(Uniforms::Uniform("uNearFar", Uniforms::DataUsage::NearFarPlane));
		deferredMaterialDirectional->DisableDepthTest();
		deferredMaterialDirectional->DisableDepthWrite();
		deferredMaterialDirectional->EnableBlending();
		deferredMaterialDirectional->BlendingEquation(BlendEq::Add);
		deferredMaterialDirectional->BlendingFunction(BlendFunc::One, BlendFunc::One);

		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uScreenDimensions", Uniforms::DataUsage::ScreenDimensions));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uLightPosition", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uLightRadius", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uLightColor", Uniforms::DataUsage::Other, Uniforms::DataType::Vec4));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uModelMatrix", Uniforms::DataUsage::ModelMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uViewMatrix", Uniforms::DataUsage::ViewMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uProjectionMatrix", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uMatProj", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialPoint->AddUniform(Uniforms::Uniform("uNearFar", Uniforms::DataUsage::NearFarPlane));
		deferredMaterialPoint->SetCullFace(CullFace::FrontFace);
		deferredMaterialPoint->DisableDepthTest();
		deferredMaterialPoint->DisableDepthWrite();
		deferredMaterialPoint->EnableBlending();
		deferredMaterialPoint->BlendingEquation(BlendEq::Add);
		deferredMaterialPoint->BlendingFunction(BlendFunc::One, BlendFunc::One);

		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uScreenDimensions", Uniforms::DataUsage::ScreenDimensions));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightPosition", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightDirection", Uniforms::DataUsage::Other, Uniforms::DataType::Vec3));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightRadius", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uOutterCone", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uInnerCone", Uniforms::DataUsage::Other, Uniforms::DataType::Float));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uLightColor", Uniforms::DataUsage::Other, Uniforms::DataType::Vec4));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uModelMatrix", Uniforms::DataUsage::ModelMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uViewMatrix", Uniforms::DataUsage::ViewMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uProjectionMatrix", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uMatProj", Uniforms::DataUsage::ProjectionMatrix));
		deferredMaterialSpot->AddUniform(Uniforms::Uniform("uNearFar", Uniforms::DataUsage::NearFarPlane));
		deferredMaterialSpot->SetCullFace(CullFace::FrontFace);
		deferredMaterialSpot->DisableDepthTest();
		deferredMaterialSpot->DisableDepthWrite();
		deferredMaterialSpot->EnableBlending();
		deferredMaterialSpot->BlendingEquation(BlendEq::Add);
		deferredMaterialSpot->BlendingFunction(BlendFunc::One, BlendFunc::One);

        // Light Volume
		quadHandle = new Plane(1, 1);
		directionalLight = new RenderingComponent(quadHandle);

        sphereHandle = new Sphere(1,6,4);
        pointLight = new RenderingComponent(sphereHandle);
		pointLight->GetMeshes()[0]->Material->SetCullFace(CullFace::FrontFace);
    }

    void DeferredRenderer::Resize(const uint32 Width, const uint32 Height)
    {
        IRenderer::Resize(Width,Height);
    }

    DeferredRenderer::~DeferredRenderer()
    {
        if (IsCulling)
        {
            delete culling;
        }

        delete shadowMaterial;
        delete sphereHandle;
    }

    std::vector<RenderingMesh*> DeferredRenderer::GroupAndSortAssets(SceneGraph* Scene, GameObject* Camera, const uint32 Tag)
    {

        // Sort and Group Objects From Scene
        std::vector<RenderingMesh*> _OpaqueMeshes;
        std::map<f32,RenderingMesh*> _TranslucidMeshes;

        std::vector<RenderingMesh*> rmeshes = RenderingComponent::GetRenderingMeshes(Scene);

        for (std::vector<RenderingMesh*>::iterator k=rmeshes.begin();k!=rmeshes.end();k++)
        {
            if ((*k)->Material->IsTransparent())
            {
                f32 index = Camera->GetPosition().distanceSQR((*k)->renderingComponent->GetOwner()->GetWorldPosition());
                while(_TranslucidMeshes.find(index)!=_TranslucidMeshes.end()) index+=1.f;
                _TranslucidMeshes[index] = (*k);
            }
            else _OpaqueMeshes.push_back((*k));
        }

        for (std::map<f32,RenderingMesh*>::iterator i=_TranslucidMeshes.begin();i!=_TranslucidMeshes.end();i++)
        {
            _OpaqueMeshes.push_back((*i).second);
        }

        return _OpaqueMeshes;

    }

    void DeferredRenderer::RenderScene(const p3d::Projection& projection, GameObject* Camera, SceneGraph* Scene, const uint32 BufferOptions)
    {

        // Initialize Renderer
        InitRender();

        // Group and Sort Meshes
        std::vector<RenderingMesh*> rmesh = GroupAndSortAssets(Scene, Camera);

        // Get Lights List
        std::vector<IComponent*> lcomps = ILightComponent::GetLightsOnScene(Scene);

        // Save Time
        Timer = Scene->GetTime();

        // First Pass

            // Save Values for Cache
            // Saves Scene
            this->Scene = Scene;

            // Saves Camera
            this->Camera = Camera;
            this->CameraPosition = this->Camera->GetWorldPosition();

            // Saves Projection
            this->projection = projection;

            // Universal Cache
            ProjectionMatrix = projection.m;
            NearFarPlane = Vec2(projection.Near, projection.Far);

            // View Matrix and Position
            ViewMatrix = Camera->GetWorldTransformation().Inverse();
            CameraPosition = Camera->GetWorldPosition();

            // Update Culling
            UpdateCulling(ProjectionMatrix*ViewMatrix);

            // Flags
            ViewMatrixInverseIsDirty = true;
            ProjectionMatrixInverseIsDirty = true;
            ViewProjectionMatrixIsDirty = true;

            // Bind Frame Buffer
            FBO->Bind();

            // Set ViewPort
            viewPortEndX = Width;
            viewPortEndY = Height;
            // Set Viewport
            _SetViewPort(viewPortStartX,viewPortStartY,viewPortEndX,viewPortEndY);
            ClearBufferBit(Buffer_Bit::Color | Buffer_Bit::Depth);
            ClearDepthBuffer();
            ClearScreen();

            // Draw Background
            DrawBackground();

            // Render Scene with Objects Material
            for (std::vector<RenderingMesh*>::iterator i=rmesh.begin();i!=rmesh.end();i++)
            {

                if ((*i)->renderingComponent->GetOwner()!=NULL)
                {
                    // Culling Test
                    bool cullingTest = false;
                    switch((*i)->CullingGeometry)
                    {
                        case CullingGeometry::Box:
                            cullingTest = CullingBoxTest((*i),(*i)->renderingComponent->GetOwner());
                            break;
                        case CullingGeometry::Sphere:
                        default:
                            cullingTest = CullingSphereTest((*i), (*i)->renderingComponent->GetOwner());
                            break;
                    }
                    if (cullingTest && (*i)->renderingComponent->IsActive() && (*i)->Active == true)
                        RenderObject((*i),(*i)->renderingComponent->GetOwner(),(*i)->Material);
                }
            }

            // End Rendering
            EndRender();

            // Unbind FrameBuffer
            FBO->UnBind();

			// Initialize Rendering
			InitRender();

			ClearBufferBit(Buffer_Bit::Color | Buffer_Bit::Depth);
			ClearScreen();

            // Bind FBO Textures
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Depth_Attachment]->TexturePTR->Bind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment0]->TexturePTR->Bind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment1]->TexturePTR->Bind();
			FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment2]->TexturePTR->Bind();

            // Render Point Lights
            for (std::vector<IComponent*>::iterator i=lcomps.begin();i!=lcomps.end();i++)
            {

                if ((*i)->GetOwner()!=NULL)
                {
                    if (PointLight* p = dynamic_cast<PointLight*>((*i))) {
                        // Point Lights
						Vec3 pos = (ViewMatrix * Vec4(p->GetOwner()->GetWorldPosition(),1.0)).xyz();
                        Vec4 color = p->GetLightColor();
                        deferredMaterialPoint->SetUniformValue("uLightPosition", &pos);
                        deferredMaterialPoint->SetUniformValue("uLightRadius", p->GetLightRadius());
                        deferredMaterialPoint->SetUniformValue("uLightColor", &color);
						// Set Scale
						f32 sc = g(f(p->GetLightRadius()));
						Matrix m; m.Scale(sc, sc, sc);
                        pointLight->GetMeshes()[0]->Pivot = m;
                        RenderObject(pointLight->GetMeshes()[0],p->GetOwner(),deferredMaterialPoint);
                    }
                    else if (SpotLight* s = dynamic_cast<SpotLight*>((*i))) {
                        // Spot Lights
						Vec3 pos = (ViewMatrix * Vec4(s->GetOwner()->GetWorldPosition(), 1.0)).xyz();
						Vec4 color = s->GetLightColor();
						Vec3 dir = (ViewMatrix * Vec4(s->GetLightDirection(), 0.0)).xyz();
						deferredMaterialSpot->SetUniformValue("uLightPosition", &pos);
						deferredMaterialSpot->SetUniformValue("uLightDirection", &dir);
						deferredMaterialSpot->SetUniformValue("uLightRadius", s->GetLightRadius());
						deferredMaterialSpot->SetUniformValue("uOutterCone", s->GetLightCosOutterCone());
						deferredMaterialSpot->SetUniformValue("uInnerCone", s->GetLightCosInnerCone());
						deferredMaterialSpot->SetUniformValue("uLightColor", &color);
						// Set Scale
						f32 sc = g(f(s->GetLightRadius()));
						Matrix m; m.Scale(sc,sc,sc);
						pointLight->GetMeshes()[0]->Pivot = m;
						RenderObject(pointLight->GetMeshes()[0], s->GetOwner(), deferredMaterialSpot);
                    }
                    else if (DirectionalLight* d = dynamic_cast<DirectionalLight*>((*i))) {
                        // Directional Lights
						Vec3 dir = (ViewMatrix * Vec4(d->GetLightDirection(),0.0)).xyz();
						Vec4 color = d->GetLightColor();
						deferredMaterialDirectional->SetUniformValue("uLightDirection", &dir);
						deferredMaterialDirectional->SetUniformValue("uLightColor", &color);
						RenderObject(directionalLight->GetMeshes()[0], d->GetOwner(), deferredMaterialDirectional);
                    }
                }
            }

			FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment2]->TexturePTR->Unbind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment1]->TexturePTR->Unbind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Color_Attachment0]->TexturePTR->Unbind();
            FBO->GetAttachments()[FrameBufferAttachmentFormat::Depth_Attachment]->TexturePTR->Unbind();

            // End Render
            EndRender();
    }

    void DeferredRenderer::SetFBO(FrameBuffer* fbo)
    {
        // Save FBO
        FBO = fbo;
    }

};
<|endoftext|>


<commit_before>
#include "tests/simple_tests.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include <chrono>
#include <map>
#include <ciso646>

#ifdef HAS_SQLITE3
#include <sqlite3.h>
#endif

namespace
{
std::vector<su::TestSuiteAbstract *> *g_testSuites;

std::string displayName( const std::string &s )
{
	std::string result( s );
	std::replace( result.begin(), result.end(), '_', ' ' );
	return result;
}

class SimpleTestDB
{
public:
	SimpleTestDB( const std::string &i_path, const std::string &i_processName );
	~SimpleTestDB();

	void addResult( const std::string &i_testSuiteName, const std::string &i_testName, const std::string &i_result, int64_t i_duration );
	int64_t mostRecentDuration( const std::string &i_testSuiteName, const std::string &i_testName );

private:
	std::string _processName;

#ifdef HAS_SQLITE3
	sqlite3 *_db = nullptr;
	std::string _datetime;

	static int sqlite3_exec_callback( void* data, int nb, char** values, char** columns )
	{
		auto result = (std::map<std::string,std::string> *)data;
		for ( int i = 0; i < nb; ++i )
		{
			if ( columns[i] and values[i] )
				(*result)[columns[i]] = values[i];
		}
		return 0;
	}
	std::map<std::string,std::string> sqlite3_exec( const std::string &i_cmd )
	{
		std::map<std::string,std::string> result;
		if ( _db )
		{
			char *errmsg = nullptr;
			int err = ::sqlite3_exec( _db, i_cmd.c_str(), &SimpleTestDB::sqlite3_exec_callback, &result, &errmsg );
			if ( err != SQLITE_OK )
			{
				throw std::runtime_error( errmsg );
			}
			if ( errmsg )
				sqlite3_free( errmsg );
		}
		return result;
	}
#endif
};

SimpleTestDB::SimpleTestDB( const std::string &i_path, const std::string &i_processName )
	: _processName( i_processName )
{
#ifdef HAS_SQLITE3
	if ( i_path.empty() )
		return;

	try
	{
		int err = sqlite3_open( i_path.c_str(), &_db );
		if ( err == SQLITE_OK )
		{
			sqlite3_exec( "CREATE TABLE IF NOT EXISTS test_cases ("
								"process_name TEXT,"
								"test_suite TEXT,"
								"test_case TEXT,"
								"result TEXT,"
								"duration INT,"
								"datetime TEXT"
								");" );
			auto result = sqlite3_exec( "SELECT datetime('now','utc');" );
			if ( not result.empty() )
				_datetime = result.begin()->second;
		}
	}
	catch ( std::exception &ex )
	{
		std::cerr << "opening database failed: " << ex.what() << std::endl;
	}
#endif
}

SimpleTestDB::~SimpleTestDB()
{
#ifdef HAS_SQLITE3
	if ( _db )
		sqlite3_close( _db );
#endif
}

void SimpleTestDB::addResult( const std::string &i_testSuiteName, const std::string &i_testName, const std::string &i_result, int64_t i_duration )
{
#ifdef HAS_SQLITE3
	try
	{
		std::string cmd( "INSERT INTO test_cases (process_name,test_suite,test_case,result,duration,datetime) VALUES (" );
		cmd += "'" + _processName + "',";
		cmd += "'" + i_testSuiteName + "',";
		cmd += "'" + i_testName + "',";
		cmd += "'" + i_result + "',";
		cmd += std::to_string(i_duration) + ",";
		cmd += "'" + _datetime;
		cmd += "');";
		sqlite3_exec( cmd );
	}
	catch ( std::exception &ex )
	{
		std::cerr << "inserting in database failed: " << ex.what() << std::endl;
	}
#endif
}

int64_t SimpleTestDB::mostRecentDuration( const std::string &i_testSuiteName, const std::string &i_testName )
{
#ifdef HAS_SQLITE3
	try
	{
		std::string cmd( "SELECT duration FROM test_cases WHERE " );
		cmd += "process_name='" + _processName + "' AND ";
		cmd += "test_suite='" + i_testSuiteName + "' AND ";
		cmd += "test_case='" + i_testName + "' AND ";
		cmd += "result='' ";
		cmd += "ORDER BY datetime DESC LIMIT 1";
		auto result = sqlite3_exec( cmd );
		if ( not result.empty() )
			return std::stoll( result.begin()->second );
	}
	catch ( std::exception &ex )
	{
		std::cerr << "inserting in database failed: " << ex.what() << std::endl;
	}
#endif
	return std::numeric_limits<int64_t>::max();
}

std::string getSimpleTestDBPath()
{
	std::string p;
	auto parent = getenv( "LOCALAPPDATA" );
	if ( parent == nullptr or *parent == 0 )
		parent = getenv( "HOME" );
	if ( parent != nullptr )
	{
		p.assign( parent );
		p += "/.simple_tests.db";
	}
	return p;
}

}

namespace su
{

TestCase::TestCase( const std::string &i_name, const func_t &i_test )
	: _name( i_name ), _test( i_test )
{
	if ( _name.compare( 0, 6, "timed_" ) == 0 )
	{
		_name.erase( 0, 6 );
		_timed = true;
	}
}

TestSuiteAbstract::TestSuiteAbstract( const std::string &i_name )
	: _name( i_name )
{
}

void addTestSuite( TestSuiteAbstract *i_tg )
{
	if ( g_testSuites == nullptr )
		g_testSuites = new std::vector<su::TestSuiteAbstract *>;
	g_testSuites->push_back( i_tg );
}

FailedTest::FailedTest( Type i_type, const char *i_file, int i_line, const std::string &i_text, const std::string &i_msg )
	: _type( i_type ),
		_file( i_file ),
		_line( i_line ),
		_text( i_text ),
		_msg( i_msg )
{
}

const char *FailedTest::what() const noexcept
{
	if ( _storage.empty() )
	{
		std::ostringstream str;
		switch ( _type )
		{
			case Type::kAssert: str << "ASSERTION("; break;
			case Type::kEqual: str << "EQUAL("; break;
			case Type::kNotEqual: str << "NOT EQUAL("; break;
			default: break;
		}
		str << _text << ")\n";
		str << _file << ":" << _line << "\n";
		if ( not _msg.empty() )
			str << _msg << "\n";
		_storage = str.str();
	}
	return _storage.c_str();
}

}

int main( int argc, char **argv )
{
	//	remove the path base, just find the process name
	const char *processName = argv[0];
	std::reverse_iterator<const char *> begin( processName + strlen( processName ) );
	std::reverse_iterator<const char *> end( processName );
	std::reverse_iterator<const char *> pos = std::find_if( begin, end, []( char c ){ return c == '/' or c == '\\'; } );
	if ( pos != end )
		processName = pos.base();

	SimpleTestDB db( getSimpleTestDBPath(), processName );

	int total = 0;
	int failure = 0;
	for ( auto testSuite : *g_testSuites )
	{
		std::cout << "Test Case : " << displayName(testSuite->name()) << std::endl;
		auto tests = testSuite->getTests();
		for ( auto test : tests )
		{
			++total;

			std::cout << "  " << displayName(test.name()) << " : ";
			std::cout.flush();

			std::string result;
			int64_t duration;
			try
			{
				auto start_time = std::chrono::high_resolution_clock::now();
				test();
				auto end_time = std::chrono::high_resolution_clock::now();
				duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count();
				std::cout << "OK";
				if ( test.timed() )
				{
					auto prev = db.mostRecentDuration( testSuite->name(), test.name() );
					std::cout << " (" << duration << "ns";
					if ( duration > prev )
						std::cout << " regression: " << duration - prev << "ns slower";
					std::cout << ")";
				}
			}
			catch ( su::FailedTest &ex )
			{
				result = "TEST FAIL - ";
				result += ex.what();
				++failure;
			}
			catch ( std::exception &ex )
			{
				result = "EXCEPTION CAUGHT - ";
				result += ex.what();
				++failure;
			}
			catch ( ... )
			{
				result = "UNKNOWN EXCEPTION CAUGHT";
				++failure;
			}
			std::cout << result << std::endl;

			db.addResult( testSuite->name(), test.name(), result, duration );
		}
	}
	std::cout << "success: " << (total-failure) << "/" << total << std::endl;
	if ( failure == 0 )
		std::cout << "All good!" << std::endl;
	std::cout << std::endl;
}
<commit_msg>add missing include with gcc<commit_after>
#include "tests/simple_tests.h"
#include <iostream>
#include <sstream>
#include <algorithm>
#include <chrono>
#include <map>
#include <string.h>
#include <ciso646>

#ifdef HAS_SQLITE3
#include <sqlite3.h>
#endif

namespace
{
std::vector<su::TestSuiteAbstract *> *g_testSuites;

std::string displayName( const std::string &s )
{
	std::string result( s );
	std::replace( result.begin(), result.end(), '_', ' ' );
	return result;
}

class SimpleTestDB
{
public:
	SimpleTestDB( const std::string &i_path, const std::string &i_processName );
	~SimpleTestDB();

	void addResult( const std::string &i_testSuiteName, const std::string &i_testName, const std::string &i_result, int64_t i_duration );
	int64_t mostRecentDuration( const std::string &i_testSuiteName, const std::string &i_testName );

private:
	std::string _processName;

#ifdef HAS_SQLITE3
	sqlite3 *_db = nullptr;
	std::string _datetime;

	static int sqlite3_exec_callback( void* data, int nb, char** values, char** columns )
	{
		auto result = (std::map<std::string,std::string> *)data;
		for ( int i = 0; i < nb; ++i )
		{
			if ( columns[i] and values[i] )
				(*result)[columns[i]] = values[i];
		}
		return 0;
	}
	std::map<std::string,std::string> sqlite3_exec( const std::string &i_cmd )
	{
		std::map<std::string,std::string> result;
		if ( _db )
		{
			char *errmsg = nullptr;
			int err = ::sqlite3_exec( _db, i_cmd.c_str(), &SimpleTestDB::sqlite3_exec_callback, &result, &errmsg );
			if ( err != SQLITE_OK )
			{
				throw std::runtime_error( errmsg );
			}
			if ( errmsg )
				sqlite3_free( errmsg );
		}
		return result;
	}
#endif
};

SimpleTestDB::SimpleTestDB( const std::string &i_path, const std::string &i_processName )
	: _processName( i_processName )
{
#ifdef HAS_SQLITE3
	if ( i_path.empty() )
		return;

	try
	{
		int err = sqlite3_open( i_path.c_str(), &_db );
		if ( err == SQLITE_OK )
		{
			sqlite3_exec( "CREATE TABLE IF NOT EXISTS test_cases ("
								"process_name TEXT,"
								"test_suite TEXT,"
								"test_case TEXT,"
								"result TEXT,"
								"duration INT,"
								"datetime TEXT"
								");" );
			auto result = sqlite3_exec( "SELECT datetime('now','utc');" );
			if ( not result.empty() )
				_datetime = result.begin()->second;
		}
	}
	catch ( std::exception &ex )
	{
		std::cerr << "opening database failed: " << ex.what() << std::endl;
	}
#endif
}

SimpleTestDB::~SimpleTestDB()
{
#ifdef HAS_SQLITE3
	if ( _db )
		sqlite3_close( _db );
#endif
}

void SimpleTestDB::addResult( const std::string &i_testSuiteName, const std::string &i_testName, const std::string &i_result, int64_t i_duration )
{
#ifdef HAS_SQLITE3
	try
	{
		std::string cmd( "INSERT INTO test_cases (process_name,test_suite,test_case,result,duration,datetime) VALUES (" );
		cmd += "'" + _processName + "',";
		cmd += "'" + i_testSuiteName + "',";
		cmd += "'" + i_testName + "',";
		cmd += "'" + i_result + "',";
		cmd += std::to_string(i_duration) + ",";
		cmd += "'" + _datetime;
		cmd += "');";
		sqlite3_exec( cmd );
	}
	catch ( std::exception &ex )
	{
		std::cerr << "inserting in database failed: " << ex.what() << std::endl;
	}
#endif
}

int64_t SimpleTestDB::mostRecentDuration( const std::string &i_testSuiteName, const std::string &i_testName )
{
#ifdef HAS_SQLITE3
	try
	{
		std::string cmd( "SELECT duration FROM test_cases WHERE " );
		cmd += "process_name='" + _processName + "' AND ";
		cmd += "test_suite='" + i_testSuiteName + "' AND ";
		cmd += "test_case='" + i_testName + "' AND ";
		cmd += "result='' ";
		cmd += "ORDER BY datetime DESC LIMIT 1";
		auto result = sqlite3_exec( cmd );
		if ( not result.empty() )
			return std::stoll( result.begin()->second );
	}
	catch ( std::exception &ex )
	{
		std::cerr << "inserting in database failed: " << ex.what() << std::endl;
	}
#endif
	return std::numeric_limits<int64_t>::max();
}

std::string getSimpleTestDBPath()
{
	std::string p;
	auto parent = getenv( "LOCALAPPDATA" );
	if ( parent == nullptr or *parent == 0 )
		parent = getenv( "HOME" );
	if ( parent != nullptr )
	{
		p.assign( parent );
		p += "/.simple_tests.db";
	}
	return p;
}

}

namespace su
{

TestCase::TestCase( const std::string &i_name, const func_t &i_test )
	: _name( i_name ), _test( i_test )
{
	if ( _name.compare( 0, 6, "timed_" ) == 0 )
	{
		_name.erase( 0, 6 );
		_timed = true;
	}
}

TestSuiteAbstract::TestSuiteAbstract( const std::string &i_name )
	: _name( i_name )
{
}

void addTestSuite( TestSuiteAbstract *i_tg )
{
	if ( g_testSuites == nullptr )
		g_testSuites = new std::vector<su::TestSuiteAbstract *>;
	g_testSuites->push_back( i_tg );
}

FailedTest::FailedTest( Type i_type, const char *i_file, int i_line, const std::string &i_text, const std::string &i_msg )
	: _type( i_type ),
		_file( i_file ),
		_line( i_line ),
		_text( i_text ),
		_msg( i_msg )
{
}

const char *FailedTest::what() const noexcept
{
	if ( _storage.empty() )
	{
		std::ostringstream str;
		switch ( _type )
		{
			case Type::kAssert: str << "ASSERTION("; break;
			case Type::kEqual: str << "EQUAL("; break;
			case Type::kNotEqual: str << "NOT EQUAL("; break;
			default: break;
		}
		str << _text << ")\n";
		str << _file << ":" << _line << "\n";
		if ( not _msg.empty() )
			str << _msg << "\n";
		_storage = str.str();
	}
	return _storage.c_str();
}

}

int main( int argc, char **argv )
{
	//	remove the path base, just find the process name
	const char *processName = argv[0];
	std::reverse_iterator<const char *> begin( processName + strlen( processName ) );
	std::reverse_iterator<const char *> end( processName );
	std::reverse_iterator<const char *> pos = std::find_if( begin, end, []( char c ){ return c == '/' or c == '\\'; } );
	if ( pos != end )
		processName = pos.base();

	SimpleTestDB db( getSimpleTestDBPath(), processName );

	int total = 0;
	int failure = 0;
	for ( auto testSuite : *g_testSuites )
	{
		std::cout << "Test Case : " << displayName(testSuite->name()) << std::endl;
		auto tests = testSuite->getTests();
		for ( auto test : tests )
		{
			++total;

			std::cout << "  " << displayName(test.name()) << " : ";
			std::cout.flush();

			std::string result;
			int64_t duration;
			try
			{
				auto start_time = std::chrono::high_resolution_clock::now();
				test();
				auto end_time = std::chrono::high_resolution_clock::now();
				duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count();
				std::cout << "OK";
				if ( test.timed() )
				{
					auto prev = db.mostRecentDuration( testSuite->name(), test.name() );
					std::cout << " (" << duration << "ns";
					if ( duration > prev )
						std::cout << " regression: " << duration - prev << "ns slower";
					std::cout << ")";
				}
			}
			catch ( su::FailedTest &ex )
			{
				result = "TEST FAIL - ";
				result += ex.what();
				++failure;
			}
			catch ( std::exception &ex )
			{
				result = "EXCEPTION CAUGHT - ";
				result += ex.what();
				++failure;
			}
			catch ( ... )
			{
				result = "UNKNOWN EXCEPTION CAUGHT";
				++failure;
			}
			std::cout << result << std::endl;

			db.addResult( testSuite->name(), test.name(), result, duration );
		}
	}
	std::cout << "success: " << (total-failure) << "/" << total << std::endl;
	if ( failure == 0 )
		std::cout << "All good!" << std::endl;
	std::cout << std::endl;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "wiredtiger.h"
#include "couch_db.h"

#define METABUF_MAXLEN (256)

struct _db {
    WT_CURSOR *cursor;
    WT_SESSION *session;
    char *filename;
    int sync;
};

static WT_CONNECTION *conn = NULL;
static uint64_t cache_size = 0;
static int indexing_type = 0;
static size_t c_period = 15;

couchstore_error_t couchstore_set_cache(uint64_t size) {
    cache_size = size;
    return COUCHSTORE_SUCCESS;
}
couchstore_error_t couchstore_set_idx_type(int type) {
    indexing_type = type;
    return COUCHSTORE_SUCCESS;
}
couchstore_error_t couchstore_set_chk_period(size_t seconds) {
    c_period = seconds;
    return COUCHSTORE_SUCCESS;
}

#ifdef PRIu64
    #define _F64 PRIu64
#else
    #define _F64 "llu"
#endif
couchstore_error_t couchstore_open_conn(const char *filename)
{
    int fd;
    int ret;
    char config[256];

    sprintf(config, "create,"
                    "log=(enabled),"
                    "checkpoint=(wait=%d),"
                    "cache_size=%" _F64,
                    c_period, cache_size);
    // create directory if not exist
    fd = open(filename, O_RDONLY, 0666);
    if (fd == -1) {
        // create
        char cmd[256];

        sprintf(cmd, "mkdir %s\n", filename);
        ret = system(cmd);
    }

    wiredtiger_open(filename, NULL, config, &conn);

    return COUCHSTORE_SUCCESS;
}

couchstore_error_t couchstore_close_conn()
{
    conn->close(conn, NULL);
    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_open_db(const char *filename,
                                      couchstore_open_flags flags,
                                      Db **pDb)
{
    return couchstore_open_db_ex(filename, flags,
                                 NULL, pDb);
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_open_db_ex(const char *filename,
                                         couchstore_open_flags flags,
                                         const couch_file_ops *ops,
                                         Db **pDb)
{
    int i, len;
    Db *ppdb;
    char fileonly[256];
    char table_name[256];
    char table_config[256];

    assert(conn);

    *pDb = (Db*)malloc(sizeof(Db));
    ppdb = *pDb;

    ppdb->filename = (char*)malloc(strlen(filename)+1);
    strcpy(ppdb->filename, filename);

    // take filename only (discard directory path)
    len = strlen(filename);
    for (i=len-1; i>=0; --i) {
        if (filename[i] == '/') {
            strcpy(fileonly, filename + (i+1));
            break;
        }
        if (i == 0) { // there is no directory path, filename only
            strcpy(fileonly, filename);
        }
    }

    sprintf(table_name, "table:%s", fileonly);
    sprintf(table_config, " ");
    if (indexing_type == 1) {
        // lsm-tree
        sprintf(table_config,
                "split_pct=100,leaf_item_max=1KB,"
                "type=lsm,internal_page_max=4KB,leaf_page_max=4KB,"
                "lsm=(chunk_size=4MB,"
                     "bloom_config=(leaf_page_max=4MB))");
    } else {
        sprintf(table_config,
                "split_pct=100,leaf_item_max=1KB,"
                "internal_page_max=4KB,leaf_page_max=4KB");
    }

    conn->open_session(conn, NULL, NULL, &ppdb->session);
    ppdb->session->create(ppdb->session, table_name, table_config);
    ppdb->session->open_cursor(ppdb->session, table_name, NULL, NULL, &ppdb->cursor);
    ppdb->sync = (flags & 0x10)?(1):(0);

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_close_db(Db *db)
{
    db->cursor->close(db->cursor);
    db->session->close(db->session, NULL);
    free(db->filename);
    free(db);

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_db_info(Db *db, DbInfo* info)
{
    struct stat filestat;

    info->filename = db->filename;
    info->doc_count = 0;
    info->deleted_count = 0;
    info->header_position = 0;
    info->last_sequence = 0;

    stat(db->filename, &filestat);
    info->space_used = filestat.st_size;

    return COUCHSTORE_SUCCESS;
}

size_t _docinfo_to_buf(DocInfo *docinfo, void *buf)
{
    // [db_seq,] rev_seq, deleted, content_meta, rev_meta (size), rev_meta (buf)
    size_t offset = 0;

    memcpy((uint8_t*)buf + offset, &docinfo->rev_seq, sizeof(docinfo->rev_seq));
    offset += sizeof(docinfo->rev_seq);

    memcpy((uint8_t*)buf + offset, &docinfo->deleted, sizeof(docinfo->deleted));
    offset += sizeof(docinfo->deleted);

    memcpy((uint8_t*)buf + offset, &docinfo->content_meta,
           sizeof(docinfo->content_meta));
    offset += sizeof(docinfo->content_meta);

    memcpy((uint8_t*)buf + offset, &docinfo->rev_meta.size,
           sizeof(docinfo->rev_meta.size));
    offset += sizeof(docinfo->rev_meta.size);

    if (docinfo->rev_meta.size > 0) {
        memcpy((uint8_t*)buf + offset, docinfo->rev_meta.buf, docinfo->rev_meta.size);
        offset += docinfo->rev_meta.size;
    }

    return offset;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_save_documents(Db *db, Doc* const docs[], DocInfo *infos[],
        unsigned numdocs, couchstore_save_options options)
{
    int ret;
    unsigned i;
    uint16_t metalen;
    uint8_t metabuf[METABUF_MAXLEN];
    uint8_t *buf;
    WT_ITEM item;

    ret = db->session->begin_transaction(db->session, (db->sync)?"sync":NULL);
    assert(ret==0);

    for (i=0;i<numdocs;++i){
        item.data = docs[i]->id.buf;
        item.size = docs[i]->id.size;
        db->cursor->set_key(db->cursor, &item);

        metalen = _docinfo_to_buf(infos[i], metabuf);
        buf = (uint8_t*)malloc(sizeof(metalen) + metalen + docs[i]->data.size);
        memcpy(buf + sizeof(metalen), metabuf, metalen);
        memcpy(buf, &metalen, sizeof(metalen));
        memcpy(buf + sizeof(metalen) + metalen, docs[i]->data.buf, docs[i]->data.size);

        item.data = buf;
        item.size = sizeof(metalen) + metalen + docs[i]->data.size;
        db->cursor->set_value(db->cursor, &item);

        ret = db->cursor->insert(db->cursor);
        if (ret != 0) {
            printf("ERR\n");
        }

        infos[i]->db_seq = 0;
        free(buf);
    }

    ret = db->session->commit_transaction(db->session, NULL);
    assert(ret==0);

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_save_document(Db *db, const Doc *doc, DocInfo *info,
        couchstore_save_options options)
{
    return couchstore_save_documents(db, (Doc**)&doc, (DocInfo**)&info, 1, options);
}

void _buf_to_docinfo(void *buf, size_t size, DocInfo *docinfo)
{
    size_t offset = 0;

    memcpy(&docinfo->rev_seq, (uint8_t*)buf + offset, sizeof(docinfo->rev_seq));
    offset += sizeof(docinfo->rev_seq);

    memcpy(&docinfo->deleted, (uint8_t*)buf + offset, sizeof(docinfo->deleted));
    offset += sizeof(docinfo->deleted);

    memcpy(&docinfo->content_meta, (uint8_t*)buf + offset,
           sizeof(docinfo->content_meta));
    offset += sizeof(docinfo->content_meta);

    memcpy(&docinfo->rev_meta.size, (uint8_t*)buf + offset,
           sizeof(docinfo->rev_meta.size));
    offset += sizeof(docinfo->rev_meta.size);

    if (docinfo->rev_meta.size > 0) {
        //docinfo->rev_meta.buf = (char *)malloc(docinfo->rev_meta.size);
        docinfo->rev_meta.buf = ((char *)docinfo) + sizeof(DocInfo);
        memcpy(docinfo->rev_meta.buf, (uint8_t*)buf + offset, docinfo->rev_meta.size);
        offset += docinfo->rev_meta.size;
    }else{
        docinfo->rev_meta.buf = NULL;
    }
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_open_document(Db *db,
                                            const void *id,
                                            size_t idlen,
                                            Doc **pDoc,
                                            couchstore_open_options options)
{
    int ret;
    size_t meta_offset;
    WT_ITEM item;

    item.data = id;
    item.size = idlen;
    db->cursor->set_key(db->cursor, &item);
    ret = db->cursor->search(db->cursor);
    assert(ret == 0);

    meta_offset = sizeof(uint64_t)*1 + sizeof(int) +
                  sizeof(couchstore_content_meta_flags);

    db->cursor->get_value(db->cursor, &item);

    *pDoc = (Doc *)malloc(sizeof(Doc));
    (*pDoc)->id.buf = (char*)id;
    (*pDoc)->id.size = idlen;
    (*pDoc)->data.buf = (char*)malloc(item.size);
    memcpy((*pDoc)->data.buf, item.data, item.size);
    (*pDoc)->data.size = item.size;

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
void couchstore_free_document(Doc *doc)
{
    if (doc->id.buf) free(doc->id.buf);
    if (doc->data.buf) free(doc->data.buf);
    free(doc);
}

LIBCOUCHSTORE_API
void couchstore_free_docinfo(DocInfo *docinfo)
{
    free(docinfo);
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_commit(Db *db)
{
    // do nothing
    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_compact_db_ex(Db* source, const char* target_filename,
        uint64_t flags, const couch_file_ops *ops)
{
    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_compact_db(Db* source, const char* target_filename)
{
    return couchstore_compact_db_ex(source, target_filename, 0x0, NULL);
}

<commit_msg>Do not use transaction for asynchronous write in WiredTiger<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "wiredtiger.h"
#include "couch_db.h"
#include "memleak.h"

#define METABUF_MAXLEN (256)

struct _db {
    WT_CURSOR *cursor;
    WT_SESSION *session;
    char *filename;
    int sync;
};

static WT_CONNECTION *conn = NULL;
static uint64_t cache_size = 0;
static int indexing_type = 0;
static size_t c_period = 15;

couchstore_error_t couchstore_set_cache(uint64_t size) {
    cache_size = size;
    return COUCHSTORE_SUCCESS;
}
couchstore_error_t couchstore_set_idx_type(int type) {
    indexing_type = type;
    return COUCHSTORE_SUCCESS;
}
couchstore_error_t couchstore_set_chk_period(size_t seconds) {
    c_period = seconds;
    return COUCHSTORE_SUCCESS;
}

#ifdef PRIu64
    #define _F64 PRIu64
#else
    #define _F64 "llu"
#endif
couchstore_error_t couchstore_open_conn(const char *filename)
{
    int fd;
    int ret;
    char config[256];

    sprintf(config, "create,"
                    "log=(enabled),"
                    "checkpoint=(wait=%d),"
                    "cache_size=%" _F64,
                    c_period,
                    cache_size);
    // create directory if not exist
    fd = open(filename, O_RDONLY, 0666);
    if (fd == -1) {
        // create
        char cmd[256];

        sprintf(cmd, "mkdir %s\n", filename);
        ret = system(cmd);
    }

    ret = wiredtiger_open(filename, NULL, config, &conn);
    assert(ret == 0);

    return COUCHSTORE_SUCCESS;
}

couchstore_error_t couchstore_close_conn()
{
    conn->close(conn, NULL);
    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_open_db(const char *filename,
                                      couchstore_open_flags flags,
                                      Db **pDb)
{
    return couchstore_open_db_ex(filename, flags,
                                 NULL, pDb);
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_open_db_ex(const char *filename,
                                         couchstore_open_flags flags,
                                         const couch_file_ops *ops,
                                         Db **pDb)
{
    int i, len, ret;
    Db *ppdb;
    char fileonly[256];
    char table_name[256];
    char table_config[256];

    assert(conn);

    *pDb = (Db*)malloc(sizeof(Db));
    ppdb = *pDb;

    ppdb->filename = (char*)malloc(strlen(filename)+1);
    strcpy(ppdb->filename, filename);

    // take filename only (discard directory path)
    len = strlen(filename);
    for (i=len-1; i>=0; --i) {
        if (filename[i] == '/') {
            strcpy(fileonly, filename + (i+1));
            break;
        }
        if (i == 0) { // there is no directory path, filename only
            strcpy(fileonly, filename);
        }
    }

    sprintf(table_name, "table:%s", fileonly);
    sprintf(table_config, " ");
    if (indexing_type == 1) {
        // lsm-tree
        sprintf(table_config,
                "split_pct=100,leaf_item_max=1KB,"
                "type=lsm,internal_page_max=4KB,leaf_page_max=4KB,"
                "lsm=(chunk_size=4MB,"
                     "bloom_config=(leaf_page_max=4MB))");
    } else {
        sprintf(table_config,
                "split_pct=100,leaf_item_max=1KB,"
                "internal_page_max=4KB,leaf_page_max=4KB");
    }

    ret = conn->open_session(conn, NULL, NULL, &ppdb->session);
    if (ret != 0) {
        fprintf(stderr, "Error: %s\n",
                        wiredtiger_strerror(ret));
        assert(0);
    }
    ppdb->session->create(ppdb->session, table_name, table_config);
    ppdb->session->open_cursor(ppdb->session, table_name, NULL, NULL, &ppdb->cursor);
    ppdb->sync = (flags & 0x10)?(1):(0);

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_close_db(Db *db)
{
    db->cursor->close(db->cursor);
    db->session->close(db->session, NULL);
    free(db->filename);
    free(db);

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_db_info(Db *db, DbInfo* info)
{
    struct stat filestat;

    info->filename = db->filename;
    info->doc_count = 0;
    info->deleted_count = 0;
    info->header_position = 0;
    info->last_sequence = 0;

    stat(db->filename, &filestat);
    info->space_used = filestat.st_size;

    return COUCHSTORE_SUCCESS;
}

size_t _docinfo_to_buf(DocInfo *docinfo, void *buf)
{
    // [db_seq,] rev_seq, deleted, content_meta, rev_meta (size), rev_meta (buf)
    size_t offset = 0;

    memcpy((uint8_t*)buf + offset, &docinfo->rev_seq, sizeof(docinfo->rev_seq));
    offset += sizeof(docinfo->rev_seq);

    memcpy((uint8_t*)buf + offset, &docinfo->deleted, sizeof(docinfo->deleted));
    offset += sizeof(docinfo->deleted);

    memcpy((uint8_t*)buf + offset, &docinfo->content_meta,
           sizeof(docinfo->content_meta));
    offset += sizeof(docinfo->content_meta);

    memcpy((uint8_t*)buf + offset, &docinfo->rev_meta.size,
           sizeof(docinfo->rev_meta.size));
    offset += sizeof(docinfo->rev_meta.size);

    if (docinfo->rev_meta.size > 0) {
        memcpy((uint8_t*)buf + offset, docinfo->rev_meta.buf, docinfo->rev_meta.size);
        offset += docinfo->rev_meta.size;
    }

    return offset;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_save_documents(Db *db, Doc* const docs[], DocInfo *infos[],
        unsigned numdocs, couchstore_save_options options)
{
    int ret;
    unsigned i;
    uint16_t metalen;
    uint8_t metabuf[METABUF_MAXLEN];
    uint8_t *buf;
    WT_ITEM item;

    if (db->sync) {
        ret = db->session->begin_transaction(db->session, "sync");
        assert(ret==0);
    }

    for (i=0;i<numdocs;++i){
        item.data = docs[i]->id.buf;
        item.size = docs[i]->id.size;
        db->cursor->set_key(db->cursor, &item);

        metalen = _docinfo_to_buf(infos[i], metabuf);
        buf = (uint8_t*)malloc(sizeof(metalen) + metalen + docs[i]->data.size);
        memcpy(buf + sizeof(metalen), metabuf, metalen);
        memcpy(buf, &metalen, sizeof(metalen));
        memcpy(buf + sizeof(metalen) + metalen, docs[i]->data.buf, docs[i]->data.size);

        item.data = buf;
        item.size = sizeof(metalen) + metalen + docs[i]->data.size;
        db->cursor->set_value(db->cursor, &item);

        ret = db->cursor->insert(db->cursor);
        if (ret != 0) {
            printf("ERR %d\n", ret);
        }

        infos[i]->db_seq = 0;
        free(buf);
    }

    if (db->sync) {
        ret = db->session->commit_transaction(db->session, NULL);
        assert(ret==0);
    }

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_save_document(Db *db, const Doc *doc, DocInfo *info,
        couchstore_save_options options)
{
    return couchstore_save_documents(db, (Doc**)&doc, (DocInfo**)&info, 1, options);
}

void _buf_to_docinfo(void *buf, size_t size, DocInfo *docinfo)
{
    size_t offset = 0;

    memcpy(&docinfo->rev_seq, (uint8_t*)buf + offset, sizeof(docinfo->rev_seq));
    offset += sizeof(docinfo->rev_seq);

    memcpy(&docinfo->deleted, (uint8_t*)buf + offset, sizeof(docinfo->deleted));
    offset += sizeof(docinfo->deleted);

    memcpy(&docinfo->content_meta, (uint8_t*)buf + offset,
           sizeof(docinfo->content_meta));
    offset += sizeof(docinfo->content_meta);

    memcpy(&docinfo->rev_meta.size, (uint8_t*)buf + offset,
           sizeof(docinfo->rev_meta.size));
    offset += sizeof(docinfo->rev_meta.size);

    if (docinfo->rev_meta.size > 0) {
        //docinfo->rev_meta.buf = (char *)malloc(docinfo->rev_meta.size);
        docinfo->rev_meta.buf = ((char *)docinfo) + sizeof(DocInfo);
        memcpy(docinfo->rev_meta.buf, (uint8_t*)buf + offset, docinfo->rev_meta.size);
        offset += docinfo->rev_meta.size;
    }else{
        docinfo->rev_meta.buf = NULL;
    }
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_open_document(Db *db,
                                            const void *id,
                                            size_t idlen,
                                            Doc **pDoc,
                                            couchstore_open_options options)
{
    int ret;
    size_t meta_offset;
    WT_ITEM item;

    item.data = id;
    item.size = idlen;
    db->cursor->set_key(db->cursor, &item);
    ret = db->cursor->search(db->cursor);
    assert(ret == 0);

    meta_offset = sizeof(uint64_t)*1 + sizeof(int) +
                  sizeof(couchstore_content_meta_flags);

    db->cursor->get_value(db->cursor, &item);

    *pDoc = (Doc *)malloc(sizeof(Doc));
    (*pDoc)->id.buf = (char*)id;
    (*pDoc)->id.size = idlen;
    (*pDoc)->data.buf = (char*)malloc(item.size);
    memcpy((*pDoc)->data.buf, item.data, item.size);
    (*pDoc)->data.size = item.size;

    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
void couchstore_free_document(Doc *doc)
{
    if (doc->id.buf) free(doc->id.buf);
    if (doc->data.buf) free(doc->data.buf);
    free(doc);
}

LIBCOUCHSTORE_API
void couchstore_free_docinfo(DocInfo *docinfo)
{
    free(docinfo);
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_commit(Db *db)
{
    // do nothing
    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_compact_db_ex(Db* source, const char* target_filename,
        uint64_t flags, const couch_file_ops *ops)
{
    return COUCHSTORE_SUCCESS;
}

LIBCOUCHSTORE_API
couchstore_error_t couchstore_compact_db(Db* source, const char* target_filename)
{
    return couchstore_compact_db_ex(source, target_filename, 0x0, NULL);
}

<|endoftext|>


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

#ifndef _SAL_CONFIG_H_
#include "sal/config.h"
#endif

#ifndef INCLUDED_SFX2_DLLAPI_H
#include "sfx2/dllapi.h"
#endif

#include <sfx2/sfxsids.hrc>

#ifndef _SFXPOOLITEM_HXX //autogen
#include <svtools/poolitem.hxx>
#endif
#ifndef _URLOBJ_HXX //autogen
#include <tools/urlobj.hxx>
#endif
#ifndef _STRING_HXX //autogen
#include <tools/string.hxx>
#endif
#ifndef _SVARRAY_HXX //autogen
#include <svtools/svarray.hxx>
#endif
#ifndef _SV_GEN_HXX
#include <tools/gen.hxx>
#endif

class SvStream;
struct SfxFrameDescriptor_Impl;
class SvStrings;
class SfxFrameDescriptor;
class Wallpaper;
typedef SfxFrameDescriptor* SfxFrameDescriptorPtr;
SV_DECL_PTRARR(SfxFramesArr, SfxFrameDescriptorPtr, 4, 2)

//===========================================================================
// Die SfxFrame...descriptoren bauen eine rekursive Struktur auf, die
// s"amtliche zur Anzeige des Frame-Dokuments erforderlichen Daten umfa\st.
// "Uber einen SfxFrameSetDescriptor hat man Zugriff auf die gesamte darunter
// liegende Struktur.
// Aufgrund der besonderen Eigenschaften des SfxFrames-Dokuments ist ein
// SfxFramesSetDescriptor nicht nur der Inhalt dieses Dokuments, sondern
// beschreibt auch die View darauf.
// Das FrameSet wird aus Zeilen aufgebaut, die wiederum die eigentlichen
// Fenster enthalten. Eine Zeile kann horizontal oder vertikal ausgerichtet
// sein, woraus sich auch das Alignment des FrameSets ergibt.
//===========================================================================

enum ScrollingMode
{
    ScrollingYes,
    ScrollingNo,
    ScrollingAuto
};

enum SizeSelector
{
    SIZE_ABS,
    SIZE_PERCENT,
    SIZE_REL
};

#define BORDER_SET          2
#define BORDER_YES          1
#define BORDER_NO           0
#define SPACING_NOT_SET     -1L
#define SIZE_NOT_SET        -1L

class SfxItemSet;
struct SfxFrameProperties;

class SFX2_DLLPUBLIC SfxFrameDescriptor
{
    INetURLObject           aURL;
    INetURLObject           aActualURL;
    String                  aName;
    Size                    aMargin;
    long                    nWidth;
    ScrollingMode           eScroll;
    SizeSelector            eSizeSelector;
    USHORT                  nHasBorder;
    USHORT                  nItemId;
    BOOL                    bResizeHorizontal;
    BOOL                    bResizeVertical;
    BOOL                    bHasUI;
    BOOL                    bReadOnly;
    SfxFrameDescriptor_Impl* pImp;
    SvStrings*              pScripts;
    SvStrings*              pComments;

public:
                            SfxFrameDescriptor();
                            ~SfxFrameDescriptor();

                            // Eigenschaften
    void                    TakeProperties( const SfxFrameProperties& rProp );

                            // FileName/URL
    SfxItemSet*             GetArgs();
    const INetURLObject&    GetURL() const
                            { return aURL; }
    void                    SetURL( const INetURLObject& rURL );
    void                    SetURL( const String& rURL );
    const INetURLObject&    GetActualURL() const
                            { return aActualURL; }
    void                    SetActualURL( const INetURLObject& rURL );
    void                    SetActualURL( const String& rURL );
    BOOL                    CheckContent() const;
    BOOL                    CompareOriginal( SfxFrameDescriptor& rSet ) const;
    void                    UnifyContent( BOOL );
    void                    SetReadOnly( BOOL bSet ) { bReadOnly = bSet;}
    BOOL                    IsReadOnly(  ) const { return bReadOnly;}
    void                    SetEditable( BOOL bSet );
    BOOL                    IsEditable() const;

                            // Size
    void                    SetWidth( long n )
                            { nWidth = n; }
    void                    SetWidthPercent( long n )
                            { nWidth = n; eSizeSelector = SIZE_PERCENT; }
    void                    SetWidthRel( long n )
                            { nWidth = n; eSizeSelector = SIZE_REL; }
    void                    SetWidthAbs( long n )
                            { nWidth = n; eSizeSelector = SIZE_ABS; }
    long                    GetWidth() const
                            { return nWidth; }
    SizeSelector            GetSizeSelector() const
                            { return eSizeSelector; }
    BOOL                    IsResizable() const
                            { return bResizeHorizontal && bResizeVertical; }
    void                    SetResizable( BOOL bRes )
                            { bResizeHorizontal = bResizeVertical = bRes; }

                            // FrameName
    const String&           GetName() const
                            { return aName; }
    void                    SetName( const String& rName )
                            { aName = rName; }

                            // Margin, Scrolling
    const Size&             GetMargin() const
                            { return aMargin; }
    void                    SetMargin( const Size& rMargin )
                            { aMargin = rMargin; }
    ScrollingMode           GetScrollingMode() const
                            { return eScroll; }
    void                    SetScrollingMode( ScrollingMode eMode )
                            { eScroll = eMode; }

                            // FrameBorder
    void                    SetWallpaper( const Wallpaper& rWallpaper );
    const Wallpaper*        GetWallpaper() const;
    BOOL                    HasFrameBorder() const;

    BOOL                    IsFrameBorderOn() const
                            { return ( nHasBorder & BORDER_YES ) != 0; }

    void                    SetFrameBorder( BOOL bBorder )
                            {
                                nHasBorder = bBorder ?
                                            BORDER_YES | BORDER_SET :
                                            BORDER_NO | BORDER_SET;
                            }
    BOOL                    IsFrameBorderSet() const
                            { return (nHasBorder & BORDER_SET) != 0; }
    void                    ResetBorder()
                            { nHasBorder = 0; }

    BOOL                    HasUI() const
                            { return bHasUI; }
    void                    SetHasUI( BOOL bOn )
                            { bHasUI = bOn; }

                            // Attribute f"ur das Splitwindow
    USHORT                  GetItemId() const
                            { return nItemId; }
    void                    SetItemId( USHORT nId )
                            { nItemId = nId; }
    USHORT                  GetWinBits() const;
    long                    GetSize() const;
    USHORT                  GetItemPos() const;

                            // Kopie z.B. f"ur die Views
    SfxFrameDescriptor*     Clone( BOOL bWithIds = TRUE ) const;
};

// Kein Bock, einen operator= zu implementieren...
struct SfxFrameProperties
{
    String                              aURL;
    String                              aName;
    long                                lMarginWidth;
    long                                lMarginHeight;
    long                                lSize;
    long                                lSetSize;
    long                                lFrameSpacing;
    long                                lInheritedFrameSpacing;
    ScrollingMode                       eScroll;
    SizeSelector                        eSizeSelector;
    SizeSelector                        eSetSizeSelector;
    BOOL                                bHasBorder;
    BOOL                                bBorderSet;
    BOOL                                bResizable;
    BOOL                                bSetResizable;
    BOOL                                bIsRootSet;
    BOOL                                bIsInColSet;
    BOOL                                bHasBorderInherited;
    SfxFrameDescriptor*                 pFrame;

private:
    SfxFrameProperties( SfxFrameProperties& ) {}
public:
                                        SfxFrameProperties()
                                            : lMarginWidth( SIZE_NOT_SET ),
                                              lMarginHeight( SIZE_NOT_SET ),
                                              lSize( 1L ),
                                              lSetSize( 1L ),
                                              lFrameSpacing( SPACING_NOT_SET ),
                                              lInheritedFrameSpacing( SPACING_NOT_SET ),
                                              eScroll( ScrollingAuto ),
                                              eSizeSelector( SIZE_REL ),
                                              eSetSizeSelector( SIZE_REL ),
                                              bHasBorder( TRUE ),
                                              bBorderSet( TRUE ),
                                              bResizable( TRUE ),
                                              bSetResizable( TRUE ),
                                              bIsRootSet( FALSE ),
                                              bIsInColSet( FALSE ),
                                              bHasBorderInherited( TRUE ),
                                              pFrame( 0 ) {}

                                        SfxFrameProperties( const SfxFrameDescriptor *pD );
                                        ~SfxFrameProperties() { delete pFrame; }

    int                                 operator ==( const SfxFrameProperties& ) const;
    SfxFrameProperties&                 operator =( const SfxFrameProperties &rProp );
};

class SfxFrameDescriptorItem : public SfxPoolItem
{
    SfxFrameProperties                  aProperties;
public:
                                        TYPEINFO();

                                        SfxFrameDescriptorItem ( const SfxFrameDescriptor *pD, const USHORT nId = SID_FRAMEDESCRIPTOR )
                                            : SfxPoolItem( nId )
                                            , aProperties( pD )
                                        {}

                                        SfxFrameDescriptorItem ( const USHORT nId = SID_FRAMEDESCRIPTOR )
                                            : SfxPoolItem( nId )
                                        {}

                                        SfxFrameDescriptorItem( const SfxFrameDescriptorItem& rCpy )
                                            : SfxPoolItem( rCpy )
                                        {
                                            aProperties = rCpy.aProperties;
                                        }

    virtual                             ~SfxFrameDescriptorItem();

    virtual int                         operator ==( const SfxPoolItem& ) const;
    SfxFrameDescriptorItem&             operator =( const SfxFrameDescriptorItem & );

    virtual SfxItemPresentation         GetPresentation( SfxItemPresentation ePres,
                                            SfxMapUnit eCoreMetric,
                                            SfxMapUnit ePresMetric,
                                            UniString &rText, const IntlWrapper * = 0 ) const;

    virtual SfxPoolItem*                Clone( SfxItemPool *pPool = 0 ) const;
    //virtual SfxPoolItem*              Create(SvStream &, USHORT) const;
    //virtual SvStream&                 Store(SvStream &, USHORT nItemVersion ) const;
    //virtual USHORT                        GetVersion( USHORT nFileFormatVersion ) const;

    const SfxFrameProperties&           GetProperties() const
                                        { return aProperties; }
    void                                SetProperties( const SfxFrameProperties& rProp )
                                        { aProperties = rProp; }
};

#endif // #ifndef _SFX_FRMDESCRHXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.280); FILE MERGED 2008/04/01 15:38:24 thb 1.2.280.3: #i85898# Stripping all external header guards 2008/04/01 12:40:35 thb 1.2.280.2: #i85898# Stripping all external header guards 2008/03/31 13:37:56 rt 1.2.280.1: #i87441# Change license header to LPGL v3.<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: frmdescr.hxx,v $
 * $Revision: 1.3 $
 *
 * 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.
 *
 ************************************************************************/
#ifndef _SFX_FRMDESCRHXX
#define _SFX_FRMDESCRHXX

#include "sal/config.h"
#include "sfx2/dllapi.h"

#include <sfx2/sfxsids.hrc>
#include <svtools/poolitem.hxx>
#include <tools/urlobj.hxx>
#include <tools/string.hxx>
#include <svtools/svarray.hxx>
#include <tools/gen.hxx>

class SvStream;
struct SfxFrameDescriptor_Impl;
class SvStrings;
class SfxFrameDescriptor;
class Wallpaper;
typedef SfxFrameDescriptor* SfxFrameDescriptorPtr;
SV_DECL_PTRARR(SfxFramesArr, SfxFrameDescriptorPtr, 4, 2)

//===========================================================================
// Die SfxFrame...descriptoren bauen eine rekursive Struktur auf, die
// s"amtliche zur Anzeige des Frame-Dokuments erforderlichen Daten umfa\st.
// "Uber einen SfxFrameSetDescriptor hat man Zugriff auf die gesamte darunter
// liegende Struktur.
// Aufgrund der besonderen Eigenschaften des SfxFrames-Dokuments ist ein
// SfxFramesSetDescriptor nicht nur der Inhalt dieses Dokuments, sondern
// beschreibt auch die View darauf.
// Das FrameSet wird aus Zeilen aufgebaut, die wiederum die eigentlichen
// Fenster enthalten. Eine Zeile kann horizontal oder vertikal ausgerichtet
// sein, woraus sich auch das Alignment des FrameSets ergibt.
//===========================================================================

enum ScrollingMode
{
    ScrollingYes,
    ScrollingNo,
    ScrollingAuto
};

enum SizeSelector
{
    SIZE_ABS,
    SIZE_PERCENT,
    SIZE_REL
};

#define BORDER_SET          2
#define BORDER_YES          1
#define BORDER_NO           0
#define SPACING_NOT_SET     -1L
#define SIZE_NOT_SET        -1L

class SfxItemSet;
struct SfxFrameProperties;

class SFX2_DLLPUBLIC SfxFrameDescriptor
{
    INetURLObject           aURL;
    INetURLObject           aActualURL;
    String                  aName;
    Size                    aMargin;
    long                    nWidth;
    ScrollingMode           eScroll;
    SizeSelector            eSizeSelector;
    USHORT                  nHasBorder;
    USHORT                  nItemId;
    BOOL                    bResizeHorizontal;
    BOOL                    bResizeVertical;
    BOOL                    bHasUI;
    BOOL                    bReadOnly;
    SfxFrameDescriptor_Impl* pImp;
    SvStrings*              pScripts;
    SvStrings*              pComments;

public:
                            SfxFrameDescriptor();
                            ~SfxFrameDescriptor();

                            // Eigenschaften
    void                    TakeProperties( const SfxFrameProperties& rProp );

                            // FileName/URL
    SfxItemSet*             GetArgs();
    const INetURLObject&    GetURL() const
                            { return aURL; }
    void                    SetURL( const INetURLObject& rURL );
    void                    SetURL( const String& rURL );
    const INetURLObject&    GetActualURL() const
                            { return aActualURL; }
    void                    SetActualURL( const INetURLObject& rURL );
    void                    SetActualURL( const String& rURL );
    BOOL                    CheckContent() const;
    BOOL                    CompareOriginal( SfxFrameDescriptor& rSet ) const;
    void                    UnifyContent( BOOL );
    void                    SetReadOnly( BOOL bSet ) { bReadOnly = bSet;}
    BOOL                    IsReadOnly(  ) const { return bReadOnly;}
    void                    SetEditable( BOOL bSet );
    BOOL                    IsEditable() const;

                            // Size
    void                    SetWidth( long n )
                            { nWidth = n; }
    void                    SetWidthPercent( long n )
                            { nWidth = n; eSizeSelector = SIZE_PERCENT; }
    void                    SetWidthRel( long n )
                            { nWidth = n; eSizeSelector = SIZE_REL; }
    void                    SetWidthAbs( long n )
                            { nWidth = n; eSizeSelector = SIZE_ABS; }
    long                    GetWidth() const
                            { return nWidth; }
    SizeSelector            GetSizeSelector() const
                            { return eSizeSelector; }
    BOOL                    IsResizable() const
                            { return bResizeHorizontal && bResizeVertical; }
    void                    SetResizable( BOOL bRes )
                            { bResizeHorizontal = bResizeVertical = bRes; }

                            // FrameName
    const String&           GetName() const
                            { return aName; }
    void                    SetName( const String& rName )
                            { aName = rName; }

                            // Margin, Scrolling
    const Size&             GetMargin() const
                            { return aMargin; }
    void                    SetMargin( const Size& rMargin )
                            { aMargin = rMargin; }
    ScrollingMode           GetScrollingMode() const
                            { return eScroll; }
    void                    SetScrollingMode( ScrollingMode eMode )
                            { eScroll = eMode; }

                            // FrameBorder
    void                    SetWallpaper( const Wallpaper& rWallpaper );
    const Wallpaper*        GetWallpaper() const;
    BOOL                    HasFrameBorder() const;

    BOOL                    IsFrameBorderOn() const
                            { return ( nHasBorder & BORDER_YES ) != 0; }

    void                    SetFrameBorder( BOOL bBorder )
                            {
                                nHasBorder = bBorder ?
                                            BORDER_YES | BORDER_SET :
                                            BORDER_NO | BORDER_SET;
                            }
    BOOL                    IsFrameBorderSet() const
                            { return (nHasBorder & BORDER_SET) != 0; }
    void                    ResetBorder()
                            { nHasBorder = 0; }

    BOOL                    HasUI() const
                            { return bHasUI; }
    void                    SetHasUI( BOOL bOn )
                            { bHasUI = bOn; }

                            // Attribute f"ur das Splitwindow
    USHORT                  GetItemId() const
                            { return nItemId; }
    void                    SetItemId( USHORT nId )
                            { nItemId = nId; }
    USHORT                  GetWinBits() const;
    long                    GetSize() const;
    USHORT                  GetItemPos() const;

                            // Kopie z.B. f"ur die Views
    SfxFrameDescriptor*     Clone( BOOL bWithIds = TRUE ) const;
};

// Kein Bock, einen operator= zu implementieren...
struct SfxFrameProperties
{
    String                              aURL;
    String                              aName;
    long                                lMarginWidth;
    long                                lMarginHeight;
    long                                lSize;
    long                                lSetSize;
    long                                lFrameSpacing;
    long                                lInheritedFrameSpacing;
    ScrollingMode                       eScroll;
    SizeSelector                        eSizeSelector;
    SizeSelector                        eSetSizeSelector;
    BOOL                                bHasBorder;
    BOOL                                bBorderSet;
    BOOL                                bResizable;
    BOOL                                bSetResizable;
    BOOL                                bIsRootSet;
    BOOL                                bIsInColSet;
    BOOL                                bHasBorderInherited;
    SfxFrameDescriptor*                 pFrame;

private:
    SfxFrameProperties( SfxFrameProperties& ) {}
public:
                                        SfxFrameProperties()
                                            : lMarginWidth( SIZE_NOT_SET ),
                                              lMarginHeight( SIZE_NOT_SET ),
                                              lSize( 1L ),
                                              lSetSize( 1L ),
                                              lFrameSpacing( SPACING_NOT_SET ),
                                              lInheritedFrameSpacing( SPACING_NOT_SET ),
                                              eScroll( ScrollingAuto ),
                                              eSizeSelector( SIZE_REL ),
                                              eSetSizeSelector( SIZE_REL ),
                                              bHasBorder( TRUE ),
                                              bBorderSet( TRUE ),
                                              bResizable( TRUE ),
                                              bSetResizable( TRUE ),
                                              bIsRootSet( FALSE ),
                                              bIsInColSet( FALSE ),
                                              bHasBorderInherited( TRUE ),
                                              pFrame( 0 ) {}

                                        SfxFrameProperties( const SfxFrameDescriptor *pD );
                                        ~SfxFrameProperties() { delete pFrame; }

    int                                 operator ==( const SfxFrameProperties& ) const;
    SfxFrameProperties&                 operator =( const SfxFrameProperties &rProp );
};

class SfxFrameDescriptorItem : public SfxPoolItem
{
    SfxFrameProperties                  aProperties;
public:
                                        TYPEINFO();

                                        SfxFrameDescriptorItem ( const SfxFrameDescriptor *pD, const USHORT nId = SID_FRAMEDESCRIPTOR )
                                            : SfxPoolItem( nId )
                                            , aProperties( pD )
                                        {}

                                        SfxFrameDescriptorItem ( const USHORT nId = SID_FRAMEDESCRIPTOR )
                                            : SfxPoolItem( nId )
                                        {}

                                        SfxFrameDescriptorItem( const SfxFrameDescriptorItem& rCpy )
                                            : SfxPoolItem( rCpy )
                                        {
                                            aProperties = rCpy.aProperties;
                                        }

    virtual                             ~SfxFrameDescriptorItem();

    virtual int                         operator ==( const SfxPoolItem& ) const;
    SfxFrameDescriptorItem&             operator =( const SfxFrameDescriptorItem & );

    virtual SfxItemPresentation         GetPresentation( SfxItemPresentation ePres,
                                            SfxMapUnit eCoreMetric,
                                            SfxMapUnit ePresMetric,
                                            UniString &rText, const IntlWrapper * = 0 ) const;

    virtual SfxPoolItem*                Clone( SfxItemPool *pPool = 0 ) const;
    //virtual SfxPoolItem*              Create(SvStream &, USHORT) const;
    //virtual SvStream&                 Store(SvStream &, USHORT nItemVersion ) const;
    //virtual USHORT                        GetVersion( USHORT nFileFormatVersion ) const;

    const SfxFrameProperties&           GetProperties() const
                                        { return aProperties; }
    void                                SetProperties( const SfxFrameProperties& rProp )
                                        { aProperties = rProp; }
};

#endif // #ifndef _SFX_FRMDESCRHXX

<|endoftext|>