<commit_before>//#include <QGraphicsScene>
//#include <QPainter>
//#include <QStyleOption>
//#include <iostream>

#include <cmath>

#include "hexon.h"

Hexon::Hexon(int a, int b)
{

    //hex.x = a;
    //hex.y = -a-b;
    //hex.z = b;
    hex = cube(a,b);

    pix p = cube2pix(hex);

    //setPos(mapToParent(x, y));
    setPos(p.x,p.y);
    color = rgb2color(0x0000ff);
    border = rgb2color(0x000000);
    //extern int visibility;
    brain.set_size(6*(3*(get_visibility()-1)*get_visibility()+1) + 6,3+2+3,30); // make size universal
    vis = true;
    stats = Stats((rand()%10)+1,rand()%5,(rand()%10)+1,(rand()%20)+21,(rand()%50)+51,(rand()%10)+1);
}

Hexon::Hexon(cube h)
{
    hex = h;
    pix p = cube2pix(hex);
    setPos(p.x,p.y);
    color = rgb2color(0x0000ff);
    border = rgb2color(0x000000);
    //extern int visibility;
    brain.set_size(6*(3*(get_visibility()-1)*get_visibility()+1) + 6,3+2+3,30);
    vis = true;
    stats = Stats((rand()%10)+1,rand()%5,(rand()%10)+1,(rand()%20)+21,(rand()%50)+51,(rand()%10)+1);
}

void Hexon::copy_hexon(const Hexon &A)
{
    hex = A.hex;
    return;
}

void Hexon::set_vis(Matrix vision)
{
    brain.set_inputs(vision);
}

void Hexon::advance(int step)
{
    if (!step)
    {
        return;
    }

    // update position
    //hex = hex+dh;
    pix p = cube2pix(hex);

    setPos(p.x,p.y);
    //std::cout << "\n" << p.x << "\t" << p.y;
    return;
}

cube Hexon::tstep()
{
    Matrix A = brain.feedforward();

    dh = hex_dir1[(int)((std::round(A[0][0]) * 4) + (std::round(A[1][0]) * 2) + std::round(A[2][0]))];
    //color = hsv2color({std::round(359*A[3][0]),std::round(255*A[4][0])});

    int st = (std::round(A[3][0]) * 2) + std::round(A[4][0]);
    if (st == 2)
    {
        stance = 'a';
    }
    else if (st == 1)
    {
        stance = 'b';
    }
    else
    {
        stance = 'n';
    }

    rgb C;
    C.red = 255-(int)(255*exp(-mel(stats.attack+stats.speed)/10));
    C.green = 255-(int)(255*exp(-mel(stats.defense+stats.health)/50));
    C.blue = 255-(int)(255*exp(-mel(stats.energy+stats.charisma)/25));
    //std::cout << C.red << "\t" << C.green << "\t" << C.blue << std::endl;

    color = rgb2color(C);

    C.red = 255*A[5][0];
    C.green = 255*A[6][0];
    C.blue = 255*A[7][0];
    border = rgb2color(C);

    //C = color2rgb(color);
    //std::cout << C.red << "\t" << C.green << "\t" << C.blue << std::endl;
    //color = rgb2color(rgb{stats.attack+stats.speed, stats.defense+stats.health, stats.energy+stats.charisma});

    //pix p = cube2pix(hex);

    //setPos(p.x,p.y);
    //std::cout << "\n" << p.x << "\t" << p.y;
    return dh;
}

char Hexon::h_type()
{
    return 'h';
}

int Hexon::interact(HexItem *hitem)
{
    if (hitem->has_vis())
    {
        if (stance == 'n')
        {
            dh = global_origin;
            return 0;
        }
        else if (stance == 'a')
        {
            //attack sequence

            //initiative
            if (hitem->stats.speed > stats.speed)
            {
                // other attacks first
                combat(&hitem->stats,&stats);
                if (stats.health <= 0)
                {
                    return 2;
                }
                combat(&stats,&hitem->stats);
                if (hitem->stats.health <= 0)
                {
                    return 3;
                }
            }
            else
            {
                // initiative won
                combat(&stats,&hitem->stats);
                if (hitem->stats.health <= 0)
                {
                    return 3;
                }
                combat(&hitem->stats,&stats);
                if (stats.health <= 0)
                {
                    return 2;
                }
            }

            return 0;
        }
        else if (stance == 'b')
        {
            //breed sequence
            dh = global_origin;
            /*
            if (!(hitem->h_type() == 'h'))
            {
                return 0;
            }
            */
            if (hitem->stance == 'b')
            {
                return 4;
            }
            return 0;
        }
    }
    else
    {
        dh = global_origin;
        return 0;
        // don't move
    }

    return 0;
}

void combat(Stats *S1, Stats *S2)
{
    if (S1->energy <= 0)
    {
        return;
    }
    S1->energy--;

    if (S1->attack <= S2->defense)
    {
        return;
    }

    //Roll to Hit
    if ((rand() % (S1->speed + S2->speed)) < S1->speed)
    {
        S2->health -= S1->attack - S2->defense;
        S1->attack++;
        S2->defense++;
    }
    else
    {
        S1->speed++;
        S2->speed++;
    }
    return;
}

Hexon * breed_hexon(HexItem *A, HexItem *B, cube h)
{
    return &Hexon(h);
}
<commit_msg>Random cube coordinate generator fixed. Breed function added.<commit_after>//#include <QGraphicsScene>
//#include <QPainter>
//#include <QStyleOption>
//#include <iostream>

#include <cmath>

#include "hexon.h"

Hexon::Hexon(int a, int b)
{

    //hex.x = a;
    //hex.y = -a-b;
    //hex.z = b;
    hex = cube(a,b);

    pix p = cube2pix(hex);

    //setPos(mapToParent(x, y));
    setPos(p.x,p.y);
    color = rgb2color(0x0000ff);
    border = rgb2color(0x000000);
    //extern int visibility;
    brain.set_size(6*(3*(get_visibility()-1)*get_visibility()+1) + 6,3+2+3,30); // make size universal
    vis = true;
    stats = Stats((rand()%10)+1,rand()%5,(rand()%10)+1,(rand()%20)+21,(rand()%50)+51,(rand()%10)+1);
}

Hexon::Hexon(cube h)
{
    hex = h;
    pix p = cube2pix(hex);
    setPos(p.x,p.y);
    color = rgb2color(0x0000ff);
    border = rgb2color(0x000000);
    //extern int visibility;
    brain.set_size(6*(3*(get_visibility()-1)*get_visibility()+1) + 6,3+2+3,30);
    vis = true;
    stats = Stats((rand()%10)+1,rand()%5,(rand()%10)+1,(rand()%20)+21,(rand()%50)+51,(rand()%10)+1);
}

void Hexon::copy_hexon(const Hexon &A)
{
    hex = A.hex;
    return;
}

void Hexon::set_vis(Matrix vision)
{
    brain.set_inputs(vision);
}

void Hexon::advance(int step)
{
    if (!step)
    {
        return;
    }

    // update position
    //hex = hex+dh;
    pix p = cube2pix(hex);

    setPos(p.x,p.y);
    //std::cout << "\n" << p.x << "\t" << p.y;
    return;
}

cube Hexon::tstep()
{
    Matrix A = brain.feedforward();

    dh = hex_dir1[(int)((std::round(A[0][0]) * 4) + (std::round(A[1][0]) * 2) + std::round(A[2][0]))];
    //color = hsv2color({std::round(359*A[3][0]),std::round(255*A[4][0])});

    int st = (std::round(A[3][0]) * 2) + std::round(A[4][0]);
    if (st == 2)
    {
        stance = 'a';
    }
    else if (st == 1)
    {
        stance = 'b';
    }
    else
    {
        stance = 'n';
    }

    rgb C;
    C.red = 255-(int)(255*exp(-mel(stats.attack+stats.speed)/10));
    C.green = 255-(int)(255*exp(-mel(stats.defense+stats.health)/50));
    C.blue = 255-(int)(255*exp(-mel(stats.energy+stats.charisma)/25));
    //std::cout << C.red << "\t" << C.green << "\t" << C.blue << std::endl;

    color = rgb2color(C);

    C.red = 255*A[5][0];
    C.green = 255*A[6][0];
    C.blue = 255*A[7][0];
    border = rgb2color(C);

    //C = color2rgb(color);
    //std::cout << C.red << "\t" << C.green << "\t" << C.blue << std::endl;
    //color = rgb2color(rgb{stats.attack+stats.speed, stats.defense+stats.health, stats.energy+stats.charisma});

    //pix p = cube2pix(hex);

    //setPos(p.x,p.y);
    //std::cout << "\n" << p.x << "\t" << p.y;
    return dh;
}

char Hexon::h_type()
{
    return 'h';
}

int Hexon::interact(HexItem *hitem)
{
    if (hitem->has_vis())
    {
        if (stance == 'n')
        {
            dh = global_origin;
            return 0;
        }
        else if (stance == 'a')
        {
            //attack sequence

            //initiative
            if (hitem->stats.speed > stats.speed)
            {
                // other attacks first
                combat(&hitem->stats,&stats);
                if (stats.health <= 0)
                {
                    return 2;
                }
                combat(&stats,&hitem->stats);
                if (hitem->stats.health <= 0)
                {
                    return 3;
                }
            }
            else
            {
                // initiative won
                combat(&stats,&hitem->stats);
                if (hitem->stats.health <= 0)
                {
                    return 3;
                }
                combat(&hitem->stats,&stats);
                if (stats.health <= 0)
                {
                    return 2;
                }
            }

            return 0;
        }
        else if (stance == 'b')
        {
            //breed sequence
            dh = global_origin;
            /*
            if (!(hitem->h_type() == 'h'))
            {
                return 0;
            }
            */
            if (hitem->stance == 'b')
            {
                return 4;
            }
            return 0;
        }
    }
    else
    {
        dh = global_origin;
        return 0;
        // don't move
    }

    return 0;
}

void combat(Stats *S1, Stats *S2)
{
    if (S1->energy <= 0)
    {
        return;
    }
    S1->energy--;

    if (S1->attack <= S2->defense)
    {
        return;
    }

    //Roll to Hit
    if ((rand() % (S1->speed + S2->speed)) < S1->speed)
    {
        S2->health -= S1->attack - S2->defense;
        S1->attack++;
        S2->defense++;
    }
    else
    {
        S1->speed++;
        S2->speed++;
    }
    return;
}

Hexon * breed_hexon(HexItem *A, HexItem *B, cube h)
{
    A;
    B;
    return &Hexon(h);
}
<|endoftext|>


<commit_before>/* This file is part of ksirc
   Copyright (c) 2001 Malte Starostik <malte@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

/*
Color parser code courtesy of ksirc <http://www.kde.org>
Modified by Jason Keirstead <jason@keirstead.org>
*/

// $Id$

#include <qstring.h>
#include <qcolor.h>
#include <qregexp.h>

#include <kdebug.h>
#include "ksparser.h"

QString KSParser::parse( const QString &message )
{
	QString res;
	m_tags.clear();
	m_attributes.clear();

	for (uint i = 0; i < message.length(); i++)
	{
		QChar ch = message[i];

		switch( ((int)ch) )
		{
			case 3:
			{
				if ( message[++i].digitValue() > -1 )
				{
					QString tagStyle;
					QString fgColor = QString( message[i] );
					while( message[++i].digitValue() > -1 )
						fgColor += message[i];

					QString bgColor;
					if( message[i] == ',' )
					{
						while( message[++i].digitValue() > -1 )
							bgColor += message[i];
					}

					QColor c = ircColor( fgColor.toInt() );
					if ( c.isValid() )
						tagStyle += QString::fromLatin1( "color:%1;" ).arg( c.name() );

					if( !bgColor.isEmpty() )
					{
						c = ircColor( bgColor.toInt() );
						if ( c.isValid() )
							tagStyle += QString::fromLatin1( "background-color:%1;" ).arg( c.name() );
					}

					if( !tagStyle.isEmpty() )
						res += pushTag(  QString::fromLatin1("span"), QString::fromLatin1("style=\"%1\"").arg( tagStyle ) );

					i--;
				}
				else
					res += popTag( QString::fromLatin1("span") );
				break;
			}
			case 2:
				res += toggleTag("b");
				break;

			case 31:
				res += toggleTag("u");
				break;

			default:
				res += ch;
		}
	}

	res.append( popAll() );

	return res;
}

