<commit_before>#ifndef OBJECT_GL_COLOUR_FORMAT_HPP
#define OBJECT_GL_COLOUR_FORMAT_HPP

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

// Contact :
// Email             : $objectgl_email
// GitHub repository : $objectgl_git

/*!
	\file ColourFormat.hpp
	\brief
	\author Adam Smith
	\date 6th November 2015
*/

#include <cstdint>
#include "ObjectGLInit.inl"
#include "BinaryData.hpp"

namespace ObjectGL { namespace ColourFormat{

	namespace Implementation{

		template<const GLuint BITS>
		static void CopyBits(const void* aSrc, const GLuint aSrcOffset, void* aDst, const GLuint aDstOffset){

			const bool byteAligned = ! ((BITS & 7) || (aSrcOffset & 7) || (aDstOffset & 7));

			if(byteAligned){
				std::memcpy(
					static_cast<const uint8_t*>(aSrc) + (aSrcOffset / 8),
					static_cast<uint8_t*>(aDst) + (aDstOffset / 8),
					BITS / 8
				);
			}else{
				//! \todo Optimise
				const uint8_t* const src = static_cast<const uint8_t*>(aSrc);
				uint8_t* const dst = static_cast<uint8_t*>(aDst);

				GLuint srcOffset = aSrcOffset;
				GLuint dstOffset = aDstOffset;
				for(GLuint i = 0; i != BITS; ++i){
					const uint8_t srcByte = src[srcOffset / 8];
					uint8_t& dstByte = dst[dstOffset / 8];

					const uint8_t srcMask = 1 << (aSrcOffset & 7);
					const uint8_t dstMask = 1 << (dstOffset & 7);

					uint8_t bit = srcByte & srcMask;

					dstByte &= ~dstMask;
					if(bit) dstByte |= dstMask;

					++srcOffset;
					++dstOffset;
				}
			}
		}
	}

	template<class Format>
	static typename Format::Type Read(const void* const aData, const GLuint aOffset){
		typename Format::Type tmp = 0;
		return Implementation::CopyBits<Format::BitDepth>(aData, aOffset * Format::BitDepth, &tmp, 0);
		return tmp;
	}

	template<class Format>
	static void Write(void* const aData, const GLuint aOffset, const typename Format::Type aValue){
		return Implementation::CopyBits<Format::BitDepth>(&aValue, 0, aData, aOffset * Format::BitDepth);
	}

	enum class Storage : GLenum{
		NONE				= GL_NONE,
		UNSIGNED_NORMALISED	= GL_UNSIGNED_NORMALIZED,
		SIGNED_NORMALISED	= GL_SIGNED_NORMALIZED,
		UNSIGNED_INTEGRAL	= GL_UNSIGNED_INT,
		SIGNED_INTEGRAL		= GL_INT,
		FLOAT				= GL_FLOAT
	};

	template<const Storage TYPE>
	struct StorageType{
		typedef void Type;
		enum : GLuint{
			SizeBytes = 0,
			SizeBits = 0
		};
	};

	template<>
	struct StorageType<Storage::NONE>{
		typedef void Type;
		enum : GLuint{
			SizeBytes = 0,
			SizeBits = 0
		};
	};

	template<>
	struct StorageType<Storage::UNSIGNED_NORMALISED>{
		typedef uint8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_NORMALISED> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_NORMALISED> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::SIGNED_NORMALISED>{
		typedef int8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<SIGNED_NORMALISED> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<SIGNED_NORMALISED> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::UNSIGNED_INTEGRAL>{
		typedef uint8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_INTEGRAL> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_INTEGRAL> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::SIGNED_INTEGRAL>{
		typedef uint8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<SIGNED_INTEGRAL> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<SIGNED_INTEGRAL> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::FLOAT>{
		typedef float Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<FLOAT> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<FLOAT> Type is not large enough to contain Size SizeBytes");
	};

	template<const Storage TYPE>
	struct R{
		enum : GLuint{
			ElementCount = 1,
			FormatEnum = GL_RED,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) >= FormatSizeBytes, "ObjectGL::R FormatType is not large enough to contain FormatSize");
	};

	template<const Storage TYPE>
	struct RG{
		enum : GLuint{
			ElementCount = 2,
			FormatEnum = GL_RG,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) >= FormatSizeBytes, "ObjectGL::RG FormatType is not large enough to contain FormatSize");
	};

	template<const Storage TYPE>
	struct RGB{
		enum : GLuint{
			ElementCount = 3,
			FormatEnum = GL_RGB,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) >= FormatSizeBytes, "ObjectGL::RGB FormatType is not large enough to contain FormatSize");
	};

	template<const Storage TYPE>
	struct RGBA{
		enum : GLuint{
			ElementCount = 4,
			FormatEnum = GL_RGBA,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) * 8 >= FormatSizeBytes, "ObjectGL::RGBA FormatType is not large enough to contain FormatSize");
	};
}}

#endif
<commit_msg>Format Read / Write fix<commit_after>#ifndef OBJECT_GL_COLOUR_FORMAT_HPP
#define OBJECT_GL_COLOUR_FORMAT_HPP

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

// Contact :
// Email             : $objectgl_email
// GitHub repository : $objectgl_git

/*!
	\file ColourFormat.hpp
	\brief
	\author Adam Smith
	\date 6th November 2015
*/

#include <cstdint>
#include "ObjectGLInit.inl"
#include "BinaryData.hpp"

namespace ObjectGL { namespace ColourFormat{

	namespace Implementation{

		template<const GLuint BITS>
		static void CopyBits(const void* aSrc, const GLuint aSrcOffset, void* aDst, const GLuint aDstOffset){

			const bool byteAligned = ! ((BITS & 7) || (aSrcOffset & 7) || (aDstOffset & 7));

			if(byteAligned){
				std::memcpy(
					static_cast<const uint8_t*>(aSrc) + (aSrcOffset / 8),
					static_cast<uint8_t*>(aDst) + (aDstOffset / 8),
					BITS / 8
				);
			}else{
				//! \todo Optimise
				const uint8_t* const src = static_cast<const uint8_t*>(aSrc);
				uint8_t* const dst = static_cast<uint8_t*>(aDst);

				GLuint srcOffset = aSrcOffset;
				GLuint dstOffset = aDstOffset;
				for(GLuint i = 0; i != BITS; ++i){
					const uint8_t srcByte = src[srcOffset / 8];
					uint8_t& dstByte = dst[dstOffset / 8];

					const uint8_t srcMask = 1 << (aSrcOffset & 7);
					const uint8_t dstMask = 1 << (dstOffset & 7);

					uint8_t bit = srcByte & srcMask;

					dstByte &= ~dstMask;
					if(bit) dstByte |= dstMask;

					++srcOffset;
					++dstOffset;
				}
			}
		}
	}

	template<class Format>
	static typename Format::FormatType Read(const void* const aData, const GLuint aOffset){
		typename Format::FormatType tmp = 0;
		return Implementation::CopyBits<Format::FormatSizeBits>(aData, aOffset * Format::FormatSizeBits, &tmp, 0);
		return tmp;
	}

	template<class Format>
	static void Write(void* const aData, const GLuint aOffset, const typename Format::FormatType aValue){
		return Implementation::CopyBits<Format::FormatSizeBits>(&aValue, 0, aData, aOffset * Format::FormatSizeBits);
	}

	enum class Storage : GLenum{
		NONE				= GL_NONE,
		UNSIGNED_NORMALISED	= GL_UNSIGNED_NORMALIZED,
		SIGNED_NORMALISED	= GL_SIGNED_NORMALIZED,
		UNSIGNED_INTEGRAL	= GL_UNSIGNED_INT,
		SIGNED_INTEGRAL		= GL_INT,
		FLOAT				= GL_FLOAT
	};

	template<const Storage TYPE>
	struct StorageType{
		typedef void Type;
		enum : GLuint{
			SizeBytes = 0,
			SizeBits = 0
		};
	};

	template<>
	struct StorageType<Storage::NONE>{
		typedef void Type;
		enum : GLuint{
			SizeBytes = 0,
			SizeBits = 0
		};
	};

	template<>
	struct StorageType<Storage::UNSIGNED_NORMALISED>{
		typedef uint8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_NORMALISED> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_NORMALISED> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::SIGNED_NORMALISED>{
		typedef int8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<SIGNED_NORMALISED> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<SIGNED_NORMALISED> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::UNSIGNED_INTEGRAL>{
		typedef uint8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_INTEGRAL> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<UNSIGNED_INTEGRAL> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::SIGNED_INTEGRAL>{
		typedef uint8_t Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<SIGNED_INTEGRAL> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<SIGNED_INTEGRAL> Type is not large enough to contain Size SizeBytes");
	};

	template<>
	struct StorageType<Storage::FLOAT>{
		typedef float Type;
		enum : GLuint{
			SizeBytes = sizeof(Type),
			SizeBits = SizeBytes * 8
		};

		static_assert(SizeBytes * 8 >= SizeBytes, "ObjectGL::StorageType<FLOAT> SizeBits is larger than SizeBytes");
		static_assert(sizeof(Type) >= SizeBytes, "ObjectGL::StorageType<FLOAT> Type is not large enough to contain Size SizeBytes");
	};

	template<const Storage TYPE>
	struct R{
		enum : GLuint{
			ElementCount = 1,
			FormatEnum = GL_RED,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) >= FormatSizeBytes, "ObjectGL::R FormatType is not large enough to contain FormatSize");
	};

	template<const Storage TYPE>
	struct RG{
		enum : GLuint{
			ElementCount = 2,
			FormatEnum = GL_RG,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) >= FormatSizeBytes, "ObjectGL::RG FormatType is not large enough to contain FormatSize");
	};

