<commit_before>/*********************************************************/
/* Bela Csound Main Program                              */
/* takes the option --csd=name                           */
/*                                                       */
/*********************************************************/
#include <Bela.h>
#include <csound/csound.hpp>
#include <unistd.h>
#include <cstring>

struct csData{
  Csound *csound;
  int blocksize;
  int res;
  int count;
  const char* csd;
};

int main(int argc, const char *argv[]) {
  csData CsData;
  const option opt[] = {{"csd", required_argument, NULL, 0},
			{NULL, 0, NULL, 0}};
  BelaInitSettings settings;
  Bela_defaultSettings(&settings);
  if(Bela_getopt_long(argc, argv, "", opt, &settings) != -1) {
    csData.csd = new char[strlen(optarg)+1];
    std::strcpy(csData.csd,optarg);
    bool res = Bela_initAudio(&settings, &CsData);
    if(res){
       Bela_startAudio();
       while(CsData.res == 0) sleep(1);
       Bela_stopAudio();
    }
    Bela_cleanupAudio();
    return 0;
  }
  fprintf(stderr, "no csd provided \n");
  return -1;
}

bool setup(BelaContext *context, void *userData)
{
  Csound *csound = new Csound();
  csData *CsData = (csData *) userData;
  csound->SetHostImplementedAudioIO(1,32);
  CsData->res = csound->Compile(CsData.csd, "-iadc", "-odac",
				"-+rtaudio=null", "--realtime"); // TODO get CSD name
  CsData->csound = csound;
  CsData->blocksize = csound->GetOutputBufferSize();
  CsData->count = 0;
  if(CsData->res != 0) return false;
  else return true;
}

void render(BelaContext *context, void *userData)
{
  csData *userData = (csData *) userData;
  if(gCsData->res == 0) {
    int n,i,frame,blocksize, res;
    MYFLT scal = userData->csound->Get0dBFS();
    MYFLT* audioIn = userData->csound->GetInputBuffer();
    MYFLT* audioOut = userData->csound->GetOutputBuffer();
    int nchnls = userData->csound->GetNchnls();
    int chns = nchnls;
    frame = userData->count;
    blocksize = userData->blocksize;

    /* this is called when Csound is not running */
    if(frame < 0) {
      for(n = 0; n < context->audioFrames; n++){
	for(i = 0; i < context->audioOutChannels; i++){
	  audioWrite(context,n,i,0);
	}
      }
      return;
    }

    if(chns > context->audioOutChannels)
      chns = context->audioOutChannels;
    /* this is where Csound is called */
    for(n = 0; n < context->audioFrames; n++){
      if(frame == blocksize) {
	if((res = userData->csound->PerformBuffer()) == 0) frame = 0;
	else {
	  frame = -1;
	  break;
	}
      }
      for(i = 0; i < chns; i++){
	audioIn[frame+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[frame+i]/scal);
      }
      frame += nchnls;
    }
    gCsData->res = res;
    userData->count = frame;
  }
}

void cleanup(BelaContext *context, void *userData)
{
  csData *CsData = (csData *) userData;
  delete CsData->csound;
}
<commit_msg>main function<commit_after>/*
  BelaCsound.cpp:

  Copyright (C) 2017 V Lazzarini

  This file is part of Csound.

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

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

  You should have received a copy of the GNU Lesser General Public
  License along with Csound; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  02111-1307 USA
*/

#include <Bela.h>
#include <Midi.h>
#include <csound/csound.hpp>
#include <csound/plugin.h>
#include <vector>
#include <sstream>

#define ANCHNS 8

static int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiInDevice(CSOUND *csound, void *userData);
static int ReadMidiData(CSOUND *csound, void *userData, unsigned char *mbuf,
			int nbytes);
static int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev);
static int CloseMidiOutDevice(CSOUND *csound, void *userData);
static int WriteMidiData(CSOUND *csound, void *userData, const unsigned char *mbuf,
			 int nbytes);

/** DigiIn opcode
    ksig digiInBela ipin
    asig digiInBela ipin
*/
struct DigiIn : csnd::Plugin<1, 1> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[0];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    fcount = 0;
    init_done = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
   if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    outargs[0] = (MYFLT) digitalRead(context,fcount,pin);
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig out(this, outargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,0);
      init_done = 1;
    }
    for (auto &s : out) {
      s = (MYFLT) digitalRead(context,cnt,pin);
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

/** DigiOut opcode
    digiOutBela ksig,ipin
    digiOutBela asig,ipin
*/
struct DigiOut : csnd::Plugin<0, 2> {
  int pin;
  int fcount;
  int frms;
  int init_done;
  BelaContext *context;

  int init() {
    pin = (int) inargs[1];
    if(pin < 0 ) pin = 0;
    if(pin > 15) pin = 15;
    context = (BelaContext *) csound->host_data();
    init_done = 0;
    fcount = 0;
    frms = context->digitalFrames;
    return OK;
  }

  int kperf() {
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    digitalWrite(context,fcount,pin,(inargs[0] > 0.0 ? 1 : 0));
    fcount += nsmps;
    fcount %= frms;
    return OK;
  }

  int aperf() {
    csnd::AudioSig in(this, inargs(0));
    int cnt = fcount;
    if(!init_done) {
      pinMode(context,0,pin,1);
      init_done = 1;
    }
    for (auto s : in) {
      digitalWriteOnce(context,cnt,pin, (s > 0.0 ? 1 : 0));
      if(cnt == frms - 1) cnt = 0;
      else cnt++;
    }
    fcount = cnt;
    return OK;
  }
};

struct CsChan {
  std::vector<MYFLT> samples;
  std::stringstream name;
};

struct CsData {
  Csound *csound;
  std::string csdfile;
  int blocksize;
  int res;
  int count;
  CsChan channel[ANCHNS];
  CsChan ochannel[ANCHNS];
  Midi midi;
};

bool setup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  Csound *csound;
  const char *midiDev = "-Mhw:1,0,0"; /* MIDI IN device */
  const char *midiOutDev = "-Qhw:1,0,0"; /* MIDI OUT device */
  const char *args[] = { "csound", csdData->csdfile.c_str(), "-iadc",
			 "-odac", "-+rtaudio=null",
			 "--realtime", "--daemon",
			 midiDev, midiOutDev };
  int numArgs = (int) (sizeof(args)/sizeof(char *));

  if(context->audioInChannels != context->audioOutChannels) {
    printf("Error: number of audio inputs != number of audio outputs.\n");
    return false;
  }

  if(context->analogInChannels != context->analogOutChannels) {
    printf("Error: number of analog inputs != number of analog outputs.\n");
    return false;
  }

  /* set up Csound */
  csound = new Csound();
  csData->csound = csound;
  csound->SetHostData((void *) context);
  csound->SetHostImplementedAudioIO(1,0);
  csound->SetHostImplementedMIDIIO(1);
  csound->SetExternalMidiInOpenCallback(OpenMidiInDevice);
  csound->SetExternalMidiReadCallback(ReadMidiData);
  csound->SetExternalMidiInCloseCallback(CloseMidiInDevice);
  csound->SetExternalMidiOutOpenCallback(OpenMidiOutDevice);
  csound->SetExternalMidiWriteCallback(WriteMidiData);
  csound->SetExternalMidiOutCloseCallback(CloseMidiOutDevice);
  /* set up digi opcodes */
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "k","i", csnd::thread::ik) != 0)
    printf("Warning: could not add digiInBela k-rate opcode\n");
  if(csnd::plugin<DigiIn>((csnd::Csound *) csound->GetCsound(), "digiInBela",
			  "a", "i", csnd::thread::ia) != 0)
    printf("Warning: could not add digiInBela a-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ki", csnd::thread::ik) != 0)
    printf("Warning: could not add digiOutBela k-rate opcode\n");
  if(csnd::plugin<DigiOut>((csnd::Csound *) csound->GetCsound(), "digiOutBela" ,
			   "", "ai", csnd::thread::ia) != 0)
    printf("Warning: could not add digiOutBela a-rate opcode\n");

  /* compile CSD */
  if((csData->res = csound->Compile(numArgs, args)) != 0) {
    printf("Error: Csound could not compile CSD file.\n");
    return false;
  }
  csData->blocksize = csound->GetKsmps()*csound->GetNchnls();
  csData->count = 0;

  /* set up the channels */
  for(int i=0; i < ANCHNS; i++) {
    csData->channel[i].samples.resize(csound->GetKsmps());
    csData->channel[i].name << "analogIn" << i;
    csData->ochannel[i].samples.resize(csound->GetKsmps());
    csData->ochannel[i].name << "analogOut" << i;
  }

  return true;
}

void render(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  if(csData->res == 0) {
    int n,i,k,count, frmcount,blocksize,res;
    Csound *csound = csData->csound;
    MYFLT scal = csound->Get0dBFS();
    MYFLT* audioIn = csound->GetSpin();
    MYFLT* audioOut = csound->GetSpout();
    int nchnls = csound->GetNchnls();
    int chns = nchnls < context->audioOutChannels ?
      nchnls : context->audioOutChannels;
    int an_chns = context->analogInChannels > ANCHNS ?
      ANCHNS : context->analogInChannels;
    CsChan *channel = csData->channel;
    CsChan *ochannel = csData->ochannel;
    float frm = 0.f, incr =
      ((float) context->analogFrames)/context->audioFrames;
    count = csData->count;
    blocksize = csData->blocksize;

    /* processing loop */
    for(n = 0; n < context->audioFrames; n++, frm+=incr, count+=nchnls){
      if(count == blocksize) {
	/* set the channels */
	for(i = 0; i < an_chns; i++) {
          csound->SetChannel(channel[i].name.str().c_str(),
			     channel[i].samples.data());
	  csound->GetAudioChannel(ochannel[i].name.str().c_str(),
				  ochannel[i].samples.data());
	}
	/* run csound */
	if((res = csound->PerformKsmps()) == 0) count = 0;
	else break;
      }
      /* read/write audio data */
      for(i = 0; i < chns; i++){
	audioIn[count+i] = audioRead(context,n,i);
	audioWrite(context,n,i,audioOut[count+i]/scal);
      }
      /* read analogue data
         analogue frame pos frm gets incremented according to the
         ratio analogFrames/audioFrames.
      */
      frmcount = count/nchnls;
      for(i = 0; i < an_chns; i++) {
	k = (int) frm;
        channel[i].samples[frmcount] = analogRead(context,k,i);
	analogWriteOnce(context,k,i,ochannel[i].samples[frmcount]);
      }
    }
    gCsData.res = res;
    gCsData.count = count;
  }
}

void cleanup(BelaContext *context, void *p)
{
  CsData *csData = (CsData *) p;
  delete csData->csound;
}

/** MIDI functions
 */