QString KSParser::pushTag(const QString &tag, const QString &attributes)
{
    QString res;
    m_tags.push(tag);
    if (!m_attributes.contains(tag))
        m_attributes.insert(tag, attributes);
    else if (!attributes.isEmpty())
        m_attributes.replace(tag, attributes);
    res.append("<" + tag);
    if (!m_attributes[tag].isEmpty())
        res.append(" " + m_attributes[tag]);
    return res + ">";
}

QString KSParser::popTag(const QString &tag)
{
    if (!m_tags.contains(tag))
        return QString::null;

    QString res;
    QValueStack<QString> savedTags;
    while (m_tags.top() != tag)
    {
        savedTags.push(m_tags.pop());
        res.append("</" + savedTags.top() + ">");
    }
    res.append("</" + m_tags.pop() + ">");
    m_attributes.remove(tag);
    while (!savedTags.isEmpty())
        res.append(pushTag(savedTags.pop()));
    return res;
}

QString KSParser::toggleTag(const QString &tag)
{
    return m_attributes.contains(tag) ? popTag(tag) : pushTag(tag);
}

QString KSParser::popAll()
{
    QString res;
    while (!m_tags.isEmpty())
        res.append("</" + m_tags.pop() + ">");
    m_attributes.clear();
    return res;
}

QColor KSParser::ircColor(int code)
{
	switch( code )
	{
		case 0:
			return Qt::white;
		case 1:
			return Qt::black;
		case 2:
			return Qt::darkBlue;
		case 3:
			return Qt::darkGreen;
		case 4:
			return Qt::red;
		case 5:
			return Qt::darkRed;
		case 6:
			return Qt::darkMagenta;
		case 7:
			return Qt::darkYellow;
		case 8:
			return Qt::yellow;
		case 9:
			return Qt::green;
		case 10:
			return Qt::darkCyan;
		case 11:
			return Qt::cyan;
		case 12:
			return Qt::blue;
		case 13:
			return Qt::magenta;
		case 14:
			return Qt::darkGray;
		case 15:
			return Qt::gray;
		default:
			return QColor();
	}
}

int KSParser::colorForHTML( const QString &html )
{
	QColor color;
	color.setNamedColor( html );

	for( int i=0; i < 16; i++ )
	{
		if( ircColor( i ) == color )
			return i;
	}

	return -1;
}
<commit_msg>Support beep and plain char codes<commit_after>/* This file is part of ksirc
   Copyright (c) 2001 Malte Starostik <malte@kde.org>

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
*/

/*
Color parser code courtesy of ksirc <http://www.kde.org>
Modified by Jason Keirstead <jason@keirstead.org>
*/

// $Id$

#include <qstring.h>
#include <qcolor.h>
#include <qregexp.h>
#include <knotifyclient.h>
#include <kdebug.h>
#include "ksparser.h"

QString KSParser::parse( const QString &message )
{
	QString res;
	m_tags.clear();
	m_attributes.clear();

	for (uint i = 0; i < message.length(); i++)
	{
		QChar ch = message[i];

		switch( ((int)ch) )
		{
			case 3:
			{
				//Color code
				if ( message[++i].digitValue() > -1 )
				{
					QString tagStyle;
					QString fgColor = QString( message[i] );
					while( message[++i].digitValue() > -1 )
						fgColor += message[i];

					QString bgColor;
					if( message[i] == ',' )
					{
						while( message[++i].digitValue() > -1 )
							bgColor += message[i];
					}

					QColor c = ircColor( fgColor.toInt() );
					if ( c.isValid() )
						tagStyle += QString::fromLatin1( "color:%1;" ).arg( c.name() );

					if( !bgColor.isEmpty() )
					{
						c = ircColor( bgColor.toInt() );
						if ( c.isValid() )
							tagStyle += QString::fromLatin1( "background-color:%1;" ).arg( c.name() );
					}

					if( !tagStyle.isEmpty() )
						res += pushTag(  QString::fromLatin1("span"), QString::fromLatin1("style=\"%1\"").arg( tagStyle ) );

					i--;
				}
				else
					res += popTag( QString::fromLatin1("span") );
				break;
			}
			case 2:
				//Bold
				res += toggleTag("b");
				break;
			case 6:
				//Invert Colors
				break;
			case 7:
				//System bell
				KNotifyClient::beep( QString::fromLatin1("IRC beep event recieved in a message") );
				break;

			case 15:
				//Plain Text, close all tags
				res.append( popAll() );
				break;

			case 31:
				//Underline
				res += toggleTag("u");
				break;

			default:
				res += ch;
		}
	}

	res.append( popAll() );

	return res;
}

QString KSParser::pushTag(const QString &tag, const QString &attributes)
{
    QString res;
    m_tags.push(tag);
    if (!m_attributes.contains(tag))
        m_attributes.insert(tag, attributes);
    else if (!attributes.isEmpty())
        m_attributes.replace(tag, attributes);
    res.append("<" + tag);
    if (!m_attributes[tag].isEmpty())
        res.append(" " + m_attributes[tag]);
    return res + ">";
}

QString KSParser::popTag(const QString &tag)
{
    if (!m_tags.contains(tag))
        return QString::null;

    QString res;
    QValueStack<QString> savedTags;
    while (m_tags.top() != tag)
    {
        savedTags.push(m_tags.pop());
        res.append("</" + savedTags.top() + ">");
    }
    res.append("</" + m_tags.pop() + ">");
    m_attributes.remove(tag);
    while (!savedTags.isEmpty())
        res.append(pushTag(savedTags.pop()));
    return res;
}

QString KSParser::toggleTag(const QString &tag)
{
    return m_attributes.contains(tag) ? popTag(tag) : pushTag(tag);
}

QString KSParser::popAll()
{
    QString res;
    while (!m_tags.isEmpty())
        res.append("</" + m_tags.pop() + ">");
    m_attributes.clear();
    return res;
}

QColor KSParser::ircColor(int code)
{
	switch( code )
	{
		case 0:
			return Qt::white;
		case 1:
			return Qt::black;
		case 2:
			return Qt::darkBlue;
		case 3:
			return Qt::darkGreen;
		case 4:
			return Qt::red;
		case 5:
			return Qt::darkRed;
		case 6:
			return Qt::darkMagenta;
		case 7:
			return Qt::darkYellow;
		case 8:
			return Qt::yellow;
		case 9:
			return Qt::green;
		case 10:
			return Qt::darkCyan;
		case 11:
			return Qt::cyan;
		case 12:
			return Qt::blue;
		case 13:
			return Qt::magenta;
		case 14:
			return Qt::darkGray;
		case 15:
			return Qt::gray;
		default:
			return QColor();
	}
}

int KSParser::colorForHTML( const QString &html )
{
	QColor color;
	color.setNamedColor( html );

	for( int i=0; i < 16; i++ )
	{
		if( ircColor( i ) == color )
			return i;
	}

	return -1;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

#include "../defines.h"
#include "game.h"

void test_print() {
  std::vector<Board> boards = {
    0x6621533332211111ull, 0x8643553333101100ull, 0x9653531032001001ull,
   0x01231334047814cdull, 0x23212234346935cdull, 0x12231334248916cdull,
    0x10022321345a34cdull, 0x11222234148a11cdull, 0x21121667028a20cdull
  };

  for (auto it = boards.begin(); it != boards.end(); ++it) {
    print_board(*it);
  }
}

Action user_move(Board board) {
  print_board(board);
  int move;
  std::cout << "Please enter 0 (up), 1 (down), 2 (left), or 3 (right): ";
  std::cin >> move;
  std::cout << "You input ";
  switch (move) {
    case 0:
      std::cout << "up\n";
      return 0;
    case 1:
      std::cout << "down\n";
      return 1;
    case 2:
      std::cout << "left\n";
      return 2;
    case 3:
      std::cout << "right\n";
      return 3;
    default:
      std::cout << "an invalid character, ending game...\n";
      return -1;
  }
}

void test_game() {
  play_game(user_move);
}

int main() {
  test_game();

  return 0;
}<commit_msg>changed user input game test<commit_after>#include <iostream>
#include <vector>

#include "../defines.h"
#include "game.h"

void test_print() {
  std::vector<Board> boards = {
    0x6621533332211111ull, 0x8643553333101100ull, 0x9653531032001001ull,
    0x01231334047814cdull, 0x23212234346935cdull, 0x12231334248916cdull,
    0x10022321345a34cdull, 0x11222234148a11cdull, 0x21121667028a20cdull
  };

  for (auto it = boards.begin(); it != boards.end(); ++it) {
    print_board(*it);
  }
}

Action user_move(Board board) {
  print_board(board);
  char move;
  std::cout << "Please enter w (up), s (down), a (left), or d (right): ";
  std::cin >> move;
  std::cout << "You input: ";
  switch (move) {
    case 'w':
      std::cout << "up\n";
      return 0;
    case 's':
      std::cout << "down\n";
      return 1;
    case 'a':
      std::cout << "left\n";
      return 2;
    case 'd':
      std::cout << "right\n";
      return 3;
    default:
      std::cout << move << "\nInvalid character, ending game...\n";
      return -1;
  }
}

void test_game() {
  play_game(user_move);
}

int main() {
  test_print();
  test_game();

  return 0;
}<|endoftext|>


<commit_before>//===-- SIFoldOperands.cpp - Fold operands --- ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
/// \file
//===----------------------------------------------------------------------===//
//

#include "AMDGPU.h"
#include "AMDGPUSubtarget.h"
#include "SIInstrInfo.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"

#define DEBUG_TYPE "si-fold-operands"
using namespace llvm;

namespace {

class SIFoldOperands : public MachineFunctionPass {
public:
  static char ID;

public:
  SIFoldOperands() : MachineFunctionPass(ID) {
    initializeSIFoldOperandsPass(*PassRegistry::getPassRegistry());
  }

  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "SI Fold Operands";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<MachineDominatorTree>();
    AU.addPreserved<MachineDominatorTree>();
    AU.setPreservesCFG();
    MachineFunctionPass::getAnalysisUsage(AU);
  }
};

struct FoldCandidate {
  MachineInstr *UseMI;
  unsigned UseOpNo;
  MachineOperand *OpToFold;
  uint64_t ImmToFold;

  FoldCandidate(MachineInstr *MI, unsigned OpNo, MachineOperand *FoldOp) :
                UseMI(MI), UseOpNo(OpNo) {

    if (FoldOp->isImm()) {
      OpToFold = nullptr;
      ImmToFold = FoldOp->getImm();
    } else {
      assert(FoldOp->isReg());
      OpToFold = FoldOp;
    }
  }

  bool isImm() const {
    return !OpToFold;
  }
};

} // End anonymous namespace.