	template<const Storage TYPE>
	struct RGB{
		enum : GLuint{
			ElementCount = 3,
			FormatEnum = GL_RGB,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) >= FormatSizeBytes, "ObjectGL::RGB FormatType is not large enough to contain FormatSize");
	};

	template<const Storage TYPE>
	struct RGBA{
		enum : GLuint{
			ElementCount = 4,
			FormatEnum = GL_RGBA,
			ElementSizeBits = StorageType<TYPE>::SizeBits,
			ElementSizeBytes = StorageType<TYPE>::SizeBytes,
			FormatSizeBits = ElementSizeBits * ElementCount,
			FormatSizeBytes = ElementSizeBytes * ElementCount,
			ElementEnum = static_cast<GLuint>(TYPE)
		};

		typedef BinaryData<FormatSizeBytes> FormatType;
		typedef typename StorageType<TYPE>::Type ElementType;

		static_assert(sizeof(FormatType) * 8 >= FormatSizeBytes, "ObjectGL::RGBA FormatType is not large enough to contain FormatSize");
	};
}}

#endif
<|endoftext|>


<commit_before>//
//  Executor.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 29/04/2022.
//  Copyright © 2022 Thomas Harte. All rights reserved.
//

#include "Executor.hpp"

using namespace InstructionSet::M68k;

template <Model model, typename BusHandler>
Executor<model, BusHandler>::Executor(BusHandler &handler) : bus_handler_(handler) {
	reset();
}

template <Model model, typename BusHandler>
void Executor<model, BusHandler>::reset() {

}

template <Model model, typename BusHandler>
void Executor<model, BusHandler>::run_for_instructions(int count) {
	while(count--) {
		// TODO: check interrupt level, trace flag.

		// Read the next instruction.
		const Preinstruction instruction = decoder_.decode(bus_handler_.template read<uint16_t>(program_counter_.l));
		const auto instruction_address = program_counter_.l;
		program_counter_.l += 2;

		// Obtain the appropriate sequence.
		Sequence<model> sequence(instruction.operation);

		// Perform it.
		while(!sequence.empty()) {
			const auto step = sequence.pop_front();
		}
	}
}
<commit_msg>Figure out what the call to `perform` should look like.<commit_after>//
//  Executor.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 29/04/2022.
//  Copyright © 2022 Thomas Harte. All rights reserved.
//

#include "Executor.hpp"

#include "Perform.hpp"

#include <cassert>

using namespace InstructionSet::M68k;

template <Model model, typename BusHandler>
Executor<model, BusHandler>::Executor(BusHandler &handler) : bus_handler_(handler) {
	reset();
}

template <Model model, typename BusHandler>
void Executor<model, BusHandler>::reset() {
	// TODO.
}

template <Model model, typename BusHandler>
void Executor<model, BusHandler>::run_for_instructions(int count) {
	while(count--) {
		// TODO: check interrupt level, trace flag.

		// Read the next instruction.
		const Preinstruction instruction = decoder_.decode(bus_handler_.template read<uint16_t>(program_counter_.l));
		const auto instruction_address = program_counter_.l;
		program_counter_.l += 2;

		// Obtain the appropriate sequence.
		Sequence<model> sequence(instruction.operation);

		// Temporary storage.
		CPU::SlicedInt32 source, dest;

		// Perform it.
		while(!sequence.empty()) {
			const auto step = sequence.pop_front();

			switch(step) {
				default: assert(false);	// i.e. TODO

				case Step::Perform:
					perform<model>(instruction, source, dest, status_, this);
				break;
			}
		}
	}
}
<|endoftext|>


<commit_before>/*
   Name: drs4analysis
   Based on read_binary.cpp by Stefan Ritt <stefan.ritt@psi.ch>

   Purpose:      analyse data saved by drs4daq

   The present version only plots the oscillograms from all 4 channels
   in a pdf file.
*/

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

#include "TGraph.h"
#include "TH1F.h"
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TStyle.h"
#include "TString.h"

#include "WaveProcessor.h"
#include "DRS4_data.h"

typedef struct {
   char           tag[3];
   char           version;
} FHEADER;

typedef struct {
   char           time_header[4];
} THEADER;

typedef struct {
   char           bn[2];
   unsigned short board_serial_number;
} BHEADER;

typedef struct {
   char           event_header[4];
   unsigned int   event_serial_number;
   unsigned short year;
   unsigned short month;
   unsigned short day;
   unsigned short hour;
   unsigned short minute;
   unsigned short second;
   unsigned short millisecond;
   unsigned short range;
} EHEADER;

typedef struct {
   char           tc[2];
   unsigned short trigger_cell;
} TCHEADER;

typedef struct {
   char           c[1];
   char           cn[3];
} CHEADER;

/*-----------------------------------------------------------------------------*/