int OpenMidiInDevice(CSOUND *csound, void **userData, const char *dev) {
  CsData *hdata = (CsData *) csound->GetHostData(csound);
  Midi *midi = &(hdata->midi);
  if(midi->readFrom(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi in device %s", dev);
  return -1;
}

int CloseMidiInDevice(CSOUND *csound, void *userData) {
  return 0;
}

int ReadMidiData(CSOUND *csound, void *userData,
		 unsigned char *mbuf, int nbytes) {
  int n = 0, byte;
  if(userData) {
    Midi *midi = (Midi *) userData;
    while((byte = midi->getInput()) >= 0) {
      *mbuf++ = (unsigned char) byte;
      if(++n == nbytes) break;
    }
    return n;
  }
  return 0;
}

int OpenMidiOutDevice(CSOUND *csound, void **userData, const char *dev) {
  CsData *hdata = (CsData *) csound->GetHostData(csound);
  Midi *midi = &(hdata->midi);
  if(midi->writeTo(dev) == 1) {
    midi->enableParser(false);
    *userData = (void *) midi;
    return 0;
  }
  csoundMessage(csound, "Could not open Midi out device %s", dev);
  return -1;
}

int CloseMidiOutDevice(CSOUND *csound, void *userData) {
  return 0;
}

int WriteMidiData(CSOUND *csound, void *userData,
		  const unsigned char *mbuf, int nbytes) {
  if(userData) {
    Midi *midi = (Midi *) userData;
    if(midi->writeOutput((midi_byte_t *)mbuf, nbytes) > 0) return nbytes;
    return 0;
  }
  return 0;
}

/**
   Main program: takes Bela options and a --csd=<csdfile>
   option for Csound
*/
int main(int argc, const char *argv[]) {
  CsData csData;
  BelaInitSettings settings;
  const option opt[] = {{"csd", required_argument, NULL, 0},
			{NULL, 0, NULL, 0}};

  Bela_defaultSettings(&settings);

  if(Bela_getopt_long(argc, argv, "", opt, &settings) != -1) {
    CsData.csdfile = optarg;
    bool res = Bela_initAudio(&settings, &CsData);
    if(res){
       Bela_startAudio();
       while(CsData.res == 0) sleep(1);
       Bela_stopAudio();
    }
    Bela_cleanupAudio();
    return 0;
  }
  fprintf(stderr, "no csd provided, use --csd=<csdfile> \n");
  Bela_usage();
  return -1;
}
<|endoftext|>


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

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLE_HPP_
#include <com/sun/star/accessibility/XAccessible.hpp>
#endif

namespace svt
{
    // impl class for the class EditBrowseBox
    class EditBrowseBoxImpl
    {
    public:
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >    m_xActiveCell;
        sal_Bool                                                                            m_bHiContrast;

        void clearActiveCell();
    };
}
#endif // SVTOOLS_EDITBROWSEBOX_IMPL_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.7.246); FILE MERGED 2008/04/01 12:43:21 thb 1.7.246.2: #i85898# Stripping all external header guards 2008/03/31 13:01:21 rt 1.7.246.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: editbrowseboximpl.hxx,v $
 * $Revision: 1.8 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef SVTOOLS_EDITBROWSEBOX_IMPL_HXX
#define SVTOOLS_EDITBROWSEBOX_IMPL_HXX

#include <com/sun/star/accessibility/XAccessible.hpp>

namespace svt
{
    // impl class for the class EditBrowseBox
    class EditBrowseBoxImpl
    {
    public:
        ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible >    m_xActiveCell;
        sal_Bool                                                                            m_bHiContrast;

        void clearActiveCell();
    };
}
#endif // SVTOOLS_EDITBROWSEBOX_IMPL_HXX

<|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
using namespace std;

vector<string> split( const string& s, const string& delim =" " ) {
    vector<string> res;
    string t;
    for ( int i = 0 ; i != s.size() ; i++ ) {
        if ( delim.find( s[i] ) != string::npos ) {
            if ( !t.empty() ) {
                res.push_back( t );
                t = "";
            }
        } else {
            t += s[i];
        }
    }
    if ( !t.empty() ) {
        res.push_back(t);
    }
    return res;
}

vector<int> splitInt( const string& s, const string& delim =" " ) {
    vector<string> tok = split( s, delim );
    vector<int> res;
    for ( int i = 0 ; i != tok.size(); i++ )
        res.push_back( atoi( tok[i].c_str() ) );
    return res;
}

// BEGIN CUT HERE
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))

template<typename T> void print( T a ) {
    cerr << a;
}
static void print( long long a ) {
    cerr << a << "L";
}
static void print( string a ) {
    cerr << '"' << a << '"';
}
template<typename T> void print( vector<T> a ) {
    cerr << "{";
    for ( int i = 0 ; i != a.size() ; i++ ) {
        if ( i != 0 ) cerr << ", ";
        print( a[i] );
    }
    cerr << "}" << endl;
}
template<typename T> void eq( int n, T have, T need ) {
    if ( have == need ) {
        cerr << "Case " << n << " passed." << endl;
    } else {
        cerr << "Case " << n << " failed: expected ";
        print( need );
        cerr << " received ";
        print( have );
        cerr << "." << endl;
    }
}
template<typename T> void eq( int n, vector<T> have, vector<T> need ) {
    if( have.size() != need.size() ) {
        cerr << "Case " << n << " failed: returned " << have.size() << " elements; expected " << need.size() << " elements.";
        print( have );
        print( need );
        return;
    }
    for( int i= 0; i < have.size(); i++ ) {
        if( have[i] != need[i] ) {
            cerr << "Case " << n << " failed. Expected and returned array differ in position " << i << ".";
            print( have );
            print( need );
            return;
        }
    }
    cerr << "Case " << n << " passed." << endl;
}
static void eq( int n, string have, string need ) {
    if ( have == need ) {
        cerr << "Case " << n << " passed." << endl;
    } else {
        cerr << "Case " << n << " failed: expected ";
        print( need );
        cerr << " received ";
        print( have );
        cerr << "." << endl;
    }
}
// END CUT HERE
class Poetry {
public:
    string rhymeScheme(vector <string> poem) {
        vector <string>::iterator string_it;
        string res, line, empty_line;
        string word;
        string::iterator ec;
        map<string,string> rhymes;
        res = "";
        string chars_in_poem = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int current_char = 0;
        int blank_line = 1;

        for(string_it = poem.begin(); string_it != poem.end(); string_it++)
        {
            line = (*string_it);
            transform(line.begin(),line.end(),line.begin(),::tolower);
            empty_line = line;
            empty_line.erase(std::remove_if(empty_line.begin(), empty_line.end(), (int(*)(int))isspace), empty_line.end());
            if (empty_line.size() == 0)
            {
                res += " ";
                continue;
            }
            for(int i=0; i<=empty_line.size()-1;i++)
            {
                if (empty_line[i] != ' ')
                {
                    blank_line = 0;
                    break;
                }
            }

            if (blank_line == 1)
            {
                res += " ";
                continue;
            }

            if (line == "")
            {
                res += " ";
                continue;
            }

            word = find_word(line);
            if (word == "" || word.size() == 0)
            {
                res += " ";
                continue;
            }

            word.erase(std::remove_if(word.begin(), word.end(), (int(*)(int))isspace), word.end());

            if (word[0] == 'y')
                word = word.substr(1);
            /**
            if (*word.rbegin() == ' ')
                word.resize(word.length() - 1);
            **/

            print(word);

            if (rhymes.count(word) > 0)
                res += rhymes[word];
            else
            {
                rhymes[word] += chars_in_poem[current_char];
                res += chars_in_poem[current_char];
                current_char++;
            }
            /**
             * The idea is form the dictionary of the rhymes and fetch from the
             * dictionary if the rhyme already exist, if not add to the
             * dictionary for the new rhyme created according to the rule.
             */
        }
        return res;
    }

