<commit_before>//
//  HaloData.cpp
//  Proton
//
//  Created by Paul Whitcomb on 2/20/15.
//  Copyright (c) 2015 Paul Whitcomb. All rights reserved.
//

#include <stdio.h>
#include <string>
#include "HaloData.h"

int main(){}

HaloCacheFileHeaderDemo HaloCacheFileHeader::asDemoHeader() {
    HaloCacheFileHeaderDemo demoHeader = {};

    demoHeader.fileCRC32 = this->fileCRC32;
    demoHeader.fileSize = this->fileSize;
    memcpy(&demoHeader.foot,"tofG",4);
    memcpy(&demoHeader.head,"dehE",4);
    memcpy(demoHeader.mapBuild,this->mapBuild,32);
    memcpy(demoHeader.mapName,this->mapName,32);
    demoHeader.mapGame = this->mapGame;
    demoHeader.mapType = this->mapType;
    demoHeader.tagDataOffset = this->tagDataOffset;
    demoHeader.tagDataSize = this->tagDataSize;

    return demoHeader;
}
HaloCacheFileHeader HaloCacheFileHeaderDemo::asStandardHeader() {
    HaloCacheFileHeader header = {};

    header.fileCRC32 = this->fileCRC32;
    header.fileSize = this->fileSize;
    memcpy(&header.foot,"toof",4);
    memcpy(&header.head,"daeh",4);
    memcpy(header.mapBuild,this->mapBuild,32);
    memcpy(header.mapName,this->mapName,32);
    header.mapGame = this->mapGame;
    header.mapType = this->mapType;
    header.tagDataOffset = this->tagDataOffset;
    header.tagDataSize = this->tagDataSize;

    return header;
}

HaloTagID::HaloTagID() {}
HaloTagID::HaloTagID(uint16_t tagIndex) {
    this->tag_index = tagIndex;
    if(tagIndex == NULLED_TAG_ID)
        this->table_id = NULLED_TAG_ID;
    else
        this->table_id = tagIndex + 0xE174;
}<commit_msg>Remove main<commit_after>//
//  HaloData.cpp
//  Proton
//
//  Created by Paul Whitcomb on 2/20/15.
//  Copyright (c) 2015 Paul Whitcomb. All rights reserved.
//

#include <stdio.h>
#include <string>
#include "HaloData.h"

HaloCacheFileHeaderDemo HaloCacheFileHeader::asDemoHeader() {
    HaloCacheFileHeaderDemo demoHeader = {};

    demoHeader.fileCRC32 = this->fileCRC32;
    demoHeader.fileSize = this->fileSize;
    memcpy(&demoHeader.foot,"tofG",4);
    memcpy(&demoHeader.head,"dehE",4);
    memcpy(demoHeader.mapBuild,this->mapBuild,32);
    memcpy(demoHeader.mapName,this->mapName,32);
    demoHeader.mapGame = this->mapGame;
    demoHeader.mapType = this->mapType;
    demoHeader.tagDataOffset = this->tagDataOffset;
    demoHeader.tagDataSize = this->tagDataSize;

    return demoHeader;
}
HaloCacheFileHeader HaloCacheFileHeaderDemo::asStandardHeader() {
    HaloCacheFileHeader header = {};

    header.fileCRC32 = this->fileCRC32;
    header.fileSize = this->fileSize;
    memcpy(&header.foot,"toof",4);
    memcpy(&header.head,"daeh",4);
    memcpy(header.mapBuild,this->mapBuild,32);
    memcpy(header.mapName,this->mapName,32);
    header.mapGame = this->mapGame;
    header.mapType = this->mapType;
    header.tagDataOffset = this->tagDataOffset;
    header.tagDataSize = this->tagDataSize;

    return header;
}

HaloTagID::HaloTagID() {}
HaloTagID::HaloTagID(uint16_t tagIndex) {
    this->tag_index = tagIndex;
    if(tagIndex == NULLED_TAG_ID)
        this->table_id = NULLED_TAG_ID;
    else
        this->table_id = tagIndex + 0xE174;
}<|endoftext|>


<commit_before>/**
 * @file
 * @author Jason Lingle
 * @brief Implementation of src/ship/ship_renderer.hxx
 */

/*
 * ship_renderer.cxx
 *
 *  Created on: 30.01.2011
 *      Author: jason
 */

//Only compile in non-2.1 mode
#ifndef AB_OPENGL_14

#include <map>
#include <vector>
#include <new>
#include <cstring>

#include <GL/gl.h>

#include "ship_renderer.hxx"
#include "render_quad.hxx"
#include "ship.hxx"
#include "cell/cell.hxx"
#include "src/graphics/vec.hxx"
#include "src/graphics/matops.hxx"
#include "src/graphics/shader.hxx"
#include "src/graphics/shader_loader.hxx"
#include "src/graphics/cmn_shaders.hxx"
#include "src/control/human_controller.hxx"
#include "ship_pallet.hxx"
#include "src/globals.hxx"
#include "src/secondary/confreg.hxx"

using namespace std;

struct ShipShaderUniform {
  GLuint mainTex, damTex;
  vec3 shipColour;
  float highColour[128*3];
  float cloak;
};

/* In order to preserve framerate, we limit the number of
 * new RenderQuads we make ready per frame. When the prepare
 * count becomes greater than the prepare limit, no non-high-
 * priority quads will be prepared. A high-priority quad is
 * one in a renderer that has been informed of a major physical
 * change (cell removal). When a renderer draws, it sets
 * the count to 0 if the current clock is different from the
 * reset clock, then updates the reset clock.
 */
static unsigned quadPrepareCount, quadPrepareLimit;
static unsigned long quadPrepareClock;

#define VERTEX_TYPE shader::VertTexc
#define UNIFORM_TYPE ShipShaderUniform
DELAY_SHADER(ship)
  sizeof(VERTEX_TYPE),
  VATTRIB(vertex), VATTRIB(texCoord), NULL,
  true,
  UNIFORM(mainTex), UNIFORM(damTex), UNIFORM(shipColour),
  UNIFLOATA(highColour), UNIFLOAT(cloak), NULL
END_DELAY_SHADER(static shipShader);

ShipRenderer::ShipRenderer(Ship* s)
: owner(s), quads(NULL), isHighPriority(false)
{
  setPallet(P_G_CYANDARK0, 0, 0xE0/255.0f, 0xE0/255.0f);
  setPallet(P_G_CYANDARK1, 0, 0xC0/255.0f, 0xC0/255.0f);
  setPallet(P_G_CYANDARK2, 0, 0xA0/255.0f, 0xA0/255.0f);
  setPallet(P_G_CYANDARK3, 0, 0x80/255.0f, 0x80/255.0f);
  setPallet(P_G_BLUEDARK0, 0, 0, 0xE0/255.0f);
  setPallet(P_G_BLUEDARK1, 0, 0, 0xC0/255.0f);
  setPallet(P_G_BLUEDARK2, 0, 0, 0xA0/255.0f);
  setPallet(P_G_BLUEDARK3, 0, 0, 0x80/255.0f);
  setPallet(P_G_YELLORNG0, 1, 1, 0);
  setPallet(P_G_YELLORNG1, 1, 0.75f, 0);
  setPallet(P_G_YELLORNG2, 1, 0.5f, 0);
  setPallet(P_G_YELLORNG2, 1, 0.25f, 0);
  setPallet(P_G_GREYLGHT0, 0x33/255.0f, 0x33/255.0f, 0x33/255.0f);
  setPallet(P_G_GREYLGHT1, 0x66/255.0f, 0x66/255.0f, 0x66/255.0f);
  setPallet(P_G_GREYLGHT2, 0x99/255.0f, 0x99/255.0f, 0x99/255.0f);
  setPallet(P_G_GREYLGHT3, 0xCC/255.0f, 0xCC/255.0f, 0xCC/255.0f);
  setPallet(P_GREEN,       0, 1, 0);
  setPallet(P_DARKYELLOW,  0xCC/255.0f, 0xCC/255.0f, 0);
  setPallet(P_DARKBLUECYAN, 0, 0.5f, 1);
  setPallet(P_WHITE, 1, 1, 1);

  quadPrepareLimit = conf["conf"]["graphics"]["ship_draw_rate"];
}

ShipRenderer::~ShipRenderer() {
  free();
}

void ShipRenderer::free() noth {
  if (quads) {
    for (unsigned i=0; i<nPerSide*nPerSide; ++i)
      delete quads[i];
    delete[] quads;
  }
  quads=NULL;
  isHighPriority=false;
  cell2Quad.clear();
}

void ShipRenderer::cellDamage(Cell* cell) noth {
  map<Cell*,vector<RenderQuad*> >::iterator it=cell2Quad.find(cell);
  if (it != cell2Quad.end()) {
    const vector<RenderQuad*>& quads((*it).second);
    for (unsigned i=0; i<quads.size(); ++i)
      quads[i]->cellDamaged();
  }
}

void ShipRenderer::cellRemoved(Cell* cell) noth {
  map<Cell*,vector<RenderQuad*> >::iterator it=cell2Quad.find(cell);
  if (it != cell2Quad.end()) {
    const vector<RenderQuad*>& quads((*it).second);
    for (unsigned i=0; i<quads.size(); ++i)
      quads[i]->physicalChange(cell);

    cell2Quad.erase(it);
  }

  isHighPriority=true;
}

void ShipRenderer::cellChanged(Cell* cell) noth {
  map<Cell*,vector<RenderQuad*> >::iterator it=cell2Quad.find(cell);
  if (it != cell2Quad.end()) {
    const vector<RenderQuad*>& quads((*it).second);
    for (unsigned i=0; i<quads.size(); ++i)
      quads[i]->physicalChange(NULL);
  }
}