INITIALIZE_PASS_BEGIN(SIFoldOperands, DEBUG_TYPE,
                      "SI Fold Operands", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_END(SIFoldOperands, DEBUG_TYPE,
                    "SI Fold Operands", false, false)

char SIFoldOperands::ID = 0;

char &llvm::SIFoldOperandsID = SIFoldOperands::ID;

FunctionPass *llvm::createSIFoldOperandsPass() {
  return new SIFoldOperands();
}

static bool isSafeToFold(unsigned Opcode) {
  switch(Opcode) {
  case AMDGPU::V_MOV_B32_e32:
  case AMDGPU::V_MOV_B32_e64:
  case AMDGPU::V_MOV_B64_PSEUDO:
  case AMDGPU::S_MOV_B32:
  case AMDGPU::S_MOV_B64:
  case AMDGPU::COPY:
    return true;
  default:
    return false;
  }
}

static bool updateOperand(FoldCandidate &Fold,
                          const TargetRegisterInfo &TRI) {
  MachineInstr *MI = Fold.UseMI;
  MachineOperand &Old = MI->getOperand(Fold.UseOpNo);
  assert(Old.isReg());

  if (Fold.isImm()) {
    Old.ChangeToImmediate(Fold.ImmToFold);
    return true;
  }

  MachineOperand *New = Fold.OpToFold;
  if (TargetRegisterInfo::isVirtualRegister(Old.getReg()) &&
      TargetRegisterInfo::isVirtualRegister(New->getReg())) {
    Old.substVirtReg(New->getReg(), New->getSubReg(), TRI);
    return true;
  }

  // FIXME: Handle physical registers.

  return false;
}

static bool isUseMIInFoldList(const std::vector<FoldCandidate> &FoldList,
                              const MachineInstr *MI) {
  for (auto Candidate : FoldList) {
    if (Candidate.UseMI == MI)
      return true;
  }
  return false;
}

static bool tryAddToFoldList(std::vector<FoldCandidate> &FoldList,
                             MachineInstr *MI, unsigned OpNo,
                             MachineOperand *OpToFold,
                             const SIInstrInfo *TII) {
  if (!TII->isOperandLegal(MI, OpNo, OpToFold)) {

    // Special case for v_mac_f32_e64 if we are trying to fold into src2
    unsigned Opc = MI->getOpcode();
    if (Opc == AMDGPU::V_MAC_F32_e64 &&
        (int)OpNo == AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2)) {
      // Check if changing this to a v_mad_f32 instruction will allow us to
      // fold the operand.
      MI->setDesc(TII->get(AMDGPU::V_MAD_F32));
      bool FoldAsMAD = tryAddToFoldList(FoldList, MI, OpNo, OpToFold, TII);
      if (FoldAsMAD) {
        MI->untieRegOperand(OpNo);
        return true;
      }
      MI->setDesc(TII->get(Opc));
    }

    // If we are already folding into another operand of MI, then
    // we can't commute the instruction, otherwise we risk making the
    // other fold illegal.
    if (isUseMIInFoldList(FoldList, MI))
      return false;

    // Operand is not legal, so try to commute the instruction to
    // see if this makes it possible to fold.
    unsigned CommuteIdx0 = TargetInstrInfo::CommuteAnyOperandIndex;
    unsigned CommuteIdx1 = TargetInstrInfo::CommuteAnyOperandIndex;
    bool CanCommute = TII->findCommutedOpIndices(MI, CommuteIdx0, CommuteIdx1);

    if (CanCommute) {
      if (CommuteIdx0 == OpNo)
        OpNo = CommuteIdx1;
      else if (CommuteIdx1 == OpNo)
        OpNo = CommuteIdx0;
    }

    // One of operands might be an Imm operand, and OpNo may refer to it after
    // the call of commuteInstruction() below. Such situations are avoided
    // here explicitly as OpNo must be a register operand to be a candidate
    // for memory folding.
    if (CanCommute && (!MI->getOperand(CommuteIdx0).isReg() ||
                       !MI->getOperand(CommuteIdx1).isReg()))
      return false;

    if (!CanCommute ||
        !TII->commuteInstruction(MI, false, CommuteIdx0, CommuteIdx1))
      return false;

    if (!TII->isOperandLegal(MI, OpNo, OpToFold))
      return false;
  }

  FoldList.push_back(FoldCandidate(MI, OpNo, OpToFold));
  return true;
}

static void foldOperand(MachineOperand &OpToFold, MachineInstr *UseMI,
                        unsigned UseOpIdx,
                        std::vector<FoldCandidate> &FoldList,
                        SmallVectorImpl<MachineInstr *> &CopiesToReplace,
                        const SIInstrInfo *TII, const SIRegisterInfo &TRI,
                        MachineRegisterInfo &MRI) {
  const MachineOperand &UseOp = UseMI->getOperand(UseOpIdx);

  // FIXME: Fold operands with subregs.
  if (UseOp.isReg() && ((UseOp.getSubReg() && OpToFold.isReg()) ||
      UseOp.isImplicit())) {
    return;
  }

  bool FoldingImm = OpToFold.isImm();
  APInt Imm;

  if (FoldingImm) {
    unsigned UseReg = UseOp.getReg();
    const TargetRegisterClass *UseRC
      = TargetRegisterInfo::isVirtualRegister(UseReg) ?
      MRI.getRegClass(UseReg) :
      TRI.getPhysRegClass(UseReg);

    Imm = APInt(64, OpToFold.getImm());

    const MCInstrDesc &FoldDesc = TII->get(OpToFold.getParent()->getOpcode());
    const TargetRegisterClass *FoldRC =
        TRI.getRegClass(FoldDesc.OpInfo[0].RegClass);

    // Split 64-bit constants into 32-bits for folding.
    if (FoldRC->getSize() == 8 && UseOp.getSubReg()) {
      if (UseRC->getSize() != 8)
        return;

      if (UseOp.getSubReg() == AMDGPU::sub0) {
        Imm = Imm.getLoBits(32);
      } else {
        assert(UseOp.getSubReg() == AMDGPU::sub1);
        Imm = Imm.getHiBits(32);
      }
    }

    // In order to fold immediates into copies, we need to change the
    // copy to a MOV.
    if (UseMI->getOpcode() == AMDGPU::COPY) {
      unsigned DestReg = UseMI->getOperand(0).getReg();
      const TargetRegisterClass *DestRC
        = TargetRegisterInfo::isVirtualRegister(DestReg) ?
        MRI.getRegClass(DestReg) :
        TRI.getPhysRegClass(DestReg);

      unsigned MovOp = TII->getMovOpcode(DestRC);
      if (MovOp == AMDGPU::COPY)
        return;

      UseMI->setDesc(TII->get(MovOp));
      CopiesToReplace.push_back(UseMI);
    }
  }

  // Special case for REG_SEQUENCE: We can't fold literals into
  // REG_SEQUENCE instructions, so we have to fold them into the
  // uses of REG_SEQUENCE.
  if (UseMI->getOpcode() == AMDGPU::REG_SEQUENCE) {
    unsigned RegSeqDstReg = UseMI->getOperand(0).getReg();
    unsigned RegSeqDstSubReg = UseMI->getOperand(UseOpIdx + 1).getImm();

    for (MachineRegisterInfo::use_iterator
         RSUse = MRI.use_begin(RegSeqDstReg),
         RSE = MRI.use_end(); RSUse != RSE; ++RSUse) {

      MachineInstr *RSUseMI = RSUse->getParent();
      if (RSUse->getSubReg() != RegSeqDstSubReg)
        continue;

      foldOperand(OpToFold, RSUseMI, RSUse.getOperandNo(), FoldList,
                  CopiesToReplace, TII, TRI, MRI);
    }
    return;
  }

  const MCInstrDesc &UseDesc = UseMI->getDesc();

  // Don't fold into target independent nodes.  Target independent opcodes
  // don't have defined register classes.
  if (UseDesc.isVariadic() ||
      UseDesc.OpInfo[UseOpIdx].RegClass == -1)
    return;

  if (FoldingImm) {
    MachineOperand ImmOp = MachineOperand::CreateImm(Imm.getSExtValue());
    tryAddToFoldList(FoldList, UseMI, UseOpIdx, &ImmOp, TII);
    return;
  }

  tryAddToFoldList(FoldList, UseMI, UseOpIdx, &OpToFold, TII);

  // FIXME: We could try to change the instruction from 64-bit to 32-bit
  // to enable more folding opportunites.  The shrink operands pass
  // already does this.
  return;
}

bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) {
  MachineRegisterInfo &MRI = MF.getRegInfo();
  const SIInstrInfo *TII =
      static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
  const SIRegisterInfo &TRI = TII->getRegisterInfo();

  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
                                                  BI != BE; ++BI) {

    MachineBasicBlock &MBB = *BI;
    MachineBasicBlock::iterator I, Next;
    for (I = MBB.begin(); I != MBB.end(); I = Next) {
      Next = std::next(I);
      MachineInstr &MI = *I;

      if (!isSafeToFold(MI.getOpcode()))
        continue;

      unsigned OpSize = TII->getOpSize(MI, 1);
      MachineOperand &OpToFold = MI.getOperand(1);
      bool FoldingImm = OpToFold.isImm();

      // FIXME: We could also be folding things like FrameIndexes and
      // TargetIndexes.
      if (!FoldingImm && !OpToFold.isReg())
        continue;

      // Folding immediates with more than one use will increase program size.
      // FIXME: This will also reduce register usage, which may be better
      // in some cases.  A better heuristic is needed.
      if (FoldingImm && !TII->isInlineConstant(OpToFold, OpSize) &&
          !MRI.hasOneUse(MI.getOperand(0).getReg()))
        continue;

      if (OpToFold.isReg() &&
          !TargetRegisterInfo::isVirtualRegister(OpToFold.getReg()))
        continue;

      // We need mutate the operands of new mov instructions to add implicit
      // uses of EXEC, but adding them invalidates the use_iterator, so defer
      // this.
      SmallVector<MachineInstr *, 4> CopiesToReplace;

      std::vector<FoldCandidate> FoldList;
      for (MachineRegisterInfo::use_iterator
           Use = MRI.use_begin(MI.getOperand(0).getReg()), E = MRI.use_end();
           Use != E; ++Use) {

        MachineInstr *UseMI = Use->getParent();

        foldOperand(OpToFold, UseMI, Use.getOperandNo(), FoldList,
                    CopiesToReplace, TII, TRI, MRI);
      }

      // Make sure we add EXEC uses to any new v_mov instructions created.
      for (MachineInstr *Copy : CopiesToReplace)
        Copy->addImplicitDefUseOperands(MF);

      for (FoldCandidate &Fold : FoldList) {
        if (updateOperand(Fold, TRI)) {
          // Clear kill flags.
          if (!Fold.isImm()) {
            assert(Fold.OpToFold && Fold.OpToFold->isReg());
            // FIXME: Probably shouldn't bother trying to fold if not an
            // SGPR. PeepholeOptimizer can eliminate redundant VGPR->VGPR
            // copies.
            MRI.clearKillFlags(Fold.OpToFold->getReg());
          }
          DEBUG(dbgs() << "Folded source from " << MI << " into OpNo " <<
                Fold.UseOpNo << " of " << *Fold.UseMI << '\n');
        }
      }
    }
  }
  return false;
}
<commit_msg>AMDGPU/SI: Fix a bug in SIFoldOperands<commit_after>//===-- SIFoldOperands.cpp - Fold operands --- ----------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
/// \file
//===----------------------------------------------------------------------===//
//

#include "AMDGPU.h"
#include "AMDGPUSubtarget.h"
#include "SIInstrInfo.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"

#define DEBUG_TYPE "si-fold-operands"
using namespace llvm;

namespace {

class SIFoldOperands : public MachineFunctionPass {
public:
  static char ID;

public:
  SIFoldOperands() : MachineFunctionPass(ID) {
    initializeSIFoldOperandsPass(*PassRegistry::getPassRegistry());
  }

  bool runOnMachineFunction(MachineFunction &MF) override;