    string find_word(string line)
    {
        // find the last contiguous vowels
        string::iterator c;
        int v;
        int len = line.size();
        int orig_size = len;
        int end_point;
        int found = 0;
        int end_char = 1;
        int end_sub = 0;
        string sub_str;
        for(c= line.end()-1; c != line.begin(); --c)
        {
            v = *c;
            if ( (v == 'y' && (c != line.begin() || c != line.end()-1)) || v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u')
            {
                len -= 1;
                found = 1;
                end_char = 0;
            }
            else
            {
                if (end_char == 1 && v == ' ')
                {
                    end_sub += 1;
                }
                else if (v != ' ')
                {
                    end_char = 0;
                }

                if (found == 0)
                {
                    len -= 1;
                }
                else
                    break;
            }
        }

        sub_str = line.substr(len);
        return sub_str;
    }

};
// BEGIN CUT HERE
int main( int argc, char* argv[] ) {
    {
        string poemARRAY[] = {"problem",
            "anotherproblem",
            "this stupid haiku"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(0, theObject.rhymeScheme(poem),"aab");
    }
    {
        string poemARRAY[] = {"I hope this problem",
            "is a whole lot better than",
            "this stupid haiku"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(0, theObject.rhymeScheme(poem),"abc");
    }

    {
        string poemARRAY[] = {"     ",
            "Measure your height",
            "AND WEIGHT      ",
            "said the doctor",
            "",
            "And make sure to take your pills",
            "   to   cure   your    ills",
            "Every",
            "DAY"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(1, theObject.rhymeScheme(poem)," aab ccde");
    }
    {
        string poemARRAY[] = {"One bright day in the middle of the night",
            "Two dead boys got up to fight",
            "Back to back they faced each other",
            "Drew their swords and shot each other",
            "",
            "A deaf policeman heard the noise",
            "And came to arrest the two dead boys",
            "And if you dont believe this lie is true",
            "Ask the blind man he saw it too"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(2, theObject.rhymeScheme(poem),"aabb cdef");
    }
    {
        string poemARRAY[] = {"",
            "",
            "",
            ""};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(3, theObject.rhymeScheme(poem),"    ");
    }
    {
        string poemARRAY[] = {"This poem has uppercase letters",
            "In its rhyme scheme",
            "Alpha", "Blaster", "Cat", "Desert", "Elephant", "Frog", "Gulch",
            "Horse", "Ireland", "Jam", "Krispy Kreme", "Loofah", "Moo", "Narf",
            "Old", "Pink", "Quash", "Rainbow", "Star", "Tour", "Uvula", "Very",
            "Will", "Xmas", "Young", "Zed", "deception", "comic", "grout",
            "oval", "cable", "rob", "steal", "steel", "weak"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(4, theObject.rhymeScheme(poem),"abcdefghibjkblmnopqrstcuvwxyzABCbDEFG");
    }
    {
        string poemARRAY[] = {" ",
            "     ",
            "This poem",
            "         ",
            " ",
            " ",
            "",
            "Has lots of blank lines",
            " ",
            "      ",
            "                                            ",
            "         ",
            " ",
            "              ",
            "                                                  ",
            "  in      it           "};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(5, theObject.rhymeScheme(poem),"  a    b       c");
    }
    {
        string poemARRAY[] = {"too bad   your",
            "     solution went   sour"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(6, theObject.rhymeScheme(poem),"aa");
    }

}
<commit_msg>solved a topcoder hard problem. C++ concepts are used a lot<commit_after>#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
using namespace std;

vector<string> split( const string& s, const string& delim =" " ) {
    vector<string> res;
    string t;
    for ( int i = 0 ; i != s.size() ; i++ ) {
        if ( delim.find( s[i] ) != string::npos ) {
            if ( !t.empty() ) {
                res.push_back( t );
                t = "";
            }
        } else {
            t += s[i];
        }
    }
    if ( !t.empty() ) {
        res.push_back(t);
    }
    return res;
}

vector<int> splitInt( const string& s, const string& delim =" " ) {
    vector<string> tok = split( s, delim );
    vector<int> res;
    for ( int i = 0 ; i != tok.size(); i++ )
        res.push_back( atoi( tok[i].c_str() ) );
    return res;
}

// BEGIN CUT HERE
#define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))

template<typename T> void print( T a ) {
    cerr << a;
}
static void print( long long a ) {
    cerr << a << "L";
}
static void print( string a ) {
    cerr << '"' << a << '"';
}
template<typename T> void print( vector<T> a ) {
    cerr << "{";
    for ( int i = 0 ; i != a.size() ; i++ ) {
        if ( i != 0 ) cerr << ", ";
        print( a[i] );
    }
    cerr << "}" << endl;
}
template<typename T> void eq( int n, T have, T need ) {
    if ( have == need ) {
        cerr << "Case " << n << " passed." << endl;
    } else {
        cerr << "Case " << n << " failed: expected ";
        print( need );
        cerr << " received ";
        print( have );
        cerr << "." << endl;
    }
}
template<typename T> void eq( int n, vector<T> have, vector<T> need ) {
    if( have.size() != need.size() ) {
        cerr << "Case " << n << " failed: returned " << have.size() << " elements; expected " << need.size() << " elements.";
        print( have );
        print( need );
        return;
    }
    for( int i= 0; i < have.size(); i++ ) {
        if( have[i] != need[i] ) {
            cerr << "Case " << n << " failed. Expected and returned array differ in position " << i << ".";
            print( have );
            print( need );
            return;
        }
    }
    cerr << "Case " << n << " passed." << endl;
}
static void eq( int n, string have, string need ) {
    if ( have == need ) {
        cerr << "Case " << n << " passed." << endl;
    } else {
        cerr << "Case " << n << " failed: expected ";
        print( need );
        cerr << " received ";
        print( have );
        cerr << "." << endl;
    }
}
// END CUT HERE
class Poetry {
public:
    string rhymeScheme(vector <string> poem) {
        vector <string>::iterator string_it;
        string res, line, empty_line;
        string word;
        string::iterator ec;
        map<string,string> rhymes;
        res = "";
        string chars_in_poem = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        int current_char = 0;
        int blank_line = 1;

        for(string_it = poem.begin(); string_it != poem.end(); string_it++)
        {
            line = (*string_it);

            /* lower case it */

            transform(line.begin(),line.end(),line.begin(),::tolower);

            /* check blank line */

            empty_line = line;
            empty_line.erase(std::remove_if(empty_line.begin(), empty_line.end(), (int(*)(int))isspace), empty_line.end());
            if (empty_line.size() == 0)
            {
                res += " ";
                continue;
            }

            /* remove spaces (trailing) and first y */

            word = find_word(line);
            word.erase(std::remove_if(word.begin(), word.end(), (int(*)(int))isspace), word.end());
            if (word[0] == 'y')
                word = word.substr(1);

            /**
             * The idea is form the dictionary of the rhymes and fetch from the
             * dictionary if the rhyme already exist, if not add to the
             * dictionary for the new rhyme created according to the rule.
             */

            if (rhymes.count(word) > 0)
                res += rhymes[word];
            else
            {
                rhymes[word] += chars_in_poem[current_char];
                res += chars_in_poem[current_char];
                current_char++;
            }
        }
        return res;
    }

    string find_word(string line)
    {
        // find the last contiguous vowels
        string::iterator c;
        int v;
        int len = line.size();
        int found = 0;
        string sub_str;
        for(c= line.end()-1; c != line.begin(); --c)
        {
            v = *c;
            if ( (v == 'y' && (c != line.begin() || c != line.end()-1)) || v == 'a' || v == 'e' || v == 'i' || v == 'o' || v == 'u')
            {
                len -= 1;
                found = 1;
            }
            else
            {
                if (found == 0)
                {
                    len -= 1;
                }
                else
                    break;
            }
        }

        sub_str = line.substr(len);
        return sub_str;
    }

};
// BEGIN CUT HERE
int main( int argc, char* argv[] ) {
    {
        string poemARRAY[] = {"problem",
            "anotherproblem",
            "this stupid haiku"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(0, theObject.rhymeScheme(poem),"aab");
    }
    {
        string poemARRAY[] = {"I hope this problem",
            "is a whole lot better than",
            "this stupid haiku"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(0, theObject.rhymeScheme(poem),"abc");
    }

    {
        string poemARRAY[] = {"     ",
            "Measure your height",
            "AND WEIGHT      ",
            "said the doctor",
            "",
            "And make sure to take your pills",
            "   to   cure   your    ills",
            "Every",
            "DAY"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(1, theObject.rhymeScheme(poem)," aab ccde");
    }
    {
        string poemARRAY[] = {"One bright day in the middle of the night",
            "Two dead boys got up to fight",
            "Back to back they faced each other",
            "Drew their swords and shot each other",
            "",
            "A deaf policeman heard the noise",
            "And came to arrest the two dead boys",
            "And if you dont believe this lie is true",
            "Ask the blind man he saw it too"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(2, theObject.rhymeScheme(poem),"aabb cdef");
    }
    {
        string poemARRAY[] = {"",
            "",
            "",
            ""};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(3, theObject.rhymeScheme(poem),"    ");
    }
    {
        string poemARRAY[] = {"This poem has uppercase letters",
            "In its rhyme scheme",
            "Alpha", "Blaster", "Cat", "Desert", "Elephant", "Frog", "Gulch",
            "Horse", "Ireland", "Jam", "Krispy Kreme", "Loofah", "Moo", "Narf",
            "Old", "Pink", "Quash", "Rainbow", "Star", "Tour", "Uvula", "Very",
            "Will", "Xmas", "Young", "Zed", "deception", "comic", "grout",
            "oval", "cable", "rob", "steal", "steel", "weak"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(4, theObject.rhymeScheme(poem),"abcdefghibjkblmnopqrstcuvwxyzABCbDEFG");
    }
    {
        string poemARRAY[] = {" ",
            "     ",
            "This poem",
            "         ",
            " ",
            " ",
            "",
            "Has lots of blank lines",
            " ",
            "      ",
            "                                            ",
            "         ",
            " ",
            "              ",
            "                                                  ",
            "  in      it           "};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(5, theObject.rhymeScheme(poem),"  a    b       c");
    }
    {
        string poemARRAY[] = {"too bad   your",
            "     solution went   sour"};
        vector <string> poem( poemARRAY, poemARRAY+ARRSIZE(poemARRAY) );
        Poetry theObject;
        eq(6, theObject.rhymeScheme(poem),"aa");
    }

}
<|endoftext|>


<commit_before>#pragma once

#include "attribute.hpp"
#include "blackhole/utils/format.hpp"

namespace blackhole {

namespace log {

class record_t {
    //!@todo: Here will be non-const `attribute_set_view_t`.
    attributes_t attributes_;

public:
    /*!
     * Default constructor.
     * Creates an empty record that is equivalent to the invalid record handle.
     * @todo: Test post condition: this->valid() == false
     */
    record_t() = default;

    /*!
     * Conversion constructor.
     * Creates a record with specified attribute set.
     * @todo: Test post condition: this->attributes() == prev attributes.
     * @todo: Instead of `attributes_t` move `attribute_set_view_t`.
     */
    record_t(attributes_t&& attributes) :
        attributes_(std::move(attributes))
    {}

    /*!
     * Conversion to an unspecified boolean type.
     * Return true if the record is valid.
     */
    operator bool() const noexcept {
        return valid();
    }

    /*!
     * Check if the record is valid.
     * A record is considered valid if it contains at least one attribute.
     */
    bool valid() const noexcept {
        return !attributes_.empty();
    }

    /*!
     * Return a const reference to the view of attribute set attached to this
     * record.
     */
    const log::attributes_t& attributes() const noexcept {
        return attributes_;
    }

    /*!
     * Insert attribute pair into the record.
     */
    void insert(attribute_pair_t pair) {
        attributes_.insert(std::move(pair));
    }

    template<typename T>
    inline T extract(const std::string& name) const {
        return blackhole::attribute::traits<T>::extract(attributes_, name);
    }
};

} // namespace log

} // namespace blackhole
<commit_msg>[Tasks] More testing tasks.<commit_after>#pragma once

#include "attribute.hpp"
#include "blackhole/utils/format.hpp"

namespace blackhole {

namespace log {

class record_t {
    //!@todo: Here will be non-const `attribute_set_view_t`.
    attributes_t attributes_;

public:
    /*!
     * Default constructor.
     * Creates an empty record that is equivalent to the invalid record handle.
     * @todo: Test post condition: this->valid() == false
     */
    record_t() = default;

    /*!
     * Conversion constructor.
     * Creates a record with specified attribute set.
     * @todo: Test post condition: this->attributes() == prev attributes.
     * @todo: Instead of `attributes_t` move `attribute_set_view_t`.
     */
    record_t(attributes_t&& attributes) :
        attributes_(std::move(attributes))
    {}

    /*!
     * Conversion to an unspecified boolean type.
     * Return true if the record is valid.
     * @todo: Test.
     */
    operator bool() const noexcept {
        return valid();
    }

    /*!
     * Check if the record is valid.
     * A record is considered valid if it contains at least one attribute.
     * @todo: Test.
     */
    bool valid() const noexcept {
        return !attributes_.empty();
    }

    /*!
     * Return a const reference to the view of attribute set attached to this
     * record.
     * @todo: Test.
     */
    const log::attributes_t& attributes() const noexcept {
        return attributes_;
    }

    /*!
     * Insert attribute pair into the record.
     * @todo: Test.
     */
    void insert(attribute_pair_t pair) {
        attributes_.insert(std::move(pair));
    }

    /*!
     * Try to extract attribute with specified name and convert it to type T.
     * @todo: What throws? Test invalid name and invalid type.
     */
    template<typename T>
    inline T extract(const std::string& name) const {
        return blackhole::attribute::traits<T>::extract(attributes_, name);
    }
};

} // namespace log

} // namespace blackhole
<|endoftext|>


<commit_before>#include "MoveDummy.h"
#include "ObjectDummy.h"
#include "BodyDummy.h"
#include "ShapeCapsule.h"

#include "Utils.h"
#include "Engine.h"
#include "Physics.h"
#include "Game.h"
#include "World.h"

#define MOVE_DUMMY_IFPS			(1.0f/100.0f)
#define MOVE_DUMMY_CLAMP           89.9f
#define MOVE_DUMMY_COLLISIONS		1

using namespace MathLib;

CMoveDummy::CMoveDummy()		//캯
{
	m_pObject = new CObjectDummy();		//һʵ
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(0.5f, 1.0f);

	SetCollisionMask(1);
	Clear();
}

CMoveDummy::~CMoveDummy()
{
	m_pDummy->SetObject(NULL);
	SAFE_DELETE(m_pObject);
	SAFE_DELETE(m_pDummy);
}

void CMoveDummy::SetCollision(int c)
{
	m_nCollision = c;
}

int CMoveDummy::GetCollision() const
{
	return m_nCollision;
}

void CMoveDummy::SetCollisionMask(int m)
{
	m_pShape->SetCollisionMask(m);
}

int CMoveDummy::GetCollisionMask() const
{
	return m_nCollisionMask;
}

void CMoveDummy::SetGround(int g)
{
	m_nGround = g;
}

int CMoveDummy::GetGround() const
{
	return m_nGround;
}

void CMoveDummy::SetCeiling(int c)
{
	m_nCeiling = c;
}

int CMoveDummy::GetCeiling() const
{
	return m_nCeiling;
}

void CMoveDummy::SetPosition(const MathLib::vec3& p)
{
	m_vPosition = p;
}

const MathLib::vec3& CMoveDummy::GetPosition() const
{
	return m_vPosition;
}

void CMoveDummy::SetCollisionRadius(float radius)
{
	if (!Compare(m_pShape->GetRadius(), radius))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (radius - m_pShape->GetRadius()))) * m_pDummy->GetTransform());
		m_pShape->SetRadius(radius);
	}

	Update_Bounds();
}

float CMoveDummy::GetCollisionRadius() const
{
	return m_pShape->GetRadius();
}

void CMoveDummy::SetCollisionHeight(float height)
{
	if (!Compare(m_pShape->GetHeight(), height))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (height - m_pShape->GetHeight()) * 0.5f)) * m_pDummy->GetTransform());
		m_pShape->SetHeight(height);
	}

	Update_Bounds();
}
float CMoveDummy::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}

<commit_msg>Signed-off-by: mrlitong <litongtongxue@gmail.com><commit_after>#include "MoveDummy.h"
#include "ObjectDummy.h"
#include "BodyDummy.h"
#include "ShapeCapsule.h"

#include "Utils.h"
#include "Engine.h"
#include "Physics.h"
#include "Game.h"
#include "World.h"

#define MOVE_DUMMY_IFPS			(1.0f/100.0f)
#define MOVE_DUMMY_CLAMP           89.9f
#define MOVE_DUMMY_COLLISIONS		1

using namespace MathLib;

CMoveDummy::CMoveDummy()		//캯
{
	m_pObject = new CObjectDummy();		//һʵ
	m_pDummy = new CBodyDummy();
	m_pShape = new CShapeCapsule(0.5f, 1.0f);

	SetCollisionMask(1);
	Clear();
}

CMoveDummy::~CMoveDummy()
{
	m_pDummy->SetObject(NULL);
	SAFE_DELETE(m_pObject);
	SAFE_DELETE(m_pDummy);
}

void CMoveDummy::SetCollision(int c)
{
	m_nCollision = c;
}

int CMoveDummy::GetCollision() const
{
	return m_nCollision;
}

void CMoveDummy::SetCollisionMask(int m)
{
	m_pShape->SetCollisionMask(m);
}

int CMoveDummy::GetCollisionMask() const
{
	return m_nCollisionMask;
}

void CMoveDummy::SetGround(int g)
{
	m_nGround = g;
}

int CMoveDummy::GetGround() const
{
	return m_nGround;
}

void CMoveDummy::SetCeiling(int c)
{
	m_nCeiling = c;
}

int CMoveDummy::GetCeiling() const
{
	return m_nCeiling;
}

void CMoveDummy::SetPosition(const MathLib::vec3& p)
{
	m_vPosition = p;
}

const MathLib::vec3& CMoveDummy::GetPosition() const
{
	return m_vPosition;
}

void CMoveDummy::SetCollisionRadius(float radius)
{
	if (!Compare(m_pShape->GetRadius(), radius))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (radius - m_pShape->GetRadius()))) * m_pDummy->GetTransform());
		m_pShape->SetRadius(radius);
	}

	Update_Bounds();
}