void ShipRenderer::draw() noth {
  if (quadPrepareClock != gameClock) {
    quadPrepareCount=0;
    quadPrepareClock = gameClock;
  }

  if (!quads || !--framesUntilDetailCheck) {
    if (!quads || detailLevel != (unsigned)conf["conf"]["graphics"]["detail_level"]) {
      if (quads) isHighPriority=true;

      free();
      owner->physicsRequire(PHYS_SHIP_COORDS_BIT | PHYS_CELL_LOCATION_PROPERTIES_BIT);
      gradius=owner->getBoundingSquareHalfEdge()+STD_CELL_SZ*2;
      bridgeX=owner->cells[0]->getX();
      bridgeY=owner->cells[0]->getY();

      detailLevel=conf["conf"]["graphics"]["detail_level"];
      nPerSide = (unsigned)ceil(gradius*2/STD_CELL_SZ/detailLevel);

      quads = new RenderQuad*[nPerSide*nPerSide];
      for (unsigned y=0; y<nPerSide; ++y) for (unsigned x=0; x<nPerSide; ++x)
        quads[y*nPerSide + x] = new RenderQuad(detailLevel, x, y);
      //Find which cells belong to which quads
      //First, teleport ship to standard location
      float* tmpDat=owner->temporaryZero();
      owner->teleport(gradius, gradius, 0);
      for (unsigned i=0; i<nPerSide*nPerSide; ++i)
        for (unsigned j=0; j<owner->cells.size(); ++j)
          if (quads[i]->doesCellIntersect(owner->cells[j]))
            cell2Quad[owner->cells[j]].push_back(quads[i]);
      owner->restoreFromZero(tmpDat);
    }

    /* Wait a while before seeing if we must change detail level. */
    framesUntilDetailCheck = 0x80 + (rand()&0xFF);
  }

  //Are all the quads ready?
  bool ready=true;
  for (unsigned i=0; i<nPerSide*nPerSide && ready; ++i)
    ready = quads[i]->isReady();

  if (!ready) {
    BEGINGP("Ship rendering")
    //Modify transforms so that ship appears in standard area
    mPush(matrix_stack::view);
    mId(matrix_stack::view);
    mPush();
    mId();

    //Now draw any that aren't ready
    for (unsigned i=0; i<nPerSide*nPerSide; ++i)
      if (!quads[i]->isReady() && (isHighPriority || quadPrepareCount < quadPrepareLimit)) {
        ++quadPrepareCount;
        quads[i]->makeReady(gradius-detailLevel*STD_CELL_SZ/2-(owner->cells[0]->getX()-bridgeX),
                            gradius-detailLevel*STD_CELL_SZ/2-(owner->cells[0]->getY()-bridgeY));
      }

    //Restore matrices
    mPop();
    mPop(matrix_stack::view);
    ENDGP
  }

  //OK, we may now proceed with drawing
  ShipShaderUniform uni;
  uni.mainTex=0;
  uni.damTex=1;
  uni.shipColour=Vec3(owner->getColourR(), owner->getColourG(), owner->getColourB());
  if (owner->isCloaked()) {
    if (owner->controller && typeid(*owner->controller) == typeid(HumanController))
      //Don't become fully transparent so that the player can still see his ship
      uni.cloak = 1.0f - 0.80*owner->getStealthCounter() / (float)STEALTH_COUNTER_MAX;
    else
      uni.cloak = 1.0f - owner->getStealthCounter() / (float)STEALTH_COUNTER_MAX;
  } else {
    uni.cloak = 1.0f;
  }
  if (uni.cloak > 0) {
    memcpy(uni.highColour, pallet, sizeof(pallet));
    mTrans(-gradius+(owner->cells[0]->getX()-bridgeX),
           -gradius+(owner->cells[0]->getY()-bridgeY));
    shipShader->activate(&uni);
    for (unsigned i=0; i<nPerSide*nPerSide; ++i)
      if (quads[i]->isReady())
        quads[i]->draw();
  }
}

#endif /* AB_OPENGL_14 */
<commit_msg>Add missing <typeinfo> include in ship_renderer.cxx.<commit_after>/**
 * @file
 * @author Jason Lingle
 * @brief Implementation of src/ship/ship_renderer.hxx
 */

/*
 * ship_renderer.cxx
 *
 *  Created on: 30.01.2011
 *      Author: jason
 */

//Only compile in non-1.4 mode
#ifndef AB_OPENGL_14

#include <map>
#include <vector>
#include <new>
#include <cstring>
#include <typeinfo>

#include <GL/gl.h>

#include "ship_renderer.hxx"
#include "render_quad.hxx"
#include "ship.hxx"
#include "cell/cell.hxx"
#include "src/graphics/vec.hxx"
#include "src/graphics/matops.hxx"
#include "src/graphics/shader.hxx"
#include "src/graphics/shader_loader.hxx"
#include "src/graphics/cmn_shaders.hxx"
#include "src/control/human_controller.hxx"
#include "ship_pallet.hxx"
#include "src/globals.hxx"
#include "src/secondary/confreg.hxx"

using namespace std;

struct ShipShaderUniform {
  GLuint mainTex, damTex;
  vec3 shipColour;
  float highColour[128*3];
  float cloak;
};

/* In order to preserve framerate, we limit the number of
 * new RenderQuads we make ready per frame. When the prepare
 * count becomes greater than the prepare limit, no non-high-
 * priority quads will be prepared. A high-priority quad is
 * one in a renderer that has been informed of a major physical
 * change (cell removal). When a renderer draws, it sets
 * the count to 0 if the current clock is different from the
 * reset clock, then updates the reset clock.
 */
static unsigned quadPrepareCount, quadPrepareLimit;
static unsigned long quadPrepareClock;

#define VERTEX_TYPE shader::VertTexc
#define UNIFORM_TYPE ShipShaderUniform
DELAY_SHADER(ship)
  sizeof(VERTEX_TYPE),
  VATTRIB(vertex), VATTRIB(texCoord), NULL,
  true,
  UNIFORM(mainTex), UNIFORM(damTex), UNIFORM(shipColour),
  UNIFLOATA(highColour), UNIFLOAT(cloak), NULL
END_DELAY_SHADER(static shipShader);

ShipRenderer::ShipRenderer(Ship* s)
: owner(s), quads(NULL), isHighPriority(false)
{
  setPallet(P_G_CYANDARK0, 0, 0xE0/255.0f, 0xE0/255.0f);
  setPallet(P_G_CYANDARK1, 0, 0xC0/255.0f, 0xC0/255.0f);
  setPallet(P_G_CYANDARK2, 0, 0xA0/255.0f, 0xA0/255.0f);
  setPallet(P_G_CYANDARK3, 0, 0x80/255.0f, 0x80/255.0f);
  setPallet(P_G_BLUEDARK0, 0, 0, 0xE0/255.0f);
  setPallet(P_G_BLUEDARK1, 0, 0, 0xC0/255.0f);
  setPallet(P_G_BLUEDARK2, 0, 0, 0xA0/255.0f);
  setPallet(P_G_BLUEDARK3, 0, 0, 0x80/255.0f);
  setPallet(P_G_YELLORNG0, 1, 1, 0);
  setPallet(P_G_YELLORNG1, 1, 0.75f, 0);
  setPallet(P_G_YELLORNG2, 1, 0.5f, 0);
  setPallet(P_G_YELLORNG2, 1, 0.25f, 0);
  setPallet(P_G_GREYLGHT0, 0x33/255.0f, 0x33/255.0f, 0x33/255.0f);
  setPallet(P_G_GREYLGHT1, 0x66/255.0f, 0x66/255.0f, 0x66/255.0f);
  setPallet(P_G_GREYLGHT2, 0x99/255.0f, 0x99/255.0f, 0x99/255.0f);
  setPallet(P_G_GREYLGHT3, 0xCC/255.0f, 0xCC/255.0f, 0xCC/255.0f);
  setPallet(P_GREEN,       0, 1, 0);
  setPallet(P_DARKYELLOW,  0xCC/255.0f, 0xCC/255.0f, 0);
  setPallet(P_DARKBLUECYAN, 0, 0.5f, 1);
  setPallet(P_WHITE, 1, 1, 1);

  quadPrepareLimit = conf["conf"]["graphics"]["ship_draw_rate"];
}

ShipRenderer::~ShipRenderer() {
  free();
}

void ShipRenderer::free() noth {
  if (quads) {
    for (unsigned i=0; i<nPerSide*nPerSide; ++i)
      delete quads[i];
    delete[] quads;
  }
  quads=NULL;
  isHighPriority=false;
  cell2Quad.clear();
}

void ShipRenderer::cellDamage(Cell* cell) noth {
  map<Cell*,vector<RenderQuad*> >::iterator it=cell2Quad.find(cell);
  if (it != cell2Quad.end()) {
    const vector<RenderQuad*>& quads((*it).second);
    for (unsigned i=0; i<quads.size(); ++i)
      quads[i]->cellDamaged();
  }
}

void ShipRenderer::cellRemoved(Cell* cell) noth {
  map<Cell*,vector<RenderQuad*> >::iterator it=cell2Quad.find(cell);
  if (it != cell2Quad.end()) {
    const vector<RenderQuad*>& quads((*it).second);
    for (unsigned i=0; i<quads.size(); ++i)
      quads[i]->physicalChange(cell);

    cell2Quad.erase(it);
  }

  isHighPriority=true;
}

void ShipRenderer::cellChanged(Cell* cell) noth {
  map<Cell*,vector<RenderQuad*> >::iterator it=cell2Quad.find(cell);
  if (it != cell2Quad.end()) {
    const vector<RenderQuad*>& quads((*it).second);
    for (unsigned i=0; i<quads.size(); ++i)
      quads[i]->physicalChange(NULL);
  }
}