  const char *getPassName() const override {
    return "SI Fold Operands";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequired<MachineDominatorTree>();
    AU.addPreserved<MachineDominatorTree>();
    AU.setPreservesCFG();
    MachineFunctionPass::getAnalysisUsage(AU);
  }
};

struct FoldCandidate {
  MachineInstr *UseMI;
  unsigned UseOpNo;
  MachineOperand *OpToFold;
  uint64_t ImmToFold;

  FoldCandidate(MachineInstr *MI, unsigned OpNo, MachineOperand *FoldOp) :
                UseMI(MI), UseOpNo(OpNo) {

    if (FoldOp->isImm()) {
      OpToFold = nullptr;
      ImmToFold = FoldOp->getImm();
    } else {
      assert(FoldOp->isReg());
      OpToFold = FoldOp;
    }
  }

  bool isImm() const {
    return !OpToFold;
  }
};

} // End anonymous namespace.

INITIALIZE_PASS_BEGIN(SIFoldOperands, DEBUG_TYPE,
                      "SI Fold Operands", false, false)
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_END(SIFoldOperands, DEBUG_TYPE,
                    "SI Fold Operands", false, false)

char SIFoldOperands::ID = 0;

char &llvm::SIFoldOperandsID = SIFoldOperands::ID;

FunctionPass *llvm::createSIFoldOperandsPass() {
  return new SIFoldOperands();
}

static bool isSafeToFold(unsigned Opcode) {
  switch(Opcode) {
  case AMDGPU::V_MOV_B32_e32:
  case AMDGPU::V_MOV_B32_e64:
  case AMDGPU::V_MOV_B64_PSEUDO:
  case AMDGPU::S_MOV_B32:
  case AMDGPU::S_MOV_B64:
  case AMDGPU::COPY:
    return true;
  default:
    return false;
  }
}

static bool updateOperand(FoldCandidate &Fold,
                          const TargetRegisterInfo &TRI) {
  MachineInstr *MI = Fold.UseMI;
  MachineOperand &Old = MI->getOperand(Fold.UseOpNo);
  assert(Old.isReg());

  if (Fold.isImm()) {
    Old.ChangeToImmediate(Fold.ImmToFold);
    return true;
  }

  MachineOperand *New = Fold.OpToFold;
  if (TargetRegisterInfo::isVirtualRegister(Old.getReg()) &&
      TargetRegisterInfo::isVirtualRegister(New->getReg())) {
    Old.substVirtReg(New->getReg(), New->getSubReg(), TRI);
    return true;
  }

  // FIXME: Handle physical registers.

  return false;
}

static bool isUseMIInFoldList(const std::vector<FoldCandidate> &FoldList,
                              const MachineInstr *MI) {
  for (auto Candidate : FoldList) {
    if (Candidate.UseMI == MI)
      return true;
  }
  return false;
}

static bool tryAddToFoldList(std::vector<FoldCandidate> &FoldList,
                             MachineInstr *MI, unsigned OpNo,
                             MachineOperand *OpToFold,
                             const SIInstrInfo *TII) {
  if (!TII->isOperandLegal(MI, OpNo, OpToFold)) {

    // Special case for v_mac_f32_e64 if we are trying to fold into src2
    unsigned Opc = MI->getOpcode();
    if (Opc == AMDGPU::V_MAC_F32_e64 &&
        (int)OpNo == AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src2)) {
      // Check if changing this to a v_mad_f32 instruction will allow us to
      // fold the operand.
      MI->setDesc(TII->get(AMDGPU::V_MAD_F32));
      bool FoldAsMAD = tryAddToFoldList(FoldList, MI, OpNo, OpToFold, TII);
      if (FoldAsMAD) {
        MI->untieRegOperand(OpNo);
        return true;
      }
      MI->setDesc(TII->get(Opc));
    }

    // If we are already folding into another operand of MI, then
    // we can't commute the instruction, otherwise we risk making the
    // other fold illegal.
    if (isUseMIInFoldList(FoldList, MI))
      return false;

    // Operand is not legal, so try to commute the instruction to
    // see if this makes it possible to fold.
    unsigned CommuteIdx0 = TargetInstrInfo::CommuteAnyOperandIndex;
    unsigned CommuteIdx1 = TargetInstrInfo::CommuteAnyOperandIndex;
    bool CanCommute = TII->findCommutedOpIndices(MI, CommuteIdx0, CommuteIdx1);

    if (CanCommute) {
      if (CommuteIdx0 == OpNo)
        OpNo = CommuteIdx1;
      else if (CommuteIdx1 == OpNo)
        OpNo = CommuteIdx0;
    }

    // One of operands might be an Imm operand, and OpNo may refer to it after
    // the call of commuteInstruction() below. Such situations are avoided
    // here explicitly as OpNo must be a register operand to be a candidate
    // for memory folding.
    if (CanCommute && (!MI->getOperand(CommuteIdx0).isReg() ||
                       !MI->getOperand(CommuteIdx1).isReg()))
      return false;

    if (!CanCommute ||
        !TII->commuteInstruction(MI, false, CommuteIdx0, CommuteIdx1))
      return false;

    if (!TII->isOperandLegal(MI, OpNo, OpToFold))
      return false;
  }

  FoldList.push_back(FoldCandidate(MI, OpNo, OpToFold));
  return true;
}

static void foldOperand(MachineOperand &OpToFold, MachineInstr *UseMI,
                        unsigned UseOpIdx,
                        std::vector<FoldCandidate> &FoldList,
                        SmallVectorImpl<MachineInstr *> &CopiesToReplace,
                        const SIInstrInfo *TII, const SIRegisterInfo &TRI,
                        MachineRegisterInfo &MRI) {
  const MachineOperand &UseOp = UseMI->getOperand(UseOpIdx);

  // FIXME: Fold operands with subregs.
  if (UseOp.isReg() && ((UseOp.getSubReg() && OpToFold.isReg()) ||
      UseOp.isImplicit())) {
    return;
  }

  bool FoldingImm = OpToFold.isImm();
  APInt Imm;

  if (FoldingImm) {
    unsigned UseReg = UseOp.getReg();
    const TargetRegisterClass *UseRC
      = TargetRegisterInfo::isVirtualRegister(UseReg) ?
      MRI.getRegClass(UseReg) :
      TRI.getPhysRegClass(UseReg);

    Imm = APInt(64, OpToFold.getImm());

    const MCInstrDesc &FoldDesc = TII->get(OpToFold.getParent()->getOpcode());
    const TargetRegisterClass *FoldRC =
        TRI.getRegClass(FoldDesc.OpInfo[0].RegClass);

    // Split 64-bit constants into 32-bits for folding.
    if (FoldRC->getSize() == 8 && UseOp.getSubReg()) {
      if (UseRC->getSize() != 8)
        return;

      if (UseOp.getSubReg() == AMDGPU::sub0) {
        Imm = Imm.getLoBits(32);
      } else {
        assert(UseOp.getSubReg() == AMDGPU::sub1);
        Imm = Imm.getHiBits(32);
      }
    }

    // In order to fold immediates into copies, we need to change the
    // copy to a MOV.
    if (UseMI->getOpcode() == AMDGPU::COPY) {
      unsigned DestReg = UseMI->getOperand(0).getReg();
      const TargetRegisterClass *DestRC
        = TargetRegisterInfo::isVirtualRegister(DestReg) ?
        MRI.getRegClass(DestReg) :
        TRI.getPhysRegClass(DestReg);

      unsigned MovOp = TII->getMovOpcode(DestRC);
      if (MovOp == AMDGPU::COPY)
        return;

      UseMI->setDesc(TII->get(MovOp));
      CopiesToReplace.push_back(UseMI);
    }
  }

  // Special case for REG_SEQUENCE: We can't fold literals into
  // REG_SEQUENCE instructions, so we have to fold them into the
  // uses of REG_SEQUENCE.
  if (UseMI->getOpcode() == AMDGPU::REG_SEQUENCE) {
    unsigned RegSeqDstReg = UseMI->getOperand(0).getReg();
    unsigned RegSeqDstSubReg = UseMI->getOperand(UseOpIdx + 1).getImm();

    for (MachineRegisterInfo::use_iterator
         RSUse = MRI.use_begin(RegSeqDstReg),
         RSE = MRI.use_end(); RSUse != RSE; ++RSUse) {

      MachineInstr *RSUseMI = RSUse->getParent();
      if (RSUse->getSubReg() != RegSeqDstSubReg)
        continue;

      foldOperand(OpToFold, RSUseMI, RSUse.getOperandNo(), FoldList,
                  CopiesToReplace, TII, TRI, MRI);
    }
    return;
  }

  const MCInstrDesc &UseDesc = UseMI->getDesc();

  // Don't fold into target independent nodes.  Target independent opcodes
  // don't have defined register classes.
  if (UseDesc.isVariadic() ||
      UseDesc.OpInfo[UseOpIdx].RegClass == -1)
    return;

  if (FoldingImm) {
    MachineOperand ImmOp = MachineOperand::CreateImm(Imm.getSExtValue());
    tryAddToFoldList(FoldList, UseMI, UseOpIdx, &ImmOp, TII);
    return;
  }

  tryAddToFoldList(FoldList, UseMI, UseOpIdx, &OpToFold, TII);

  // FIXME: We could try to change the instruction from 64-bit to 32-bit
  // to enable more folding opportunites.  The shrink operands pass
  // already does this.
  return;
}

bool SIFoldOperands::runOnMachineFunction(MachineFunction &MF) {
  MachineRegisterInfo &MRI = MF.getRegInfo();
  const SIInstrInfo *TII =
      static_cast<const SIInstrInfo *>(MF.getSubtarget().getInstrInfo());
  const SIRegisterInfo &TRI = TII->getRegisterInfo();

  for (MachineFunction::iterator BI = MF.begin(), BE = MF.end();
                                                  BI != BE; ++BI) {

    MachineBasicBlock &MBB = *BI;
    MachineBasicBlock::iterator I, Next;
    for (I = MBB.begin(); I != MBB.end(); I = Next) {
      Next = std::next(I);
      MachineInstr &MI = *I;

      if (!isSafeToFold(MI.getOpcode()))
        continue;

      unsigned OpSize = TII->getOpSize(MI, 1);
      MachineOperand &OpToFold = MI.getOperand(1);
      bool FoldingImm = OpToFold.isImm();

      // FIXME: We could also be folding things like FrameIndexes and
      // TargetIndexes.
      if (!FoldingImm && !OpToFold.isReg())
        continue;

      // Folding immediates with more than one use will increase program size.
      // FIXME: This will also reduce register usage, which may be better
      // in some cases.  A better heuristic is needed.
      if (FoldingImm && !TII->isInlineConstant(OpToFold, OpSize) &&
          !MRI.hasOneUse(MI.getOperand(0).getReg()))
        continue;

      if (OpToFold.isReg() &&
          !TargetRegisterInfo::isVirtualRegister(OpToFold.getReg()))
        continue;

      // Prevent folding operands backwards in the function. For example,
      // the COPY opcode must not be replaced by 1 in this example:
      //
      //    %vreg3<def> = COPY %VGPR0; VGPR_32:%vreg3
      //    ...
      //    %VGPR0<def> = V_MOV_B32_e32 1, %EXEC<imp-use>
      MachineOperand &Dst = MI.getOperand(0);
      if (Dst.isReg() &&
          !TargetRegisterInfo::isVirtualRegister(Dst.getReg()))
        continue;

      // We need mutate the operands of new mov instructions to add implicit
      // uses of EXEC, but adding them invalidates the use_iterator, so defer
      // this.
      SmallVector<MachineInstr *, 4> CopiesToReplace;

      std::vector<FoldCandidate> FoldList;
      for (MachineRegisterInfo::use_iterator
           Use = MRI.use_begin(MI.getOperand(0).getReg()), E = MRI.use_end();
           Use != E; ++Use) {

        MachineInstr *UseMI = Use->getParent();

        foldOperand(OpToFold, UseMI, Use.getOperandNo(), FoldList,
                    CopiesToReplace, TII, TRI, MRI);
      }

      // Make sure we add EXEC uses to any new v_mov instructions created.
      for (MachineInstr *Copy : CopiesToReplace)
        Copy->addImplicitDefUseOperands(MF);

      for (FoldCandidate &Fold : FoldList) {
        if (updateOperand(Fold, TRI)) {
          // Clear kill flags.
          if (!Fold.isImm()) {
            assert(Fold.OpToFold && Fold.OpToFold->isReg());
            // FIXME: Probably shouldn't bother trying to fold if not an
            // SGPR. PeepholeOptimizer can eliminate redundant VGPR->VGPR
            // copies.
            MRI.clearKillFlags(Fold.OpToFold->getReg());
          }
          DEBUG(dbgs() << "Folded source from " << MI << " into OpNo " <<
                Fold.UseOpNo << " of " << *Fold.UseMI << '\n');
        }
      }
    }
  }
  return false;
}
<|endoftext|>