float CMoveDummy::GetCollisionRadius() const
{
	return m_pShape->GetRadius();
}

void CMoveDummy::SetCollisionHeight(float height)
{
	if (!Compare(m_pShape->GetHeight(), height))
	{
		m_pDummy->SetPreserveTransform(Mat4(Translate(m_vUp * (height - m_pShape->GetHeight()) * 0.5f)) * m_pDummy->GetTransform());
		m_pShape->SetHeight(height);
	}

	Update_Bounds();
}
float CMoveDummy::GetCollisionHeight() const
{
	return m_pShape->GetHeight();
}

void CMoveDummy::SetUp(const MathLib::vec3& u)
{
	m_vUp = u;
}

<|endoftext|>


<commit_before>#include "Particle3DToLuaString.h"

#include <easybuilder.h>

namespace lua = ebuilder::lua;

namespace librespacker
{

void Particle3DToLuaString::Pack(const PackParticle3D* p3d, ebuilder::CodeGenerator& gen)
{
	gen.line("{");
	gen.tab();

	lua::comments(gen, "file: " + p3d->GetFilepath());

	lua::assign_with_end(gen, "type", "\"particle3d\"");
	lua::assign_with_end(gen, "id", d2d::StringTools::ToString(p3d->GetID()));
	if (!p3d->export_name.empty()) {
		lua::assign_with_end(gen, "export", "\"" + p3d->export_name + "\"");
	}

	{
		lua::TableAssign ta(gen, "component", true);
		for (int i = 0, n = p3d->components.size(); i < n; ++i) {
			PackComponent(p3d->components[i], gen);
		}
	}
	PackPS(p3d, gen);

	gen.detab();
	gen.line("},");
}

void Particle3DToLuaString::PackPS(const PackParticle3D* p3d, ebuilder::CodeGenerator& gen)
{
	lua::connect(gen, 1,
		lua::assign("capacity", p3d->capacity));

	lua::connect(gen, 2,
		lua::assign("emission_time", TransTime(p3d->emission_time)),
		lua::assign("count", p3d->count));

	lua::connect(gen, 2,
		lua::assign("life", TransTime(p3d->life)),
		lua::assign("life_var", TransTime(p3d->life_var)));

	lua::connect(gen, 4,
		lua::assign("hori", TransRadian(p3d->hori)),
		lua::assign("hori_var", TransRadian(p3d->hori_var)),
		lua::assign("vert", TransRadian(p3d->vert)),
		lua::assign("vert_var", TransRadian(p3d->vert_var)));

	lua::connect(gen, 4,
		lua::assign("spd", TransFloat(p3d->spd)),
		lua::assign("spd_var", TransFloat(p3d->spd_var)),
		lua::assign("angular_spd", TransRadian(p3d->angular_spd)),
		lua::assign("angular_spd_var", TransRadian(p3d->angular_spd_var)));

	lua::connect(gen, 4,
		lua::assign("dis_region", TransFloat(p3d->dis_region)),
		lua::assign("dis_region_var", TransFloat(p3d->dis_region_var)),
		lua::assign("dis_spd", TransFloat(p3d->dis_spd)),
		lua::assign("dis_spd_var", TransFloat(p3d->dis_spd_var)));

	lua::connect(gen, 1,
		lua::assign("gravity", TransFloat(p3d->gravity)));

	lua::connect(gen, 2,
		lua::assign("linear_acc", TransFloat(p3d->linear_acc)),
		lua::assign("linear_acc_var", TransFloat(p3d->linear_acc_var)));

	lua::connect(gen, 1,
		lua::assign("fadeout_time", TransTime(p3d->fadeout_time)));

	lua::connect(gen, 1,
		lua::assign("ground", p3d->ground));

	lua::connect(gen, 2,
		lua::assign("start_radius", TransFloat(p3d->start_radius)),
		lua::assign("is_start_radius_3d", TransBool(p3d->is_start_radius_3d)));

	lua::connect(gen, 1,
		lua::assign("orient_to_movement", TransBool(p3d->orient_to_movement)));
}

void Particle3DToLuaString::PackComponent(const PackParticle3D::Component& comp,
										  ebuilder::CodeGenerator& gen)
{
	lua::TableAssign ta(gen, "", true);

	lua::connect(gen, 1,
		lua::assign("id", comp.node->GetID()));

	lua::connect(gen, 2,
		lua::assign("scale_start", TransFloatX100(comp.scale_start)),
		lua::assign("scale_end", TransFloatX100(comp.scale_end)));

	lua::connect(gen, 2,
		lua::assign("angle", TransFloat(comp.angle)),
		lua::assign("angle_var", TransFloat(comp.angle_var)));

	lua::connect(gen, 4,
		lua::assign("col_mul", comp.col_mul),
		lua::assign("col_add", comp.col_add),
		lua::assign("alpha_start", comp.alpha_start),
		lua::assign("alpha_end", comp.alpha_end));
}

int Particle3DToLuaString::TransTime(float time)
{
	return floor(time * 1000 + 0.5f);
}

int Particle3DToLuaString::TransRadian(float r)
{
	return floor(r * d2d::TRANS_RAD_TO_DEG + 0.5f);
}

int Particle3DToLuaString::TransFloat(float f)
{
	return floor(f + 0.5f);
}

int Particle3DToLuaString::TransFloatX100(float f)
{
	return TransFloat(100 * f);
}

std::string Particle3DToLuaString::TransBool(bool b)
{
	return b ? "true" : "false";
}

}<commit_msg>[FIXED] pack p3d lua<commit_after>#include "Particle3DToLuaString.h"

#include <easybuilder.h>

namespace lua = ebuilder::lua;