int main(int argc, const char * argv[])
{
   FHEADER  fh;
   THEADER  th;
   BHEADER  bh;
   EHEADER  eh;
   TCHEADER tch;
   CHEADER  ch;

   unsigned int scaler;
   int16_t voltage[4][1024];
   float waveform[16][4][1024], time[16][4][1024];
   float bin_width[16][4][1024];
   int i, j, b, chn, iEvt, n_boards;
   int chn_index[4];
   double t1, t2, dt;
   char filename[256];

   int ndt;
   double threshold, sumdt, sumdt2;

   if (argc > 1)
      strcpy(filename, argv[1]);
   else {
      printf("Usage: drs4analysis <filename>\n");
      return 0;
   }

   // open the binary waveform file
   FILE *f = fopen(filename, "rb");
   if (f == NULL) {
      printf("Cannot find file \'%s\'\n", filename);
      return 0;
   }

   // read file header
   fread(&fh, sizeof(fh), 1, f);
   if (fh.tag[0] != 'D' || fh.tag[1] != 'R' || fh.tag[2] != 'S') {
      printf("Found invalid file header in file \'%s\', aborting.\n", filename);
      return 0;
   }

   if (fh.version != '2' && fh.version != '4') {
      printf("Found invalid file version \'%c\' in file \'%s\', should be \'2\', aborting.\n", fh.version, filename);
      return 0;
   }

   // read time header
   fread(&th, sizeof(th), 1, f);
   if (memcmp(th.time_header, "TIME", 4) != 0) {
      printf("Invalid time header in file \'%s\', aborting.\n", filename);
      return 0;
   }

   for (b = 0 ; ; b++) {
      // read board header
      fread(&bh, sizeof(bh), 1, f);
      if (memcmp(bh.bn, "B#", 2) != 0) {
         // probably event header found
         fseek(f, -4, SEEK_CUR);
         break;
      }

      printf("Found data for board #%d\n", bh.board_serial_number);

      // read time bin widths
      memset(bin_width[b], sizeof(bin_width[0]), 0);
      for (chn=0 ; chn<5 ; chn++) {
         fread(&ch, sizeof(ch), 1, f);
         if (ch.c[0] != 'C') {
            // event header found
            fseek(f, -4, SEEK_CUR);
            break;
         }
         i = ch.cn[2] - '0' - 1;
         printf("Found timing calibration for channel #%d\n", i+1);
         fread(&bin_width[b][i][0], sizeof(float), 1024, f);
         // fix for 2048 bin mode: double channel
         if (bin_width[b][i][1023] > 10 || bin_width[b][i][1023] < 0.01) {
            for (j=0 ; j<512 ; j++)
               bin_width[b][i][j+512] = bin_width[b][i][j];
         }
      }
   }
   n_boards = b;

   // initialize statistics
   ndt = 0;
   sumdt = sumdt2 = 0;

   /*** Prepare oscillogram plots ***/
   TCanvas c("can", "cancan", 800, 600);
   gStyle->SetPaperSize(18, 12);
   gStyle->SetLabelSize(0.06, "XY");
   gStyle->SetTitleSize(0.06, "XY");
   gStyle->SetPadLeftMargin(0.12);
   gStyle->SetPadBottomMargin(0.12);
   c.Divide(2, 2, .01, .01);
   c.GetPad(1)->SetGrid(1, 0);
   c.GetPad(2)->SetGrid(1, 0);
   c.GetPad(3)->SetGrid(1, 0);
   c.GetPad(4)->SetGrid(1, 0);
   TH1F frame("frame", "frame; t (ns); A (mV)", 10, 0., 200);
   frame.SetMinimum(-500);
   frame.SetMaximum(50);
   frame.SetLineColor(kGray);
   frame.SetStats(false);
   TString pdfname(filename);
   if (pdfname.EndsWith(".dat")) pdfname.Resize(pdfname.Sizeof() - 5);
   pdfname += ".pdf";
   bool firstpage = true, lastpage = false;

   /*** Prepare tree ***/

   TString rfname(filename);
   if (rfname.EndsWith(".dat")) rfname.Resize(pdfname.Sizeof() - 5);
   rfname += ".root";
   TFile file(rfname, "RECREATE");

   unsigned nCh = 4;
   DRS4_data::Observables obs[nCh];
   TTree events("events", "events");

   for (unsigned iCh=0; iCh<nCh; iCh++) {

     for (unsigned iObs=0; iObs<DRS4_data::nObservables; iObs++) {
       const char *varname = Form("%s_S%d", obs[iCh].Name(DRS4_data::kObservables(iObs)), iCh+1);
       events.Branch(varname, &obs[iCh].Value(DRS4_data::kObservables(iObs)), varname);
     }
   }

   /*** Prepare average waveforms ***/

   TH1F *havg[4];
   for (int ich=0; ich<4; ich++) {
     havg[ich] = new TH1F(Form("havg_S%d", ich+1), "Average waveform; t (ns); A (mV)", 1000, 0., 200.);
   }

   // loop over all events in the data file
   for (iEvt=0 ; iEvt<100000; iEvt++) {
      // read event header
      i = (int)fread(&eh, sizeof(eh), 1, f);
      if (i < 1)
         break;

      if (iEvt%100 == 0) {
        printf("Found event #%d at %d s %d ms\n", eh.event_serial_number, eh.second, eh.millisecond);
      }

      // loop over all boards in data file
      for (b=0 ; b<n_boards ; b++) {

         // read board header
         fread(&bh, sizeof(bh), 1, f);
         if (memcmp(bh.bn, "B#", 2) != 0) {
            printf("Invalid board header in file \'%s\', aborting.\n", filename);
            return 0;
         }

         // read trigger cell
         fread(&tch, sizeof(tch), 1, f);
         if (memcmp(tch.tc, "T#", 2) != 0) {
            printf("Invalid trigger cell header in file \'%s\', aborting.\n", filename);
            return 0;
         }

         if (n_boards > 1)
            printf("Found data for board #%d\n", bh.board_serial_number);

         for (chn=0 ; chn<4 ; chn++) {
           chn_index[chn] = 0;
         }

         // read channel data
         for (chn=0 ; chn<4 ; chn++) {

            // read channel header
            fread(&ch, sizeof(ch), 1, f);
            if (ch.c[0] != 'C') {
               // event header found
               fseek(f, -4, SEEK_CUR);
               break;
            }
            chn_index[chn] = ch.cn[2] - '0' - 1;
            fread(&scaler, sizeof(int), 1, f);
            fread(voltage[chn], sizeof(short), 1024, f);
         }

         // Remove spikes
         // Wrote own function because trigger cell is not always well written in file
        // DRS4_data::RemoveSpikes(voltage, 20, 2);

         for (chn=0 ; chn<4 ; chn++) {

           int chidx = chn_index[chn];

            for (i=0 ; i<1024 ; i++) {

               float t = 0;
               for (j=0,time[b][(chidx)][i]=0 ; j<i ; j++)
                  t += bin_width[b][chidx][(j+tch.trigger_cell) % 1024];

               time[b][chidx][i] = t;

               // Voltage data is encoded in units of 0.1 mV
               float v = static_cast<float>(voltage[chn][i]) / 10;
               waveform[b][chidx][i] = v;

            }

            float blw = 30.;
            if (chidx < 2) blw = 38;
            DRS4_data::Observables *tmpObs = WaveProcessor::ProcessOnline(time[b][chidx], waveform[b][chidx], 1024, 5., blw);

            obs[chn] = *tmpObs;

            delete tmpObs; tmpObs = NULL;

         } // Loop over channels

         events.Fill();

         float tref = (obs[2].Value(DRS4_data::arrivalTime) + obs[3].Value(DRS4_data::arrivalTime)) / 2;

         for (unsigned ichan=0 ; ichan<4 ; ichan++) {
            // Selection of amplitudes of at least 10 MIP in S1, S2
            if (ichan==0 && obs[ichan].Value(DRS4_data::maxVal) > 18) continue;
            if (ichan==1 && obs[ichan].Value(DRS4_data::maxVal) > 16) continue;
            for (unsigned ibin=0 ; ibin<1024 ; ibin++) {
              float t = time[b][ichan][ibin] - tref + 30.;
              float v = waveform[b][ichan][ibin] + obs[ichan].Value(DRS4_data::baseLine);
              havg[ichan]->Fill(t, v);
            }
         }

//         if (iEvt < 20) {
         if (   obs[0].Value(DRS4_data::baseLineRMS) > 1
             || obs[1].Value(DRS4_data::baseLineRMS) > 1
             || obs[2].Value(DRS4_data::baseLineRMS) > 1
             || obs[3].Value(DRS4_data::baseLineRMS) > 1 )
      /*   if (   obs[0].Value(DRS4_data::arrivalTime) < 42.
             || obs[0].Value(DRS4_data::arrivalTime) > 52.
             || obs[1].Value(DRS4_data::arrivalTime) < 41.
             || obs[1].Value(DRS4_data::arrivalTime) > 51. )*/
         {

           for (unsigned ichan=0; ichan<4; ichan++) {
             TGraph *gr = new TGraph(1024, time[b][ichan], waveform[b][ichan]);

             if (gr->IsZombie()) {
               printf("Zombie.\n");
               exit(0);
             }
             c.cd(ichan+1);
             frame.SetTitle(Form("Ch. %d, baseline RMS %.1f, evt. %d", ichan+1, obs[ichan].Value(DRS4_data::baseLineRMS), iEvt));
             frame.DrawCopy();
             gr->SetLineColor(kRed);
             gr->SetLineWidth(1);
             gr->Draw("l");
           }

           if (firstpage) {
             c.Print(TString(pdfname + "(").Data());
             firstpage = false;
           }
           else {
             c.Print(pdfname.Data());
             }
         } // if  printing pdf

      } // Loop over the boards
   } // Loop over events

   c.Print(TString(pdfname + ")").Data());
   file.Write();
   file.Close();

   return 1;
}

<commit_msg>Subtraction of common baseline drift in drs4analysis. Option to switch spike removal on and off.<commit_after>/*
   Name: drs4analysis
   Based on read_binary.cpp by Stefan Ritt <stefan.ritt@psi.ch>

   Purpose:      analyse data saved by drs4daq

   The present version only plots the oscillograms from all 4 channels
   in a pdf file.
*/

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <math.h>

#include "TGraph.h"
#include "TH1F.h"
#include "TFile.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TStyle.h"
#include "TString.h"

#include "WaveProcessor.h"
#include "DRS4_data.h"

typedef struct {
   char           tag[3];
   char           version;
} FHEADER;

typedef struct {
   char           time_header[4];
} THEADER;

typedef struct {
   char           bn[2];
   unsigned short board_serial_number;
} BHEADER;

typedef struct {
   char           event_header[4];
   unsigned int   event_serial_number;
   unsigned short year;
   unsigned short month;
   unsigned short day;
   unsigned short hour;
   unsigned short minute;
   unsigned short second;
   unsigned short millisecond;
   unsigned short range;
} EHEADER;

typedef struct {
   char           tc[2];
   unsigned short trigger_cell;
} TCHEADER;

typedef struct {
   char           c[1];
   char           cn[3];
} CHEADER;

/*-----------------------------------------------------------------------------*/