<commit_before>#include "ofApp.h"

//By default, the screen is cleared with every draw() call.We can change that with
//  ofSetBackgroundAuto(...).Passing in a value of false turns off the automatic background clearing.

namespace Software2552 {

	shared_ptr<Stage> stage=nullptr; // one global stage, makes it easy to change between stages
	// always valid stage pointer
	shared_ptr<Stage> getStage() {
		if (stage == nullptr) {
			getScene("Generic"); // default
		}
		return stage;
	}
	// convert name to object
	shared_ptr<Stage> getScene(const string&name)
	{
		if (name == "Test") {
			return stage = std::make_shared<TestScene>();
		}
		if (name == "Generic") {
			return stage = std::make_shared<GenericScene>();
		}
		ofLogError("Stage") << "name not known (ignored) using default scene " << name;
		return stage = std::make_shared<GenericScene>();
	}

	// return a possibly modifed version such as camera moved
	shared_ptr<FixedCamera> Director::pickem(vector<shared_ptr<FixedCamera>>&cameras, bool orbiting) {
		for (auto it = cameras.begin(); it != cameras.end(); ++it) {
			if (orbiting) {
				if ((*it)->isOrbiting()) {
					return (*it);
				}
			}
			else {
				if (!(*it)->isOrbiting()) {
					//bugbug return only fixed cameras
					return (*it);// stuff data in the Camera class
									  // lots to do here to make things nice, learn and see how to bring this in
									  //void lookAt(const ofNode& lookAtNode, const ofVec3f& upVector = ofVec3f(0, 1, 0));
									  //if (j == 1) {
									  //cameras[j].move(-100,0,0);
									  //cameras[j].pan(5);
									  //}
									  //else {
									  //cameras[j].move(100, 0, 0);
									  //}
									  //bugbug just one thing we can direct http://halfdanj.github.io/ofDocGenerator/ofEasyCam.html#CameraSettings
									  //float f = cameras[j].getDistance();
									  //figure all this out, with times, animation etc:
									  //cameras[j].setDistance(cameras[j].getDistance() + ofRandom(-100,100));
									  //return &cameras[j];
				}

			}
		}
		ofLogError("Director") << "no camera";
		return nullptr;
	}
	// set background object at location 0 every time
	shared_ptr<Background> Stage::CreateReadAndaddBackgroundItems(const Json::Value &data) {
		if (!data.empty()) {
			shared_ptr<Background> b = std::make_shared<Background>();
			if (b != nullptr) {
				if (b->setup(data)) {
					// only save if data was read in
					addToAnimatable(b, true);
				}
			}
			return b;
		}
		else {
			return nullptr;
		}
	}
	///bigger the number the more forward
	bool compareOrder(shared_ptr<ActorRole>first, shared_ptr<ActorRole>second)	{
		return (first->getDrawOrder()  < second->getDrawOrder());
	}
	// samples https://sites.google.com/site/ofauckland/examples
#define ADDANIMATION(name,type,parent)	if (!data[STRINGIFY(name)].empty()) CreateReadAndaddAnimatable<type>(data[STRINGIFY(name)], parent)
#define ADDLIGHTS(name,type)	if (!data[STRINGIFY(name)].empty()) CreateReadAndaddLight<type>(data[STRINGIFY(name)])
#define ADDCAMERAS(name,type)	if (!data[STRINGIFY(name)].empty()) CreateReadAndaddCamera<type>(data[STRINGIFY(name)])

	void Stage::readCameras(const Json::Value &data) {
		if (!data.empty()) {
			if (deleteExisting(data)) {
				getCameras().clear();
			}
			ADDCAMERAS(cameraFixed, FixedCamera);
			ADDCAMERAS(camera, MovingCamera);
		}
		// set a default camera if none exist
		if (getCameras().size() == 0) {
			shared_ptr<FixedCamera> camera = std::make_shared<FixedCamera>();
			if (camera) {
				if (camera->setup(data)) {
					camera->worker.setPosition(0, 0, 0);//bugbug clean up the rand stuff via data and more organized random
					add(camera);
				}
			}
			shared_ptr<MovingCamera> camera2 = std::make_shared<MovingCamera>();
			if (camera2) {
				if (camera2->setup(data)) {
					camera2->worker.setPosition(0, 0, 600);//bugbug clean up the rand stuff via data and more organized random
					add(camera2);
				}
			}
		}

	}
	void Stage::readLights(const Json::Value &data) {
		if (!data.empty()) {
			if (deleteExisting(data)) {
				getLights().clear();
			}
			ADDLIGHTS(light, Light);
			ADDLIGHTS(pointLight, PointLight);
			ADDLIGHTS(directionalLight, DirectionalLight);
			ADDLIGHTS(spotLight, SpotLight);
		}

		// set a default light if none exist
		if (getLights().size() == 0) {
			shared_ptr<Light> light = std::make_shared<Light>();
			if (light) {
				if (light->setup(data)) {
					add(light);
				}
			}
		}

	}
	// delete existing data
	bool Stage::deleteExisting(const Json::Value &data) {
		bool deleteExisting = false;// delete existing
		READBOOL(deleteExisting, data);
		return deleteExisting;

	}
	void Stage::readNextwork() {

	}

	//recursive reader
	void Stage::readGraphics(const Json::Value &data, shared_ptr<ActorRole> parent) {
		// read from input (web, osc etc and queue input, resort by priority post each read and remove timed out data
		if (!data.empty()) {
			if (deleteExisting(data)) {
				getAnimatables().clear();
			}
			ADDANIMATION(videos, Video, parent);
			ADDANIMATION(pictures, Image, parent);
			ADDANIMATION(rainbows, Rainbow, parent);
			ADDANIMATION(circles, Ball, parent);
			ADDANIMATION(cubes, Cube, parent);
			ADDANIMATION(spheres, Sphere, parent);
			ADDANIMATION(videos, Video, parent);
			ADDANIMATION(grabbers, CameraGrabber, parent);
			ADDANIMATION(texts, Text, parent);
			ADDANIMATION(paragraphs, Paragraph, parent);
			ADDANIMATION(planets, Planet, parent);
			ADDANIMATION(videoSpheres, VideoSphere, parent);
			ADDANIMATION(solarSystems, SolarSystem, parent);//bugbug forgot how to rotate around clyde, does not run w/ others
			ADDANIMATION(audio, Audio, parent);// sound phase 1a
			getAnimatables().sort(compareOrder);

		}
		return;
	}

	bool Stage::updateData(shared_ptr<ofxJSON> data) {
		if (data) {
			Json::Value::Members m = data->getMemberNames();
			readGraphics((*data)["graphics"], nullptr);
			readNextwork();
			CreateReadAndaddBackgroundItems((*data)["background"]);
			readLights((*data)["lights"]);
			readCameras((*data)["cameras"]);
		}

		return true;
	};

	void Stage::draw() {
		preDraw();
		if (drawIn2d) {
			ofPushStyle();
			ofPushMatrix();
			ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2);// default position, cameras may change location
			draw2d();
			ofPopMatrix();
			ofPopStyle();
		}
		if (drawIn3dMoving || drawIn3dFixed) {
			ofPushStyle();
			ofPushMatrix();
			draw3d();
			ofPopMatrix();
			ofPopStyle();
		}
		postDraw();
	}
	// pause them all
	void Stage::pause() {
		for (auto& a : animatables) {
			a->pause();
		}
		//bugbug pause moving camera, grabber etc
		myPause();
	}
	void Stage::resume() {
		for (auto& a : animatables) {
			a->resume();
		}
		//bugbug pause moving camera, grabber etc
		myResume();
	}
	// clear objects
	void Stage::clear(bool force) {
		if (force) {
			animatables.clear();
			cameras.clear();
			lights.clear();
		}
		else {
			removeExpiredItems(animatables);
			removeExpiredItems<FixedCamera>(cameras);
			removeExpiredItems<Light>(lights);
		}
		myClear(force);
	}

	void Stage::setup(shared_ptr<Client>clientIn) {
		client = clientIn;
		mySetup();
	}
	void Stage::update() {

		for (auto& a : animatables) {
			a->updateForDrawing();
		}
		myUpdate();// dervived class update

	}
	// setup light and material for drawing
	void Stage::installLightAndMaterialThenDraw(shared_ptr<FixedCamera>cam, bool drawFixed) {
		if (cam != nullptr) {
			cam->worker.begin();
			cam->orbit();
			for (auto& light : lights) {
				ofPoint p = light->worker.getPosition();
				light->worker.setPosition(light->loc);
				light->worker.enable();
				light->worker.draw();
			}
			if (cam->isOrbiting()) {
				if (drawIn3dMoving && !drawFixed) {
					draw3dMoving();
				}
			}
			else {
				if (drawIn3dFixed && drawFixed) {
					draw3dFixed();
				}
			}
			cam->worker.end();
		}
		else {
			// draw w/o a camera
			ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2); // center when not using a camera
			for (auto& light : lights) {
				light->worker.setPosition(0, 0, 600);
				light->worker.enable();
				light->worker.draw();
			}
			if (drawIn3dMoving && !drawFixed) {
				draw3dMoving();
			}
			if (drawIn3dFixed && drawFixed) {
				draw3dFixed();
			}
		}
	}
	void Stage::addToAnimatable(shared_ptr<ActorRole>p, bool inFront) {
		// only save working pointers
		if (p != nullptr) {
			ActorRole::drawtype tp = p->getType();
			if (p->getType() == ActorRole::draw3dFixedCamera) {
				fixed3d(true); // do not set to false in case its already set
			}
			if (p->getType() == ActorRole::draw3dMovingCamera) {
				moving3d(true); // do not set to false in case its already set
			}
			if (p->getType() == ActorRole::draw2d) {
				fixed2d(true); // do not set to false in case its already set
			}
			p->setupForDrawing();
			if (inFront) {
				animatables.push_front(p);
			}
			else {
				animatables.push_back(p);
			}
		}
	}

	void Stage::preDraw() {
		ofDisableDepthTest(); // bugbug make this a var read in via json so we can make more advanced graphics later
		//ofBackground(ofColor::blue); // white enables all colors in pictures/videos
		ofSetSmoothLighting(true);
		ofDisableAlphaBlending();

		//ofEnableDepthTest();
	}
	void Stage::postDraw() {
		// clean up
		ofEnableDepthTest();
		for (auto& light : lights) {
			light->worker.disable();
		}
		ofDisableLighting();
	}
	void Stage::draw3d() {

		// fixed camera
		if (drawIn3dFixed) {
			shared_ptr<FixedCamera> cam = director.pickem(cameras, false);
			if (cam != nullptr) {
				installLightAndMaterialThenDraw(cam, true);
			}
		}
		if (drawIn3dMoving) {
			shared_ptr<FixedCamera> cam = director.pickem(cameras, true);
			if (cam != nullptr) {
				installLightAndMaterialThenDraw(cam, false);
			}
		}

	}
	// find overall duration of a scene
	float Stage::findMaxWait() {
		float f = 0;

		for (const auto& a : getAnimatables()) {
			setIfGreater(f, a->getObjectLifetime() + a->getWait());
		}

		return f;
	}
	// show light location, great for debugging and kind of fun too
	void Stage::drawlights() {
		for (const auto& light : getLights()) {
			ofSetColor(light->worker.getDiffuseColor());
			ofPoint pos = light->worker.getPosition();
			ofDrawSphere(light->worker.getPosition(), 20.f);
		}
	}
	void Stage::draw2d() {
		myDraw2d();
		for (auto& a : animatables) {
			a->drawIt(ActorRole::draw2d);
		}

		//ofBackground(ofColor::black);
		//bugbug option is to add vs replace:ofEnableBlendMode(OF_BLENDMODE_ADD);//bugbug can make these attributes somewhere
		//ofEnableAlphaBlending();
	}
	// juse need to draw the SpaceScene, base class does the rest
	void Stage::draw3dMoving() {
		myDraw3dMoving();
		for (auto& a : animatables) {
			a->drawIt(ActorRole::draw3dMovingCamera);
		}
	}
	void Stage::draw3dFixed() {
		myDraw3dFixed();
		for (auto& a : animatables) {
			a->drawIt(ActorRole::draw3dFixedCamera);
		}
	}
	template<typename T>void Stage::CreateReadAndaddCamera(const Json::Value &data) {
		for (Json::ArrayIndex j = 0; j < data.size(); ++j) {
			shared_ptr<T> camera = std::make_shared<T>();
			if (camera) {
				if (camera->setup(data[j])) {
					camera->worker.setPosition(0, 0, ofRandom(100, 500));//bugbug clean up the rand stuff via data and more organized random
					add(camera);
				}
			}
		}
	}
	template<typename T>void Stage::CreateReadAndaddLight(const Json::Value &data) {

		for (Json::ArrayIndex j = 0; j < data.size(); ++j) {
			shared_ptr<T> light = std::make_shared<T>();
			if (light) {
				if (light->setup(data[j])) {
					add(light);
				}
			}
		}
	}

	// bugbug all items in test() to come from json or are this is done in Director
	bool TestScene::myCreate(const Json::Value &data) {

		return true;

	}
	void TestScene::myUpdate() {
		mesh.update();
	}
	void TestScene::myDraw3dFixed() {

		//drawlights();

		return; // comment out to draw by vertice, less confusing but feel free to add it back in
		//bugbug item below needs to be put in a drawing class or should be removed
		ofSetHexColor(0xffffff);
		glPointSize(2);
		glEnable(GL_POINT_SMOOTH);
		mesh.drawVertices();
	}
	void TestScene::mySetup() {
		ofSetSmoothLighting(true);
		mesh.setup();
	}

}<commit_msg>working on integration<commit_after>#include "ofApp.h"