namespace librespacker
{

void Particle3DToLuaString::Pack(const PackParticle3D* p3d, ebuilder::CodeGenerator& gen)
{
	gen.line("{");
	gen.tab();

	lua::comments(gen, "file: " + p3d->GetFilepath());

	lua::assign_with_end(gen, "type", "\"particle3d\"");
	lua::assign_with_end(gen, "id", d2d::StringTools::ToString(p3d->GetID()));
	if (!p3d->export_name.empty()) {
		lua::assign_with_end(gen, "export", "\"" + p3d->export_name + "\"");
	}

	{
		lua::TableAssign ta(gen, "component", true);
		for (int i = 0, n = p3d->components.size(); i < n; ++i) {
			PackComponent(p3d->components[i], gen);
		}
	}
	PackPS(p3d, gen);

	gen.detab();
	gen.line("},");
}

void Particle3DToLuaString::PackPS(const PackParticle3D* p3d, ebuilder::CodeGenerator& gen)
{
	lua::connect(gen, 1,
		lua::assign("capacity", p3d->capacity));

	lua::connect(gen, 2,
		lua::assign("emission_time", TransTime(p3d->emission_time)),
		lua::assign("count", p3d->count));

	lua::connect(gen, 2,
		lua::assign("life", TransTime(p3d->life)),
		lua::assign("life_var", TransTime(p3d->life_var)));

	lua::connect(gen, 4,
		lua::assign("hori", TransRadian(p3d->hori)),
		lua::assign("hori_var", TransRadian(p3d->hori_var)),
		lua::assign("vert", TransRadian(p3d->vert)),
		lua::assign("vert_var", TransRadian(p3d->vert_var)));

	lua::connect(gen, 4,
		lua::assign("spd", TransFloat(p3d->spd)),
		lua::assign("spd_var", TransFloat(p3d->spd_var)),
		lua::assign("angular_spd", TransRadian(p3d->angular_spd)),
		lua::assign("angular_spd_var", TransRadian(p3d->angular_spd_var)));

	lua::connect(gen, 4,
		lua::assign("dis_region", TransFloat(p3d->dis_region)),
		lua::assign("dis_region_var", TransFloat(p3d->dis_region_var)),
		lua::assign("dis_spd", TransFloat(p3d->dis_spd)),
		lua::assign("dis_spd_var", TransFloat(p3d->dis_spd_var)));

	lua::connect(gen, 1,
		lua::assign("gravity", TransFloat(p3d->gravity)));

	lua::connect(gen, 2,
		lua::assign("linear_acc", TransFloat(p3d->linear_acc)),
		lua::assign("linear_acc_var", TransFloat(p3d->linear_acc_var)));

	lua::connect(gen, 1,
		lua::assign("fadeout_time", TransTime(p3d->fadeout_time)));

	lua::connect(gen, 1,
		lua::assign("ground", p3d->ground));

	lua::connect(gen, 2,
		lua::assign("start_radius", TransFloat(p3d->start_radius)),
		lua::assign("is_start_radius_3d", TransBool(p3d->is_start_radius_3d)));

	lua::connect(gen, 1,
		lua::assign("orient_to_movement", TransBool(p3d->orient_to_movement)));
}

void Particle3DToLuaString::PackComponent(const PackParticle3D::Component& comp,
										  ebuilder::CodeGenerator& gen)
{
	lua::TableAssign ta(gen, "", true);

	lua::connect(gen, 1,
		lua::assign("id", comp.node->GetID()));

	lua::connect(gen, 2,
		lua::assign("scale_start", TransFloatX100(comp.scale_start)),
		lua::assign("scale_end", TransFloatX100(comp.scale_end)));

	lua::connect(gen, 2,
		lua::assign("angle", TransFloat(comp.angle)),
		lua::assign("angle_var", TransFloat(comp.angle_var)));

	lua::connect(gen, 4,
		lua::assign("col_mul", comp.col_mul),
		lua::assign("col_add", comp.col_add),
		lua::assign("alpha_start", (int)comp.alpha_start),
		lua::assign("alpha_end", (int)comp.alpha_end));
}

int Particle3DToLuaString::TransTime(float time)
{
	return floor(time * 1000 + 0.5f);
}

int Particle3DToLuaString::TransRadian(float r)
{
	return floor(r * d2d::TRANS_RAD_TO_DEG + 0.5f);
}

int Particle3DToLuaString::TransFloat(float f)
{
	return floor(f + 0.5f);
}

int Particle3DToLuaString::TransFloatX100(float f)
{
	return TransFloat(100 * f);
}

std::string Particle3DToLuaString::TransBool(bool b)
{
	return b ? "true" : "false";
}

}<|endoftext|>


<commit_before>// Copyright (c) 2013-2016 mogemimi. Distributed under the MIT license.

#include "SpriteFont.hpp"
#include "TrueTypeFont.hpp"
#include "SpriteBatchRenderer.hpp"
#include "Pomdog/Math/Color.hpp"
#include "Pomdog/Math/Matrix4x4.hpp"
#include "Pomdog/Math/Vector2.hpp"
#include "Pomdog/Math/Vector3.hpp"
#include "Pomdog/Math/Radian.hpp"
#include "Pomdog/Graphics/Texture2D.hpp"
#include "Pomdog/Utility/Assert.hpp"

#ifndef _MSC_VER
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"
#endif
#include <utfcpp/source/utf8.h>
#ifndef _MSC_VER
#pragma clang diagnostic pop
#endif

#include <unordered_map>

namespace Pomdog {
namespace {

std::vector<std::uint8_t> ConvertTextureDataByteToByte4(const std::uint8_t* source, size_t size)
{
    std::vector<std::uint8_t> output;
    output.reserve(size * 4);

    for (size_t i = 0; i < size; ++i) {
        output.push_back(255);
        output.push_back(255);
        output.push_back(255);
        output.push_back(source[i]);
    }
    return std::move(output);
}

} // unnamed namespace

// MARK: - SpriteFont::Impl

class SpriteFont::Impl {
public:
    typedef Detail::SpriteFonts::Glyph Glyph;

    static constexpr int TextureWidth = 512;
    static constexpr int TextureHeight = 512;

    std::unordered_map<char32_t, Glyph> spriteFontMap;

    char32_t defaultCharacter;
    float lineSpacing;
    std::uint16_t spacing;

    Impl(
        std::vector<std::shared_ptr<Texture2D>> && textures,
        const std::vector<Detail::SpriteFonts::Glyph>& glyphs,
        char32_t defaultCharacter,
        std::int16_t spacing,
        std::int16_t lineSpacing);

    Impl(
        const std::shared_ptr<GraphicsDevice>& graphicsDevice,
        const std::shared_ptr<TrueTypeFont>& font,
        char32_t defaultCharacter,
        std::int16_t lineSpacing);

    Vector2 MeasureString(const std::string& text) const;

    void Draw(
        SpriteBatchRenderer & spriteBatch,
        const std::string& text,
        const Vector2& position,
        const Color& color);

    void Draw(
        SpriteBatchRenderer & spriteBatch,
        const std::string& text,
        const Vector2& position,
        const Color& color,
        const Radian<float>& rotation,
        //const Vector2& originPivot,
        const Vector2& scale);

    void PrepareFonts(const std::string& text);

private:
    std::vector<std::shared_ptr<Texture2D>> textures;
    std::shared_ptr<GraphicsDevice> graphicsDevice;
    std::shared_ptr<TrueTypeFont> font;
    std::vector<std::uint8_t> pixelData;
    Point2D currentPoint;
    int bottomY;
};
constexpr int SpriteFont::Impl::TextureWidth;
constexpr int SpriteFont::Impl::TextureHeight;

SpriteFont::Impl::Impl(
    std::vector<std::shared_ptr<Texture2D>> && texturesIn,
    const std::vector<Detail::SpriteFonts::Glyph>& glyphsIn,
    char32_t defaultCharacterIn,
    std::int16_t spacingIn,
    std::int16_t lineSpacingIn)
    : textures(std::move(texturesIn))
    , defaultCharacter(defaultCharacterIn)
    , spacing(spacingIn)
    , lineSpacing(lineSpacingIn)
{
    for (auto & glyph: glyphsIn) {
        spriteFontMap.emplace(glyph.Character, glyph);
    }
}

SpriteFont::Impl::Impl(
    const std::shared_ptr<GraphicsDevice>& graphicsDeviceIn,
    const std::shared_ptr<TrueTypeFont>& fontIn,
    char32_t defaultCharacterIn,
    std::int16_t lineSpacingIn)
    : graphicsDevice(graphicsDeviceIn)
    , font(fontIn)
    , defaultCharacter(defaultCharacterIn)
    , spacing(0)
    , lineSpacing(lineSpacingIn)
{
    POMDOG_ASSERT(font);

    pixelData.resize(TextureWidth * TextureHeight, 0);
    currentPoint = {1, 1};
    bottomY = 1;

    auto texture = std::make_shared<Texture2D>(graphicsDevice,
        TextureWidth, TextureHeight, false, SurfaceFormat::R8G8B8A8_UNorm);
    textures.push_back(texture);
}

void SpriteFont::Impl::PrepareFonts(const std::string& text)
{
    POMDOG_ASSERT(!text.empty());

    if (!graphicsDevice || !font) {
        return;
    }

    float fontSize = lineSpacing;

    bool needToFetchPixelData = false;

    auto fetchTextureData = [&] {
        if (needToFetchPixelData) {
            auto texture = textures.back();
            texture->SetData(ConvertTextureDataByteToByte4(pixelData.data(), pixelData.size()).data());
            needToFetchPixelData = false;
        }
    };

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd) {
        const auto character = utf8::next(textIter, textIterEnd);

        if (spriteFontMap.find(character) != std::end(spriteFontMap)) {
            continue;
        }

        auto glyph = font->RasterizeGlyph(character, fontSize, TextureWidth,
        [&](int glyphWidth, int glyphHeight, Point2D & pointOut, std::uint8_t* & output) {
            if (currentPoint.X + glyphWidth + 1 >= TextureWidth) {
                // advance to next row
                currentPoint.Y = bottomY;
                currentPoint.X = 1;
            }
            if (currentPoint.Y + glyphHeight + 1 >= TextureHeight) {
                fetchTextureData();
                std::fill(std::begin(pixelData), std::end(pixelData), 0);

                auto textureNew = std::make_shared<Texture2D>(graphicsDevice,
                    TextureWidth, TextureHeight, false, SurfaceFormat::R8G8B8A8_UNorm);
                textures.push_back(textureNew);
                currentPoint = {1, 1};
                bottomY = 1;
            }

            POMDOG_ASSERT(currentPoint.X + glyphWidth < TextureWidth);
            POMDOG_ASSERT(currentPoint.Y + glyphHeight < TextureHeight);

            pointOut = currentPoint;
            output = pixelData.data();
        });

        if (!glyph) {
            continue;
        }

        currentPoint.X = currentPoint.X + glyph->Subrect.Width + 1;
        bottomY = std::max(bottomY, currentPoint.Y + glyph->Subrect.Height + 1);

        POMDOG_ASSERT(!textures.empty() && textures.size() > 0);
        glyph->TexturePage = textures.size() - 1;

        spriteFontMap.emplace(glyph->Character, *glyph);
        needToFetchPixelData = true;
    }