int main(int argc, const char * argv[])
{
   FHEADER  fh;
   THEADER  th;
   BHEADER  bh;
   EHEADER  eh;
   TCHEADER tch;
   CHEADER  ch;

   unsigned int scaler;
   int16_t voltage[4][1024];
   float waveform[16][4][1024], time[16][4][1024];
   float bin_width[16][4][1024];
   int i, j, b, chn, iEvt, n_boards;
   int chn_index[4];
   double t1, t2, dt;
   TString infilename, cmfilename;

   int ndt;
   double threshold, sumdt, sumdt2;

   if (argc > 1)  infilename = argv[1];
   else {
      printf("Usage: drs4analysis <filename> <remove spikes (1|0)> [<common mode file name>]\n");
      return 0;
   }
   bool removeSpikes = false;
   if (argc > 2) removeSpikes = atoi(argv[2]);
   if (argc > 3) cmfilename = argv[3];
   else cmfilename = "BaseLine_CommonMode.root";

   // open the binary waveform file
   FILE *f = fopen(infilename.Data(), "rb");
   if (f == NULL) {
      printf("Cannot find file \'%s\'\n", infilename.Data());
      return 0;
   }

   // read file header
   fread(&fh, sizeof(fh), 1, f);
   if (fh.tag[0] != 'D' || fh.tag[1] != 'R' || fh.tag[2] != 'S') {
      printf("Found invalid file header in file \'%s\', aborting.\n", infilename.Data());
      return 0;
   }

   if (fh.version != '2' && fh.version != '4') {
      printf("Found invalid file version \'%c\' in file \'%s\', should be \'2\' or \'4\', aborting.\n",
          fh.version, infilename.Data());
      return 0;
   }

   // read time header
   fread(&th, sizeof(th), 1, f);
   if (memcmp(th.time_header, "TIME", 4) != 0) {
      printf("Invalid time header in file \'%s\', aborting.\n", infilename.Data());
      return 0;
   }

   for (b = 0 ; ; b++) {
      // read board header
      fread(&bh, sizeof(bh), 1, f);
      if (memcmp(bh.bn, "B#", 2) != 0) {
         // probably event header found
         fseek(f, -4, SEEK_CUR);
         break;
      }

      printf("Found data for board #%d\n", bh.board_serial_number);

      // read time bin widths
      memset(bin_width[b], sizeof(bin_width[0]), 0);
      for (chn=0 ; chn<5 ; chn++) {
         fread(&ch, sizeof(ch), 1, f);
         if (ch.c[0] != 'C') {
            // event header found
            fseek(f, -4, SEEK_CUR);
            break;
         }
         i = ch.cn[2] - '0' - 1;
         printf("Found timing calibration for channel #%d\n", i+1);
         fread(&bin_width[b][i][0], sizeof(float), 1024, f);
         // fix for 2048 bin mode: double channel
         if (bin_width[b][i][1023] > 10 || bin_width[b][i][1023] < 0.01) {
            for (j=0 ; j<512 ; j++)
               bin_width[b][i][j+512] = bin_width[b][i][j];
         }
      }
   }
   n_boards = b;

   // initialize statistics
   ndt = 0;
   sumdt = sumdt2 = 0;

   /*** Prepare oscillogram plots ***/
   TCanvas c("can", "cancan", 800, 600);
   gStyle->SetPaperSize(18, 12);
   gStyle->SetLabelSize(0.06, "XY");
   gStyle->SetTitleSize(0.06, "XY");
   gStyle->SetPadLeftMargin(0.12);
   gStyle->SetPadBottomMargin(0.12);
   c.Divide(2, 2, .01, .01);
   c.GetPad(1)->SetGrid(1, 0);
   c.GetPad(2)->SetGrid(1, 0);
   c.GetPad(3)->SetGrid(1, 0);
   c.GetPad(4)->SetGrid(1, 0);
   TH1F frame("frame", "frame; t (ns); A (mV)", 10, 0., 200);
   frame.SetMinimum(-500);
   frame.SetMaximum(50);
   frame.SetLineColor(kGray);
   frame.SetStats(false);
   TString pdfname(infilename);
   if (pdfname.EndsWith(".dat")) pdfname.Resize(pdfname.Sizeof() - 5);
   pdfname += ".pdf";
   bool firstpage = true, lastpage = false;

   /*** Prepare average waveforms ***/

   TFile cmHistos(cmfilename.Data());
   if (!cmHistos.IsOpen()) {
     std::cout << "Error: Cannot open file " << cmfilename.Data() << ".\n";
     return -1;
   }
   TH1F *hcm[2] = { NULL, NULL};
   cmHistos.GetObject("havg_S1", hcm[0]);
   hcm[0]->SetName("commonModeCH1");
   cmHistos.GetObject("havg_S2", hcm[1]);
   hcm[1]->SetName("commonModeCH2");
   if (!hcm[0] || !hcm[1]) {
     std::cout << "Error: Cannot read common mode histograms \'havg_S1\' and \'havg_S2\' from file "
         << cmfilename.Data() << ".\n";
     return -2;
   }

   /*** Prepare tree and output histos ***/

   TString rfname(infilename);
   if (rfname.EndsWith(".dat")) rfname.Resize(pdfname.Sizeof() - 5);
   rfname += ".root";
   TFile file(rfname, "RECREATE");

   TH1F *havg[4];
   for (int ich=0; ich<4; ich++) {
     havg[ich] = new TH1F(Form("havg_S%d", ich+1), "Average waveform; t (ns); A (mV)", 1000, 0., 200.);
   }

   unsigned nCh = 4;
   DRS4_data::Observables obs[nCh];
   TTree events("events", "events");

   for (unsigned iCh=0; iCh<nCh; iCh++) {

     for (unsigned iObs=0; iObs<DRS4_data::nObservables; iObs++) {
       const char *varname = Form("%s_S%d", obs[iCh].Name(DRS4_data::kObservables(iObs)), iCh+1);
       events.Branch(varname, &obs[iCh].Value(DRS4_data::kObservables(iObs)), varname);
     }
   }

   // loop over all events in the data file
   for (iEvt=0 ; iEvt<100000; iEvt++) {
      // read event header
      i = (int)fread(&eh, sizeof(eh), 1, f);
      if (i < 1)
         break;

      if (iEvt%100 == 0) {
        printf("Found event #%d at %d s %d ms\n", eh.event_serial_number, eh.second, eh.millisecond);
      }

      // loop over all boards in data file
      for (b=0 ; b<n_boards ; b++) {

         // read board header
         fread(&bh, sizeof(bh), 1, f);
         if (memcmp(bh.bn, "B#", 2) != 0) {
            printf("Invalid board header in file \'%s\', aborting.\n", infilename.Data());
            return 0;
         }

         // read trigger cell
         fread(&tch, sizeof(tch), 1, f);
         if (memcmp(tch.tc, "T#", 2) != 0) {
            printf("Invalid trigger cell header in file \'%s\', aborting.\n", infilename.Data());
            return 0;
         }

         if (n_boards > 1)
            printf("Found data for board #%d\n", bh.board_serial_number);

         for (chn=0 ; chn<4 ; chn++) {
           chn_index[chn] = 0;
         }

         // read channel data
         for (chn=0 ; chn<4 ; chn++) {

            // read channel header
            fread(&ch, sizeof(ch), 1, f);
            if (ch.c[0] != 'C') {
               // event header found
               fseek(f, -4, SEEK_CUR);
               break;
            }
            chn_index[chn] = ch.cn[2] - '0' - 1;
            fread(&scaler, sizeof(int), 1, f);
            fread(voltage[chn], sizeof(short), 1024, f);
         }

         // Remove spikes
         // Wrote own function because trigger cell is not always well written in file
         if (removeSpikes) DRS4_data::RemoveSpikes(voltage, 20, 2);

         for (chn=0 ; chn<4 ; chn++) {

           int chidx = chn_index[chn];

            for (i=0 ; i<1024 ; i++) {

               float t = 0;
               for (j=0,time[b][(chidx)][i]=0 ; j<i ; j++)
                  t += bin_width[b][chidx][(j+tch.trigger_cell) % 1024];

               time[b][chidx][i] = t;

               // Voltage data is encoded in units of 0.1 mV
               float v = static_cast<float>(voltage[chn][i]) / 10;
               waveform[b][chidx][i] = v;

            }

            float blw = 30.;
            if (chidx < 2) blw = 38;
            DRS4_data::Observables *tmpObs = WaveProcessor::ProcessOnline(time[b][chidx], waveform[b][chidx], 1024, 5., blw);

            obs[chn] = *tmpObs;

            delete tmpObs; tmpObs = NULL;

         } // Loop over channels

         events.Fill();

         float tref = (obs[2].Value(DRS4_data::arrivalTime) + obs[3].Value(DRS4_data::arrivalTime)) / 2;

         for (unsigned ichan=0 ; ichan<4 ; ichan++) {
            // Selection of amplitudes of at least 10 MIP in S1, S2
            if (ichan==0 && obs[ichan].Value(DRS4_data::maxVal) > 18) continue;
            if (ichan==1 && obs[ichan].Value(DRS4_data::maxVal) > 16) continue;
            for (unsigned ibin=0 ; ibin<1024 ; ibin++) {
              float t = time[b][ichan][ibin] - tref + 30.;
              float v = waveform[b][ichan][ibin] + obs[ichan].Value(DRS4_data::baseLine);
              havg[ichan]->Fill(t, v);
            }
         }

//         if (iEvt < 20) {
         if (   obs[0].Value(DRS4_data::baseLineRMS) > 1
             || obs[1].Value(DRS4_data::baseLineRMS) > 1
             || obs[2].Value(DRS4_data::baseLineRMS) > 1
             || obs[3].Value(DRS4_data::baseLineRMS) > 1 )
      /*   if (   obs[0].Value(DRS4_data::arrivalTime) < 42.
             || obs[0].Value(DRS4_data::arrivalTime) > 52.
             || obs[1].Value(DRS4_data::arrivalTime) < 41.
             || obs[1].Value(DRS4_data::arrivalTime) > 51. )*/
         {

           for (unsigned ichan=0; ichan<4; ichan++) {
             TGraph *gr = new TGraph(1024, time[b][ichan], waveform[b][ichan]);

             if (gr->IsZombie()) {
               printf("Zombie.\n");
               exit(0);
             }
             c.cd(ichan+1);
             frame.SetTitle(Form("Ch. %d, baseline RMS %.1f, evt. %d", ichan+1, obs[ichan].Value(DRS4_data::baseLineRMS), iEvt));
             frame.DrawCopy();
             gr->SetLineColor(kRed);
             gr->SetLineWidth(1);
             gr->Draw("l");
           }

           if (firstpage) {
             c.Print(TString(pdfname + "(").Data());
             firstpage = false;
           }
           else {
             c.Print(pdfname.Data());
             }
         } // if  printing pdf

      } // Loop over the boards
   } // Loop over events

   std::cout << "Counted " << iEvt << " events. Event tree has " << events.GetEntries() << " entries.\n";

   c.Print(TString(pdfname + ")").Data());
   for (int ich=0; ich<4; ich++) {
     havg[ich]->Scale(1./iEvt);
     if (ich<2) {
       havg[ich]->Add(hcm[ich], -1.);
     }
   }
   file.Write();
   file.Close();

   cmHistos.Close();

   return 1;
}