void ShipRenderer::draw() noth {
  if (quadPrepareClock != gameClock) {
    quadPrepareCount=0;
    quadPrepareClock = gameClock;
  }

  if (!quads || !--framesUntilDetailCheck) {
    if (!quads || detailLevel != (unsigned)conf["conf"]["graphics"]["detail_level"]) {
      if (quads) isHighPriority=true;

      free();
      owner->physicsRequire(PHYS_SHIP_COORDS_BIT | PHYS_CELL_LOCATION_PROPERTIES_BIT);
      gradius=owner->getBoundingSquareHalfEdge()+STD_CELL_SZ*2;
      bridgeX=owner->cells[0]->getX();
      bridgeY=owner->cells[0]->getY();

      detailLevel=conf["conf"]["graphics"]["detail_level"];
      nPerSide = (unsigned)ceil(gradius*2/STD_CELL_SZ/detailLevel);

      quads = new RenderQuad*[nPerSide*nPerSide];
      for (unsigned y=0; y<nPerSide; ++y) for (unsigned x=0; x<nPerSide; ++x)
        quads[y*nPerSide + x] = new RenderQuad(detailLevel, x, y);
      //Find which cells belong to which quads
      //First, teleport ship to standard location
      float* tmpDat=owner->temporaryZero();
      owner->teleport(gradius, gradius, 0);
      for (unsigned i=0; i<nPerSide*nPerSide; ++i)
        for (unsigned j=0; j<owner->cells.size(); ++j)
          if (quads[i]->doesCellIntersect(owner->cells[j]))
            cell2Quad[owner->cells[j]].push_back(quads[i]);
      owner->restoreFromZero(tmpDat);
    }

    /* Wait a while before seeing if we must change detail level. */
    framesUntilDetailCheck = 0x80 + (rand()&0xFF);
  }

  //Are all the quads ready?
  bool ready=true;
  for (unsigned i=0; i<nPerSide*nPerSide && ready; ++i)
    ready = quads[i]->isReady();

  if (!ready) {
    BEGINGP("Ship rendering")
    //Modify transforms so that ship appears in standard area
    mPush(matrix_stack::view);
    mId(matrix_stack::view);
    mPush();
    mId();

    //Now draw any that aren't ready
    for (unsigned i=0; i<nPerSide*nPerSide; ++i)
      if (!quads[i]->isReady() && (isHighPriority || quadPrepareCount < quadPrepareLimit)) {
        ++quadPrepareCount;
        quads[i]->makeReady(gradius-detailLevel*STD_CELL_SZ/2-(owner->cells[0]->getX()-bridgeX),
                            gradius-detailLevel*STD_CELL_SZ/2-(owner->cells[0]->getY()-bridgeY));
      }

    //Restore matrices
    mPop();
    mPop(matrix_stack::view);
    ENDGP
  }

  //OK, we may now proceed with drawing
  ShipShaderUniform uni;
  uni.mainTex=0;
  uni.damTex=1;
  uni.shipColour=Vec3(owner->getColourR(), owner->getColourG(), owner->getColourB());
  if (owner->isCloaked()) {
    if (owner->controller && typeid(*owner->controller) == typeid(HumanController))
      //Don't become fully transparent so that the player can still see his ship
      uni.cloak = 1.0f - 0.80*owner->getStealthCounter() / (float)STEALTH_COUNTER_MAX;
    else
      uni.cloak = 1.0f - owner->getStealthCounter() / (float)STEALTH_COUNTER_MAX;
  } else {
    uni.cloak = 1.0f;
  }
  if (uni.cloak > 0) {
    memcpy(uni.highColour, pallet, sizeof(pallet));
    mTrans(-gradius+(owner->cells[0]->getX()-bridgeX),
           -gradius+(owner->cells[0]->getY()-bridgeY));
    shipShader->activate(&uni);
    for (unsigned i=0; i<nPerSide*nPerSide; ++i)
      if (quads[i]->isReady())
        quads[i]->draw();
  }
}

#endif /* AB_OPENGL_14 */
<|endoftext|>


<commit_before><commit_msg>How did this happen<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "util/ConstBuffer.hxx"

#include <sodium/crypto_generichash.h>

class GenericHashState {
	crypto_generichash_state state;

public:
	GenericHashState(size_t outlen) noexcept {
		crypto_generichash_init(&state, nullptr, 0, outlen);
	}

	void Update(ConstBuffer<void> p) noexcept {
		crypto_generichash_update(&state,
					  (const unsigned char *)p.data,
					  p.size);
	}

	template<typename T>
	void UpdateT(const T &p) noexcept {
		Update({&p, sizeof(p)});
	}

	void Final(void *out, size_t outlen) noexcept {
		crypto_generichash_blake2b_final(&state, (unsigned char *)out, outlen);
	}

	template<typename T>
	void FinalT(T &p) noexcept {
		Final(&p, sizeof(p));
	}
};
<commit_msg>sodium/GenericHash: add GetFinalT()<commit_after>/*
 * Copyright 2020 CM4all GmbH
 * All rights reserved.
 *
 * author: Max Kellermann <mk@cm4all.com>
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * - Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the
 * distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
 * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include "util/ConstBuffer.hxx"
#include "util/Compiler.h"

#include <sodium/crypto_generichash.h>

class GenericHashState {
	crypto_generichash_state state;

public:
	GenericHashState(size_t outlen) noexcept {
		crypto_generichash_init(&state, nullptr, 0, outlen);
	}

	void Update(ConstBuffer<void> p) noexcept {
		crypto_generichash_update(&state,
					  (const unsigned char *)p.data,
					  p.size);
	}

	template<typename T>
	void UpdateT(const T &p) noexcept {
		Update({&p, sizeof(p)});
	}

	void Final(void *out, size_t outlen) noexcept {
		crypto_generichash_blake2b_final(&state, (unsigned char *)out, outlen);
	}

	template<typename T>
	void FinalT(T &p) noexcept {
		Final(&p, sizeof(p));
	}

	template<typename T>
	gcc_pure
	T GetFinalT() noexcept {
		T result;
		FinalT(result);
		return result;
	}
};
<|endoftext|>


<commit_before>#ifndef __STAN__IO__CSV_WRITER_HPP__
#define __STAN__IO__CSV_WRITER_HPP__

#include <ostream>
#include <limits>
#include <stan/math/matrix.hpp>

namespace stan {

  namespace io {

    /**
     * Writes Stan variables in comma-separated-value format to
     * an output stream.
     *
     *
All output is written to the same line and separated by commas.
     * Use the newline() method to advance to the next line
     * of CSV output.
     */
    class csv_writer {
    private:
      std::ostream& o_;
      bool at_bol_;

    public:

      /**
       * Write a comma.
       *
       * On the first call do nothing, subsequently write
       * a comma.
       */
      void comma() {
        if (at_bol_) {
          at_bol_ = false;
          return;
        }
        o_ << ",";
      }

      /**
       * Construct a CSV writer that writes to the specified
       * output stream.
       *
       * @param o Output stream on which to write.
       */
      csv_writer(std::ostream& o)
        : o_(o), at_bol_(true) {
      }

      /**
       * Write a newline character.
       *
       * End a line of output and start a new line.  This
       * method needs to be called rather than writing
       * a newline to the output stream because it resets
       * the comma flag.
       */
      void newline() {
        o_ << "\n";
        at_bol_ = true;
      }

      /**
       * Write a value.
       *
       * Write the specified integer to the output stream
       * on the current line.
       *
       * @param n Integer to write.
       */
      void write(int n) {
        comma();
        o_ << n;
      }

      /**
       * Write a value.
       *
       * Write the specified double to the output stream
       * on the current line.
       *
       * @param x Double to write.
       */
      void write(double x) {
        comma();
        o_ << std::setprecision (std::numeric_limits<double>::digits10 + 1) << x;
      }

      /**
       * Write a value.
       *
       * Write the specified matrix to the output stream in
       * row-major order.
       *
       * @param m Matrix to write.
       */
      template<int R, int C>
      void write(const Eigen::Matrix<double,R,C>& m) {
        typedef typename Eigen::Matrix<double,R,C>::size_type size_type;
        for (size_type i = 0; i < m.rows(); ++i)
          for (size_type j = 0; j < m.cols(); ++j)
            write(m(i,j));
      }

      /**
       * Write a value in column-major order.
       *
       * Write the specified matrix to the output stream in
       * column-major order.
       *
       * @param m Matrix of doubles to write.
       */
      template<int R, int C>
      void write_col_major(const Eigen::Matrix<double,R,C>& m) {
        typedef typename Eigen::Matrix<double,R,C>::size_type size_type;
        for (size_type j = 0; j < m.cols(); ++j)
          for (size_type i = 0; i < m.rows(); ++i)
            write(m(i,j));
      }

      /**
       * Write a value.
       *
       * Write the specified string to the output stream with
       * quotes around it and quotes inside escaped to double
       * quotes.
       *
       * @param s String to write.
       */
      void write(const std::string& s) {
        comma();

        o_ << '"';
        for (size_t i = 0; i < s.size(); ++i) {
          if (s.at(i) == '"') {
            o_ << '"' << '"'; // double quotes
          } else {
            o_ << s.at(i);
          }
        }
        o_ << '"';
      }

    };

  }

}

#endif
<commit_msg>Include iomanip in csv_writer.hpp.<commit_after>#ifndef __STAN__IO__CSV_WRITER_HPP__
#define __STAN__IO__CSV_WRITER_HPP__

#include <ostream>
#include <limits>
#include <iomanip>
#include <stan/math/matrix.hpp>

namespace stan {

  namespace io {

    /**
     * Writes Stan variables in comma-separated-value format to
     * an output stream.
     *
     *
All output is written to the same line and separated by commas.
     * Use the newline() method to advance to the next line
     * of CSV output.
     */
    class csv_writer {
    private:
      std::ostream& o_;
      bool at_bol_;

    public:

      /**
       * Write a comma.
       *
       * On the first call do nothing, subsequently write
       * a comma.
       */
      void comma() {
        if (at_bol_) {
          at_bol_ = false;
          return;
        }
        o_ << ",";
      }

      /**
       * Construct a CSV writer that writes to the specified
       * output stream.
       *
       * @param o Output stream on which to write.
       */
      csv_writer(std::ostream& o)
        : o_(o), at_bol_(true) {
      }

      /**
       * Write a newline character.
       *
       * End a line of output and start a new line.  This
       * method needs to be called rather than writing
       * a newline to the output stream because it resets
       * the comma flag.
       */
      void newline() {
        o_ << "\n";
        at_bol_ = true;
      }

      /**
       * Write a value.
       *
       * Write the specified integer to the output stream
       * on the current line.
       *
       * @param n Integer to write.
       */
      void write(int n) {
        comma();
        o_ << n;
      }

      /**
       * Write a value.
       *
       * Write the specified double to the output stream
       * on the current line.
       *
       * @param x Double to write.
       */
      void write(double x) {
        comma();
        o_ << std::setprecision (std::numeric_limits<double>::digits10 + 1) << x;
      }

      /**
       * Write a value.
       *
       * Write the specified matrix to the output stream in
       * row-major order.
       *
       * @param m Matrix to write.
       */
      template<int R, int C>
      void write(const Eigen::Matrix<double,R,C>& m) {
        typedef typename Eigen::Matrix<double,R,C>::size_type size_type;
        for (size_type i = 0; i < m.rows(); ++i)
          for (size_type j = 0; j < m.cols(); ++j)
            write(m(i,j));
      }

      /**
       * Write a value in column-major order.
       *
       * Write the specified matrix to the output stream in
       * column-major order.
       *
       * @param m Matrix of doubles to write.
       */
      template<int R, int C>
      void write_col_major(const Eigen::Matrix<double,R,C>& m) {
        typedef typename Eigen::Matrix<double,R,C>::size_type size_type;
        for (size_type j = 0; j < m.cols(); ++j)
          for (size_type i = 0; i < m.rows(); ++i)
            write(m(i,j));
      }