    fetchTextureData();
}

Vector2 SpriteFont::Impl::MeasureString(const std::string& text) const
{
    POMDOG_ASSERT(!text.empty());

    Vector2 result = Vector2::Zero;
    Vector2 currentPosition = Vector2::Zero;

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd)
    {
        const auto character = utf8::next(textIter, textIterEnd);

        if (character == U'\n') {
            currentPosition.X = 0;
            currentPosition.Y -= lineSpacing;
            continue;
        }

        auto iter = spriteFontMap.find(character);
        if (iter == std::end(spriteFontMap)) {
            iter = spriteFontMap.find(defaultCharacter);
            POMDOG_ASSERT(iter != std::end(spriteFontMap));
        }

        POMDOG_ASSERT(iter != std::end(spriteFontMap));
        auto const & glyph = iter->second;

        currentPosition.X += (glyph.XAdvance - spacing);

        result.X = std::max(result.X, currentPosition.X);
        result.Y = std::max(result.Y, currentPosition.Y);
    }

    return std::move(result);
}

void SpriteFont::Impl::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color)
{
    if (text.empty()) {
        return;
    }

    if (textures.empty()) {
        return;
    }

    Vector2 currentPosition = position;

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd)
    {
        const auto character = utf8::next(textIter, textIterEnd);

        if (character == U'\n') {
            currentPosition.X = position.X;
            currentPosition.Y -= lineSpacing;
            continue;
        }

        auto iter = spriteFontMap.find(character);
        if (iter == std::end(spriteFontMap)) {
            iter = spriteFontMap.find(defaultCharacter);
            if (iter == std::end(spriteFontMap)) {
                continue;
            }
        }

        POMDOG_ASSERT(iter != std::end(spriteFontMap));
        auto const & glyph = iter->second;

        if (glyph.Subrect.Width > 0 && glyph.Subrect.Height > 0)
        {
            POMDOG_ASSERT(glyph.TexturePage >= 0);
            POMDOG_ASSERT(glyph.TexturePage < static_cast<int>(textures.size()));

            spriteBatch.Draw(textures[glyph.TexturePage],
                currentPosition + Vector2(glyph.XOffset, -glyph.YOffset),
                glyph.Subrect, color, 0.0f, Vector2{0.0f, 1.0f}, Vector2{1.0f, 1.0f});
        }

        currentPosition.X += (glyph.XAdvance - spacing);
    }
}

void SpriteFont::Impl::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color,
    const Radian<float>& rotation,
    //const Vector2& originPivot,
    const Vector2& scale)
{
    if (text.empty()) {
        return;
    }

    if (textures.empty()) {
        return;
    }

    Vector2 currentPosition = position;

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd)
    {
        const auto character = utf8::next(textIter, textIterEnd);

        if (character == U'\n') {
            currentPosition.X = 0.0f;
            currentPosition.Y += lineSpacing * scale.Y;
            continue;
        }

        auto iter = spriteFontMap.find(character);
        if (iter == std::end(spriteFontMap)) {
            iter = spriteFontMap.find(defaultCharacter);
            if (iter == std::end(spriteFontMap)) {
                continue;
            }
        }

        POMDOG_ASSERT(iter != std::end(spriteFontMap));
        auto const & glyph = iter->second;

        if (glyph.Subrect.Width > 0 && glyph.Subrect.Height > 0)
        {
            POMDOG_ASSERT(glyph.TexturePage >= 0);
            POMDOG_ASSERT(glyph.TexturePage < static_cast<int>(textures.size()));

            spriteBatch.Draw(textures[glyph.TexturePage],
                currentPosition + Vector2(glyph.XOffset, -glyph.YOffset) * scale,
                glyph.Subrect, color, 0.0f, Vector2{0.0f, 1.0f}, scale);
        }

        currentPosition.X += (glyph.XAdvance - spacing) * scale.X;
    }
}

// MARK: - SpriteFont

SpriteFont::SpriteFont(
    std::vector<std::shared_ptr<Texture2D>> && textures,
    const std::vector<Detail::SpriteFonts::Glyph>& glyphs,
    char32_t defaultCharacter,
    std::int16_t spacing,
    std::int16_t lineSpacing)
    : impl(std::make_unique<Impl>(std::move(textures), glyphs, defaultCharacter, spacing, lineSpacing))
{
}

SpriteFont::SpriteFont(
    const std::shared_ptr<GraphicsDevice>& graphicsDevice,
    const std::shared_ptr<TrueTypeFont>& font,
    char32_t defaultCharacter,
    std::int16_t lineSpacing)
    : impl(std::make_unique<Impl>(graphicsDevice, font, defaultCharacter, lineSpacing))
{
}

SpriteFont::~SpriteFont() = default;

Vector2 SpriteFont::MeasureString(const std::string& utf8String) const
{
    if (utf8String.empty()) {
        return Vector2::Zero;
    }
    return impl->MeasureString(utf8String);
}

char32_t SpriteFont::GetDefaultCharacter() const
{
    POMDOG_ASSERT(impl);
    return impl->defaultCharacter;
}

void SpriteFont::SetDefaultCharacter(char32_t character)
{
    POMDOG_ASSERT(impl);
    POMDOG_ASSERT(ContainsCharacter(character));
    impl->defaultCharacter = character;
}

float SpriteFont::GetLineSpacing() const
{
    POMDOG_ASSERT(impl);
    return impl->lineSpacing;
}

void SpriteFont::SetLineSpacing(float lineSpacingIn)
{
    POMDOG_ASSERT(impl);
    impl->lineSpacing = lineSpacingIn;
}

bool SpriteFont::ContainsCharacter(char32_t character) const
{
    POMDOG_ASSERT(impl);
    return impl->spriteFontMap.find(character) != std::end(impl->spriteFontMap);
}

void SpriteFont::Begin(
    const std::shared_ptr<GraphicsCommandList>& commandList,
    SpriteBatchRenderer & spriteBatch,
    const Matrix4x4& transformMatrix)
{
    POMDOG_ASSERT(impl);
    POMDOG_ASSERT(commandList);

    spriteBatch.Begin(commandList, transformMatrix);

//    spriteBatch.Begin(SpriteSortMode::Deferred, Matrix4x4::CreateRotationZ(rotation)
//        * Matrix4x4::CreateScale({scale, 1.0f})
//        * Matrix4x4::CreateTranslation({position, 0.0f})
//        * transformMatrix);
}

void SpriteFont::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color)
{
    if (text.empty()) {
        return;
    }

    impl->PrepareFonts(text);
    impl->Draw(spriteBatch, text, position, color);
}

void SpriteFont::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color,
    const Radian<float>& rotation,
    //const Vector2& originPivot,
    float scale)
{
    this->Draw(spriteBatch, text, position, color,
        rotation, Vector2{scale, scale});
}

void SpriteFont::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color,
    const Radian<float>& rotation,
    //const Vector2& originPivot,
    const Vector2& scale)
{
    if (text.empty()) {
        return;
    }

    impl->PrepareFonts(text);
    impl->Draw(spriteBatch, text, position, color,
        rotation, scale);
}

void SpriteFont::End(SpriteBatchRenderer & spriteBatch)
{
    spriteBatch.End();
}

} // namespace Pomdog
<commit_msg>Fix SpriteFont bug<commit_after>// Copyright (c) 2013-2016 mogemimi. Distributed under the MIT license.

#include "SpriteFont.hpp"
#include "TrueTypeFont.hpp"
#include "SpriteBatchRenderer.hpp"
#include "Pomdog/Math/Color.hpp"
#include "Pomdog/Math/Matrix4x4.hpp"
#include "Pomdog/Math/Vector2.hpp"
#include "Pomdog/Math/Vector3.hpp"
#include "Pomdog/Math/Radian.hpp"
#include "Pomdog/Graphics/Texture2D.hpp"
#include "Pomdog/Utility/Assert.hpp"

#ifndef _MSC_VER
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wshadow"
#endif
#include <utfcpp/source/utf8.h>
#ifndef _MSC_VER
#pragma clang diagnostic pop
#endif

#include <unordered_map>

namespace Pomdog {
namespace {

std::vector<std::uint8_t> ConvertTextureDataByteToByte4(const std::uint8_t* source, size_t size)
{
    std::vector<std::uint8_t> output;
    output.reserve(size * 4);

    for (size_t i = 0; i < size; ++i) {
        output.push_back(255);
        output.push_back(255);
        output.push_back(255);
        output.push_back(source[i]);
    }
    return std::move(output);
}

} // unnamed namespace

// MARK: - SpriteFont::Impl

class SpriteFont::Impl {
public:
    typedef Detail::SpriteFonts::Glyph Glyph;

    static constexpr int TextureWidth = 512;
    static constexpr int TextureHeight = 512;

    std::unordered_map<char32_t, Glyph> spriteFontMap;

    char32_t defaultCharacter;
    float lineSpacing;
    std::uint16_t spacing;

    Impl(
        std::vector<std::shared_ptr<Texture2D>> && textures,
        const std::vector<Detail::SpriteFonts::Glyph>& glyphs,
        char32_t defaultCharacter,
        std::int16_t spacing,
        std::int16_t lineSpacing);

    Impl(
        const std::shared_ptr<GraphicsDevice>& graphicsDevice,
        const std::shared_ptr<TrueTypeFont>& font,
        char32_t defaultCharacter,
        std::int16_t lineSpacing);

    Vector2 MeasureString(const std::string& text) const;

    void Draw(
        SpriteBatchRenderer & spriteBatch,
        const std::string& text,
        const Vector2& position,
        const Color& color);

    void Draw(
        SpriteBatchRenderer & spriteBatch,
        const std::string& text,
        const Vector2& position,
        const Color& color,
        const Radian<float>& rotation,
        //const Vector2& originPivot,
        const Vector2& scale);