//By default, the screen is cleared with every draw() call.We can change that with
//  ofSetBackgroundAuto(...).Passing in a value of false turns off the automatic background clearing.

namespace Software2552 {

	shared_ptr<Stage> stage=nullptr; // one global stage, makes it easy to change between stages
	// always valid stage pointer
	shared_ptr<Stage> getStage() {
		if (stage == nullptr) {
			getScene("Generic"); // default
		}
		return stage;
	}
	// convert name to object
	shared_ptr<Stage> getScene(const string&name)
	{
		if (name == "Test") {
			return stage = std::make_shared<TestScene>();
		}
		if (name == "Generic") {
			return stage = std::make_shared<GenericScene>();
		}
		ofLogError("Stage") << "name not known (ignored) using default scene " << name;
		return stage = std::make_shared<GenericScene>();
	}

	// return a possibly modifed version such as camera moved
	shared_ptr<FixedCamera> Director::pickem(vector<shared_ptr<FixedCamera>>&cameras, bool orbiting) {
		for (auto it = cameras.begin(); it != cameras.end(); ++it) {
			if (orbiting) {
				if ((*it)->isOrbiting()) {
					return (*it);
				}
			}
			else {
				if (!(*it)->isOrbiting()) {
					//bugbug return only fixed cameras
					return (*it);// stuff data in the Camera class
									  // lots to do here to make things nice, learn and see how to bring this in
									  //void lookAt(const ofNode& lookAtNode, const ofVec3f& upVector = ofVec3f(0, 1, 0));
									  //if (j == 1) {
									  //cameras[j].move(-100,0,0);
									  //cameras[j].pan(5);
									  //}
									  //else {
									  //cameras[j].move(100, 0, 0);
									  //}
									  //bugbug just one thing we can direct http://halfdanj.github.io/ofDocGenerator/ofEasyCam.html#CameraSettings
									  //float f = cameras[j].getDistance();
									  //figure all this out, with times, animation etc:
									  //cameras[j].setDistance(cameras[j].getDistance() + ofRandom(-100,100));
									  //return &cameras[j];
				}

			}
		}
		ofLogError("Director") << "no camera";
		return nullptr;
	}
	// set background object at location 0 every time
	shared_ptr<Background> Stage::CreateReadAndaddBackgroundItems(const Json::Value &data) {
		if (!data.empty()) {
			shared_ptr<Background> b = std::make_shared<Background>();
			if (b != nullptr) {
				if (b->setup(data)) {
					// only save if data was read in
					addToAnimatable(b, true);
				}
			}
			return b;
		}
		else {
			return nullptr;
		}
	}
	///bigger the number the more forward
	bool compareOrder(shared_ptr<ActorRole>first, shared_ptr<ActorRole>second)	{
		return (first->getDrawOrder()  < second->getDrawOrder());
	}
	// samples https://sites.google.com/site/ofauckland/examples
#define ADDANIMATION(name,type,parent)	if (!data[STRINGIFY(name)].empty()) CreateReadAndaddAnimatable<type>(data[STRINGIFY(name)], parent)
#define ADDLIGHTS(name,type)	if (!data[STRINGIFY(name)].empty()) CreateReadAndaddLight<type>(data[STRINGIFY(name)])
#define ADDCAMERAS(name,type)	if (!data[STRINGIFY(name)].empty()) CreateReadAndaddCamera<type>(data[STRINGIFY(name)])

	void Stage::readCameras(const Json::Value &data) {
		if (!data.empty()) {
			if (deleteExisting(data)) {
				getCameras().clear();
			}
			ADDCAMERAS(cameraFixed, FixedCamera);
			ADDCAMERAS(camera, MovingCamera);
		}
		// set a default camera if none exist
		if (getCameras().size() == 0) {
			shared_ptr<FixedCamera> camera = std::make_shared<FixedCamera>();
			if (camera) {
				if (camera->setup(data)) {
					camera->worker.setPosition(0, 0, 0);//bugbug clean up the rand stuff via data and more organized random
					add(camera);
				}
			}
			shared_ptr<MovingCamera> camera2 = std::make_shared<MovingCamera>();
			if (camera2) {
				if (camera2->setup(data)) {
					camera2->worker.setPosition(0, 0, 600);//bugbug clean up the rand stuff via data and more organized random
					add(camera2);
				}
			}
		}

	}
	void Stage::readLights(const Json::Value &data) {
		if (!data.empty()) {
			if (deleteExisting(data)) {
				getLights().clear();
			}
			ADDLIGHTS(light, Light);
			ADDLIGHTS(pointLight, PointLight);
			ADDLIGHTS(directionalLight, DirectionalLight);
			ADDLIGHTS(spotLight, SpotLight);
		}

		// set a default light if none exist
		if (getLights().size() == 0) {
			shared_ptr<Light> light = std::make_shared<Light>();
			if (light) {
				if (light->setup(data)) {
					add(light);
				}
			}
		}

	}
	// delete existing data
	bool Stage::deleteExisting(const Json::Value &data) {
		bool deleteExisting = false;// delete existing
		READBOOL(deleteExisting, data);
		return deleteExisting;

	}
	void Stage::readNextwork() {
		if (client) {
			for (const auto&c : client->IRQ()) {
				addToAnimatable(c);
			}
			for (const auto&c : client->bodyIndexQ()) {
				addToAnimatable(c);
			}
			for (const auto&c : client->kinectQ()) {
				addToAnimatable(c);
			}
			shared_ptr<ofxJSON> json = client->get(const string&address);

		}

	}

	//recursive reader
	void Stage::readGraphics(const Json::Value &data, shared_ptr<ActorRole> parent) {
		// read from input (web, osc etc and queue input, resort by priority post each read and remove timed out data
		if (!data.empty()) {
			if (deleteExisting(data)) {
				getAnimatables().clear();
			}
			ADDANIMATION(videos, Video, parent);
			ADDANIMATION(pictures, Image, parent);
			ADDANIMATION(rainbows, Rainbow, parent);
			ADDANIMATION(circles, Ball, parent);
			ADDANIMATION(cubes, Cube, parent);
			ADDANIMATION(spheres, Sphere, parent);
			ADDANIMATION(videos, Video, parent);
			ADDANIMATION(grabbers, CameraGrabber, parent);
			ADDANIMATION(texts, Text, parent);
			ADDANIMATION(paragraphs, Paragraph, parent);
			ADDANIMATION(planets, Planet, parent);
			ADDANIMATION(videoSpheres, VideoSphere, parent);
			ADDANIMATION(solarSystems, SolarSystem, parent);//bugbug forgot how to rotate around clyde, does not run w/ others
			ADDANIMATION(audio, Audio, parent);// sound phase 1a
			getAnimatables().sort(compareOrder);

		}
		return;
	}

	bool Stage::updateData(shared_ptr<ofxJSON> data) {
		if (data) {
			Json::Value::Members m = data->getMemberNames();
			readGraphics((*data)["graphics"], nullptr);

			CreateReadAndaddBackgroundItems((*data)["background"]);
			readLights((*data)["lights"]);
			readCameras((*data)["cameras"]);
		}

		return true;
	};