      /**
       * Write a value.
       *
       * Write the specified string to the output stream with
       * quotes around it and quotes inside escaped to double
       * quotes.
       *
       * @param s String to write.
       */
      void write(const std::string& s) {
        comma();

        o_ << '"';
        for (size_t i = 0; i < s.size(); ++i) {
          if (s.at(i) == '"') {
            o_ << '"' << '"'; // double quotes
          } else {
            o_ << s.at(i);
          }
        }
        o_ << '"';
      }

    };

  }

}

#endif
<|endoftext|>


<commit_before>#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include <cctype>
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include "include/KaleidoscopeJIT.h"

using namespace llvm;
using namespace llvm::orc;

int main() {

  // create a builder for intermediate representation (IR)
  IRBuilder<> builder(getGlobalContext());

  // create a jit compiler object
  std::unique_ptr<KaleidoscopeJIT> jit = llvm::make_unique<KaleidoscopeJIT>(); //TODO: this call fails, why?!

  // make a module, which holds all the code and the builder that uses it to create code
  std::unique_ptr<Module> module = llvm::make_unique<Module>("my cool jit", getGlobalContext());
  module->setDataLayout(jit->getTargetMachine().createDataLayout());

  // create a function pass manager attached to the module with some optimizations
  std::unique_ptr<legacy::FunctionPassManager> functionPassMgr = llvm::make_unique<legacy::FunctionPassManager>(module.get());
  // Provide basic AliasAnalysis support for GVN.
  functionPassMgr->add(createBasicAliasAnalysisPass());
  // Do simple "peephole" optimizations and bit-twiddling optzns.
  functionPassMgr->add(createInstructionCombiningPass());
  // Reassociate expressions.
  functionPassMgr->add(createReassociatePass());
  // Eliminate Common SubExpressions.
  functionPassMgr->add(createGVNPass());
  // Simplify the control flow graph (deleting unreachable blocks, etc).
  functionPassMgr->add(createCFGSimplificationPass());
  functionPassMgr->doInitialization();

  // create a function mult2 bottom up

  // create the function protoype
  std::vector<Type*> intarg (1, Type::getInt32Ty(getGlobalContext()));
  FunctionType *fType = FunctionType::get(Type::getInt32Ty(getGlobalContext()), intarg, false);
  Function *func = Function::Create(fType, Function::ExternalLinkage, "mult2add3", module.get());
  func->args().begin()->setName("x");
  Value *varx = func->args().begin();

  // create an entry point for this function and link function prototype and body
  // important: this has to be done before the creation of the function body!!
  BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", func);
  builder.SetInsertPoint(bb);

  // create the function body and add it as return value
  Value *const2 = ConstantInt::get(getGlobalContext(), APInt(32, 2)); // 32 bits, value 2
  Value *const3 = ConstantInt::get(getGlobalContext(), APInt(32, 3));
  Value *mult2 = builder.CreateMul(const2, varx, "tmpMult");
  Value *add3 = builder.CreateAdd(const3, mult2, "tmpAdd");
  builder.CreateRet(add3);

  // verify function
  if (!verifyFunction(*func))
      fprintf(stderr, "Verification failed!\n");

  // Print out all of the generated code.
  module->dump();

  // optimize the function with the created optimizer (function pass manager)
  functionPassMgr->run(*func);
  module->dump();

  // run the code
  auto H = jit->addModule(std::move(module));
  auto exprSymbol = jit->findSymbol("mult2add3");
  if (!exprSymbol)
      fprintf(stderr, "Didn't finde expression symbol!\n");
  int (*funcPtr) (int) = (int (*)(int))(intptr_t) exprSymbol.getAddress();
  fprintf(stderr, "Evaluates 7 to: %d\n", funcPtr(7));

  jit->removeModule(H);

  return 0;
}
<commit_msg>added if-conditions<commit_after>#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Vectorize.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include <cctype>
#include <cstdio>
#include <map>
#include <string>
#include <vector>
#include "include/KaleidoscopeJIT.h"

using namespace llvm;
using namespace llvm::orc;

// step-by-step example of how to use LLVM to generate the following program
// for (int i = 0; i < count; ++i) if a(i) < 10: result += b(i)

int main() {

    // initialize target machine and machine-specific settings
    InitializeNativeTarget();
    InitializeNativeTargetAsmPrinter();
    InitializeNativeTargetAsmParser();

    // create a builder for intermediate representation (IR)
    IRBuilder<> builder(getGlobalContext());

    // create a jit compiler object
    std::unique_ptr<KaleidoscopeJIT> jit = llvm::make_unique<KaleidoscopeJIT>();

    // make a module, which holds all the code and the builder that uses it to create code
    std::unique_ptr<Module> module = llvm::make_unique<Module>("my cool jit", getGlobalContext());
    module->setDataLayout(jit->getTargetMachine().createDataLayout());

    // create a function pass manager attached to the module with some optimizations
    std::unique_ptr<legacy::FunctionPassManager> functionPassMgr = llvm::make_unique<legacy::FunctionPassManager>(module.get());
    // Provide basic AliasAnalysis support for GVN.
    functionPassMgr->add(createBasicAliasAnalysisPass());
    // Do simple "peephole" optimizations and bit-twiddling optzns.
    functionPassMgr->add(createInstructionCombiningPass());
    // Reassociate expressions.
    functionPassMgr->add(createReassociatePass());
    // Eliminate Common SubExpressions.
    functionPassMgr->add(createGVNPass());
    // Simplify the control flow graph (deleting unreachable blocks, etc).
    functionPassMgr->add(createCFGSimplificationPass());
    // add basic block vectorization
//    functionPassMgr->add(createBBVectorizePass()); --> TODO: resolve linker problems
    // add loop vectorization
//    functionPassMgr->add(createLoopVectorizePass()); --> TODO: resolve linker problems
    // initialize function pass manager
    functionPassMgr->doInitialization();

    // create a function mult2 bottom up

    // create the function protoype
    std::string cmpFunctionName = "mult2cmp10";
    std::vector<Type*> intarg (1, Type::getInt32Ty(getGlobalContext()));
    FunctionType *cmpFuncType = FunctionType::get(Type::getInt32Ty(getGlobalContext()), intarg, false);
    Function *cmpFunc = Function::Create(cmpFuncType, Function::ExternalLinkage, cmpFunctionName, module.get());
    cmpFunc->args().begin()->setName("x");
    Value *varx = cmpFunc->args().begin();

    // create an entry point for this function and link function prototype and body
    // important: this has to be done before the creation of the function body!!
    BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", cmpFunc);
    builder.SetInsertPoint(bb);

    // Create blocks for the then and else cases.  Insert the 'then' block at the
    // end of the function.
//    BasicBlock *ThenBB =
//        BasicBlock::Create(getGlobalContext(), "then", TheFunction);
//    BasicBlock *ElseBB = BasicBlock::Create(getGlobalContext(), "else");
//    BasicBlock *MergeBB = BasicBlock::Create(getGlobalContext(), "ifcont");
//    builder.CreateCondBr(CondV, ThenBB, ElseBB);

    // create the comparison function body and add it as return value
    Value *const2 = ConstantInt::get(getGlobalContext(), APInt(32, 2)); // 32 bits, value 2
    Value *const10 = ConstantInt::get(getGlobalContext(), APInt(32, 10));
    Value *mult2 = builder.CreateMul(const2, varx, "tmpMult");
    Value *compOp = builder.CreateICmpSLT(mult2, const10, "ifcmp");
    builder.CreateRet(compOp);

    // verify function
    if (!verifyFunction(*cmpFunc))
        fprintf(stderr, "Verification failed!\n");

    // Print out all of the generated code.
    module->dump();

    // optimize the function with the created optimizer (function pass manager)
    functionPassMgr->run(*cmpFunc);
    module->dump();

    // run the code
    auto H = jit->addModule(std::move(module));
    auto exprSymbol = jit->findSymbol(cmpFunctionName);
    if (!exprSymbol)
        fprintf(stderr, "Didn't finde expression symbol!\n");
    int (*funcPtr) (int) = (int (*)(int))(intptr_t) exprSymbol.getAddress();
    fprintf(stderr, "Evaluates 3 to: %u\n --> True?", funcPtr(3));
    fprintf(stderr, "Evaluates 7 to: %u\n --> False?", funcPtr(7));

    jit->removeModule(H);

    return 0;
}
<|endoftext|>


<commit_before>/*
    fastsim.cpp  -  Don Cross  -  1 July 2016.

    A simulation of mutually repulsive particles trapped on the surface of a sphere.
    This is also known as the Thompson Problem.
    See:  https://en.wikipedia.org/wiki/Thomson_problem
*/

#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <utility>
#include <cstdint>
#include <cmath>
#include <cstring>
#include <string>

namespace Electrons
{
    // Vector ---------------------------------------------------------------

    struct Vector
    {
        double  x;
        double  y;
        double  z;

        Vector(): x(0), y(0), z(0) {}
        Vector(double _x, double _y, double _z): x(_x), y(_y), z(_z) {}

        void Reset()
        {
            x = 0;
            y = 0;
            z = 0;
        }

        double MagSquared() const
        {
            return (x*x) + (y*y) + (z*z);
        }

        double Mag() const
        {
            return sqrt(MagSquared());
        }

        Vector UnitVector() const
        {
            double r = Mag();
            if (r < 1.0e-9)
            {
                throw "Cannot find unit vector for near-zero magnitude vector.";
            }
            return Vector(x/r, y/r, z/r);
        }

        Vector& operator += (const Vector& other)
        {
            x += other.x;
            y += other.y;
            z += other.z;
            return *this;
        }

        Vector& operator -= (const Vector& other)
        {
            x -= other.x;
            y -= other.y;
            z -= other.z;
            return *this;
        }

        static double Dot(const Vector& a, const Vector& b)
        {
            return (a.x*b.x) + (a.y*b.y) + (a.z*b.z);
        }
    };

    typedef std::vector<Vector> VectorList;

    inline Vector operator + (const Vector& a, const Vector& b)
    {
        return Vector(a.x + b.x, a.y + b.y, a.z + b.z);
    }

    inline Vector operator - (const Vector& a, const Vector& b)
    {
        return Vector(a.x - b.x, a.y - b.y, a.z - b.z);
    }