    void PrepareFonts(const std::string& text);

private:
    std::vector<std::shared_ptr<Texture2D>> textures;
    std::shared_ptr<GraphicsDevice> graphicsDevice;
    std::shared_ptr<TrueTypeFont> font;
    std::vector<std::uint8_t> pixelData;
    Point2D currentPoint;
    int bottomY;
};
constexpr int SpriteFont::Impl::TextureWidth;
constexpr int SpriteFont::Impl::TextureHeight;

SpriteFont::Impl::Impl(
    std::vector<std::shared_ptr<Texture2D>> && texturesIn,
    const std::vector<Detail::SpriteFonts::Glyph>& glyphsIn,
    char32_t defaultCharacterIn,
    std::int16_t spacingIn,
    std::int16_t lineSpacingIn)
    : textures(std::move(texturesIn))
    , defaultCharacter(defaultCharacterIn)
    , spacing(spacingIn)
    , lineSpacing(lineSpacingIn)
{
    for (auto & glyph: glyphsIn) {
        spriteFontMap.emplace(glyph.Character, glyph);
    }
}

SpriteFont::Impl::Impl(
    const std::shared_ptr<GraphicsDevice>& graphicsDeviceIn,
    const std::shared_ptr<TrueTypeFont>& fontIn,
    char32_t defaultCharacterIn,
    std::int16_t lineSpacingIn)
    : graphicsDevice(graphicsDeviceIn)
    , font(fontIn)
    , defaultCharacter(defaultCharacterIn)
    , spacing(0)
    , lineSpacing(lineSpacingIn)
{
    POMDOG_ASSERT(font);

    pixelData.resize(TextureWidth * TextureHeight, 0);
    currentPoint = {1, 1};
    bottomY = 1;

    auto texture = std::make_shared<Texture2D>(graphicsDevice,
        TextureWidth, TextureHeight, false, SurfaceFormat::R8G8B8A8_UNorm);
    textures.push_back(texture);
}

void SpriteFont::Impl::PrepareFonts(const std::string& text)
{
    POMDOG_ASSERT(!text.empty());

    if (!graphicsDevice || !font) {
        return;
    }

    float fontSize = lineSpacing;

    bool needToFetchPixelData = false;

    auto fetchTextureData = [&] {
        if (needToFetchPixelData) {
            auto texture = textures.back();
            texture->SetData(ConvertTextureDataByteToByte4(pixelData.data(), pixelData.size()).data());
            needToFetchPixelData = false;
        }
    };

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd) {
        const auto character = utf8::next(textIter, textIterEnd);

        if (spriteFontMap.find(character) != std::end(spriteFontMap)) {
            continue;
        }

        auto glyph = font->RasterizeGlyph(character, fontSize, TextureWidth,
        [&](int glyphWidth, int glyphHeight, Point2D & pointOut, std::uint8_t* & output) {
            if (currentPoint.X + glyphWidth + 1 >= TextureWidth) {
                // advance to next row
                currentPoint.Y = bottomY;
                currentPoint.X = 1;
            }
            if (currentPoint.Y + glyphHeight + 1 >= TextureHeight) {
                fetchTextureData();
                std::fill(std::begin(pixelData), std::end(pixelData), 0);

                auto textureNew = std::make_shared<Texture2D>(graphicsDevice,
                    TextureWidth, TextureHeight, false, SurfaceFormat::R8G8B8A8_UNorm);
                textures.push_back(textureNew);
                currentPoint = {1, 1};
                bottomY = 1;
            }

            POMDOG_ASSERT(currentPoint.X + glyphWidth < TextureWidth);
            POMDOG_ASSERT(currentPoint.Y + glyphHeight < TextureHeight);

            pointOut = currentPoint;
            output = pixelData.data();
        });

        if (!glyph) {
            continue;
        }

        currentPoint.X = currentPoint.X + glyph->Subrect.Width + 1;
        bottomY = std::max(bottomY, currentPoint.Y + glyph->Subrect.Height + 1);

        POMDOG_ASSERT(!textures.empty() && textures.size() > 0);
        glyph->TexturePage = textures.size() - 1;

        spriteFontMap.emplace(glyph->Character, *glyph);
        needToFetchPixelData = true;
    }

    fetchTextureData();
}

Vector2 SpriteFont::Impl::MeasureString(const std::string& text) const
{
    POMDOG_ASSERT(!text.empty());

    Vector2 result = Vector2::Zero;
    Vector2 currentPosition = Vector2::Zero;

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd)
    {
        const auto character = utf8::next(textIter, textIterEnd);

        if (character == U'\n') {
            currentPosition.X = 0;
            currentPosition.Y -= lineSpacing;
            continue;
        }

        auto iter = spriteFontMap.find(character);
        if (iter == std::end(spriteFontMap)) {
            iter = spriteFontMap.find(defaultCharacter);
            POMDOG_ASSERT(iter != std::end(spriteFontMap));
        }

        POMDOG_ASSERT(iter != std::end(spriteFontMap));
        auto const & glyph = iter->second;

        currentPosition.X += (glyph.XAdvance - spacing);

        result.X = std::max(result.X, currentPosition.X);
        result.Y = std::max(result.Y, currentPosition.Y);
    }

    return std::move(result);
}

void SpriteFont::Impl::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color)
{
    if (text.empty()) {
        return;
    }

    if (textures.empty()) {
        return;
    }

    Vector2 currentPosition = position;

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd)
    {
        const auto character = utf8::next(textIter, textIterEnd);

        if (character == U'\n') {
            currentPosition.X = position.X;
            currentPosition.Y -= lineSpacing;
            continue;
        }

        auto iter = spriteFontMap.find(character);
        if (iter == std::end(spriteFontMap)) {
            iter = spriteFontMap.find(defaultCharacter);
            if (iter == std::end(spriteFontMap)) {
                continue;
            }
        }

        POMDOG_ASSERT(iter != std::end(spriteFontMap));
        auto const & glyph = iter->second;

        if (glyph.Subrect.Width > 0 && glyph.Subrect.Height > 0)
        {
            POMDOG_ASSERT(glyph.TexturePage >= 0);
            POMDOG_ASSERT(glyph.TexturePage < static_cast<int>(textures.size()));

            spriteBatch.Draw(textures[glyph.TexturePage],
                currentPosition + Vector2(glyph.XOffset, -glyph.YOffset),
                glyph.Subrect, color, 0.0f, Vector2{0.0f, 1.0f}, Vector2{1.0f, 1.0f});
        }

        currentPosition.X += (glyph.XAdvance - spacing);
    }
}

void SpriteFont::Impl::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color,
    const Radian<float>& rotation,
    //const Vector2& originPivot,
    const Vector2& scale)
{
    if (text.empty()) {
        return;
    }

    if (textures.empty()) {
        return;
    }

    Vector2 currentPosition = position;

    auto textIter = std::begin(text);
    auto textIterEnd = std::end(text);

    while (textIter != textIterEnd)
    {
        const auto character = utf8::next(textIter, textIterEnd);

        if (character == U'\n') {
            currentPosition.X = position.X;
            currentPosition.Y -= lineSpacing * scale.Y;
            continue;
        }

        auto iter = spriteFontMap.find(character);
        if (iter == std::end(spriteFontMap)) {
            iter = spriteFontMap.find(defaultCharacter);
            if (iter == std::end(spriteFontMap)) {
                continue;
            }
        }

        POMDOG_ASSERT(iter != std::end(spriteFontMap));
        auto const & glyph = iter->second;

        if (glyph.Subrect.Width > 0 && glyph.Subrect.Height > 0)
        {
            POMDOG_ASSERT(glyph.TexturePage >= 0);
            POMDOG_ASSERT(glyph.TexturePage < static_cast<int>(textures.size()));

            spriteBatch.Draw(textures[glyph.TexturePage],
                currentPosition + Vector2(glyph.XOffset, -glyph.YOffset) * scale,
                glyph.Subrect, color, 0.0f, Vector2{0.0f, 1.0f}, scale);
        }

        currentPosition.X += ((glyph.XAdvance - spacing) * scale.X);
    }
}

// MARK: - SpriteFont

SpriteFont::SpriteFont(
    std::vector<std::shared_ptr<Texture2D>> && textures,
    const std::vector<Detail::SpriteFonts::Glyph>& glyphs,
    char32_t defaultCharacter,
    std::int16_t spacing,
    std::int16_t lineSpacing)
    : impl(std::make_unique<Impl>(std::move(textures), glyphs, defaultCharacter, spacing, lineSpacing))
{
}

SpriteFont::SpriteFont(
    const std::shared_ptr<GraphicsDevice>& graphicsDevice,
    const std::shared_ptr<TrueTypeFont>& font,
    char32_t defaultCharacter,
    std::int16_t lineSpacing)
    : impl(std::make_unique<Impl>(graphicsDevice, font, defaultCharacter, lineSpacing))
{
}

SpriteFont::~SpriteFont() = default;

Vector2 SpriteFont::MeasureString(const std::string& utf8String) const
{
    if (utf8String.empty()) {
        return Vector2::Zero;
    }
    return impl->MeasureString(utf8String);
}

char32_t SpriteFont::GetDefaultCharacter() const
{
    POMDOG_ASSERT(impl);
    return impl->defaultCharacter;
}

void SpriteFont::SetDefaultCharacter(char32_t character)
{
    POMDOG_ASSERT(impl);
    POMDOG_ASSERT(ContainsCharacter(character));
    impl->defaultCharacter = character;
}

float SpriteFont::GetLineSpacing() const
{
    POMDOG_ASSERT(impl);
    return impl->lineSpacing;
}

void SpriteFont::SetLineSpacing(float lineSpacingIn)
{
    POMDOG_ASSERT(impl);
    impl->lineSpacing = lineSpacingIn;
}

bool SpriteFont::ContainsCharacter(char32_t character) const
{
    POMDOG_ASSERT(impl);
    return impl->spriteFontMap.find(character) != std::end(impl->spriteFontMap);
}

void SpriteFont::Begin(
    const std::shared_ptr<GraphicsCommandList>& commandList,
    SpriteBatchRenderer & spriteBatch,
    const Matrix4x4& transformMatrix)
{
    POMDOG_ASSERT(impl);
    POMDOG_ASSERT(commandList);

    spriteBatch.Begin(commandList, transformMatrix);

//    spriteBatch.Begin(SpriteSortMode::Deferred, Matrix4x4::CreateRotationZ(rotation)
//        * Matrix4x4::CreateScale({scale, 1.0f})
//        * Matrix4x4::CreateTranslation({position, 0.0f})
//        * transformMatrix);
}

void SpriteFont::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color)
{
    if (text.empty()) {
        return;
    }

    impl->PrepareFonts(text);
    impl->Draw(spriteBatch, text, position, color);
}

void SpriteFont::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color,
    const Radian<float>& rotation,
    //const Vector2& originPivot,
    float scale)
{
    this->Draw(spriteBatch, text, position, color,
        rotation, Vector2{scale, scale});
}

void SpriteFont::Draw(
    SpriteBatchRenderer & spriteBatch,
    const std::string& text,
    const Vector2& position,
    const Color& color,
    const Radian<float>& rotation,
    //const Vector2& originPivot,
    const Vector2& scale)
{
    if (text.empty()) {
        return;
    }

    impl->PrepareFonts(text);
    impl->Draw(spriteBatch, text, position, color,
        rotation, scale);
}