<|endoftext|>


<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_TEST_PROLONGATIONS_L2_HH
#define DUNE_GDT_TEST_PROLONGATIONS_L2_HH

#include <dune/common/unused.hh>

#include <dune/gdt/prolongations/l2.hh>

#include "base.hh"

namespace Dune {
namespace GDT {
namespace Test {

template <class SpaceType>
struct L2ProlongationLocalizableOperatorTest
    : public LocalizableProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationLocalizableOperator>
{
  typedef LocalizableProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationLocalizableOperator> BaseType;
  using typename BaseType::ProlongationOperatorType;

  void constructible_by_ctor(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    ProlongationOperatorType DUNE_UNUSED(w_over_integrate)(0, grid_view, source, range);
    ProlongationOperatorType DUNE_UNUSED(wo_over_integrate)(grid_view, source, range);
  } // ... constructible_by_ctor(...)

  void constructible_by_factory(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    auto DUNE_UNUSED(w_gv_w_oi) = make_global_l2_prolongation_localizable_operator(grid_view, source, range, 1);
    auto DUNE_UNUSED(w_gv_wo_oi) = make_global_l2_prolongation_localizable_operator(grid_view, source, range);
    auto DUNE_UNUSED(wo_gv_w_oi) = make_global_l2_prolongation_localizable_operator(source, range, 1);
    auto DUNE_UNUSED(wo_gv_wo_oi) = make_global_l2_prolongation_localizable_operator(source, range);
  } // ... constructible_by_factory(...)
};

template <class SpaceType>
struct L2ProlongationOperatorTest : public ProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationOperator>
{
  typedef ProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationOperator> BaseType;
  using typename BaseType::ProlongationOperatorType;

  void constructible_by_ctor(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    ProlongationOperatorType DUNE_UNUSED(w_over_integrate)(0, grid_view);
    ProlongationOperatorType DUNE_UNUSED(wo_over_integrate)(grid_view);
  } // ... constructible_by_ctor(...)

  void constructible_by_factory(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view = this->fine_space_.grid_view();

    auto DUNE_UNUSED(w_over_integrate) = make_l2_prolongation_operator(grid_view, 1);
    auto DUNE_UNUSED(wo_over_integrate) = make_l2_prolongation_operator(grid_view);
  } // ... constructible_by_factory(...)

  void free_function_callable(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    prolong_l2(grid_view, source, range);
    prolong_l2(source, range);
  } // ... free_function_callable(...)
};

} // namespace Test
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_TEST_PROLONGATIONS_L2_HH
<commit_msg>[test.prolongations.l2] add more signatures of prolong_l2<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_TEST_PROLONGATIONS_L2_HH
#define DUNE_GDT_TEST_PROLONGATIONS_L2_HH

#include <dune/common/unused.hh>

#include <dune/gdt/prolongations/l2.hh>

#include "base.hh"

namespace Dune {
namespace GDT {
namespace Test {

template <class SpaceType>
struct L2ProlongationLocalizableOperatorTest
    : public LocalizableProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationLocalizableOperator>
{
  typedef LocalizableProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationLocalizableOperator> BaseType;
  using typename BaseType::ProlongationOperatorType;

  void constructible_by_ctor(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    ProlongationOperatorType DUNE_UNUSED(w_over_integrate)(0, grid_view, source, range);
    ProlongationOperatorType DUNE_UNUSED(wo_over_integrate)(grid_view, source, range);
  } // ... constructible_by_ctor(...)

  void constructible_by_factory(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    auto DUNE_UNUSED(w_gv_w_oi) = make_global_l2_prolongation_localizable_operator(grid_view, source, range, 1);
    auto DUNE_UNUSED(w_gv_wo_oi) = make_global_l2_prolongation_localizable_operator(grid_view, source, range);
    auto DUNE_UNUSED(wo_gv_w_oi) = make_global_l2_prolongation_localizable_operator(source, range, 1);
    auto DUNE_UNUSED(wo_gv_wo_oi) = make_global_l2_prolongation_localizable_operator(source, range);
  } // ... constructible_by_factory(...)
};

template <class SpaceType>
struct L2ProlongationOperatorTest : public ProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationOperator>
{
  typedef ProlongationOperatorBase<SpaceType, SpaceType, L2ProlongationOperator> BaseType;
  using typename BaseType::ProlongationOperatorType;

  void constructible_by_ctor(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    ProlongationOperatorType DUNE_UNUSED(w_over_integrate)(0, grid_view);
    ProlongationOperatorType DUNE_UNUSED(wo_over_integrate)(grid_view);
  } // ... constructible_by_ctor(...)

  void constructible_by_factory(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view = this->fine_space_.grid_view();

    auto DUNE_UNUSED(w_over_integrate) = make_l2_prolongation_operator(grid_view, 1);
    auto DUNE_UNUSED(wo_over_integrate) = make_l2_prolongation_operator(grid_view);
  } // ... constructible_by_factory(...)

  void free_function_callable(const double tolerance = 1e-15)
  {
    this->prepare(tolerance);

    auto grid_view     = this->fine_space_.grid_view();
    const auto& source = this->coarse_discrete_function_;
    auto& range        = this->fine_discrete_function_;

    prolong_l2(grid_view, source, range, 1);
    prolong_l2(grid_view, source, range);
    prolong_l2(source, range, 1);
    prolong_l2(source, range);
  } // ... free_function_callable(...)
};

} // namespace Test
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_TEST_PROLONGATIONS_L2_HH
<|endoftext|>


<commit_before><commit_msg>Control: fixed a bug in control.<commit_after><|endoftext|>


<commit_before>#include <MutilaDebug.h>
#include <stdint.h>
#include "SmallTextMode.h"
#include "Matrix.h"

SmallTextMode_ SmallTextMode;

void SmallTextMode_::start(const char* data)
{
    DB(F("SmallTextMode::start "));
    DBLN(data);
    String line[3];
    uint8_t lineCount = 1;
    for (uint8_t i=0; i<strlen(data); i++) {
        DB("in: ");
        DB(data[i]);
        DB(" (int)");
        DBLN((int)data[i]);
        if (data[i] == '\r' && lineCount<3) {
            DBLN("newline");
            lineCount++;
            continue;
        }
        DB("append:");
        DB(data[i]);
        DB(" (int)");
        DBLN((int)data[i]);
        line[lineCount-1] += data[i];
    }
    DB("lines=");
    DBLN(lineCount);
    for (uint8_t i=0; i<lineCount; i++) {
        DB(i);
        DB('=');
        DBLN(line[i]);
    }

    uint8_t y;
    if (lineCount == 1) y = 18;
    else if (lineCount == 2) y = 14;
    else y = 10;

    Matrix.clear();
    Matrix.setFont(2);
    for (uint8_t i=0; i<lineCount; i++) {
        Matrix.text(MATRIX_ORANGE, 1, y, line[i]);
        y += 8;
    }
    Matrix.paint();
}

<commit_msg>add alternative newline characters<commit_after>#include <MutilaDebug.h>
#include <stdint.h>
#include "SmallTextMode.h"
#include "Matrix.h"

SmallTextMode_ SmallTextMode;

void SmallTextMode_::start(const char* data)
{
    DB(F("SmallTextMode::start "));
    DBLN(data);
    String line[3];
    uint8_t lineCount = 1;
    for (uint8_t i=0; i<strlen(data); i++) {
        DB("in: ");
        DB(data[i]);
        DB(" (int)");
        DBLN((int)data[i]);
        if ((data[i] == '\r' || data[i] == '\n' || data[i] == '|') && lineCount<3) {
            DBLN("newline");
            lineCount++;
            continue;
        }
        DB("append:");
        DB(data[i]);
        DB(" (int)");
        DBLN((int)data[i]);
        line[lineCount-1] += data[i];
    }
    DB("lines=");
    DBLN(lineCount);
    for (uint8_t i=0; i<lineCount; i++) {
        DB(i);
        DB('=');
        DBLN(line[i]);
    }

    uint8_t y;
    if (lineCount == 1) y = 18;
    else if (lineCount == 2) y = 14;
    else y = 10;

    Matrix.clear();
    Matrix.setFont(2);
    for (uint8_t i=0; i<lineCount; i++) {
        Matrix.text(MATRIX_ORANGE, 1, y, line[i]);
        y += 8;
    }
    Matrix.paint();
}

<|endoftext|>


<commit_before>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/stringutil.h>
#include <fnord-base/exception.h>
#include <fnord-base/inspect.h>
#include <fnord-msg/MessageSchema.h>
#include <fnord-msg/CodingOptions.pb.h>
#include <fnord-msg/msg.h>

namespace fnord {
namespace msg {

RefPtr<MessageSchema> MessageSchema::fromProtobuf(
    const google::protobuf::Descriptor* dsc) {
  Vector<msg::MessageSchemaField> fields;

  auto nfields = dsc->field_count();
  for (size_t i = 0; i < nfields; ++i) {
    auto field = dsc->field(i);

    CodingOptions coding;

    auto fopts_str = field->options().SerializeAsString();
    if (!fopts_str.empty()) {
      coding = msg::decode<CodingOptions>(fopts_str.substr(2)); // FIXPAUL HACK!!! ;)
    }

    EncodingHint enc_hint = EncodingHint::NONE;
    if (coding.encoding() == "BITPACK") enc_hint = EncodingHint::BITPACK;
    if (coding.encoding() == "LEB128") enc_hint = EncodingHint::LEB128;

    switch (field->type()) {

      case google::protobuf::FieldDescriptor::TYPE_BOOL:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::BOOLEAN,
            0,
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_STRING:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::STRING,
            coding.has_maxval() ? coding.maxval() : 0xffffffff,
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_UINT64:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::UINT64,
            coding.has_maxval() ?
                coding.maxval() : std::numeric_limits<uint64_t>::max(),
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_UINT32:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::UINT32,
            coding.has_maxval() ?
                coding.maxval() : std::numeric_limits<uint32_t>::max(),
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_ENUM: {
        size_t maxval = 0;
        auto enum_dsc = field->enum_type();
        auto nvals = enum_dsc->value_count();
        for (int j = 0; j < nvals; ++j) {
          auto enum_val = enum_dsc->value(j);
          if (enum_val->number() > maxval) {
            maxval = enum_val->number();
          }
        }

        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::UINT64,
            maxval,
            field->is_repeated(),
            field->is_optional());
        break;
      }

      case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
        fields.emplace_back(
            MessageSchemaField::mkObjectField(
                field->number(),
                field->name(),
                field->is_repeated(),
                field->is_optional(),
                MessageSchema::fromProtobuf(field->message_type())));
        break;

      default:
        RAISEF(
            kNotImplementedError,
            "field type not implemented: $0",
            field->type_name());

    }
  }