    inline Vector operator * (double s, const Vector& v)
    {
        return Vector(s*v.x, s*v.y, s*v.z);
    }

    // Particle ---------------------------------------------------------------

    struct Particle
    {
        Vector position;
        Vector force;

        Particle(): position(), force() {}
        Particle(const Vector& _position): position(_position), force() {}
        Particle(const Vector& _position, const Vector& _force): position(_position), force(_force) {}
    };

    typedef std::vector<Particle> ParticleList;

    // JSON output ------------------------------------------------------------

    void Print(std::ostream& output, double t)
    {
        using namespace std;
        output << setprecision(14) << fixed;
        if (t >= 0.0) output << " ";
        output << t;
    }

    void JsonIndent(std::ostream& output, int indent)
    {
        int spaces = 4*indent;
        for (int i=0; i < spaces; ++i)
        {
            output << " ";
        }
    }

    void JsonPrint(std::ostream& output, const Vector& v)
    {
        output << "{\"x\":";
        Print(output, v.x);
        output << ", \"y\":";
        Print(output, v.y);
        output << ", \"z\":";
        Print(output, v.z);
        output << "}";
    }

    void JsonPrint(std::ostream& output, const Particle& p)
    {
        output << "{\"position\":";
        JsonPrint(output, p.position);
        output << ", \"force\":";
        JsonPrint(output, p.force);
        output << "}";
    }

    void JsonPrint(std::ostream& output, const VectorList& list, int indent)
    {
        using namespace std;
        JsonIndent(output, indent);
        output << "[\n";
        bool first = true;
        for (const Vector& v : list)
        {
            JsonIndent(output, indent);
            output << (first ? "    " : ",   ");
            JsonPrint(output, v);
            output << "\n";
            first = false;
        }
        JsonIndent(output, indent);
        output << "]\n";
    }

    // Random generators ------------------------------------------------------------

    double Random(std::ifstream& infile)
    {
        using namespace std;

        uint64_t data;
        infile.read((char *)&data, sizeof(data));
        if (!infile) throw "Read failure generating random number.";

        // Convert the 64-bit integer to double-precision floating point.
        // Divide by maximum possible value to get a number in the closed range [0, +1].
        double x = static_cast<double>(data) / static_cast<double>(UINT64_MAX);

        // Convert to the closed range [-1, +1].
        return 1.0 - (2.0 * x);
    }

    Vector RandomSpherePoint(std::ifstream& infile)
    {
        // Algorithm for picking a random point on a sphere.
        // Avoids any clustering of points.
        // See equations (9), (10), (11) in:
        // http://mathworld.wolfram.com/SpherePointPicking.html
        while (true)
        {
            double a = Random(infile);
            double b = Random(infile);
            double mag = (a*a) + (b*b);
            if (mag < 1.0)
            {
                double root = 2.0 * sqrt(1.0 - mag);
                return Vector(a*root, b*root, 1.0 - (2.0*mag));
            }
        }
    }

    // Simulation ---------------------------------------------------------------

    class Simulation
    {
    private:
        ParticleList particles;
        int frameCount;
        int updateCount;

    public:
        Simulation(int numPoints)       // create an initial random state
            : frameCount(0)
            , updateCount(0)
        {
            using namespace std;

            if (numPoints < 0) throw "Number of points not allowed to be negative.";
            ifstream infile("/dev/urandom", ios::in | ios::binary);
            if (!infile) throw "Could not open /dev/urandom to obtain random numbers.";
            particles.reserve(static_cast<ParticleList::size_type>(numPoints));
            for (int i=0; i < numPoints; ++i)
            {
                particles.push_back(Particle(RandomSpherePoint(infile)));
            }
        }

        int ParticleCount() const
        {
            return static_cast<int>(particles.size());
        }

        int FrameCount() const
        {
            return frameCount;
        }

        int UpdateCount() const
        {
            return updateCount;
        }

        void JsonPrint(std::ostream& output, int indent) const
        {
            using namespace std;

            JsonIndent(output, indent);
            output << "{\"frame\": " << frameCount << ", \"update\":" << updateCount << ", \"particles\": [\n";
            bool first = true;
            for (const Particle& p : particles)
            {
                JsonIndent(output, indent);
                output << (first ? "    " : ",   ");
                Electrons::JsonPrint(output, p);
                output << "\n";
                first = false;
            }
            JsonIndent(output, indent);
            output << "]}\n";
        }

        bool Converge()
        {
            using namespace std;

            // Create auxiliary particle lists to hold candidate next frames.
            ParticleList nextlist = CreateParticleList();
            ParticleList bestlist = CreateParticleList();

            double energy = CalcTangentialForces(particles);
            while (true)    // frame loop: each iteration updates the particles' positions
            {
                ++frameCount;

                // Search for dt value that decreases potential energy as much as possible.
                // This is a balance between searching as few dt values as possible
                // and homing in on as good value as possible.
                // Calculate reasonable upper bound for dt.
                double dt = DeltaTimeUpperLimit();

                // Use dtAttempt to simulate a possible frame.
                double nextenergy = Update(particles, nextlist, dt);
                while (nextenergy >= energy)
                {
                    if (dt < 1.0e-20)
                    {
                        // We have made dt extremely small, yet we still can't decrease potential energy
                        // of the system. Consider the system to be converged.
                        return true;
                    }
                    dt *= 0.5;
                    nextenergy = Update(particles, nextlist, dt);
                }

                swap(particles, nextlist);
                energy = nextenergy;
            }
        }

    private:
        double Update(ParticleList& currlist, ParticleList& nextlist, double dt)
        {
            ++updateCount;
            UpdatePositions(currlist, nextlist, dt);
            return CalcTangentialForces(nextlist);      // returns updated potential energy of particles in 'nextlist'
        }

        double DeltaTimeUpperLimit() const
        {
            // Goal: find a reasonable upper bound for simulation increment dt.
            // Strategy: Approximate the value of dt that would result in the closest
            // pair of particles (ignoring all other particles) to increase their
            // distance from each other by no more than their current distance times alpha.
            const double alpha = 0.5;

            // Find the minimum distance between any pair of particles.
            double r = MinimumPairDistance(particles);

            // dr = 2*dt/(r^2), because both particles move by dt/(r^2).
            // dr = alpha*r.
            // Therefore, dt = (alpha/2)*r^3.

            return (alpha/2.0) * (r*r*r);
        }

        static double MinimumPairDistance(const ParticleList& particles)
        {
            const ParticleList::size_type numParticles = particles.size();
            if (numParticles < 2)
            {
                throw "There must be at least 2 particles to find a minimum pair distance.";
            }

            double minDistanceSquared = 5.0;  // particles can never be more than 2 units apart, and 2^2 = 4.
            for (ParticleList::size_type i=0; i < numParticles-1; ++i)
            {
                for (ParticleList::size_type j=i+1; j < numParticles; ++j)
                {
                    double distanceSquared = (particles[i].position - particles[j].position).MagSquared();
                    if (distanceSquared < minDistanceSquared)
                    {
                        minDistanceSquared = distanceSquared;
                    }
                }
            }

            if (minDistanceSquared > 4.000000001)       // allow ample room for roundoff error in the n=2 case
            {
                throw "Impossible minimum distance between particles!";
            }

            return sqrt(minDistanceSquared);
        }

        static double CalcTangentialForces(ParticleList& particles)
        {
            // Reset each particle's force to a zero vector.
            for (Particle& p : particles)
            {
                p.force.Reset();
            }

            // Compute force between each unique pair of particles
            // and total potential energy of the system.
            double energy = 0.0;
            const ParticleList::size_type numParticles = particles.size();
            for (ParticleList::size_type i=0; i < numParticles-1; ++i)
            {
                for (ParticleList::size_type j=i+1; j < numParticles; ++j)
                {
                    energy += AddForces(particles[i], particles[j]);
                }
            }

            // The particles can only move along the surface of the sphere,
            // so eliminate the radial component of all forces,
            // leaving tangential forces.
            for (Particle& p : particles)
            {
                // Calculate radial component using dot product and subtract
                // to get tangential component.
                p.force -= Vector::Dot(p.force, p.position) * p.position;
            }

            return energy;
        }

        static void UpdatePositions(ParticleList& inlist, ParticleList& outlist, double dt)
        {
            const ParticleList::size_type numParticles = inlist.size();
            if (numParticles != outlist.size())
            {
                throw "Inconsistent particle list sizes.";
            }

            for (ParticleList::size_type i=0; i < numParticles; ++i)
            {
                Particle& p = inlist[i];
                Particle& q = outlist[i];
                q.position = ((dt * p.force) + p.position).UnitVector();
                // IMPORTANT: q.force is left whatever random garbage was there before - NOT VALID VALUES!
            }
        }

        static double AddForces(Particle& a, Particle& b)
        {
            // Force of electrically charged particles:
            // F = k*q1*q2/r^2.
            // We simplify the problem as:  F = 1/r^2.
            // Force is along the direction of the line passing through both.
            Vector dp = a.position - b.position;
            double forcemag = 1.0 / dp.MagSquared();
            Vector force = forcemag * dp.UnitVector();
            a.force += force;
            b.force -= force;

            // Calculate potential energy of this pair and return it.
            // Potential energy is proportional to 1/r = sqrt(1/r^2).
            return sqrt(forcemag);
        }

        ParticleList CreateParticleList()
        {
            const ParticleList::size_type n = particles.size();
            ParticleList list;
            list.reserve(n);
            for (ParticleList::size_type i = 0; i < n; ++i)
            {
                list.push_back(Particle());
            }
            return list;
        }
    };
}

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

const int MinParticles = 2;
const int MaxParticles = 1000;

void PrintUsage()
{
    std::cout <<
        "\n"
        "USAGE: (where N=" << MinParticles << ".." << MaxParticles << ")\n"
        "\n"
        "fastsim converge N [outfile.json]\n"
        "    Simulate N particles until they reach minimum potential energy.\n"
        "    If output filename is omitted, it defaults to 'sim.json'.\n"
        "\n";
}

int ScanNumParticles(const char *text)
{
    int n = atoi(text);
    if (n<MinParticles || n>MaxParticles)
    {
        throw "Invalid number of particles.";
    }
    return n;
}

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