	void Stage::draw() {
		preDraw();
		if (drawIn2d) {
			ofPushStyle();
			ofPushMatrix();
			ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2);// default position, cameras may change location
			draw2d();
			ofPopMatrix();
			ofPopStyle();
		}
		if (drawIn3dMoving || drawIn3dFixed) {
			ofPushStyle();
			ofPushMatrix();
			draw3d();
			ofPopMatrix();
			ofPopStyle();
		}
		postDraw();
	}
	// pause them all
	void Stage::pause() {
		for (auto& a : animatables) {
			a->pause();
		}
		//bugbug pause moving camera, grabber etc
		myPause();
	}
	void Stage::resume() {
		for (auto& a : animatables) {
			a->resume();
		}
		//bugbug pause moving camera, grabber etc
		myResume();
	}
	// clear objects
	void Stage::clear(bool force) {
		if (force) {
			animatables.clear();
			cameras.clear();
			lights.clear();
		}
		else {
			removeExpiredItems(animatables);
			removeExpiredItems<FixedCamera>(cameras);
			removeExpiredItems<Light>(lights);
		}
		myClear(force);
	}

	void Stage::setup(shared_ptr<Client>clientIn) {
		client = clientIn;
		mySetup();
	}
	void Stage::update() {
		readNextwork();
		for (auto& a : animatables) {
			a->updateForDrawing();
		}
		myUpdate();// dervived class update

	}
	// setup light and material for drawing
	void Stage::installLightAndMaterialThenDraw(shared_ptr<FixedCamera>cam, bool drawFixed) {
		if (cam != nullptr) {
			cam->worker.begin();
			cam->orbit();
			for (auto& light : lights) {
				ofPoint p = light->worker.getPosition();
				light->worker.setPosition(light->loc);
				light->worker.enable();
				light->worker.draw();
			}
			if (cam->isOrbiting()) {
				if (drawIn3dMoving && !drawFixed) {
					draw3dMoving();
				}
			}
			else {
				if (drawIn3dFixed && drawFixed) {
					draw3dFixed();
				}
			}
			cam->worker.end();
		}
		else {
			// draw w/o a camera
			ofTranslate(ofGetWidth() / 2, ofGetHeight() / 2); // center when not using a camera
			for (auto& light : lights) {
				light->worker.setPosition(0, 0, 600);
				light->worker.enable();
				light->worker.draw();
			}
			if (drawIn3dMoving && !drawFixed) {
				draw3dMoving();
			}
			if (drawIn3dFixed && drawFixed) {
				draw3dFixed();
			}
		}
	}
	void Stage::addToAnimatable(shared_ptr<ActorRole>p, bool inFront) {
		// only save working pointers
		if (p != nullptr) {
			ActorRole::drawtype tp = p->getType();
			if (p->getType() == ActorRole::draw3dFixedCamera) {
				fixed3d(true); // do not set to false in case its already set
			}
			if (p->getType() == ActorRole::draw3dMovingCamera) {
				moving3d(true); // do not set to false in case its already set
			}
			if (p->getType() == ActorRole::draw2d) {
				fixed2d(true); // do not set to false in case its already set
			}
			p->setupForDrawing();
			if (inFront) {
				animatables.push_front(p);
			}
			else {
				animatables.push_back(p);
			}
		}
	}

	void Stage::preDraw() {
		ofDisableDepthTest(); // bugbug make this a var read in via json so we can make more advanced graphics later
		//ofBackground(ofColor::blue); // white enables all colors in pictures/videos
		ofSetSmoothLighting(true);
		ofDisableAlphaBlending();

		//ofEnableDepthTest();
	}
	void Stage::postDraw() {
		// clean up
		ofEnableDepthTest();
		for (auto& light : lights) {
			light->worker.disable();
		}
		ofDisableLighting();
	}
	void Stage::draw3d() {

		// fixed camera
		if (drawIn3dFixed) {
			shared_ptr<FixedCamera> cam = director.pickem(cameras, false);
			if (cam != nullptr) {
				installLightAndMaterialThenDraw(cam, true);
			}
		}
		if (drawIn3dMoving) {
			shared_ptr<FixedCamera> cam = director.pickem(cameras, true);
			if (cam != nullptr) {
				installLightAndMaterialThenDraw(cam, false);
			}
		}

	}
	// find overall duration of a scene
	float Stage::findMaxWait() {
		float f = 0;

		for (const auto& a : getAnimatables()) {
			setIfGreater(f, a->getObjectLifetime() + a->getWait());
		}

		return f;
	}
	// show light location, great for debugging and kind of fun too
	void Stage::drawlights() {
		for (const auto& light : getLights()) {
			ofSetColor(light->worker.getDiffuseColor());
			ofPoint pos = light->worker.getPosition();
			ofDrawSphere(light->worker.getPosition(), 20.f);
		}
	}
	void Stage::draw2d() {
		myDraw2d();
		for (auto& a : animatables) {
			a->drawIt(ActorRole::draw2d);
		}

		//ofBackground(ofColor::black);
		//bugbug option is to add vs replace:ofEnableBlendMode(OF_BLENDMODE_ADD);//bugbug can make these attributes somewhere
		//ofEnableAlphaBlending();
	}
	// juse need to draw the SpaceScene, base class does the rest
	void Stage::draw3dMoving() {
		myDraw3dMoving();
		for (auto& a : animatables) {
			a->drawIt(ActorRole::draw3dMovingCamera);
		}
	}
	void Stage::draw3dFixed() {
		myDraw3dFixed();
		for (auto& a : animatables) {
			a->drawIt(ActorRole::draw3dFixedCamera);
		}
	}
	template<typename T>void Stage::CreateReadAndaddCamera(const Json::Value &data) {
		for (Json::ArrayIndex j = 0; j < data.size(); ++j) {
			shared_ptr<T> camera = std::make_shared<T>();
			if (camera) {
				if (camera->setup(data[j])) {
					camera->worker.setPosition(0, 0, ofRandom(100, 500));//bugbug clean up the rand stuff via data and more organized random
					add(camera);
				}
			}
		}
	}
	template<typename T>void Stage::CreateReadAndaddLight(const Json::Value &data) {

		for (Json::ArrayIndex j = 0; j < data.size(); ++j) {
			shared_ptr<T> light = std::make_shared<T>();
			if (light) {
				if (light->setup(data[j])) {
					add(light);
				}
			}
		}
	}

	// bugbug all items in test() to come from json or are this is done in Director
	bool TestScene::myCreate(const Json::Value &data) {

		return true;

	}
	void TestScene::myUpdate() {
		mesh.update();
	}
	void TestScene::myDraw3dFixed() {

		//drawlights();

		return; // comment out to draw by vertice, less confusing but feel free to add it back in
		//bugbug item below needs to be put in a drawing class or should be removed
		ofSetHexColor(0xffffff);
		glPointSize(2);
		glEnable(GL_POINT_SMOOTH);
		mesh.drawVertices();
	}
	void TestScene::mySetup() {
		ofSetSmoothLighting(true);
		mesh.setup();
	}

}<|endoftext|>


<commit_before>#pragma once

#include <unordered_map>

namespace detail
{
	class connection : public std::enable_shared_from_this<connection>
	{
		connection(boost::asio::local::stream_protocol::socket& socket);
	public:
		typedef std::shared_ptr<connection> pointer;

		static pointer create(boost::asio::io_service& io_service);

		template <class T>
		static pointer create(T&& socket)
		{
			return std::make_shared<connection>(std::forward(socket));
		}

		boost::asio::local::stream_protocol::socket socket();

		void queue_write(const std::string& msg);

		template <class Callable>
		boost::signals2::connection connect_read(Callable&& f)
		{
			return read_handlers_.connect(std::forward(f));
		}

	protected:
		boost::asio::local::stream_protocol::socket socket_;

		std::deque<std::string> write_queue_;

		boost::signals2::signal<void (const std::string&)> read_handlers_;

		void handle_read(boost::system::error_code& error, std::size_t bytes_tx);
		void handle_write(boost::system::error_code& error);
	};

}

//! Responsible for handling the connection to a CLI instance; provides callbacks for this.
class RemoteControl
{
public:
	//! Provides thread-safe write access to a ctl.
	/*!
	 *  This class provides thread-safe write access to a controller. It should
	 *  close the connection when the final instance targeted at the session is
	 *  destructed -- do this by wrapping a shared connection object managed by a
	 *  shared_ptr; this shared connection object should handle the connection via
	 *  RAII.
	 */
	class CtlSession
	{};

	typedef boost::signals2::signal<void(const std::vector<std::string>&, const CtlSession&)> signal_type;

	RemoteControl(boost::asio::io_service& io, const boost::filesystem::path& socket);

	//! Register a handler for a verb.
	/*!
	 *  This function registers a callback for a verb sent for the CTL.
	 *  \param verb The verb for which this callback should be called
	 *  \param f The callback. Must be a callable of type void f(const
	 *  std::vector<std::string>&, const CtlSession&);
	 *
	 *  \returns A Boost.Signals2 connection object; use this to unregister.
	 */
	template <class Callable>
	boost::signals2::connection connect(const std::string& verb, Callable&& f)
	{
		//construct the signal if it doesn't exist
		if(registry_.count(verb) == 0)
			registry_[verb] = signal_type();

		//Forward the connect
		return registry_[verb].connect(std::forward(f));
	}

protected:
	boost::asio::io_service& io_;

	std::unordered_map<std::string, signal_type> registry_;
};
<commit_msg>detail::connection::socket() returns a reference.<commit_after>#pragma once

#include <unordered_map>

namespace detail
{
	class connection : public std::enable_shared_from_this<connection>
	{
		connection(boost::asio::local::stream_protocol::socket& socket);
	public:
		typedef std::shared_ptr<connection> pointer;

		static pointer create(boost::asio::io_service& io_service);

		template <class T>
		static pointer create(T&& socket)
		{
			return std::make_shared<connection>(std::forward(socket));
		}

		boost::asio::local::stream_protocol::socket& socket();

		void queue_write(const std::string& msg);

		template <class Callable>
		boost::signals2::connection connect_read(Callable&& f)
		{
			return read_handlers_.connect(std::forward(f));
		}

	protected:
		boost::asio::local::stream_protocol::socket socket_;

		std::deque<std::string> write_queue_;

		boost::signals2::signal<void (const std::string&)> read_handlers_;

		void handle_read(boost::system::error_code& error, std::size_t bytes_tx);
		void handle_write(boost::system::error_code& error);
	};

}

//! Responsible for handling the connection to a CLI instance; provides callbacks for this.
class RemoteControl
{
public:
	//! Provides thread-safe write access to a ctl.
	/*!
	 *  This class provides thread-safe write access to a controller. It should
	 *  close the connection when the final instance targeted at the session is
	 *  destructed -- do this by wrapping a shared connection object managed by a
	 *  shared_ptr; this shared connection object should handle the connection via
	 *  RAII.
	 */
	class CtlSession
	{};

	typedef boost::signals2::signal<void(const std::vector<std::string>&, const CtlSession&)> signal_type;

	RemoteControl(boost::asio::io_service& io, const boost::filesystem::path& socket);

	//! Register a handler for a verb.
	/*!
	 *  This function registers a callback for a verb sent for the CTL.
	 *  \param verb The verb for which this callback should be called
	 *  \param f The callback. Must be a callable of type void f(const
	 *  std::vector<std::string>&, const CtlSession&);
	 *
	 *  \returns A Boost.Signals2 connection object; use this to unregister.
	 */
	template <class Callable>
	boost::signals2::connection connect(const std::string& verb, Callable&& f)
	{
		//construct the signal if it doesn't exist
		if(registry_.count(verb) == 0)
			registry_[verb] = signal_type();

		//Forward the connect
		return registry_[verb].connect(std::forward(f));
	}

protected:
	boost::asio::io_service& io_;

	std::unordered_map<std::string, signal_type> registry_;
};
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "nanoFramework_hardware_esp32_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Logging::NativeSetLogLevel___STATIC__VOID__STRING__I4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerCreate___I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerDispose___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStop___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartOneShot___VOID__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartPeriodic___VOID__U8,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeGetCurrent___STATIC__U8,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32 =
{
    "nanoFramework.Hardware.Esp32",
    0xF8079179,
    method_lookup,
    { 1, 0, 2, 12 }
};
<commit_msg>Update nanoFramework.Hardware.Esp32 version to 1.0.2-preview-015 ***NO_CI***<commit_after>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "nanoFramework_hardware_esp32_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Logging::NativeSetLogLevel___STATIC__VOID__STRING__I4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTimer___STATIC__nanoFrameworkHardwareEsp32EspNativeError__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByPin___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByMultiPins___STATIC__nanoFrameworkHardwareEsp32EspNativeError__nanoFrameworkHardwareEsp32SleepWakeupGpioPin__nanoFrameworkHardwareEsp32SleepWakeupMode,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeEnableWakeupByTouchPad___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartLightSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeStartDeepSleep___STATIC__nanoFrameworkHardwareEsp32EspNativeError,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupCause___STATIC__nanoFrameworkHardwareEsp32SleepWakeupCause,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupGpioPin___STATIC__nanoFrameworkHardwareEsp32SleepWakeupGpioPin,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_Sleep::NativeGetWakeupTouchpad___STATIC__nanoFrameworkHardwareEsp32SleepTouchPad,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerCreate___I4,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeEspTimerDispose___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStop___VOID,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartOneShot___VOID__U8,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeStartPeriodic___VOID__U8,
    NULL,
    Library_nanoFramework_hardware_esp32_native_nanoFramework_Hardware_Esp32_HighResTimer::NativeGetCurrent___STATIC__U8,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_nanoFramework_Hardware_Esp32 =
{
    "nanoFramework.Hardware.Esp32",
    0xF8079179,
    method_lookup,
    { 1, 0, 2, 15 }
};
<|endoftext|>