  return new msg::MessageSchema(dsc->full_name(), fields);
}

static void schemaNodeToString(
    size_t level,
    const MessageSchemaField& field,
    String* str) {
  String ws(level * 2, ' ');
  String type_name;
  String attrs;

  String type_prefix = "";
  String type_suffix = "";

  if (field.optional) {
    type_prefix += "optional[";
    type_suffix += "]";
  }

  if (field.repeated) {
    type_prefix += "list[";
    type_suffix += "]";
  }

  switch (field.type) {

    case FieldType::OBJECT:
      str->append(StringUtil::format(
          "$0$1object$2 $3 = $4 {\n",
          ws,
          type_prefix,
          type_suffix,
          field.name,
          field.id));

      for (const auto& f : field.schema->fields()) {
        schemaNodeToString(level + 1, f, str);
      }

      str->append(ws + "}\n");
      return;

    case FieldType::BOOLEAN:
      type_name = "bool";
      break;

    case FieldType::UINT32:
      type_name = "uint32";
      attrs += StringUtil::format(" @maxval=$0", field.type_size);
      break;

    case FieldType::UINT64:
      type_name = "uint64";
      attrs += StringUtil::format(" @maxval=$0", field.type_size);
      break;

    case FieldType::STRING:
      type_name = "string";
      attrs += StringUtil::format(" @maxlen=$0", field.type_size);
      break;

  }

  switch (field.encoding) {

    case EncodingHint::NONE:
      break;

    case EncodingHint::BITPACK:
      attrs += " @encoding=BITPACK";
      break;

    case EncodingHint::LEB128:
      attrs += " @encoding=LEB128";
      break;

  }

  str->append(StringUtil::format(
      "$0$1$2$3 $4 = $5$6;\n",
      ws,
      type_prefix,
      type_name,
      type_suffix,
      field.name,
      field.id,
      attrs));
}

MessageSchemaField MessageSchemaField::mkObjectField(
    uint32_t id,
    String name,
    bool repeated,
    bool optional,
    RefPtr<msg::MessageSchema> schema) {
  MessageSchemaField field(
      id,
      name,
      FieldType::OBJECT,
      0,
      repeated,
      optional);

  field.schema = schema;
  return field;
}

MessageSchema::MessageSchema(
    const String& name,
    Vector<MessageSchemaField> fields) :
    name_(name),
    fields_(fields) {
  for (const auto& field : fields_) {
    field_ids_.emplace(field.name, field.id);
    field_types_.emplace(field.id, field.type);
    field_names_.emplace(field.id, field.name);
  }
}

MessageSchema::MessageSchema(const MessageSchema& other) :
    name_(other.name_),
    fields_(other.fields_),
    field_ids_(other.field_ids_),
    field_types_(other.field_types_),
    field_names_(other.field_names_) {}

const String& MessageSchema::name() const {
  return name_;
}

const Vector<MessageSchemaField>& MessageSchema::fields() const {
  return fields_;
}

String MessageSchema::toString() const {
  String str = StringUtil::format("object $0 {\n", name_);

  for (const auto& f : fields_) {
    schemaNodeToString(1, f, &str);
  }

  str += "}";
  return str;
}

uint32_t MessageSchema::fieldId(const String& path) const {
  auto id = field_ids_.find(path);
  if (id == field_ids_.end()) {
    RAISEF(kIndexError, "field not found: $0", path);
  } else {
    return id->second;
  }
}

FieldType MessageSchema::fieldType(uint32_t id) const {
  if (id == 0) {
    return FieldType::OBJECT;
  }

  auto type = field_types_.find(id);
  if (type == field_types_.end()) {
    RAISEF(kIndexError, "field not found: $0", id);
  } else {
    return type->second;
  }
}

const String& MessageSchema::fieldName(uint32_t id) const {
  if (id == 0) {
    return name_;
  }

  auto name = field_names_.find(id);
  if (name == field_names_.end()) {
    RAISEF(kIndexError, "field not found: $0", id);
  } else {
    return name->second;
  }
}

RefPtr<MessageSchema> MessageSchema::fieldSchema(uint32_t id) const {
  for (const auto& field : fields_) {
    if (field.id == id) {
      return field.schema;
    }
  }

  RAISEF(kIndexError, "field not found: $0", id);
}

Set<String> MessageSchema::columns() const {
  Set<String> columns;

  for (const auto& c : field_names_) {
    columns.emplace(c.second);
  }

  return columns;
}

RefPtr<MessageSchema> MessageSchemaRepository::getSchema(
    const String& name) const {
  auto iter = schemas_.find(name);
  if (iter == schemas_.end()) {
    RAISEF(kRuntimeError, "schema not found: '$0'", name);
  }

  return iter->second;
}

void MessageSchemaRepository::registerSchema(RefPtr<MessageSchema> schema) {
  schemas_.emplace(schema->name(), schema);
}

} // namespace msg
} // namespace fnord
<commit_msg>remove hack<commit_after>/**
 * This file is part of the "libfnord" project
 *   Copyright (c) 2015 Paul Asmuth
 *
 * FnordMetric is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <fnord-base/stringutil.h>
#include <fnord-base/exception.h>
#include <fnord-base/inspect.h>
#include <fnord-msg/MessageSchema.h>
#include <fnord-msg/CodingOptions.pb.h>
#include <fnord-msg/msg.h>

namespace fnord {
namespace msg {

RefPtr<MessageSchema> MessageSchema::fromProtobuf(
    const google::protobuf::Descriptor* dsc) {
  Vector<msg::MessageSchemaField> fields;

  auto nfields = dsc->field_count();
  for (size_t i = 0; i < nfields; ++i) {
    auto field = dsc->field(i);

    CodingOptions copts = field->options().GetExtension(coding);

    EncodingHint enc_hint = EncodingHint::NONE;
    if (copts.encoding() == "BITPACK") enc_hint = EncodingHint::BITPACK;
    if (copts.encoding() == "LEB128") enc_hint = EncodingHint::LEB128;

    switch (field->type()) {

      case google::protobuf::FieldDescriptor::TYPE_BOOL:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::BOOLEAN,
            0,
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_STRING:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::STRING,
            copts.has_maxval() ? copts.maxval() : 0xffffffff,
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_UINT64:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::UINT64,
            copts.has_maxval() ?
                copts.maxval() : std::numeric_limits<uint64_t>::max(),
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_UINT32:
        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::UINT32,
            copts.has_maxval() ?
                copts.maxval() : std::numeric_limits<uint32_t>::max(),
            field->is_repeated(),
            field->is_optional(),
            enc_hint);
        break;

      case google::protobuf::FieldDescriptor::TYPE_ENUM: {
        size_t maxval = 0;
        auto enum_dsc = field->enum_type();
        auto nvals = enum_dsc->value_count();
        for (int j = 0; j < nvals; ++j) {
          auto enum_val = enum_dsc->value(j);
          if (enum_val->number() > maxval) {
            maxval = enum_val->number();
          }
        }

        fields.emplace_back(
            field->number(),
            field->name(),
            msg::FieldType::UINT64,
            maxval,
            field->is_repeated(),
            field->is_optional());
        break;
      }

      case google::protobuf::FieldDescriptor::TYPE_MESSAGE:
        fields.emplace_back(
            MessageSchemaField::mkObjectField(
                field->number(),
                field->name(),
                field->is_repeated(),
                field->is_optional(),
                MessageSchema::fromProtobuf(field->message_type())));
        break;

      default:
        RAISEF(
            kNotImplementedError,
            "field type not implemented: $0",
            field->type_name());

    }
  }

  return new msg::MessageSchema(dsc->full_name(), fields);
}

static void schemaNodeToString(
    size_t level,
    const MessageSchemaField& field,
    String* str) {
  String ws(level * 2, ' ');
  String type_name;
  String attrs;

  String type_prefix = "";
  String type_suffix = "";

  if (field.optional) {
    type_prefix += "optional[";
    type_suffix += "]";
  }

  if (field.repeated) {
    type_prefix += "list[";
    type_suffix += "]";
  }

  switch (field.type) {

    case FieldType::OBJECT:
      str->append(StringUtil::format(
          "$0$1object$2 $3 = $4 {\n",
          ws,
          type_prefix,
          type_suffix,
          field.name,
          field.id));

      for (const auto& f : field.schema->fields()) {
        schemaNodeToString(level + 1, f, str);
      }

      str->append(ws + "}\n");
      return;

    case FieldType::BOOLEAN:
      type_name = "bool";
      break;

    case FieldType::UINT32:
      type_name = "uint32";
      attrs += StringUtil::format(" @maxval=$0", field.type_size);
      break;

    case FieldType::UINT64:
      type_name = "uint64";
      attrs += StringUtil::format(" @maxval=$0", field.type_size);
      break;

    case FieldType::STRING:
      type_name = "string";
      attrs += StringUtil::format(" @maxlen=$0", field.type_size);
      break;

  }

  switch (field.encoding) {

    case EncodingHint::NONE:
      break;

    case EncodingHint::BITPACK:
      attrs += " @encoding=BITPACK";
      break;

    case EncodingHint::LEB128:
      attrs += " @encoding=LEB128";
      break;

  }

  str->append(StringUtil::format(
      "$0$1$2$3 $4 = $5$6;\n",
      ws,
      type_prefix,
      type_name,
      type_suffix,
      field.name,
      field.id,
      attrs));
}

MessageSchemaField MessageSchemaField::mkObjectField(
    uint32_t id,
    String name,
    bool repeated,
    bool optional,
    RefPtr<msg::MessageSchema> schema) {
  MessageSchemaField field(
      id,
      name,
      FieldType::OBJECT,
      0,
      repeated,
      optional);

  field.schema = schema;
  return field;
}

MessageSchema::MessageSchema(
    const String& name,
    Vector<MessageSchemaField> fields) :
    name_(name),
    fields_(fields) {
  for (const auto& field : fields_) {
    field_ids_.emplace(field.name, field.id);
    field_types_.emplace(field.id, field.type);
    field_names_.emplace(field.id, field.name);
  }
}

MessageSchema::MessageSchema(const MessageSchema& other) :
    name_(other.name_),
    fields_(other.fields_),
    field_ids_(other.field_ids_),
    field_types_(other.field_types_),
    field_names_(other.field_names_) {}

const String& MessageSchema::name() const {
  return name_;
}

const Vector<MessageSchemaField>& MessageSchema::fields() const {
  return fields_;
}

String MessageSchema::toString() const {
  String str = StringUtil::format("object $0 {\n", name_);

  for (const auto& f : fields_) {
    schemaNodeToString(1, f, &str);
  }

  str += "}";
  return str;
}

uint32_t MessageSchema::fieldId(const String& path) const {
  auto id = field_ids_.find(path);
  if (id == field_ids_.end()) {
    RAISEF(kIndexError, "field not found: $0", path);
  } else {
    return id->second;
  }
}

FieldType MessageSchema::fieldType(uint32_t id) const {
  if (id == 0) {
    return FieldType::OBJECT;
  }

  auto type = field_types_.find(id);
  if (type == field_types_.end()) {
    RAISEF(kIndexError, "field not found: $0", id);
  } else {
    return type->second;
  }
}

const String& MessageSchema::fieldName(uint32_t id) const {
  if (id == 0) {
    return name_;
  }

  auto name = field_names_.find(id);
  if (name == field_names_.end()) {
    RAISEF(kIndexError, "field not found: $0", id);
  } else {
    return name->second;
  }
}

RefPtr<MessageSchema> MessageSchema::fieldSchema(uint32_t id) const {
  for (const auto& field : fields_) {
    if (field.id == id) {
      return field.schema;
    }
  }

  RAISEF(kIndexError, "field not found: $0", id);
}

Set<String> MessageSchema::columns() const {
  Set<String> columns;

  for (const auto& c : field_names_) {
    columns.emplace(c.second);
  }

  return columns;
}

RefPtr<MessageSchema> MessageSchemaRepository::getSchema(
    const String& name) const {
  auto iter = schemas_.find(name);
  if (iter == schemas_.end()) {
    RAISEF(kRuntimeError, "schema not found: '$0'", name);
  }

  return iter->second;
}

void MessageSchemaRepository::registerSchema(RefPtr<MessageSchema> schema) {
  schemas_.emplace(schema->name(), schema);
}

} // namespace msg
} // namespace fnord
<|endoftext|>


<commit_before>#include "Render.h"
#include "interface/Interface.h"
#include "base/basedef.h"
#include "math/hash.h"
#include <GL/glew.h>

using fei::Render;

static const GLchar *basicVertexShader = {
	"void main()"
	"{"
	"	gl_TexCoord[0] = gl_MultiTexCoord0;"
	"	gl_FrontColor = gl_Color;"
	"	gl_Position = ftransform();"
	"}"
};

static const GLchar *basicFragmentShader = {
	"uniform sampler2D feiTex;"
	"uniform float feiUseTex;"
	"void main() {"
	"	vec4 color = gl_Color;"
	"	if (feiUseTex == 1.0) {"
	"		vec4 texColor = texture2D(feiTex, gl_TexCoord[0].st);"
	"		if (texColor.a == 0.0 || color.a == 0.0) discard;"
	"		color *= texColor;"
	"	}"
	"	gl_FragColor = color;"
	"}"
};

Render* Render::instance = nullptr;

Render* Render::getInstance()
{
	if (!instance) {
		instance = new Render();
	}
	return instance;
}

Render::Render()
{
}

bool Render::init()
{
	if (_isLoad) return true;
	_isLoad = true;
	if (!fei::Interface::getInstance()->init()) {
		_isLoad = false;
		return false;
	}
	GLenum err = glewInit();
	if (GLEW_OK != err) {
		std::fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		_isLoad = false;
	} else {
		std::printf("GLEW Version: %s\n", glewGetString(GLEW_VERSION));
		std::printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
		if (GLEW_VERSION_2_0) {
			std::printf("GLSL Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
			basicShader.loadString(basicVertexShader, basicFragmentShader);
			basicShader.push();
		} else {
			std::printf("Shader unsupported!\n");
		}
		glEnable(GL_CULL_FACE);
		glCullFace(GL_FRONT);
	}
	return _isLoad;
}

void Render::destroy()
{
	while (!shaderStack.empty()) {
		shaderStack.pop();
	}
	deleteUnusedTexture();
}

void Render::executeBeforeFrame()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	auto shader = getShaderProgram();
	if (shader) {
		shader->use();
	}
}

void Render::executeAfterFrame()
{
	deleteUnusedTexture();
}

void Render::setViewport(const fei::Rect& viewport)
{
	glViewport((GLint)viewport.getPosition().x, (GLint)viewport.getPosition().y,
		(GLsizei)viewport.getSize().x, (GLsizei)viewport.getSize().y);
}

const fei::Rect Render::getViewport()
{
	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	return fei::Rect((float)viewport[0], (float)viewport[1], (float)viewport[2], (float)viewport[3]);
}

void Render::pushShader(fei::ShaderProgram* shader)
{
	if (shaderStack.empty() || shaderStack.top() != shader) {
		shaderStack.push(shader);
		shader->use();
	}
}

void Render::popShader(fei::ShaderProgram* shader)
{
	if (!shaderStack.empty() && shaderStack.top() == shader) {
		shaderStack.pop();
		if (shaderStack.empty()) {
			glUseProgram(0);
		} else {
			shaderStack.top()->use();
		}
	}
}

fei::ShaderProgram* Render::getShaderProgram()
{
	if (!shaderStack.empty()) {
		return shaderStack.top();
	} else {
		return nullptr;
	}
}

void Render::registTexture(const char* filename, GLuint id)
{
	int hash = fei::bkdrHash(filename);
	fileTextureMap[hash] = id;
}

void Render::deleteTexture(GLuint id)
{
	glDeleteTextures(1, &id);
	textureSizeMap.erase(textureSizeMap.find(id));
	for (auto it = fileTextureMap.begin(); it != fileTextureMap.end(); ++it) {
		if (it->second == id) {
			fileTextureMap.erase(it);
			break;
		}
	}
}

int Render::queryTexture(const char* filename)
{
	int hash = fei::bkdrHash(filename);
	GLuint ans = 0;
	auto it = fileTextureMap.find(hash);
	if (it != fileTextureMap.end()) {
		ans = it->second;
	}
	return ans;
}

void Render::registTexSize(GLuint id, const Vec2& s)
{
	textureSizeMap[id] = s;
}

const fei::Vec2 Render::queryTexSize(GLuint id)
{
	return textureSizeMap[id];
}

void Render::addRefTexture(GLuint id)
{
	if (!id) return;
	textureRCMap[id]++;
}

void Render::releaseTexture(GLuint id)
{
	if (!id) return;
	textureRCMap[id]--;
}

void Render::deleteUnusedTexture()
{
	for (auto it = textureRCMap.begin(); it != textureRCMap.end();) {
		if (it->second == 0) {
			deleteTexture(it->first);
			it = textureRCMap.erase(it);
		} else {
			++it;
		}
	}
}

void Render::bindTexture(GLuint tex)
{
	glBindTexture(GL_TEXTURE_2D, tex);
	auto shader = getShaderProgram();
	if (shader) {
		shader->setUniform("feiUseTex", 1.0f);
		shader->setUniform("feiTex", (float)tex);
	}
}

void Render::drawTexQuad(const fei::Vec2& size, GLfloat* texCoord)
{
	GLfloat w2 = size.x / 2.0f;
	GLfloat h2 = size.y / 2.0f;
	GLfloat vertex[] = {-w2, h2, -w2, -h2, w2, h2, w2, -h2};
	GLfloat defaultTexCoord[] = {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f};
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glVertexPointer(2, GL_FLOAT, 0, vertex);
	if (texCoord) {
		glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
	} else {
		glTexCoordPointer(2, GL_FLOAT, 0, defaultTexCoord);
	}
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
<commit_msg>fix namespace problem<commit_after>#include "Render.h"
#include "interface/Interface.h"
#include "base/basedef.h"
#include "math/hash.h"
#include <GL/glew.h>

using fei::Render;

static const GLchar *basicVertexShader = {
	"void main()"
	"{"
	"	gl_TexCoord[0] = gl_MultiTexCoord0;"
	"	gl_FrontColor = gl_Color;"
	"	gl_Position = ftransform();"
	"}"
};

static const GLchar *basicFragmentShader = {
	"uniform sampler2D feiTex;"
	"uniform float feiUseTex;"
	"void main() {"
	"	vec4 color = gl_Color;"
	"	if (feiUseTex == 1.0) {"
	"		vec4 texColor = texture2D(feiTex, gl_TexCoord[0].st);"
	"		if (texColor.a == 0.0 || color.a == 0.0) discard;"
	"		color *= texColor;"
	"	}"
	"	gl_FragColor = color;"
	"}"
};

Render* Render::instance = nullptr;

Render* Render::getInstance()
{
	if (!instance) {
		instance = new Render();
	}
	return instance;
}

Render::Render()
{
}

bool Render::init()
{
	if (_isLoad) return true;
	_isLoad = true;
	if (!fei::Interface::getInstance()->init()) {
		_isLoad = false;
		return false;
	}
	GLenum err = glewInit();
	if (GLEW_OK != err) {
		std::fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
		_isLoad = false;
	} else {
		std::printf("GLEW Version: %s\n", glewGetString(GLEW_VERSION));
		std::printf("OpenGL Version: %s\n", glGetString(GL_VERSION));
		if (GLEW_VERSION_2_0) {
			std::printf("GLSL Version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
			basicShader.loadString(basicVertexShader, basicFragmentShader);
			basicShader.push();
		} else {
			std::printf("Shader unsupported!\n");
		}
		glEnable(GL_CULL_FACE);
		glCullFace(GL_FRONT);
	}
	return _isLoad;
}

void Render::destroy()
{
	while (!shaderStack.empty()) {
		shaderStack.pop();
	}
	deleteUnusedTexture();
}

void Render::executeBeforeFrame()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	auto shader = getShaderProgram();
	if (shader) {
		shader->use();
	}
}

void Render::executeAfterFrame()
{
	deleteUnusedTexture();
}

void Render::setViewport(const fei::Rect& viewport)
{
	glViewport((GLint)viewport.getPosition().x, (GLint)viewport.getPosition().y,
		(GLsizei)viewport.getSize().x, (GLsizei)viewport.getSize().y);
}

const fei::Rect Render::getViewport()
{
	int viewport[4];
	glGetIntegerv(GL_VIEWPORT, viewport);
	return fei::Rect((float)viewport[0], (float)viewport[1], (float)viewport[2], (float)viewport[3]);
}

void Render::pushShader(fei::ShaderProgram* shader)
{
	if (shaderStack.empty() || shaderStack.top() != shader) {
		shaderStack.push(shader);
		shader->use();
	}
}

void Render::popShader(fei::ShaderProgram* shader)
{
	if (!shaderStack.empty() && shaderStack.top() == shader) {
		shaderStack.pop();
		if (shaderStack.empty()) {
			glUseProgram(0);
		} else {
			shaderStack.top()->use();
		}
	}
}

fei::ShaderProgram* Render::getShaderProgram()
{
	if (!shaderStack.empty()) {
		return shaderStack.top();
	} else {
		return nullptr;
	}
}

void Render::registTexture(const char* filename, GLuint id)
{
	int hash = fei::bkdrHash(filename);
	fileTextureMap[hash] = id;
}

void Render::deleteTexture(GLuint id)
{
	glDeleteTextures(1, &id);
	textureSizeMap.erase(textureSizeMap.find(id));
	for (auto it = fileTextureMap.begin(); it != fileTextureMap.end(); ++it) {
		if (it->second == id) {
			fileTextureMap.erase(it);
			break;
		}
	}
}

int Render::queryTexture(const char* filename)
{
	int hash = fei::bkdrHash(filename);
	GLuint ans = 0;
	auto it = fileTextureMap.find(hash);
	if (it != fileTextureMap.end()) {
		ans = it->second;
	}
	return ans;
}

void Render::registTexSize(GLuint id, const fei::Vec2& size)
{
	textureSizeMap[id] = size;
}

const fei::Vec2 Render::queryTexSize(GLuint id)
{
	return textureSizeMap[id];
}

void Render::addRefTexture(GLuint id)
{
	if (!id) return;
	textureRCMap[id]++;
}

void Render::releaseTexture(GLuint id)
{
	if (!id) return;
	textureRCMap[id]--;
}

void Render::deleteUnusedTexture()
{
	for (auto it = textureRCMap.begin(); it != textureRCMap.end();) {
		if (it->second == 0) {
			deleteTexture(it->first);
			it = textureRCMap.erase(it);
		} else {
			++it;
		}
	}
}

void Render::bindTexture(GLuint tex)
{
	glBindTexture(GL_TEXTURE_2D, tex);
	auto shader = getShaderProgram();
	if (shader) {
		shader->setUniform("feiUseTex", 1.0f);
		shader->setUniform("feiTex", (float)tex);
	}
}

void Render::drawTexQuad(const fei::Vec2& size, GLfloat* texCoord)
{
	GLfloat w2 = size.x / 2.0f;
	GLfloat h2 = size.y / 2.0f;
	GLfloat vertex[] = {-w2, h2, -w2, -h2, w2, h2, w2, -h2};
	GLfloat defaultTexCoord[] = {0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f};
	glEnableClientState(GL_VERTEX_ARRAY);
	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
	glVertexPointer(2, GL_FLOAT, 0, vertex);
	if (texCoord) {
		glTexCoordPointer(2, GL_FLOAT, 0, texCoord);
	} else {
		glTexCoordPointer(2, GL_FLOAT, 0, defaultTexCoord);
	}
	glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
	glDisableClientState(GL_VERTEX_ARRAY);
	glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
<|endoftext|>


<commit_before>/*
 *   Copyright (c) 2006, Mathieu Champlon
 *   All rights reserved.
 *
 *   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.
 *
 *   . Neither  the name  of  the  copyright  holders  nor the names  of the
 *     contributors may be used to endorse  or promote products derived from
 *     this software without specific prior written permission.
 *
 *   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 THE COPYRIGHT
 *   OWNERS 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.
 */

#include "xeumeuleu_test_pch.h"
#include <string>

namespace
{
    static std::string data_directory;