int main(int argc, const char *argv[])
{
    using namespace std;
    using namespace Electrons;
    try
    {
        if (argc > 1)
        {
            const char *verb = argv[1];

            if (!strcmp(verb, "converge") && (argc >= 3) && (argc <= 4))
            {
                int n = ScanNumParticles(argv[2]);
                const char *outFileName = (argc > 3) ? argv[3] : "sim.json";
                if (0 == remove(outFileName))
                {
                    cout << "Deleted existing file '" << outFileName << "'" << endl;
                }
                Simulation sim(n);
                if (sim.Converge())
                {
                    cout << "Converged after " << sim.FrameCount() << " frames, " << sim.UpdateCount() << " updates." << endl;
                    {
                        ofstream outfile(outFileName);
                        if (!outfile)
                        {
                            cout << "Error opening output file!" << endl;
                            return 1;
                        }
                        sim.JsonPrint(outfile, 0);
                        cout << "Saved final state to file '" << outFileName << "'" << endl;
                    }
                    return 0;
                }
                cout << "FAILED TO CONVERGE!" << endl;
                return 1;
            }
        }

        PrintUsage();
        return 2;
    }
    catch (const char *message)
    {
        cerr << "EXCEPTION: " << message << endl;
        return 3;
    }
}

<commit_msg>Added command to save a random configuration of particles to a json file.<commit_after>/*
    fastsim.cpp  -  Don Cross  -  1 July 2016.

    A simulation of mutually repulsive particles trapped on the surface of a sphere.
    This is also known as the Thompson Problem.
    See:  https://en.wikipedia.org/wiki/Thomson_problem
*/

#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <utility>
#include <cstdint>
#include <cmath>
#include <cstring>
#include <string>

namespace Electrons
{
    // Vector ---------------------------------------------------------------

    struct Vector
    {
        double  x;
        double  y;
        double  z;

        Vector(): x(0), y(0), z(0) {}
        Vector(double _x, double _y, double _z): x(_x), y(_y), z(_z) {}

        void Reset()
        {
            x = 0;
            y = 0;
            z = 0;
        }

        double MagSquared() const
        {
            return (x*x) + (y*y) + (z*z);
        }

        double Mag() const
        {
            return sqrt(MagSquared());
        }

        Vector UnitVector() const
        {
            double r = Mag();
            if (r < 1.0e-9)
            {
                throw "Cannot find unit vector for near-zero magnitude vector.";
            }
            return Vector(x/r, y/r, z/r);
        }

        Vector& operator += (const Vector& other)
        {
            x += other.x;
            y += other.y;
            z += other.z;
            return *this;
        }

        Vector& operator -= (const Vector& other)
        {
            x -= other.x;
            y -= other.y;
            z -= other.z;
            return *this;
        }

        static double Dot(const Vector& a, const Vector& b)
        {
            return (a.x*b.x) + (a.y*b.y) + (a.z*b.z);
        }
    };

    typedef std::vector<Vector> VectorList;

    inline Vector operator + (const Vector& a, const Vector& b)
    {
        return Vector(a.x + b.x, a.y + b.y, a.z + b.z);
    }

    inline Vector operator - (const Vector& a, const Vector& b)
    {
        return Vector(a.x - b.x, a.y - b.y, a.z - b.z);
    }

    inline Vector operator * (double s, const Vector& v)
    {
        return Vector(s*v.x, s*v.y, s*v.z);
    }

    // Particle ---------------------------------------------------------------

    struct Particle
    {
        Vector position;
        Vector force;

        Particle(): position(), force() {}
        Particle(const Vector& _position): position(_position), force() {}
        Particle(const Vector& _position, const Vector& _force): position(_position), force(_force) {}
    };

    typedef std::vector<Particle> ParticleList;

    // JSON output ------------------------------------------------------------

    void Print(std::ostream& output, double t)
    {
        using namespace std;
        output << setprecision(14) << fixed;
        if (t >= 0.0) output << " ";
        output << t;
    }

    void JsonIndent(std::ostream& output, int indent)
    {
        int spaces = 4*indent;
        for (int i=0; i < spaces; ++i)
        {
            output << " ";
        }
    }

    void JsonPrint(std::ostream& output, const Vector& v)
    {
        output << "{\"x\":";
        Print(output, v.x);
        output << ", \"y\":";
        Print(output, v.y);
        output << ", \"z\":";
        Print(output, v.z);
        output << "}";
    }

    void JsonPrint(std::ostream& output, const Particle& p)
    {
        output << "{\"position\":";
        JsonPrint(output, p.position);
        output << ", \"force\":";
        JsonPrint(output, p.force);
        output << "}";
    }

    void JsonPrint(std::ostream& output, const VectorList& list, int indent)
    {
        using namespace std;
        JsonIndent(output, indent);
        output << "[\n";
        bool first = true;
        for (const Vector& v : list)
        {
            JsonIndent(output, indent);
            output << (first ? "    " : ",   ");
            JsonPrint(output, v);
            output << "\n";
            first = false;
        }
        JsonIndent(output, indent);
        output << "]\n";
    }

    // Random generators ------------------------------------------------------------

    double Random(std::ifstream& infile)
    {
        using namespace std;

        uint64_t data;
        infile.read((char *)&data, sizeof(data));
        if (!infile) throw "Read failure generating random number.";

        // Convert the 64-bit integer to double-precision floating point.
        // Divide by maximum possible value to get a number in the closed range [0, +1].
        double x = static_cast<double>(data) / static_cast<double>(UINT64_MAX);

        // Convert to the closed range [-1, +1].
        return 1.0 - (2.0 * x);
    }

    Vector RandomSpherePoint(std::ifstream& infile)
    {
        // Algorithm for picking a random point on a sphere.
        // Avoids any clustering of points.
        // See equations (9), (10), (11) in:
        // http://mathworld.wolfram.com/SpherePointPicking.html
        while (true)
        {
            double a = Random(infile);
            double b = Random(infile);
            double mag = (a*a) + (b*b);
            if (mag < 1.0)
            {
                double root = 2.0 * sqrt(1.0 - mag);
                return Vector(a*root, b*root, 1.0 - (2.0*mag));
            }
        }
    }

    // Simulation ---------------------------------------------------------------

    class Simulation
    {
    private:
        ParticleList particles;
        int frameCount;
        int updateCount;
        double energy;

    public:
        static const int MinParticles = 2;
        static const int MaxParticles = 1000;

        Simulation(int numPoints)       // create an initial random state
            : frameCount(0)
            , updateCount(0)
        {
            using namespace std;

            if ((numPoints < MinParticles) || (numPoints > MaxParticles))
            {
                throw "Invalid number of particles.";
            }

            ifstream infile("/dev/urandom", ios::in | ios::binary);
            if (!infile)
            {
                throw "Could not open /dev/urandom to obtain random numbers.";
            }

            particles.reserve(static_cast<ParticleList::size_type>(numPoints));
            for (int i=0; i < numPoints; ++i)
            {
                particles.push_back(Particle(RandomSpherePoint(infile)));
            }

            energy = CalcTangentialForces(particles);
        }

        int ParticleCount() const
        {
            return static_cast<int>(particles.size());
        }

        int FrameCount() const
        {
            return frameCount;
        }

        int UpdateCount() const
        {
            return updateCount;
        }

        double PotentialEnergy() const
        {
            return energy;
        }

        void JsonPrint(std::ostream& output, int indent) const
        {
            using namespace std;

            JsonIndent(output, indent);
            output << setprecision(12) <<
                "{\"frame\": " << frameCount <<
                ", \"update\":" << updateCount <<
                ", \"energy\":" << energy <<
                ", \"particles\": [\n";

            bool first = true;
            for (const Particle& p : particles)
            {
                JsonIndent(output, indent);
                output << (first ? "    " : ",   ");
                Electrons::JsonPrint(output, p);
                output << "\n";
                first = false;
            }

            JsonIndent(output, indent);
            output << "]}\n";
        }

        bool Converge()
        {
            using namespace std;

            // Create auxiliary particle lists to hold candidate next frames.
            ParticleList nextlist = CreateParticleList();
            ParticleList bestlist = CreateParticleList();

            // The potential energy and tangential forces have already been calculated
            // for the current configuration.  See constructor.

            while (true)    // frame loop: each iteration updates the particles' positions
            {
                // Search for dt value that decreases potential energy as much as possible.
                // This is a balance between searching as few dt values as possible
                // and homing in on as good value as possible.
                // Calculate reasonable upper bound for dt.
                double dt = DeltaTimeUpperLimit();

                // Use dtAttempt to simulate a possible frame.
                double nextenergy = Update(particles, nextlist, dt);
                while (nextenergy >= energy)
                {
                    if (dt < 1.0e-20)
                    {
                        // We have made dt extremely small, yet we still can't decrease potential energy
                        // of the system. Consider the system to be converged.
                        return true;
                    }
                    dt *= 0.5;      // shrink dt and try adjusting the particle locations again
                    nextenergy = Update(particles, nextlist, dt);
                }

                swap(particles, nextlist);
                energy = nextenergy;
                ++frameCount;
            }
        }

    private:
        double Update(ParticleList& currlist, ParticleList& nextlist, double dt)
        {
            ++updateCount;
            UpdatePositions(currlist, nextlist, dt);
            return CalcTangentialForces(nextlist);      // returns updated potential energy of particles in 'nextlist'
        }

        double DeltaTimeUpperLimit() const
        {
            // Goal: find a reasonable upper bound for simulation increment dt.
            // Strategy: Approximate the value of dt that would result in the closest
            // pair of particles (ignoring all other particles) to increase their
            // distance from each other by no more than their current distance times alpha.
            const double alpha = 0.5;

            // Find the minimum distance between any pair of particles.
            double r = MinimumPairDistance(particles);

            // dr = 2*dt/(r^2), because both particles move by dt/(r^2).
            // dr = alpha*r.
            // Therefore, dt = (alpha/2)*r^3.

            return (alpha/2.0) * (r*r*r);
        }

        static double MinimumPairDistance(const ParticleList& particles)
        {
            const ParticleList::size_type numParticles = particles.size();
            if (numParticles < 2)
            {
                throw "There must be at least 2 particles to find a minimum pair distance.";
            }

            double minDistanceSquared = 5.0;  // particles can never be more than 2 units apart, and 2^2 = 4.
            for (ParticleList::size_type i=0; i < numParticles-1; ++i)
            {
                for (ParticleList::size_type j=i+1; j < numParticles; ++j)
                {
                    double distanceSquared = (particles[i].position - particles[j].position).MagSquared();
                    if (distanceSquared < minDistanceSquared)
                    {
                        minDistanceSquared = distanceSquared;
                    }
                }
            }

            if (minDistanceSquared > 4.000000001)       // allow ample room for roundoff error in the n=2 case
            {
                throw "Impossible minimum distance between particles!";
            }

            return sqrt(minDistanceSquared);
        }