<commit_before>#include <iostream>

#include "hitable_list.h"
#include "sphere.h"
#include "float.h"

vec3 color(const ray&, hitable*);
float hit_sphere(const vec3&, float, const ray&);

int main() {
    int nx = 200;
    int ny = 100;

    vec3 lower_left_corner(-2.0, -1.0, -1.0);
    vec3 horizontal(4, 0, 0);
    vec3 vertical(0, 2, 0);
    vec3 origin(0, 0, 0);

    hitable* list[2];
    list[0] = new sphere(vec3(0, 0, -1), 0.5);
    list[1] = new sphere(vec3(0, -100.5, -1), 100);

    hitable* world = new hitable_list(list, 2);

    std::cout << "P3\n" << nx << " " << ny << "\n255\n";
    for (int j = ny - 1; j >= 0; j--) {
        for (int i = 0; i < nx; i++) {
            float u = float(i) / float(nx);
            float v = float(j) / float(ny);

            ray r(origin, lower_left_corner + u * horizontal + v * vertical);

            vec3 p = r.point_at_parameter(2.0);
            vec3 col = color(r, world);

            int ir = int(255.99 * col.r());
            int ig = int(255.99 * col.g());
            int ib = int(255.99 * col.b());

            std::cout << ir << " " << ig << " " << ib << "\n";
        }
    }
}

vec3 color(const ray& r, hitable* world) {
    hit_record rec;
    if (world->hit(r, 0.0, MAXFLOAT, rec)) {
        return 0.5 * (rec.normal + 1);
    } else {
        vec3 unit_direction = unit_vector(r.direction);
        float t = 0.5 * (unit_direction.y() + 1.0);
        return (1 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
    }
}
<commit_msg>fix maxfloat<commit_after>#include <iostream>

#include "hitable_list.h"
#include "sphere.h"
#include "float.h"

vec3 color(const ray&, hitable*);
float hit_sphere(const vec3&, float, const ray&);

int main() {
    int nx = 200;
    int ny = 100;

    vec3 lower_left_corner(-2.0, -1.0, -1.0);
    vec3 horizontal(4, 0, 0);
    vec3 vertical(0, 2, 0);
    vec3 origin(0, 0, 0);

    hitable* list[2];
    list[0] = new sphere(vec3(0, 0, -1), 0.5);
    list[1] = new sphere(vec3(0, -100.5, -1), 100);

    hitable* world = new hitable_list(list, 2);

    std::cout << "P3\n" << nx << " " << ny << "\n255\n";
    for (int j = ny - 1; j >= 0; j--) {
        for (int i = 0; i < nx; i++) {
            float u = float(i) / float(nx);
            float v = float(j) / float(ny);

            ray r(origin, lower_left_corner + u * horizontal + v * vertical);

            vec3 p = r.point_at_parameter(2.0);
            vec3 col = color(r, world);

            int ir = int(255.99 * col.r());
            int ig = int(255.99 * col.g());
            int ib = int(255.99 * col.b());

            std::cout << ir << " " << ig << " " << ib << "\n";
        }
    }
}

vec3 color(const ray& r, hitable* world) {
    hit_record rec;
    if (world->hit(r, 0.0, FLT_MAX, rec)) {
        return 0.5 * (rec.normal + 1);
    } else {
        vec3 unit_direction = unit_vector(r.direction);
        float t = 0.5 * (unit_direction.y() + 1.0);
        return (1 - t) * vec3(1.0, 1.0, 1.0) + t * vec3(0.5, 0.7, 1.0);
    }
}
<|endoftext|>


<commit_before>/*
* Written by David A. Burgess, Kestrel Signal Processing, Inc., 2010
* The author disclaims copyright to this source code.
*/

#include "sqlite3.h"
#include "sqlite3util.h"

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

// Wrappers to sqlite operations.
// These will eventually get moved to commonlibs.

int sqlite3_prepare_statement(sqlite3* DB, sqlite3_stmt **stmt, const char* query)
{
	int prc = sqlite3_prepare_v2(DB,query,strlen(query),stmt,NULL);
	if (prc) {
		fprintf(stderr,"sqlite3_prepare_v2 failed for \"%s\": %s\n",query,sqlite3_errmsg(DB));
		sqlite3_finalize(*stmt);
	}
	return prc;
}

int sqlite3_run_query(sqlite3* DB, sqlite3_stmt *stmt)
{
	int src = SQLITE_BUSY;
	while (src==SQLITE_BUSY) {
		src = sqlite3_step(stmt);
		if (src==SQLITE_BUSY) {
			usleep(100000);
		}
	}
	if ((src!=SQLITE_DONE) && (src!=SQLITE_ROW)) {
		fprintf(stderr,"sqlite3_run_query failed: %s: %s\n", sqlite3_sql(stmt), sqlite3_errmsg(DB));
	}
	return src;
}

bool sqlite3_exists(sqlite3* DB, const char *tableName,
		const char* keyName, const char* keyData)
{
	size_t stringSize = 100 + strlen(tableName) + strlen(keyName) + strlen(keyData);
	char query[stringSize];
	sprintf(query,"SELECT * FROM %s WHERE %s == \"%s\"",tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	sqlite3_finalize(stmt);
	// Anything there?
	return (src == SQLITE_ROW);
}

bool sqlite3_single_lookup(sqlite3* DB, const char *tableName,
		const char* keyName, const char* keyData,
		const char* valueName, unsigned &valueData)
{
	size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + strlen(keyData);
	char query[stringSize];
	sprintf(query,"SELECT %s FROM %s WHERE %s == \"%s\"",valueName,tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	bool retVal = false;
	if (src == SQLITE_ROW) {
		valueData = (unsigned)sqlite3_column_int64(stmt,0);
		retVal = true;
	}
	sqlite3_finalize(stmt);
	return retVal;
}

// This function returns an allocated string that must be free'd by the caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
		const char* keyName, const char* keyData,
		const char* valueName, char* &valueData)
{
	valueData=NULL;
	size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + strlen(keyData);
	char query[stringSize];
	sprintf(query,"SELECT %s FROM %s WHERE %s == \"%s\"",valueName,tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	bool retVal = false;
	if (src == SQLITE_ROW) {
		const char* ptr = (const char*)sqlite3_column_text(stmt,0);
		if (ptr) valueData = strdup(ptr);
		retVal = true;
	}
	sqlite3_finalize(stmt);
	return retVal;
}

// This function returns an allocated string that must be free'd by tha caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
		const char* keyName, unsigned keyData,
		const char* valueName, char* &valueData)
{
	valueData=NULL;
	size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + 20;
	char query[stringSize];
	sprintf(query,"SELECT %s FROM %s WHERE %s == %u",valueName,tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	bool retVal = false;
	if (src == SQLITE_ROW) {
		const char* ptr = (const char*)sqlite3_column_text(stmt,0);
		if (ptr) valueData = strdup(ptr);
		retVal = true;
	}
	sqlite3_finalize(stmt);
	return retVal;
}

bool sqlite3_command(sqlite3* DB, const char* query)
{
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Run the query.
	int src = sqlite3_run_query(DB,stmt);
	return src==SQLITE_DONE;
}

<commit_msg>Synced sqlite3utils with private and fixed a small recursive bug in SIPEngine that was already fixed in private<commit_after>/*
* Copyright 2010 Kestrel Signal Processing, Inc.
* All rights reserved.
*/

#include "sqlite3.h"
#include "sqlite3util.h"

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

// Wrappers to sqlite operations.
// These will eventually get moved to commonlibs.

int sqlite3_prepare_statement(sqlite3* DB, sqlite3_stmt **stmt, const char* query)
{
        int src = SQLITE_BUSY;
        while (src==SQLITE_BUSY) {
                src = sqlite3_prepare_v2(DB,query,strlen(query),stmt,NULL);
                if (src==SQLITE_BUSY) {
                        usleep(100000);
                }
        }
        if (src) {
                fprintf(stderr,"sqlite3_prepare_v2 failed for \"%s\": %s\n",query,sqlite3_errmsg(DB));
                sqlite3_finalize(*stmt);
        }
        return src;
}

int sqlite3_run_query(sqlite3* DB, sqlite3_stmt *stmt)
{
	int src = SQLITE_BUSY;
	while (src==SQLITE_BUSY) {
		src = sqlite3_step(stmt);
		if (src==SQLITE_BUSY) {
			usleep(100000);
		}
	}
	if ((src!=SQLITE_DONE) && (src!=SQLITE_ROW)) {
		fprintf(stderr,"sqlite3_run_query failed: %s: %s\n", sqlite3_sql(stmt), sqlite3_errmsg(DB));
	}
	return src;
}

bool sqlite3_exists(sqlite3* DB, const char *tableName,
		const char* keyName, const char* keyData)
{
	size_t stringSize = 100 + strlen(tableName) + strlen(keyName) + strlen(keyData);
	char query[stringSize];
	sprintf(query,"SELECT * FROM %s WHERE %s == \"%s\"",tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	sqlite3_finalize(stmt);
	// Anything there?
	return (src == SQLITE_ROW);
}

bool sqlite3_single_lookup(sqlite3* DB, const char *tableName,
		const char* keyName, const char* keyData,
		const char* valueName, unsigned &valueData)
{
	size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + strlen(keyData);
	char query[stringSize];
	sprintf(query,"SELECT %s FROM %s WHERE %s == \"%s\"",valueName,tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	bool retVal = false;
	if (src == SQLITE_ROW) {
		valueData = (unsigned)sqlite3_column_int64(stmt,0);
		retVal = true;
	}
	sqlite3_finalize(stmt);
	return retVal;
}

// This function returns an allocated string that must be free'd by the caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
		const char* keyName, const char* keyData,
		const char* valueName, char* &valueData)
{
	valueData=NULL;
	size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + strlen(keyData);
	char query[stringSize];
	sprintf(query,"SELECT %s FROM %s WHERE %s == \"%s\"",valueName,tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	bool retVal = false;
	if (src == SQLITE_ROW) {
		const char* ptr = (const char*)sqlite3_column_text(stmt,0);
		if (ptr) valueData = strdup(ptr);
		retVal = true;
	}
	sqlite3_finalize(stmt);
	return retVal;
}

// This function returns an allocated string that must be free'd by tha caller.
bool sqlite3_single_lookup(sqlite3* DB, const char* tableName,
		const char* keyName, unsigned keyData,
		const char* valueName, char* &valueData)
{
	valueData=NULL;
	size_t stringSize = 100 + strlen(valueName) + strlen(tableName) + strlen(keyName) + 20;
	char query[stringSize];
	sprintf(query,"SELECT %s FROM %s WHERE %s == %u",valueName,tableName,keyName,keyData);
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Read the result.
	int src = sqlite3_run_query(DB,stmt);
	bool retVal = false;
	if (src == SQLITE_ROW) {
		const char* ptr = (const char*)sqlite3_column_text(stmt,0);
		if (ptr) valueData = strdup(ptr);
		retVal = true;
	}
	sqlite3_finalize(stmt);
	return retVal;
}

bool sqlite3_command(sqlite3* DB, const char* query)
{
	// Prepare the statement.
	sqlite3_stmt *stmt;
	if (sqlite3_prepare_statement(DB,&stmt,query)) return false;
	// Run the query.
	int src = sqlite3_run_query(DB,stmt);
	sqlite3_finalize(stmt);
	return src==SQLITE_DONE;
}

<|endoftext|>