    void set_data_directory( int argc, char* argv[] )
    {
        while( argc-- )
        {
            const std::string argument = argv[argc];
            const std::string::size_type n = argument.find( '=' );
            if( n != std::string::npos && argument.substr( 0, n ) == "--data_directory" )
                data_directory = argument.substr( n+1 );
        }
    }
}

::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
{
    set_data_directory( argc, argv );
    return 0;
}

std::string BOOST_RESOLVE( const std::string& filename )
{
    if( data_directory.empty() )
        return filename;
    return data_directory + '/' + filename;
}
<commit_msg>Cleanup<commit_after>/*
 *   Copyright (c) 2006, Mathieu Champlon
 *   All rights reserved.
 *
 *   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.
 *
 *   . Neither  the name  of  the  copyright  holders  nor the names  of the
 *     contributors may be used to endorse  or promote products derived from
 *     this software without specific prior written permission.
 *
 *   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 THE COPYRIGHT
 *   OWNERS 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.
 */

#include "xeumeuleu_test_pch.h"
#include <string>

namespace
{
    std::string data_directory;

    void set_data_directory( int argc, char* argv[] )
    {
        while( argc-- )
        {
            const std::string argument = argv[argc];
            const std::string::size_type n = argument.find( '=' );
            if( n != std::string::npos && argument.substr( 0, n ) == "--data_directory" )
                data_directory = argument.substr( n+1 );
        }
    }
}

::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] )
{
    set_data_directory( argc, argv );
    return 0;
}

std::string BOOST_RESOLVE( const std::string& filename )
{
    if( data_directory.empty() )
        return filename;
    return data_directory + '/' + filename;
}
<|endoftext|>