        static double CalcTangentialForces(ParticleList& particles)
        {
            // Reset each particle's force to a zero vector.
            for (Particle& p : particles)
            {
                p.force.Reset();
            }

            // Compute force between each unique pair of particles
            // and total potential energy of the system.
            double energy = 0.0;
            const ParticleList::size_type numParticles = particles.size();
            for (ParticleList::size_type i=0; i < numParticles-1; ++i)
            {
                for (ParticleList::size_type j=i+1; j < numParticles; ++j)
                {
                    energy += AddForces(particles[i], particles[j]);
                }
            }

            // The particles can only move along the surface of the sphere,
            // so eliminate the radial component of all forces,
            // leaving tangential forces.
            for (Particle& p : particles)
            {
                // Calculate radial component using dot product and subtract
                // to get tangential component.
                p.force -= Vector::Dot(p.force, p.position) * p.position;
            }

            return energy;
        }

        static void UpdatePositions(ParticleList& inlist, ParticleList& outlist, double dt)
        {
            const ParticleList::size_type numParticles = inlist.size();
            if (numParticles != outlist.size())
            {
                throw "Inconsistent particle list sizes.";
            }

            for (ParticleList::size_type i=0; i < numParticles; ++i)
            {
                Particle& p = inlist[i];
                Particle& q = outlist[i];
                q.position = ((dt * p.force) + p.position).UnitVector();
                // IMPORTANT: q.force is left whatever random garbage was there before - NOT VALID VALUES!
            }
        }

        static double AddForces(Particle& a, Particle& b)
        {
            // Force of electrically charged particles:
            // F = k*q1*q2/r^2.
            // We simplify the problem as:  F = 1/r^2.
            // Force is along the direction of the line passing through both.
            Vector dp = a.position - b.position;
            double forcemag = 1.0 / dp.MagSquared();
            Vector force = forcemag * dp.UnitVector();
            a.force += force;
            b.force -= force;

            // Calculate potential energy of this pair and return it.
            // Potential energy is proportional to 1/r = sqrt(1/r^2).
            return sqrt(forcemag);
        }

        ParticleList CreateParticleList()
        {
            const ParticleList::size_type n = particles.size();
            ParticleList list;
            list.reserve(n);
            for (ParticleList::size_type i = 0; i < n; ++i)
            {
                list.push_back(Particle());
            }
            return list;
        }
    };
}

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

void PrintUsage()
{
    std::cout <<
        "\n"
        "USAGE: (where N=" << Electrons::Simulation::MinParticles << ".." << Electrons::Simulation::MaxParticles << ")\n"
        "\n"
        "fastsim converge N [outfile.json]\n"
        "    Simulate N particles until they reach minimum potential energy.\n"
        "    If output filename is omitted, it defaults to 'sim.json'.\n"
        "\n"
        "fastsim random N outfile.json\n"
        "    Save a random configuration of N particles to the specified file.\n"
        "\n";
}

int ScanNumParticles(const char *text)
{
    int n = atoi(text);
    if ((n < Electrons::Simulation::MinParticles) || (n > Electrons::Simulation::MaxParticles))
    {
        throw "Invalid number of particles.";
    }
    return n;
}

void Save(Electrons::Simulation& sim, const char *outFileName)
{
    std::ofstream outfile(outFileName);
    if (!outfile)
    {
        throw "Error opening output file!";
    }
    sim.JsonPrint(outfile, 0);
    if (!outfile)
    {
        throw "Error writing to output file!";
    }
}

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

int main(int argc, const char *argv[])
{
    using namespace std;
    using namespace Electrons;
    try
    {
        if (argc > 1)
        {
            const char *verb = argv[1];

            if (!strcmp(verb, "converge") && (argc >= 3) && (argc <= 4))
            {
                int n = ScanNumParticles(argv[2]);
                const char *outFileName = (argc > 3) ? argv[3] : "sim.json";
                if (0 == remove(outFileName))
                {
                    cout << "Deleted existing file '" << outFileName << "'" << endl;
                }
                Simulation sim(n);
                if (sim.Converge())
                {
                    cout << "Converged after " << sim.FrameCount() << " frames, " << sim.UpdateCount() << " updates." << endl;
                    Save(sim, outFileName);
                    return 0;
                }
                cout << "FAILED TO CONVERGE!" << endl;
                return 1;
            }

            if (!strcmp(verb, "random") && (argc == 4))
            {
                int n = ScanNumParticles(argv[2]);
                const char *outFileName = argv[3];
                Simulation sim(n);
                Save(sim, outFileName);
                return 0;
            }
        }

        PrintUsage();
        return 2;
    }
    catch (const char *message)
    {
        cerr << "EXCEPTION: " << message << endl;
        return 3;
    }
}

<|endoftext|>


<commit_before>/*
    This file is part of the kolab resource - the implementation of the
    Kolab storage format. See www.kolab.org for documentation on this.

    Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "journal.h"

#include <libkcal/journal.h>
#include <korganizer/version.h>
#include <kdebug.h>

using namespace Kolab;

KCal::Journal* Journal::xmlToJournal( const QString& xml, const QString& tz )
{
  Journal journal( tz );
  journal.load( xml );
  KCal::Journal* kcalJournal = new KCal::Journal();
  journal.saveTo( kcalJournal );
  return kcalJournal;
}

QString Journal::journalToXML( KCal::Journal* kcalJournal, const QString& tz )
{
  Journal journal( tz, kcalJournal );
  return journal.saveXML();
}

Journal::Journal( const QString& tz, KCal::Journal* journal )
  : KolabBase( tz )
{
  if ( journal )
    setFields( journal );
}

Journal::~Journal()
{
}

void Journal::setSummary( const QString& summary )
{
  mSummary = summary;
}

QString Journal::summary() const
{
  return mSummary;
}

void Journal::setStartDate( const QDateTime& startDate )
{
  mStartDate = startDate;
}

QDateTime Journal::startDate() const
{
  return mStartDate;
}

void Journal::setEndDate( const QDateTime& endDate )
{
  mEndDate = endDate;
}

QDateTime Journal::endDate() const
{
  return mEndDate;
}

bool Journal::loadAttribute( QDomElement& element )
{
  QString tagName = element.tagName();

  if ( tagName == "summary" )
    setSummary( element.text() );
  else if ( tagName == "start-date" )
    setStartDate( stringToDateTime( element.text() ) );
  else
    // Not handled here
    return KolabBase::loadAttribute( element );

  // We handled this
  return true;
}

bool Journal::saveAttributes( QDomElement& element ) const
{
  // Save the base class elements
  KolabBase::saveAttributes( element );

  writeString( element, "summary", summary() );
  writeString( element, "start-date", dateTimeToString( startDate() ) );

  return true;
}

bool Journal::loadXML( const QDomDocument& document )
{
  QDomElement top = document.documentElement();

  if ( top.tagName() != "journal" ) {
    qWarning( "XML error: Top tag was %s instead of the expected Journal",
              top.tagName().ascii() );
    return false;
  }

  for ( QDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) {
    if ( n.isComment() )
      continue;
    if ( n.isElement() ) {
      QDomElement e = n.toElement();
      if ( !loadAttribute( e ) )
        // Unhandled tag - save for later storage
        ;//qDebug( "Unhandled tag: %s", e.toCString().data() );
    } else
      qDebug( "Node is not a comment or an element???" );
  }

  return true;
}

QString Journal::saveXML() const
{
  QDomDocument document = domTree();
  QDomElement element = document.createElement( "journal" );
  element.setAttribute( "version", "1.0" );
  saveAttributes( element );
  document.appendChild( element );
  return document.toString();
}

void Journal::saveTo( KCal::Journal* journal )
{
  KolabBase::saveTo( journal );

  journal->setSummary( summary() );
  journal->setDtStart( utcToLocal( startDate() ) );
}

void Journal::setFields( const KCal::Journal* journal )
{
  // Set baseclass fields
  KolabBase::setFields( journal );

  // Set our own fields
  setSummary( journal->summary() );
  setStartDate( localToUTC( journal->dtStart() ) );
}

QString Journal::productID() const
{
  return QString( "KOrganizer " ) + korgVersion + ", Kolab resource";
}
<commit_msg>avoid compiler warning<commit_after>/*
    This file is part of the kolab resource - the implementation of the
    Kolab storage format. See www.kolab.org for documentation on this.

    Copyright (c) 2004 Bo Thorsen <bo@sonofthor.dk>

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

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

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    Boston, MA 02110-1301, USA.

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#include "journal.h"

#include <libkcal/journal.h>
#include <korganizer/version.h>
#include <kdebug.h>

using namespace Kolab;

KCal::Journal* Journal::xmlToJournal( const QString& xml, const QString& tz )
{
  Journal journal( tz );
  journal.load( xml );
  KCal::Journal* kcalJournal = new KCal::Journal();
  journal.saveTo( kcalJournal );
  return kcalJournal;
}

QString Journal::journalToXML( KCal::Journal* kcalJournal, const QString& tz )
{
  Journal journal( tz, kcalJournal );
  return journal.saveXML();
}

Journal::Journal( const QString& tz, KCal::Journal* journal )
  : KolabBase( tz )
{
  if ( journal )
    setFields( journal );
}

Journal::~Journal()
{
}

void Journal::setSummary( const QString& summary )
{
  mSummary = summary;
}

QString Journal::summary() const
{
  return mSummary;
}

void Journal::setStartDate( const QDateTime& startDate )
{
  mStartDate = startDate;
}

QDateTime Journal::startDate() const
{
  return mStartDate;
}

void Journal::setEndDate( const QDateTime& endDate )
{
  mEndDate = endDate;
}

QDateTime Journal::endDate() const
{
  return mEndDate;
}

bool Journal::loadAttribute( QDomElement& element )
{
  QString tagName = element.tagName();

  if ( tagName == "summary" )
    setSummary( element.text() );
  else if ( tagName == "start-date" )
    setStartDate( stringToDateTime( element.text() ) );
  else
    // Not handled here
    return KolabBase::loadAttribute( element );

  // We handled this
  return true;
}

bool Journal::saveAttributes( QDomElement& element ) const
{
  // Save the base class elements
  KolabBase::saveAttributes( element );

  writeString( element, "summary", summary() );
  writeString( element, "start-date", dateTimeToString( startDate() ) );

  return true;
}

bool Journal::loadXML( const QDomDocument& document )
{
  QDomElement top = document.documentElement();

  if ( top.tagName() != "journal" ) {
    qWarning( "XML error: Top tag was %s instead of the expected Journal",
              top.tagName().ascii() );
    return false;
  }

  for ( QDomNode n = top.firstChild(); !n.isNull(); n = n.nextSibling() ) {
    if ( n.isComment() )
      continue;
    if ( n.isElement() ) {
      QDomElement e = n.toElement();
      if ( !loadAttribute( e ) ) {
        // Unhandled tag - save for later storage
        //qDebug( "Unhandled tag: %s", e.toCString().data() );
      }
    } else
      qDebug( "Node is not a comment or an element???" );
  }

  return true;
}

QString Journal::saveXML() const
{
  QDomDocument document = domTree();
  QDomElement element = document.createElement( "journal" );
  element.setAttribute( "version", "1.0" );
  saveAttributes( element );
  document.appendChild( element );
  return document.toString();
}

void Journal::saveTo( KCal::Journal* journal )
{
  KolabBase::saveTo( journal );

  journal->setSummary( summary() );
  journal->setDtStart( utcToLocal( startDate() ) );
}

void Journal::setFields( const KCal::Journal* journal )
{
  // Set baseclass fields
  KolabBase::setFields( journal );

  // Set our own fields
  setSummary( journal->summary() );
  setStartDate( localToUTC( journal->dtStart() ) );
}

QString Journal::productID() const
{
  return QString( "KOrganizer " ) + korgVersion + ", Kolab resource";
}
<|endoftext|>


<commit_before>/**
 * @file   tracker.cpp
 * @author Matheus Vieira Portela
 * @date   29/07/2014
 *
 * @attention Copyright (C) 2014 UnBall Robot Soccer Team
 *
 * @brief Tracker implementation file for vision module
 */