void SpriteFont::End(SpriteBatchRenderer & spriteBatch)
{
    spriteBatch.End();
}

} // namespace Pomdog
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2013, Hernan Saez
 * 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 <organization> nor the
 *       names of its 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 <COPYRIGHT HOLDER> 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.
 */

#ifndef CRIMILD_CORE_FOUNDATION_PROFILER_
#define CRIMILD_CORE_FOUNDATION_PROFILER_

#include "Macros.hpp"
#include "Memory.hpp"
#include "SharedObject.hpp"
#include "Singleton.hpp"

#include <string>
#include <sstream>
#include <thread>
#include <map>

namespace crimild {

    class ProfilerSample {
    public:
        explicit ProfilerSample( std::string name );
        ~ProfilerSample( void );

    private:
        int _sampleIndex;
    };

    class ProfilerOutputHandler : public SharedObject {
    public:
        virtual void beginOutput( void ) = 0;
        virtual void sample( float minPc, float avgPc, float maxPc, unsigned int totalTime, unsigned int callCount, std::string name, unsigned int parentCount ) = 0;
        virtual void endOutput( void ) = 0;
    };

    using ProfilerOutputHandlerPtr = SharedPointer< ProfilerOutputHandler >;

    class ProfilerConsoleOutputHandler : public ProfilerOutputHandler {
    public:
        virtual void beginOutput( void ) override;
        virtual void sample( float minPc, float avgPc, float maxPc, unsigned int totalTime, unsigned int callCount, std::string name, unsigned int parentCount ) override;
        virtual void endOutput( void ) override;
    };

    class Profiler : public DynamicSingleton< Profiler > {
    private:
        static constexpr int MAX_SAMPLES = 50;

    public:
        Profiler( void );
        ~Profiler( void );

        void dump( void );

        void resetAll( void );
        void reset( std::string name );

        void setOutputHandler( ProfilerOutputHandlerPtr const &handler ) { _outputHandler = handler; }
        ProfilerOutputHandlerPtr &getOutputHandler( void ) { return _outputHandler; }

    // internal use only
    public:
        int onSampleCreated( std::string name );
        void onSampleDestroyed( int index );

    private:
        unsigned long getTime( void );

    private:

        class ProfilerSampleStack : public SharedObject {
        public:
            struct ProfilerSampleInfo {
                bool isValid = false;
                bool isOpened = false;

                std::string name;
                unsigned int callCount = 0;

                unsigned long startTime = 0;
                unsigned long totalTime = 0;
                unsigned long childTime = 0;

                float avgTime = 0.0f;
                float minTime = 0.0f;
                float maxTime = 0.0f;

                unsigned int dataCount = 0;

                int parentCount = 0;
                int parentIndex = -1;

            };

            ProfilerSampleInfo samples[ MAX_SAMPLES ];

            int lastOpenedSample = -1;
            int openSampleCount = 0;
            float rootBegin = 0.0f;
            float rootEnd = 0.0f;
        };

        using ProfilerSampleStackPtr = SharedPointer< ProfilerSampleStack >;
        std::map< std::thread::id, ProfilerSampleStackPtr > _samples;

        /*
        struct ProfilerSampleInfo {
            bool isValid = false;
            bool isOpened = false;

            std::string name;
            unsigned int callCount = 0;

            unsigned long startTime = 0;
            unsigned long totalTime = 0;
            unsigned long childTime = 0;

            float avgTime = 0.0f;
            float minTime = 0.0f;
            float maxTime = 0.0f;

            unsigned int dataCount = 0;

            int parentCount = 0;
            int parentIndex = -1;
        };

        ProfilerSampleInfo _samples[ MAX_SAMPLES ];

        int _lastOpenedSample = -1;
        int _openSampleCount = 0;
        float _rootBegin = 0.0f;
        float _rootEnd = 0.0f;
        */

        ProfilerOutputHandlerPtr _outputHandler;
    };

}

#define CRIMILD_PROFILE( X ) crimild::ProfilerSample __crimild__profile__sample__instance__( X );

#endif

<commit_msg>Disable profiler<commit_after>/*
 * Copyright (c) 2013, Hernan Saez
 * 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 <organization> nor the
 *       names of its 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 <COPYRIGHT HOLDER> 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.
 */

#ifndef CRIMILD_CORE_FOUNDATION_PROFILER_
#define CRIMILD_CORE_FOUNDATION_PROFILER_

#include "Macros.hpp"
#include "Memory.hpp"
#include "SharedObject.hpp"
#include "Singleton.hpp"

#include <string>
#include <sstream>
#include <thread>
#include <map>

namespace crimild {

    class ProfilerSample {
    public:
        explicit ProfilerSample( std::string name );
        ~ProfilerSample( void );

    private:
        int _sampleIndex;
    };

    class ProfilerOutputHandler : public SharedObject {
    public:
        virtual void beginOutput( void ) = 0;
        virtual void sample( float minPc, float avgPc, float maxPc, unsigned int totalTime, unsigned int callCount, std::string name, unsigned int parentCount ) = 0;
        virtual void endOutput( void ) = 0;
    };

    using ProfilerOutputHandlerPtr = SharedPointer< ProfilerOutputHandler >;

    class ProfilerConsoleOutputHandler : public ProfilerOutputHandler {
    public:
        virtual void beginOutput( void ) override;
        virtual void sample( float minPc, float avgPc, float maxPc, unsigned int totalTime, unsigned int callCount, std::string name, unsigned int parentCount ) override;
        virtual void endOutput( void ) override;
    };

    class Profiler : public DynamicSingleton< Profiler > {
    private:
        static constexpr int MAX_SAMPLES = 50;

    public:
        Profiler( void );
        ~Profiler( void );

        void dump( void );

        void resetAll( void );
        void reset( std::string name );

        void setOutputHandler( ProfilerOutputHandlerPtr const &handler ) { _outputHandler = handler; }
        ProfilerOutputHandlerPtr &getOutputHandler( void ) { return _outputHandler; }

    // internal use only
    public:
        int onSampleCreated( std::string name );
        void onSampleDestroyed( int index );

    private:
        unsigned long getTime( void );

    private:

        class ProfilerSampleStack : public SharedObject {
        public:
            struct ProfilerSampleInfo {
                bool isValid = false;
                bool isOpened = false;

                std::string name;
                unsigned int callCount = 0;

                unsigned long startTime = 0;
                unsigned long totalTime = 0;
                unsigned long childTime = 0;

                float avgTime = 0.0f;
                float minTime = 0.0f;
                float maxTime = 0.0f;

                unsigned int dataCount = 0;

                int parentCount = 0;
                int parentIndex = -1;

            };

            ProfilerSampleInfo samples[ MAX_SAMPLES ];

            int lastOpenedSample = -1;
            int openSampleCount = 0;
            float rootBegin = 0.0f;
            float rootEnd = 0.0f;
        };

        using ProfilerSampleStackPtr = SharedPointer< ProfilerSampleStack >;
        std::map< std::thread::id, ProfilerSampleStackPtr > _samples;

        /*
        struct ProfilerSampleInfo {
            bool isValid = false;
            bool isOpened = false;

            std::string name;
            unsigned int callCount = 0;

            unsigned long startTime = 0;
            unsigned long totalTime = 0;
            unsigned long childTime = 0;

            float avgTime = 0.0f;
            float minTime = 0.0f;
            float maxTime = 0.0f;

            unsigned int dataCount = 0;

            int parentCount = 0;
            int parentIndex = -1;
        };

        ProfilerSampleInfo _samples[ MAX_SAMPLES ];

        int _lastOpenedSample = -1;
        int _openSampleCount = 0;
        float _rootBegin = 0.0f;
        float _rootEnd = 0.0f;
        */

        ProfilerOutputHandlerPtr _outputHandler;
    };

}

#ifdef CRIMILD_PROFILER_ENABLE
    #define CRIMILD_PROFILE( X ) crimild::ProfilerSample __crimild__profile__sample__instance__( X );
#else
    #define CRIMILD_PROFILE( X )
#endif

#endif

<|endoftext|>


<commit_before>#include "../../core_include/api.h"
#include "../../core_include/msg.h"
#include "../../core_include/audio.h"
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>

typedef void(*ANDROID_PLAY_WAV)(const char* fileName);
ANDROID_PLAY_WAV gAndroidPlayWav;

typedef struct
{
	AUDIO_TYPE type;
}AUDIO_REQUEST;

static c_fifo s_request_fifo("aduio fifo");

static void* render_thread(void* param)
{
	while (true)
	{
		AUDIO_REQUEST request;
		s_request_fifo.read(&request, sizeof(request));

		if (AUDIO_MAX <= request.type)
		{
			continue;
		}
		if(gAndroidPlayWav)
		{
			gAndroidPlayWav("hello");
		}
	}
}

void c_audio::init()
{
	static bool s_flag = false;
	if (s_flag)
	{
		return;
	}

	unsigned long pid;
	create_thread(&pid, NULL, render_thread, NULL);
	s_flag = true;
}

int c_audio::play(AUDIO_TYPE type)
{
	if (AUDIO_MAX <= type)
	{
		return -1;
	}

	init();

	AUDIO_REQUEST request;
	request.type = type;
	s_request_fifo.write(&request, sizeof(request));
	return 0;
}
<commit_msg>fix android audio<commit_after>#include "../../core_include/api.h"
#include "../../core_include/msg.h"
#include "../../core_include/audio.h"
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>

typedef void(*ANDROID_PLAY_WAV)(const char* fileName);
ANDROID_PLAY_WAV gAndroidPlayWav;

typedef struct
{
	AUDIO_TYPE type;
}AUDIO_REQUEST;

static c_fifo s_request_fifo("aduio fifo");

static void* render_thread(void* param)
{
	while (true)
	{
		AUDIO_REQUEST request;
		s_request_fifo.read(&request, sizeof(request));

		if (AUDIO_MAX <= request.type)
		{
			continue;
		}
		if(gAndroidPlayWav)
		{
			gAndroidPlayWav("heart_beat.wav");
		}
	}
}

void c_audio::init()
{
	static bool s_flag = false;
	if (s_flag)
	{
		return;
	}

	unsigned long pid;
	create_thread(&pid, NULL, render_thread, NULL);
	s_flag = true;
}

int c_audio::play(AUDIO_TYPE type)
{
	if (AUDIO_MAX <= type)
	{
		return -1;
	}

	init();

	AUDIO_REQUEST request;
	request.type = type;
	s_request_fifo.write(&request, sizeof(request));
	return 0;
}
<|endoftext|>