#include <unball/vision/tracker.hpp>

Tracker::Tracker()
{
    window_name_ = "Tracker";
    calculated_measurement_parameters_ = false;
}

Tracker::~Tracker()
{
    if (show_image_)
        cv::destroyWindow(window_name_);
}

/**
 * Load show image. Creates an OpenCV window if show image is set to true.
 */
void Tracker::loadShowImage()
{
    ros::param::get("/vision/tracker/show_image", show_image_);
    ROS_INFO("Tracker show image: %d", show_image_);

    if (show_image_)
        cv::namedWindow(window_name_);
}

/**
 * Load configurations.
 * @warning This method must be called after initializing ROS using ros::init in the node main function.
 */
void Tracker::loadConfig()
{
    loadShowImage();
    tracked_field_.loadConfig();
    measurement_conversion_.loadConfig();
    robot_tracker_.loadConfig();
}

/**
 * Track objects in RGB and depth images
 * @param preprocessed OpenCV BGR image
 * @param segmented OpenCV segmented image
 */
void Tracker::track(cv::Mat rgb_frame, cv::Mat depth_frame, cv::Mat rgb_segmented_frame, cv::Mat depth_segmented_frame)
{
    tracked_field_.track(rgb_frame, depth_frame, rgb_segmented_frame);
    robot_tracker_.track(rgb_frame, depth_frame, rgb_segmented_frame);

    if (tracked_field_.isFieldStable() && !calculated_measurement_parameters_)
        calculateMeasurementConversion();

    tracked_field_.draw(rgb_frame);
    robot_tracker_.draw(rgb_frame);
}

/**
 * Sends the field dimensions to the measurement conversion class
 */
void Tracker::calculateMeasurementConversion()
{
    cv::Point field_dimensions = tracked_field_.getFieldDimensions();
    measurement_conversion_.calculateConversion(field_dimensions.x, field_dimensions.y);
    measurement_conversion_.setFieldCenter(tracked_field_.getFieldCenter());
    calculated_measurement_parameters_ = true;
}

std::vector<float> Tracker::getRobotPose(int robot_index)
{
    return robot_tracker_.getRobotPose(robot_index);
}
<commit_msg>Disabled robot tracking for now.<commit_after>/**
 * @file   tracker.cpp
 * @author Matheus Vieira Portela
 * @date   29/07/2014
 *
 * @attention Copyright (C) 2014 UnBall Robot Soccer Team
 *
 * @brief Tracker implementation file for vision module
 */

#include <unball/vision/tracker.hpp>

Tracker::Tracker()
{
    window_name_ = "Tracker";
    calculated_measurement_parameters_ = false;
}

Tracker::~Tracker()
{
    if (show_image_)
        cv::destroyWindow(window_name_);
}

/**
 * Load show image. Creates an OpenCV window if show image is set to true.
 */
void Tracker::loadShowImage()
{
    ros::param::get("/vision/tracker/show_image", show_image_);
    ROS_INFO("Tracker show image: %d", show_image_);

    if (show_image_)
        cv::namedWindow(window_name_);
}

/**
 * Load configurations.
 * @warning This method must be called after initializing ROS using ros::init in the node main function.
 */
void Tracker::loadConfig()
{
    loadShowImage();
    tracked_field_.loadConfig();
    measurement_conversion_.loadConfig();
    robot_tracker_.loadConfig();
}

/**
 * Track objects in RGB and depth images
 * @param preprocessed OpenCV BGR image
 * @param segmented OpenCV segmented image
 */
void Tracker::track(cv::Mat rgb_frame, cv::Mat depth_frame, cv::Mat rgb_segmented_frame, cv::Mat depth_segmented_frame)
{
    tracked_field_.track(rgb_frame, depth_frame, rgb_segmented_frame);
    // robot_tracker_.track(rgb_frame, depth_frame, rgb_segmented_frame);

    if (tracked_field_.isFieldStable() && !calculated_measurement_parameters_)
        calculateMeasurementConversion();

    tracked_field_.draw(rgb_frame);
    // robot_tracker_.draw(rgb_frame);
}

/**
 * Sends the field dimensions to the measurement conversion class
 */
void Tracker::calculateMeasurementConversion()
{
    cv::Point field_dimensions = tracked_field_.getFieldDimensions();
    measurement_conversion_.calculateConversion(field_dimensions.x, field_dimensions.y);
    measurement_conversion_.setFieldCenter(tracked_field_.getFieldCenter());
    calculated_measurement_parameters_ = true;
}

std::vector<float> Tracker::getRobotPose(int robot_index)
{
    return robot_tracker_.getRobotPose(robot_index);
}
<|endoftext|>


<commit_before>#include <BALL/STRUCTURE/geometricProperties.h>

#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/molecule.h>

#include <BALL/CONCEPT/classTest.h>

START_TEST(GeometricProperties, "")

using namespace BALL;

CHECK(setTorsionAngle unsuccessful)
	Molecule m;
	Atom a1, a2, a3, a4;
	a1.setPosition(Vector3(0.0f,1.0f,0.0f));
	a2.setPosition(Vector3(0.0f,0.0f,0.0f));
	a3.setPosition(Vector3(1.0f,0.0f,0.0f));
	a4.setPosition(Vector3(1.0f,-1.0f,0.0f));

	m.insert(a1);
	m.insert(a2);
	m.insert(a3);
	m.insert(a4);

	a1.createBond(a2);
	a2.createBond(a3);
	a3.createBond(a4);
	a4.createBond(a1);

	float angle = 90.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), false);
RESULT

CHECK(setTorsionAngle successful)
	Molecule m;
	Atom a1, a2, a3, a4;
	a1.setPosition(Vector3(0.0f, 1.0f, 0.0f));
	a2.setPosition(Vector3(0.0f, 0.0f, 0.0f));
	a3.setPosition(Vector3(1.0f, 0.0f, 0.0f));
	a4.setPosition(Vector3(1.0f,-1.0f, 0.0f));

	m.insert(a1);
	m.insert(a2);
	m.insert(a3);
	m.insert(a4);

	a1.createBond(a2);
	a2.createBond(a3);
	a3.createBond(a4);

	PRECISION(1e-5)
	float angle = 90.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	Angle result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);

	angle = 120.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);

	angle = 37.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);

	angle = 0.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);
RESULT

END_TEST
<commit_msg>Made the GeometricProperties_test slightly less sensitive<commit_after>#include <BALL/STRUCTURE/geometricProperties.h>

#include <BALL/KERNEL/atom.h>
#include <BALL/KERNEL/molecule.h>

#include <BALL/CONCEPT/classTest.h>

START_TEST(GeometricProperties, "")

using namespace BALL;

CHECK(setTorsionAngle unsuccessful)
	Molecule m;
	Atom a1, a2, a3, a4;
	a1.setPosition(Vector3(0.0f,1.0f,0.0f));
	a2.setPosition(Vector3(0.0f,0.0f,0.0f));
	a3.setPosition(Vector3(1.0f,0.0f,0.0f));
	a4.setPosition(Vector3(1.0f,-1.0f,0.0f));

	m.insert(a1);
	m.insert(a2);
	m.insert(a3);
	m.insert(a4);

	a1.createBond(a2);
	a2.createBond(a3);
	a3.createBond(a4);
	a4.createBond(a1);

	float angle = 90.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), false);
RESULT

CHECK(setTorsionAngle successful)
	Molecule m;
	Atom a1, a2, a3, a4;
	a1.setPosition(Vector3(0.0f, 1.0f, 0.0f));
	a2.setPosition(Vector3(0.0f, 0.0f, 0.0f));
	a3.setPosition(Vector3(1.0f, 0.0f, 0.0f));
	a4.setPosition(Vector3(1.0f,-1.0f, 0.0f));

	m.insert(a1);
	m.insert(a2);
	m.insert(a3);
	m.insert(a4);

	a1.createBond(a2);
	a2.createBond(a3);
	a3.createBond(a4);

	PRECISION(1e-4)
	float angle = 90.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	Angle result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);

	angle = 120.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);

	angle = 37.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);

	angle = 0.0f;
	TEST_EQUAL(setTorsionAngle(a1, a2, a3, a4, Angle(angle, false)), true);
	result = calculateTorsionAngle(a1, a2, a3, a4);
	TEST_REAL_EQUAL(result.toDegree(), angle);
RESULT

END_TEST
<|endoftext|>