<commit_before>// @(#) $Id$

/** \class AliL3TPCBeamTestMemHandler

//_____________________________________________________________
// AliL3TPCBeamTestMemHandler
//
// Class for converting the test beam data of May 2004
// to the HLT file format using R. Bramms tables.
//
// Author: C. Loizides <loizides@ikf.uni-frankfurt.de>
// -- Copyright &copy ALICE HLT Group

*/

#include "AliL3StandardIncludes.h"
#include "AliL3RootTypes.h"
#include "AliL3Logging.h"
#include "AliL3Transform.h"
#include "AliL3MemHandler.h"
#include "AliL3DigitData.h"
#include "AliL3TPCBeamTestMemHandler.h"

#if __GNUC__ == 3
using namespace std;
#endif

ClassImp(AliL3TPCBeamTestMemHandler)

AliL3TPCBeamTestMemHandler::AliL3TPCBeamTestMemHandler(Char_t *fPathToMappingFile) : AliL3MemHandler()
{
  //constructor
  fMinTimeBin=1;
  fNumOfChannels=7807+1; //must be big enough to contain all channels (per patch)

  Char_t readcarry[255];
  Int_t actPos=0;
  Int_t oldPos=0;
  ifstream *in = new ifstream();
  in->open(fPathToMappingFile);
#if defined(__HP_aCC) || defined(__DECCXX)
  if(!in.rdbuf()->is_open()){
#else
  if(!in->is_open()){
#endif
    LOG(AliL3Log::kFatal,"AliL3TPCBeamTestMemHandler","Mapping File")
	<<"Can't open file " << fPathToMappingFile << " !!!" <<ENDLOG;
  }
  fMapping = new short*[fNumOfChannels];
  for ( Int_t i = 0; i < fNumOfChannels; i++ )
      fMapping[i] = 0;
  fMappingEmptyRow = new short[11]; //11 colums per row in mapping file
  for(Int_t i = 0; i < 11 ; i++){
      fMappingEmptyRow[i] = 0;
  }
  Short_t *mappingRow;
  for(Int_t i = 0; i < 5504 ; i++) { //5504 is size of irorc mapping at the moment only for irorc
      mappingRow = new Short_t[11];
      for(Int_t j = 0 ; j < 11 ; j++) {
	  *in >> readcarry;
	  mappingRow[j] = atoi(readcarry);
     }
      actPos = mappingRow[0];
      fMapping[actPos] = mappingRow;
      if( (actPos - oldPos) > 1){
	  for(Int_t j = (oldPos+1); j < actPos; j++){
	      fMapping[j] = fMappingEmptyRow;
	  }
      }
      oldPos = actPos;
  }
  in->close();
  delete in;
}

AliL3TPCBeamTestMemHandler::~AliL3TPCBeamTestMemHandler()
{
  //destructor
  for(Int_t i = 0; i < 5504 ; i++) {
	if(fMapping[i] != fMappingEmptyRow && fMapping[i]) delete[] fMapping[i];
  }
  delete [] fMappingEmptyRow;
 delete[] fMapping;
}

AliL3DigitRowData* AliL3TPCBeamTestMemHandler::RawData2Memory(UInt_t &nrow,Int_t /*event*/)
{
  //convert the raw data
  AliL3DigitRowData *data = 0;
  nrow=0;

  Int_t nrowsdummy=AliL3Transform::GetNRows(fPatch);
  fRows = new AliRowStructure[nrowsdummy];
  for(Int_t i=0;i<nrowsdummy;i++){
   fRows[i].fRow=-1;
   fRows[i].fNDigits=0;
   fRows[i].fPadPos= new Int_t[AliL3Transform::GetNPads(i+fRowMin)];
   for(Int_t p=0;p<AliL3Transform::GetNPads(i+fRowMin);p++)
     fRows[i].fPadPos[p]=-1;
  }

  Int_t ntimebins=AliL3Transform::GetNTimeBins();
  Int_t npads=fInputSize/(ntimebins+1);
  Int_t ndigitcount=0; //total number of digits to be published
  for(Int_t i=0;i<npads;i++){
    Int_t pos=i*(ntimebins+1);
    Short_t hw=fInputPtr[pos];
    if(hw>=fNumOfChannels) continue;
    Int_t pad=MappingGetPad(hw);
    Int_t lrow=MappingGetPadRow(hw);
    if((lrow<0) ||(pad<0)) continue;
    if(lrow+fRowMin>fRowMax) continue;
    fRows[lrow].fRow=lrow+fRowMin;
    if(fRows[lrow].fPadPos[pad]!=-1){
      continue;
    }
    Bool_t isThereDataOnThisPad=kFALSE;
    Int_t digmean=0;
#if 1
    for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
      Int_t dig=fInputPtr[pos+timebin];
      digmean+=dig;
    }
    digmean/=(ntimebins-fMinTimeBin+1);
#else
    digmean = 40;
#endif
    for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
      Int_t dig=fInputPtr[pos+timebin]-digmean;

      if(dig <= AliL3Transform::GetZeroSup()) continue;
      if(dig >= AliL3Transform::GetADCSat())
        dig = AliL3Transform::GetADCSat();

	fRows[lrow].fNDigits++; //for this row only
	ndigitcount++;
	isThereDataOnThisPad=kTRUE;
      }

    if(isThereDataOnThisPad) {
      fRows[lrow].fPadPos[pad]=pos;
    }
  }

  Int_t nrows=0;
  for(Int_t i=0;i<AliL3Transform::GetNRows(fPatch);i++){
      if(fRows[i].fRow!=-1) nrows++;
  }
  if(nrows!=AliL3Transform::GetNRows(fPatch))
    LOG(AliL3Log::kError,"AliL3TPCBeamTestMemHandler::RawData2Memory","nrows")
      <<AliL3Log::kDec<<"Found Inconsistency "<<nrows<<" != "<<AliL3Transform::GetNRows(fPatch)<<ENDLOG;

  //allocate memory
  Int_t size = sizeof(AliL3DigitData)*ndigitcount
    + nrows*sizeof(AliL3DigitRowData);
  LOG(AliL3Log::kDebug,"AliL3TPCBeamTestMemHandler::RawData2Memory","Digits")
    <<AliL3Log::kDec<<"Found "<<ndigitcount<<" Digits on "<<nrows<<" rows"<<ENDLOG;

  data=(AliL3DigitRowData*)Allocate(size);
  nrow = (UInt_t)nrows;
  //memset(data,1,size); //for debugging

  Int_t ndigitcounttest=0;
  AliL3DigitRowData *tempPt = data;
  for(Int_t i=0;i<AliL3Transform::GetNRows(fPatch);i++){
    Int_t slrow=i+fRowMin;

    if(slrow!=fRows[i].fRow){
      LOG(AliL3Log::kFatal,"AliL3TPCBeamTestMemHandler::RawData2Memory","Row Mismatch")
	<<AliL3Log::kDec<<"Mismatch: slrow "<<slrow<<" row "
	<<fRows[i].fRow<<ENDLOG;
    }

    tempPt->fRow = slrow;
    tempPt->fNDigit = fRows[i].fNDigits;

    Int_t localcount=0;
    for(Int_t pad=0;pad<AliL3Transform::GetNPads(slrow);pad++){
      Int_t pos=fRows[i].fPadPos[pad];
      if(pos==-1) continue; //no data on that pad;
      Int_t digmean=0;
#if 1
      for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
        Int_t dig=fInputPtr[pos+timebin];
	digmean+=dig;
      }
      digmean/=(ntimebins-fMinTimeBin+1);
#else
    digmean = 40;
#endif
      for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
        Int_t dig=fInputPtr[pos+timebin]-digmean;

	if(dig <= AliL3Transform::GetZeroSup()) continue;
	if(dig >= AliL3Transform::GetADCSat())
	    dig = AliL3Transform::GetADCSat();

	//Exclude data outside cone:
	//AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
	//if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2])) continue;

	tempPt->fDigitData[localcount].fCharge=(UShort_t)dig;
	tempPt->fDigitData[localcount].fPad=(UChar_t)pad;
	tempPt->fDigitData[localcount].fTime=(UShort_t)timebin-1;
	//cout << slrow << " " << pad << " " << timebin << " " << dig << endl;
#ifdef do_mc
	tempPt->fDigitData[localcount].fTrackID[0] = 0;
	tempPt->fDigitData[localcount].fTrackID[1] = 0;
	tempPt->fDigitData[localcount].fTrackID[2] = 0;
#endif
	localcount++;
	ndigitcounttest++;
      } //time
    } //pad

    if(localcount != fRows[i].fNDigits)
      LOG(AliL3Log::kFatal,"AliL3TPCBeamTestMemHandler::RawData2Memory","Memory")
	<<AliL3Log::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
	<<fRows[i].fNDigits<<ENDLOG;

    Byte_t *tmp = (Byte_t*)tempPt;
    Int_t size = sizeof(AliL3DigitRowData)
      + localcount*sizeof(AliL3DigitData);
    tmp += size;
    tempPt = (AliL3DigitRowData*)tmp;
  }//row

  if(ndigitcount!=ndigitcounttest)
    LOG(AliL3Log::kError,"AliL3TPCBeamTestMemHandler::RawData2Memory","Digits")
      <<AliL3Log::kDec<<"Found Inconsistency "<<ndigitcount<<" != "<<ndigitcounttest<<ENDLOG;

  for(Int_t i=0;i<nrowsdummy;i++){
    delete[] fRows[i].fPadPos;
  }
  delete[] fRows;
  return data;
}

Bool_t AliL3TPCBeamTestMemHandler::RawData2CompBinary(Int_t event)
{
  //raw data to memory
  Bool_t out = kTRUE;
  UInt_t ndigits=0;
  AliL3DigitRowData *digits=0;
  digits = RawData2Memory(ndigits,event);
  out = Memory2CompBinary(ndigits,digits);
  Free();
  return out;
}

<commit_msg>Typo fixed<commit_after>// @(#) $Id$

/** \class AliL3TPCBeamTestMemHandler

//_____________________________________________________________
// AliL3TPCBeamTestMemHandler
//
// Class for converting the test beam data of May 2004
// to the HLT file format using R. Bramms tables.
//
// Author: C. Loizides <loizides@ikf.uni-frankfurt.de>
// -- Copyright &copy ALICE HLT Group

*/

#include "AliL3StandardIncludes.h"
#include "AliL3RootTypes.h"
#include "AliL3Logging.h"
#include "AliL3Transform.h"
#include "AliL3MemHandler.h"
#include "AliL3DigitData.h"
#include "AliL3TPCBeamTestMemHandler.h"

#if __GNUC__ == 3
using namespace std;
#endif

ClassImp(AliL3TPCBeamTestMemHandler)

AliL3TPCBeamTestMemHandler::AliL3TPCBeamTestMemHandler(Char_t *fPathToMappingFile) : AliL3MemHandler()
{
  //constructor
  fMinTimeBin=1;
  fNumOfChannels=7807+1; //must be big enough to contain all channels (per patch)

  Char_t readcarry[255];
  Int_t actPos=0;
  Int_t oldPos=0;
  ifstream *in = new ifstream();
  in->open(fPathToMappingFile);
#if defined(__HP_aCC) || defined(__DECCXX)
  if(!in->rdbuf()->is_open()){
#else
  if(!in->is_open()){
#endif
    LOG(AliL3Log::kFatal,"AliL3TPCBeamTestMemHandler","Mapping File")
	<<"Can't open file " << fPathToMappingFile << " !!!" <<ENDLOG;
  }
  fMapping = new short*[fNumOfChannels];
  for ( Int_t i = 0; i < fNumOfChannels; i++ )
      fMapping[i] = 0;
  fMappingEmptyRow = new short[11]; //11 colums per row in mapping file
  for(Int_t i = 0; i < 11 ; i++){
      fMappingEmptyRow[i] = 0;
  }
  Short_t *mappingRow;
  for(Int_t i = 0; i < 5504 ; i++) { //5504 is size of irorc mapping at the moment only for irorc
      mappingRow = new Short_t[11];
      for(Int_t j = 0 ; j < 11 ; j++) {
	  *in >> readcarry;
	  mappingRow[j] = atoi(readcarry);
     }
      actPos = mappingRow[0];
      fMapping[actPos] = mappingRow;
      if( (actPos - oldPos) > 1){
	  for(Int_t j = (oldPos+1); j < actPos; j++){
	      fMapping[j] = fMappingEmptyRow;
	  }
      }
      oldPos = actPos;
  }
  in->close();
  delete in;
}

AliL3TPCBeamTestMemHandler::~AliL3TPCBeamTestMemHandler()
{
  //destructor
  for(Int_t i = 0; i < 5504 ; i++) {
	if(fMapping[i] != fMappingEmptyRow && fMapping[i]) delete[] fMapping[i];
  }
  delete [] fMappingEmptyRow;
 delete[] fMapping;
}

AliL3DigitRowData* AliL3TPCBeamTestMemHandler::RawData2Memory(UInt_t &nrow,Int_t /*event*/)
{
  //convert the raw data
  AliL3DigitRowData *data = 0;
  nrow=0;

  Int_t nrowsdummy=AliL3Transform::GetNRows(fPatch);
  fRows = new AliRowStructure[nrowsdummy];
  for(Int_t i=0;i<nrowsdummy;i++){
   fRows[i].fRow=-1;
   fRows[i].fNDigits=0;
   fRows[i].fPadPos= new Int_t[AliL3Transform::GetNPads(i+fRowMin)];
   for(Int_t p=0;p<AliL3Transform::GetNPads(i+fRowMin);p++)
     fRows[i].fPadPos[p]=-1;
  }

  Int_t ntimebins=AliL3Transform::GetNTimeBins();
  Int_t npads=fInputSize/(ntimebins+1);
  Int_t ndigitcount=0; //total number of digits to be published
  for(Int_t i=0;i<npads;i++){
    Int_t pos=i*(ntimebins+1);
    Short_t hw=fInputPtr[pos];
    if(hw>=fNumOfChannels) continue;
    Int_t pad=MappingGetPad(hw);
    Int_t lrow=MappingGetPadRow(hw);
    if((lrow<0) ||(pad<0)) continue;
    if(lrow+fRowMin>fRowMax) continue;
    fRows[lrow].fRow=lrow+fRowMin;
    if(fRows[lrow].fPadPos[pad]!=-1){
      continue;
    }
    Bool_t isThereDataOnThisPad=kFALSE;
    Int_t digmean=0;
#if 1
    for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
      Int_t dig=fInputPtr[pos+timebin];
      digmean+=dig;
    }
    digmean/=(ntimebins-fMinTimeBin+1);
#else
    digmean = 40;
#endif
    for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
      Int_t dig=fInputPtr[pos+timebin]-digmean;

      if(dig <= AliL3Transform::GetZeroSup()) continue;
      if(dig >= AliL3Transform::GetADCSat())
        dig = AliL3Transform::GetADCSat();

	fRows[lrow].fNDigits++; //for this row only
	ndigitcount++;
	isThereDataOnThisPad=kTRUE;
      }

    if(isThereDataOnThisPad) {
      fRows[lrow].fPadPos[pad]=pos;
    }
  }

  Int_t nrows=0;
  for(Int_t i=0;i<AliL3Transform::GetNRows(fPatch);i++){
      if(fRows[i].fRow!=-1) nrows++;
  }
  if(nrows!=AliL3Transform::GetNRows(fPatch))
    LOG(AliL3Log::kError,"AliL3TPCBeamTestMemHandler::RawData2Memory","nrows")
      <<AliL3Log::kDec<<"Found Inconsistency "<<nrows<<" != "<<AliL3Transform::GetNRows(fPatch)<<ENDLOG;

  //allocate memory
  Int_t size = sizeof(AliL3DigitData)*ndigitcount
    + nrows*sizeof(AliL3DigitRowData);
  LOG(AliL3Log::kDebug,"AliL3TPCBeamTestMemHandler::RawData2Memory","Digits")
    <<AliL3Log::kDec<<"Found "<<ndigitcount<<" Digits on "<<nrows<<" rows"<<ENDLOG;

  data=(AliL3DigitRowData*)Allocate(size);
  nrow = (UInt_t)nrows;
  //memset(data,1,size); //for debugging

  Int_t ndigitcounttest=0;
  AliL3DigitRowData *tempPt = data;
  for(Int_t i=0;i<AliL3Transform::GetNRows(fPatch);i++){
    Int_t slrow=i+fRowMin;

    if(slrow!=fRows[i].fRow){
      LOG(AliL3Log::kFatal,"AliL3TPCBeamTestMemHandler::RawData2Memory","Row Mismatch")
	<<AliL3Log::kDec<<"Mismatch: slrow "<<slrow<<" row "
	<<fRows[i].fRow<<ENDLOG;
    }

    tempPt->fRow = slrow;
    tempPt->fNDigit = fRows[i].fNDigits;

    Int_t localcount=0;
    for(Int_t pad=0;pad<AliL3Transform::GetNPads(slrow);pad++){
      Int_t pos=fRows[i].fPadPos[pad];
      if(pos==-1) continue; //no data on that pad;
      Int_t digmean=0;
#if 1
      for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
        Int_t dig=fInputPtr[pos+timebin];
	digmean+=dig;
      }
      digmean/=(ntimebins-fMinTimeBin+1);
#else
    digmean = 40;
#endif
      for(Int_t timebin = fMinTimeBin ; timebin <= ntimebins ; timebin++){
        Int_t dig=fInputPtr[pos+timebin]-digmean;

	if(dig <= AliL3Transform::GetZeroSup()) continue;
	if(dig >= AliL3Transform::GetADCSat())
	    dig = AliL3Transform::GetADCSat();

	//Exclude data outside cone:
	//AliL3Transform::Raw2Local(xyz,sector,row,pad,time);
	//if(fParam->GetPadRowRadii(sector,row)<230./250.*fabs(xyz[2])) continue;

	tempPt->fDigitData[localcount].fCharge=(UShort_t)dig;
	tempPt->fDigitData[localcount].fPad=(UChar_t)pad;
	tempPt->fDigitData[localcount].fTime=(UShort_t)timebin-1;
	//cout << slrow << " " << pad << " " << timebin << " " << dig << endl;
#ifdef do_mc
	tempPt->fDigitData[localcount].fTrackID[0] = 0;
	tempPt->fDigitData[localcount].fTrackID[1] = 0;
	tempPt->fDigitData[localcount].fTrackID[2] = 0;
#endif
	localcount++;
	ndigitcounttest++;
      } //time
    } //pad

    if(localcount != fRows[i].fNDigits)
      LOG(AliL3Log::kFatal,"AliL3TPCBeamTestMemHandler::RawData2Memory","Memory")
	<<AliL3Log::kDec<<"Mismatch: localcount "<<localcount<<" ndigits "
	<<fRows[i].fNDigits<<ENDLOG;

    Byte_t *tmp = (Byte_t*)tempPt;
    Int_t size = sizeof(AliL3DigitRowData)
      + localcount*sizeof(AliL3DigitData);
    tmp += size;
    tempPt = (AliL3DigitRowData*)tmp;
  }//row

  if(ndigitcount!=ndigitcounttest)
    LOG(AliL3Log::kError,"AliL3TPCBeamTestMemHandler::RawData2Memory","Digits")
      <<AliL3Log::kDec<<"Found Inconsistency "<<ndigitcount<<" != "<<ndigitcounttest<<ENDLOG;

  for(Int_t i=0;i<nrowsdummy;i++){
    delete[] fRows[i].fPadPos;
  }
  delete[] fRows;
  return data;
}

Bool_t AliL3TPCBeamTestMemHandler::RawData2CompBinary(Int_t event)
{
  //raw data to memory
  Bool_t out = kTRUE;
  UInt_t ndigits=0;
  AliL3DigitRowData *digits=0;
  digits = RawData2Memory(ndigits,event);
  out = Memory2CompBinary(ndigits,digits);
  Free();
  return out;
}

<|endoftext|>


<commit_before>#include "Path.h"
#include "Logging.h"

using namespace std;

namespace map_solver {

void Path::calculateFromDistances(std::vector<int32_t> dist, const Point& start, const Point& end) {
    m_cells(end.first, end.second) = 1;
    const auto minimum = [](const int32_t a, const int32_t b, const int32_t c, const int32_t d) {
        return min(min(min(a, b), c), d);
    };

    Point current = end;
    int32_t x, y;

    // TODO: corner case: unreachable end point

    while (true) {
        if (current == start)
            break;

        x = current.first;
        y = current.second;

        int32_t top = numeric_limits<int32_t>::max();
        int32_t bottom = numeric_limits<int32_t>::max();
        int32_t left = numeric_limits<int32_t>::max();
        int32_t right = numeric_limits<int32_t>::max();
        if (y != 0)
            top = dist[x + (y-1) * m_cells.size1()];
        if (x != 0)
            left = dist[x-1 +  y * m_cells.size1()];
        if (y != m_cells.size2() -1)
            bottom = dist[x + (y+1)*m_cells.size1()];
        if (x != m_cells.size1() -1)
            bottom = dist[x+1 + y*m_cells.size1()];
        int min_int = minimum(top, bottom, left, right);

        if (min_int == top)
            m_cells(current.first, --current.second) = 1;
        else if (min_int == bottom)
            m_cells(current.first, ++current.second) = 1;
        else if (min_int == left)
            m_cells(--current.first, current.second) = 1;
        else if (min_int == bottom)
            m_cells(current.first, ++current.second) = 1;

    }

    for (unsigned i = 0; i < m_cells.size1 (); ++ i)
        for (unsigned j = 0; j < m_cells.size2 (); ++ j) {
            LOG_TRACE << "Matrix element " << i << ", " << j <<": " << m_cells (i, j);
        }

}

}
<commit_msg>Fixed copy&paste bug in Dijkstra impl<commit_after>#include "Path.h"
#include "Logging.h"

using namespace std;

namespace map_solver {

void Path::calculateFromDistances(std::vector<int32_t> dist, const Point& start, const Point& end) {
    m_cells(end.first, end.second) = 1;
    const auto minimum = [](const int32_t a, const int32_t b, const int32_t c, const int32_t d) {
        return min(min(min(a, b), c), d);
    };

    Point current = end;
    int32_t x, y;

    // TODO: corner case: unreachable end point

    while (true) {
        if (current == start)
            break;

        x = current.first;
        y = current.second;

        int32_t top = numeric_limits<int32_t>::max();
        int32_t bottom = numeric_limits<int32_t>::max();
        int32_t left = numeric_limits<int32_t>::max();
        int32_t right = numeric_limits<int32_t>::max();
        if (y != 0)
            top = dist[x + (y-1) * m_cells.size1()];
        if (x != 0)
            left = dist[x-1 +  y * m_cells.size1()];
        if (y != m_cells.size2() -1)
            bottom = dist[x + (y+1)*m_cells.size1()];
        if (x != m_cells.size1() -1)
            right = dist[x+1 + y*m_cells.size1()];
        int min_int = minimum(top, bottom, left, right);

        if (min_int == top)
            m_cells(current.first, --current.second) = 1;
        else if (min_int == bottom)
            m_cells(current.first, ++current.second) = 1;
        else if (min_int == left)
            m_cells(--current.first, current.second) = 1;
        else if (min_int == right)
            m_cells(++current.first, current.second) = 1;

    }

    for (unsigned i = 0; i < m_cells.size1 (); ++ i)
        for (unsigned j = 0; j < m_cells.size2 (); ++ j) {
            LOG_TRACE << "Matrix element " << i << ", " << j <<": " << m_cells (i, j);
        }

}

}
<|endoftext|>


<commit_before>// Fill out your copyright notice in the Description page of Project Settings.

#include "GDC_Demo.h"
#include "Engine/World.h"
#include <EngineGlobals.h>
#include "Engine.h"
#include "CameraManager.h"

// Sets default values
ACameraManager::ACameraManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

}

// Called when the game starts or when spawned
void ACameraManager::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void ACameraManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	UWorld* world = GetWorld();
	APawn* PlayerPawn = world->GetFirstPlayerController()->GetPawn();
	framenr += 5.0;

	GEngine->AddOnScreenDebugMessage(1, 1.0f, FColor::Green, "Scene: " + FString::FromInt(scenenr) + " framenr: " + FString::FromInt(framenr));

	switch (scenenr) {
	case 0: {
		if (framenr == 120.0) {
			framenr = 0.0;
			scenenr += 1;
		}
		break;
	}
	case 1: {
		FRotator rotate = FRotator((framenr / 10.0)-170, 0, 0);
		FVector NewLoc = centerpos + rotate.RotateVector(centerpos - playerstartpos);
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 1800.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 2: {
		FVector NewLoc = playerlastpos + (playerstartpos - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (centerpos - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 650.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 3: {
		FRotator rotate = FRotator(0, framenr / 4.0, 0);
		FVector NewLoc = centerpos + rotate.RotateVector(centerpos - playerstartpos);
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 1000.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 4: {
		FVector NewLoc = playerlastpos + (playerstartpos - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 600.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 5: {
		FVector Pos1 = FVector(38622.285, 703740.188, -107188.945);
		FVector Pos2 = FVector(40000.000, 703400.875, -107189.617);
		FVector NewLoc = Pos1 + (Pos2 - Pos1) * framenr / 60.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 60.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 6: {
		FVector Pos2 = FVector(59940.891, 680811.250, -119856.438);
		FVector NewLoc = playerlastpos + (Pos2 - playerlastpos) * framenr / 300.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 300.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 7: {
		//FVector Pos2 = FVector(97568.750, 620657.250, -117801.898);
		//FVector Pos2 = FVector(95185.313, 641331.438, -116694.117);
		FVector Pos2 = FVector(96444.648, 634757.688, -117495.625);
		//FVector Pos2 = FVector(100944.430, 607356.250, -118364.445);
		FVector NewLoc = playerlastpos + (Pos2 - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (Pos2 - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 600.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
			this->Destroy();
		}
		break;
	}

	}

	//FVector NewLoc = centerpos + rotate.RotateVector(centerpos - playerstartpos);
	//FVector NewLoc = playerpos + (centerpos - playerpos) * framenr / 1000.0f;

	//FRotator NewRot = FRotator(0, 0, 0);
	//PlayerPawn->TeleportTo(NewLoc, NewRot);
	//PlayerPawn->SetActorLocation(NewLoc);
	//PlayerPawn->SetActorRotation(0,0,l0)

	//ACharacter* myCharacter = UGameplayStatics::GetPlayerCharacter(world, 0);

	//myCharacter->SetActorLocation(playerpos + rotate.RotateVector(centerpos - playerpos));

}

<commit_msg>Continued with the CameraManager<commit_after>// Fill out your copyright notice in the Description page of Project Settings.

#include "GDC_Demo.h"
#include "Engine/World.h"
#include <EngineGlobals.h>
#include "Engine.h"
#include "CameraManager.h"

// Sets default values
ACameraManager::ACameraManager()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;
}

// Called when the game starts or when spawned
void ACameraManager::BeginPlay()
{
	Super::BeginPlay();
}

// Called every frame
void ACameraManager::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

	UWorld* world = GetWorld();
	APawn* PlayerPawn = world->GetFirstPlayerController()->GetPawn();
	framenr += 1.0;

	GEngine->AddOnScreenDebugMessage(1, 1.0f, FColor::Green, "Scene: " + FString::FromInt(scenenr) + " framenr: " + FString::FromInt(framenr));

	switch (scenenr) {
	case 0: {
		if (framenr == 120.0) {
			framenr = 0.0;
			scenenr += 1;
		}
		break;
	}
	case 1: {
		FRotator rotate = FRotator((framenr / 10.0)-170, 0, 0);
		FVector NewLoc = centerpos + rotate.RotateVector(centerpos - playerstartpos);
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 1800.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 2: {
		FVector NewLoc = playerlastpos + (playerstartpos - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (centerpos - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 650.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 3: {
		FRotator rotate = FRotator(0, framenr / 4.0, 0);
		FVector NewLoc = centerpos + rotate.RotateVector(centerpos - playerstartpos);
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 1000.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 4: {
		FVector NewLoc = playerlastpos + (playerstartpos - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 600.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 5: {
		FVector Pos1 = FVector(38622.285, 703740.188, -107188.945);
		FVector Pos2 = FVector(40000.000, 703400.875, -107189.617);
		FVector NewLoc = Pos1 + (Pos2 - Pos1) * framenr / 60.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 60.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 6: {
		FVector Pos2 = FVector(59940.891, 680811.250, -119856.438);
		FVector NewLoc = playerlastpos + (Pos2 - playerlastpos) * framenr / 300.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 300.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 7: {
		//FVector Pos2 = FVector(97568.750, 620657.250, -117801.898);
		//FVector Pos2 = FVector(95185.313, 641331.438, -116694.117);
		FVector Pos2 = FVector(96444.648, 634757.688, -117495.625);
		//FVector Pos2 = FVector(100944.430, 607356.250, -118364.445);
		FVector NewLoc = playerlastpos + (Pos2 - playerlastpos) * framenr / 800.0f;
		FRotator NewRot = (Pos2 - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 800.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 8: {
		FVector Pos1 = FVector(174994.547, 675927.188, -86679.375);
		FVector Pos2 = FVector(-19848.641, 608025.688, -110734.070);
		FVector NewLoc = Pos1 + (Pos2 - Pos1) * framenr / 1200.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 1200.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 9: {
		//FVector Pos2 = FVector(18697.531, 643321.875, -118784.719);
		FVector Pos2 = FVector(64852.566, 650231.813, -120194.289);
		FVector NewLoc = playerlastpos + (Pos2 - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 600.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
		}
		break;
	}
	case 10: {
		//FVector Pos2 = FVector(25300.885, 646003.500, -120586.031);
		FVector Pos2 = FVector(74327.547, 642531.375, -116940.477);
		FVector NewLoc = playerlastpos + (Pos2 - playerlastpos) * framenr / 600.0f;
		FRotator NewRot = (centerposdown - NewLoc).Rotation();
		PlayerPawn->TeleportTo(NewLoc, NewRot);
		if (framenr == 600.0) {
			framenr = 0.0;
			playerlastpos = NewLoc;
			scenenr += 1;
			//FVector NewLoc = FVector(97886.914, 644859.750,-115223.320);
			FVector NewLoc = FVector(97823.852, 653343.125, -111936.500);
			FRotator NewRot = (centerposdown - NewLoc).Rotation();
			PlayerPawn->TeleportTo(NewLoc, NewRot);
			this->Destroy();
		}
		break;
	}

	}

	//FVector NewLoc = centerpos + rotate.RotateVector(centerpos - playerstartpos);
	//FVector NewLoc = playerpos + (centerpos - playerpos) * framenr / 1000.0f;

	//FRotator NewRot = FRotator(0, 0, 0);
	//PlayerPawn->TeleportTo(NewLoc, NewRot);
	//PlayerPawn->SetActorLocation(NewLoc);
	//PlayerPawn->SetActorRotation(0,0,l0)

	//ACharacter* myCharacter = UGameplayStatics::GetPlayerCharacter(world, 0);

	//myCharacter->SetActorLocation(playerpos + rotate.RotateVector(centerpos - playerpos));

}

<|endoftext|>


<commit_before>/*************************************************************************/
/*  input_event.cpp                                                      */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "input_event.h"
#include "input_map.h"
#include "os/keyboard.h"
/**
 *
 */

bool InputEvent::operator==(const InputEvent &p_event) const {
	if (type != p_event.type){
		return false;
	}

	switch(type) {
		case NONE:
			return true;
		case KEY:
			return key.unicode == p_event.key.unicode
				&& key.scancode == p_event.key.scancode
				&& key.echo == p_event.key.echo
				&& key.pressed == p_event.key.pressed
				&& key.mod == p_event.key.mod;
		case MOUSE_MOTION:
			return mouse_motion.x == p_event.mouse_motion.x
				&& mouse_motion.y == p_event.mouse_motion.y
				&& mouse_motion.relative_x == p_event.mouse_motion.relative_y
				&& mouse_motion.button_mask == p_event.mouse_motion.button_mask
				&& key.mod == p_event.key.mod;
		case MOUSE_BUTTON:
			return mouse_button.pressed == p_event.mouse_button.pressed
				&& mouse_button.x == p_event.mouse_button.x
				&& mouse_button.y == p_event.mouse_button.y
				&& mouse_button.button_index == p_event.mouse_button.button_index
				&& mouse_button.button_mask == p_event.mouse_button.button_mask
				&& key.mod == p_event.key.mod;
		case JOYSTICK_MOTION:
			return joy_motion.axis == p_event.joy_motion.axis
				&& joy_motion.axis_value == p_event.joy_motion.axis_value;
		case JOYSTICK_BUTTON:
			return joy_button.pressed == p_event.joy_button.pressed
				&& joy_button.button_index == p_event.joy_button.button_index
				&& joy_button.pressure == p_event.joy_button.pressure;
		case SCREEN_TOUCH:
			return screen_touch.pressed == p_event.screen_touch.pressed
				&& screen_touch.index == p_event.screen_touch.index
				&& screen_touch.x == p_event.screen_touch.x
				&& screen_touch.y == p_event.screen_touch.y;
		case SCREEN_DRAG:
			return screen_drag.index == p_event.screen_drag.index
				&& screen_drag.x == p_event.screen_drag.x
				&& screen_drag.y == p_event.screen_drag.y;
		case ACTION:
			return action.action == p_event.action.action
				&& action.pressed == p_event.action.pressed;
		default:
			ERR_PRINT("No logic to compare InputEvents of this type, this shouldn't happen.");
	}

	return false;
}
InputEvent::operator String() const {

	String str="Device "+itos(device)+" ID "+itos(ID)+" ";

	switch(type) {

		case NONE: {

			return "Event: None";
		} break;
		case KEY: {

			str+= "Event: Key ";
			str=str+"Unicode: "+String::chr(key.unicode)+" Scan: "+itos( key.scancode )+" Echo: "+String(key.echo?"True":"False")+" Pressed"+String(key.pressed?"True":"False")+" Mod: ";
			if (key.mod.shift)
				str+="S";
			if (key.mod.control)
				str+="C";
			if (key.mod.alt)
				str+="A";
			if (key.mod.meta)
				str+="M";

			return str;
		} break;
		case MOUSE_MOTION: {

			str+= "Event: Motion ";
			str=str+" Pos: " +itos(mouse_motion.x)+","+itos(mouse_motion.y)+" Rel: "+itos(mouse_motion.relative_x)+","+itos(mouse_motion.relative_y)+" Mask: ";
			for (int i=0;i<8;i++) {

				if ((1<<i)&mouse_motion.button_mask)
					str+=itos(i+1);
			}
			str+=" Mod: ";
			if (key.mod.shift)
				str+="S";
			if (key.mod.control)
				str+="C";
			if (key.mod.alt)
				str+="A";
			if (key.mod.meta)
				str+="M";

			return str;
		} break;
		case MOUSE_BUTTON: {
			str+= "Event: Button ";
			str=str+"Pressed: "+itos(mouse_button.pressed)+" Pos: " +itos(mouse_button.x)+","+itos(mouse_button.y)+" Button: "+itos(mouse_button.button_index)+" Mask: ";
			for (int i=0;i<8;i++) {

				if ((1<<i)&mouse_button.button_mask)
					str+=itos(i+1);
			}
			str+=" Mod: ";
			if (key.mod.shift)
				str+="S";
			if (key.mod.control)
				str+="C";
			if (key.mod.alt)
				str+="A";
			if (key.mod.meta)
				str+="M";

			str+=String(" DoubleClick: ")+(mouse_button.doubleclick?"Yes":"No");

			return str;

		} break;
		case JOYSTICK_MOTION: {
			str+= "Event: JoystickMotion ";
			str=str+"Axis: "+itos(joy_motion.axis)+" Value: " +rtos(joy_motion.axis_value);
			return str;

		} break;
		case JOYSTICK_BUTTON: {
			str+= "Event: JoystickButton ";
			str=str+"Pressed: "+itos(joy_button.pressed)+" Index: " +itos(joy_button.button_index)+" pressure "+rtos(joy_button.pressure);
			return str;

		} break;
		case SCREEN_TOUCH: {
			str+= "Event: ScreenTouch ";
			str=str+"Pressed: "+itos(screen_touch.pressed)+" Index: " +itos(screen_touch.index)+" pos "+rtos(screen_touch.x)+","+rtos(screen_touch.y);
			return str;

		} break;
		case SCREEN_DRAG: {
			str+= "Event: ScreenDrag ";
			str=str+" Index: " +itos(screen_drag.index)+" pos "+rtos(screen_drag.x)+","+rtos(screen_drag.y);
			return str;

		} break;
		case ACTION: {
			str+= "Event: Action: "+InputMap::get_singleton()->get_action_from_id(action.action)+" Pressed: "+itos(action.pressed);
			return str;

		} break;

	}

	return "";
}

void InputEvent::set_as_action(const String& p_action, bool p_pressed) {

	type=ACTION;
	action.action=InputMap::get_singleton()->get_action_id(p_action);
	action.pressed=p_pressed;
}

bool InputEvent::is_pressed() const {

	switch(type) {

		case KEY: return key.pressed;
		case MOUSE_BUTTON: return mouse_button.pressed;
		case JOYSTICK_BUTTON: return joy_button.pressed;
		case SCREEN_TOUCH: return screen_touch.pressed;
		case JOYSTICK_MOTION: return ABS(joy_motion.axis_value) > 0.5;
		case ACTION: return action.pressed;
		default: {}
	}

	return false;
}

bool InputEvent::is_echo() const {

	return (type==KEY && key.echo);
}

bool InputEvent::is_action(const String& p_action) const {

	return InputMap::get_singleton()->event_is_action(*this,p_action);
}

bool InputEvent::is_action_pressed(const String& p_action) const {

	return is_action(p_action) && is_pressed() && !is_echo();
}

bool InputEvent::is_action_released(const String& p_action) const {

	return is_action(p_action) && !is_pressed();
}

uint32_t InputEventKey::get_scancode_with_modifiers() const {

	uint32_t sc=scancode;
	if (mod.control)
		sc|=KEY_MASK_CTRL;
	if (mod.alt)
		sc|=KEY_MASK_ALT;
	if (mod.shift)
		sc|=KEY_MASK_SHIFT;
	if (mod.meta)
		sc|=KEY_MASK_META;

	return sc;

}

InputEvent InputEvent::xform_by(const Matrix32& p_xform) const {

	InputEvent ev=*this;

	switch(ev.type) {

		case InputEvent::MOUSE_BUTTON: {

			Vector2 g = p_xform.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y));
			Vector2 l = p_xform.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y));
			ev.mouse_button.x=l.x;
			ev.mouse_button.y=l.y;
			ev.mouse_button.global_x=g.x;
			ev.mouse_button.global_y=g.y;

		} break;
		case InputEvent::MOUSE_MOTION: {

			Vector2 g = p_xform.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
			Vector2 l = p_xform.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
			Vector2 r = p_xform.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
			Vector2 s = p_xform.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y));
			ev.mouse_motion.x=l.x;
			ev.mouse_motion.y=l.y;
			ev.mouse_motion.global_x=g.x;
			ev.mouse_motion.global_y=g.y;
			ev.mouse_motion.relative_x=r.x;
			ev.mouse_motion.relative_y=r.y;
			ev.mouse_motion.speed_x=s.x;
			ev.mouse_motion.speed_y=s.y;

		} break;
		case InputEvent::SCREEN_TOUCH: {

			Vector2 t = p_xform.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y));
			ev.screen_touch.x=t.x;
			ev.screen_touch.y=t.y;

		} break;
		case InputEvent::SCREEN_DRAG: {

			Vector2 t = p_xform.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y));
			Vector2 r = p_xform.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
			Vector2 s = p_xform.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
			ev.screen_drag.x=t.x;
			ev.screen_drag.y=t.y;
			ev.screen_drag.relative_x=r.x;
			ev.screen_drag.relative_y=r.y;
			ev.screen_drag.speed_x=s.x;
			ev.screen_drag.speed_y=s.y;
		} break;
	}

	return ev;
}
<commit_msg>Fix comparison bug with InputEvent<commit_after>/*************************************************************************/
/*  input_event.cpp                                                      */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2016 Juan Linietsky, Ariel Manzur.                 */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "input_event.h"
#include "input_map.h"
#include "os/keyboard.h"
/**
 *
 */

bool InputEvent::operator==(const InputEvent &p_event) const {
	if (type != p_event.type){
		return false;
	}

	switch(type) {
		case NONE:
			return true;
		case KEY:
			return key.unicode == p_event.key.unicode
				&& key.scancode == p_event.key.scancode
				&& key.echo == p_event.key.echo
				&& key.pressed == p_event.key.pressed
				&& key.mod == p_event.key.mod;
		case MOUSE_MOTION:
			return mouse_motion.x == p_event.mouse_motion.x
				&& mouse_motion.y == p_event.mouse_motion.y
				&& mouse_motion.relative_x == p_event.mouse_motion.relative_x
				&& mouse_motion.relative_y == p_event.mouse_motion.relative_y
				&& mouse_motion.button_mask == p_event.mouse_motion.button_mask
				&& key.mod == p_event.key.mod;
		case MOUSE_BUTTON:
			return mouse_button.pressed == p_event.mouse_button.pressed
				&& mouse_button.x == p_event.mouse_button.x
				&& mouse_button.y == p_event.mouse_button.y
				&& mouse_button.button_index == p_event.mouse_button.button_index
				&& mouse_button.button_mask == p_event.mouse_button.button_mask
				&& key.mod == p_event.key.mod;
		case JOYSTICK_MOTION:
			return joy_motion.axis == p_event.joy_motion.axis
				&& joy_motion.axis_value == p_event.joy_motion.axis_value;
		case JOYSTICK_BUTTON:
			return joy_button.pressed == p_event.joy_button.pressed
				&& joy_button.button_index == p_event.joy_button.button_index
				&& joy_button.pressure == p_event.joy_button.pressure;
		case SCREEN_TOUCH:
			return screen_touch.pressed == p_event.screen_touch.pressed
				&& screen_touch.index == p_event.screen_touch.index
				&& screen_touch.x == p_event.screen_touch.x
				&& screen_touch.y == p_event.screen_touch.y;
		case SCREEN_DRAG:
			return screen_drag.index == p_event.screen_drag.index
				&& screen_drag.x == p_event.screen_drag.x
				&& screen_drag.y == p_event.screen_drag.y;
		case ACTION:
			return action.action == p_event.action.action
				&& action.pressed == p_event.action.pressed;
		default:
			ERR_PRINT("No logic to compare InputEvents of this type, this shouldn't happen.");
	}

	return false;
}
InputEvent::operator String() const {

	String str="Device "+itos(device)+" ID "+itos(ID)+" ";

	switch(type) {

		case NONE: {

			return "Event: None";
		} break;
		case KEY: {

			str+= "Event: Key ";
			str=str+"Unicode: "+String::chr(key.unicode)+" Scan: "+itos( key.scancode )+" Echo: "+String(key.echo?"True":"False")+" Pressed"+String(key.pressed?"True":"False")+" Mod: ";
			if (key.mod.shift)
				str+="S";
			if (key.mod.control)
				str+="C";
			if (key.mod.alt)
				str+="A";
			if (key.mod.meta)
				str+="M";

			return str;
		} break;
		case MOUSE_MOTION: {

			str+= "Event: Motion ";
			str=str+" Pos: " +itos(mouse_motion.x)+","+itos(mouse_motion.y)+" Rel: "+itos(mouse_motion.relative_x)+","+itos(mouse_motion.relative_y)+" Mask: ";
			for (int i=0;i<8;i++) {

				if ((1<<i)&mouse_motion.button_mask)
					str+=itos(i+1);
			}
			str+=" Mod: ";
			if (key.mod.shift)
				str+="S";
			if (key.mod.control)
				str+="C";
			if (key.mod.alt)
				str+="A";
			if (key.mod.meta)
				str+="M";

			return str;
		} break;
		case MOUSE_BUTTON: {
			str+= "Event: Button ";
			str=str+"Pressed: "+itos(mouse_button.pressed)+" Pos: " +itos(mouse_button.x)+","+itos(mouse_button.y)+" Button: "+itos(mouse_button.button_index)+" Mask: ";
			for (int i=0;i<8;i++) {

				if ((1<<i)&mouse_button.button_mask)
					str+=itos(i+1);
			}
			str+=" Mod: ";
			if (key.mod.shift)
				str+="S";
			if (key.mod.control)
				str+="C";
			if (key.mod.alt)
				str+="A";
			if (key.mod.meta)
				str+="M";

			str+=String(" DoubleClick: ")+(mouse_button.doubleclick?"Yes":"No");

			return str;

		} break;
		case JOYSTICK_MOTION: {
			str+= "Event: JoystickMotion ";
			str=str+"Axis: "+itos(joy_motion.axis)+" Value: " +rtos(joy_motion.axis_value);
			return str;

		} break;
		case JOYSTICK_BUTTON: {
			str+= "Event: JoystickButton ";
			str=str+"Pressed: "+itos(joy_button.pressed)+" Index: " +itos(joy_button.button_index)+" pressure "+rtos(joy_button.pressure);
			return str;

		} break;
		case SCREEN_TOUCH: {
			str+= "Event: ScreenTouch ";
			str=str+"Pressed: "+itos(screen_touch.pressed)+" Index: " +itos(screen_touch.index)+" pos "+rtos(screen_touch.x)+","+rtos(screen_touch.y);
			return str;

		} break;
		case SCREEN_DRAG: {
			str+= "Event: ScreenDrag ";
			str=str+" Index: " +itos(screen_drag.index)+" pos "+rtos(screen_drag.x)+","+rtos(screen_drag.y);
			return str;

		} break;
		case ACTION: {
			str+= "Event: Action: "+InputMap::get_singleton()->get_action_from_id(action.action)+" Pressed: "+itos(action.pressed);
			return str;

		} break;

	}

	return "";
}

void InputEvent::set_as_action(const String& p_action, bool p_pressed) {

	type=ACTION;
	action.action=InputMap::get_singleton()->get_action_id(p_action);
	action.pressed=p_pressed;
}

bool InputEvent::is_pressed() const {

	switch(type) {

		case KEY: return key.pressed;
		case MOUSE_BUTTON: return mouse_button.pressed;
		case JOYSTICK_BUTTON: return joy_button.pressed;
		case SCREEN_TOUCH: return screen_touch.pressed;
		case JOYSTICK_MOTION: return ABS(joy_motion.axis_value) > 0.5;
		case ACTION: return action.pressed;
		default: {}
	}

	return false;
}

bool InputEvent::is_echo() const {

	return (type==KEY && key.echo);
}

bool InputEvent::is_action(const String& p_action) const {

	return InputMap::get_singleton()->event_is_action(*this,p_action);
}

bool InputEvent::is_action_pressed(const String& p_action) const {

	return is_action(p_action) && is_pressed() && !is_echo();
}

bool InputEvent::is_action_released(const String& p_action) const {

	return is_action(p_action) && !is_pressed();
}

uint32_t InputEventKey::get_scancode_with_modifiers() const {

	uint32_t sc=scancode;
	if (mod.control)
		sc|=KEY_MASK_CTRL;
	if (mod.alt)
		sc|=KEY_MASK_ALT;
	if (mod.shift)
		sc|=KEY_MASK_SHIFT;
	if (mod.meta)
		sc|=KEY_MASK_META;

	return sc;

}

InputEvent InputEvent::xform_by(const Matrix32& p_xform) const {

	InputEvent ev=*this;

	switch(ev.type) {

		case InputEvent::MOUSE_BUTTON: {

			Vector2 g = p_xform.xform(Vector2(ev.mouse_button.global_x,ev.mouse_button.global_y));
			Vector2 l = p_xform.xform(Vector2(ev.mouse_button.x,ev.mouse_button.y));
			ev.mouse_button.x=l.x;
			ev.mouse_button.y=l.y;
			ev.mouse_button.global_x=g.x;
			ev.mouse_button.global_y=g.y;

		} break;
		case InputEvent::MOUSE_MOTION: {

			Vector2 g = p_xform.xform(Vector2(ev.mouse_motion.global_x,ev.mouse_motion.global_y));
			Vector2 l = p_xform.xform(Vector2(ev.mouse_motion.x,ev.mouse_motion.y));
			Vector2 r = p_xform.basis_xform(Vector2(ev.mouse_motion.relative_x,ev.mouse_motion.relative_y));
			Vector2 s = p_xform.basis_xform(Vector2(ev.mouse_motion.speed_x,ev.mouse_motion.speed_y));
			ev.mouse_motion.x=l.x;
			ev.mouse_motion.y=l.y;
			ev.mouse_motion.global_x=g.x;
			ev.mouse_motion.global_y=g.y;
			ev.mouse_motion.relative_x=r.x;
			ev.mouse_motion.relative_y=r.y;
			ev.mouse_motion.speed_x=s.x;
			ev.mouse_motion.speed_y=s.y;

		} break;
		case InputEvent::SCREEN_TOUCH: {

			Vector2 t = p_xform.xform(Vector2(ev.screen_touch.x,ev.screen_touch.y));
			ev.screen_touch.x=t.x;
			ev.screen_touch.y=t.y;

		} break;
		case InputEvent::SCREEN_DRAG: {

			Vector2 t = p_xform.xform(Vector2(ev.screen_drag.x,ev.screen_drag.y));
			Vector2 r = p_xform.basis_xform(Vector2(ev.screen_drag.relative_x,ev.screen_drag.relative_y));
			Vector2 s = p_xform.basis_xform(Vector2(ev.screen_drag.speed_x,ev.screen_drag.speed_y));
			ev.screen_drag.x=t.x;
			ev.screen_drag.y=t.y;
			ev.screen_drag.relative_x=r.x;
			ev.screen_drag.relative_y=r.y;
			ev.screen_drag.speed_x=s.x;
			ev.screen_drag.speed_y=s.y;
		} break;
	}

	return ev;
}
<|endoftext|>


<commit_before>//===--- SILGlobalVariable.cpp - Defines SILGlobalVariable structure ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILGlobalVariable.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILLinkage.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage,
                                             IsSerialized_t isSerialized,
                                             StringRef name,
                                             SILType loweredType,
                                             Optional<SILLocation> loc,
                                             VarDecl *Decl) {
  // Get a StringMapEntry for the variable.  As a sop to error cases,
  // allow the name to have an empty string.
  llvm::StringMapEntry<SILGlobalVariable*> *entry = nullptr;
  if (!name.empty()) {
    entry = &*M.GlobalVariableMap.insert(std::make_pair(name, nullptr)).first;
    assert(!entry->getValue() && "global variable already exists");
    name = entry->getKey();
  }

  auto var = new (M) SILGlobalVariable(M, linkage, isSerialized, name,
                                       loweredType, loc, Decl);

  if (entry) entry->setValue(var);
  return var;
}

SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
                                     IsSerialized_t isSerialized,
                                     StringRef Name, SILType LoweredType,
                                     Optional<SILLocation> Loc, VarDecl *Decl)
  : Module(Module),
    Name(Name),
    LoweredType(LoweredType),
    Location(Loc),
    Linkage(unsigned(Linkage)),
    VDecl(Decl) {
  setSerialized(isSerialized);
  IsDeclaration = isAvailableExternally(Linkage);
  setLet(Decl ? Decl->isLet() : false);
  Module.silGlobals.push_back(this);
}

SILGlobalVariable::~SILGlobalVariable() {
  getModule().GlobalVariableMap.erase(Name);
}

/// Get this global variable's fragile attribute.
IsSerialized_t SILGlobalVariable::isSerialized() const {
  return Serialized ? IsSerialized : IsNotSerialized;
}
void SILGlobalVariable::setSerialized(IsSerialized_t isSerialized) {
  assert(isSerialized != IsSerializable);
  Serialized = isSerialized ? 1 : 0;
}

/// Return the value that is written into the global variable.
SILInstruction *SILGlobalVariable::getStaticInitializerValue() {
  if (StaticInitializerBlock.empty())
    return nullptr;

  return &StaticInitializerBlock.back();
}

BuiltinInst *SILGlobalVariable::getOffsetSubtract(const TupleExtractInst *TE,
                                                  SILModule &M) {

  // Match the pattern:
  // tuple_extract(usub_with_overflow(x, integer_literal, integer_literal 0), 0)

  if (TE->getFieldNo() != 0)
    return nullptr;

  auto *BI = dyn_cast<BuiltinInst>(TE->getOperand());
  if (!BI)
    return nullptr;
  if (M.getBuiltinInfo(BI->getName()).ID != BuiltinValueKind::USubOver)
    return nullptr;

  if (!isa<IntegerLiteralInst>(BI->getArguments()[1]))
    return nullptr;

  auto *overflowFlag = dyn_cast<IntegerLiteralInst>(BI->getArguments()[2]);
  if (!overflowFlag || !overflowFlag->getValue().isNullValue())
    return nullptr;

  return BI;
}

bool SILGlobalVariable::isValidStaticInitializerInst(const SILInstruction *I,
                                                     SILModule &M) {
  switch (I->getKind()) {
    case SILInstructionKind::BuiltinInst: {
      auto *bi = cast<BuiltinInst>(I);
      switch (M.getBuiltinInfo(bi->getName()).ID) {
        case BuiltinValueKind::ZeroInitializer: {
          auto type = bi->getType().getASTType();
          if (auto vector = dyn_cast<BuiltinVectorType>(type))
            type = vector.getElementType();
          return isa<BuiltinIntegerType>(type) || isa<BuiltinFloatType>(type);
        }
        case BuiltinValueKind::PtrToInt:
          if (isa<LiteralInst>(bi->getArguments()[0]))
            return true;
          break;
        case BuiltinValueKind::StringObjectOr:
          // The first operand can be a string literal (i.e. a pointer), but the
          // second operand must be a constant. This enables creating a
          // a pointer+offset relocation.
          // Note that StringObjectOr requires the or'd bits in the first
          // operand to be 0, so the operation is equivalent to an addition.
          if (isa<IntegerLiteralInst>(bi->getArguments()[1]))
            return true;
          break;
        case BuiltinValueKind::ZExtOrBitCast:
          return true;
        case BuiltinValueKind::USubOver: {
          // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
          // This pattern appears in UTF8 String literal construction.
          auto *TE = bi->getSingleUserOfType<TupleExtractInst>();
          return TE && getOffsetSubtract(TE, M);
        }
        default:
          break;
      }
      return false;
    }
    case SILInstructionKind::TupleExtractInst: {
      // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
      // This pattern appears in UTF8 String literal construction.
      auto *TE = cast<TupleExtractInst>(I);
      if (!getOffsetSubtract(TE, M))
        return false;
      auto *BI = TE->getSingleUserOfType<BuiltinInst>();
      return BI &&
        M.getBuiltinInfo(BI->getName()).ID == BuiltinValueKind::StringObjectOr;
    }
    case SILInstructionKind::StringLiteralInst:
      switch (cast<StringLiteralInst>(I)->getEncoding()) {
        case StringLiteralInst::Encoding::Bytes:
        case StringLiteralInst::Encoding::UTF8:
        case StringLiteralInst::Encoding::UTF16:
          return true;
        case StringLiteralInst::Encoding::ObjCSelector:
          // Objective-C selector string literals cannot be used in static
          // initializers.
          return false;
      }
      return false;
    case SILInstructionKind::StructInst:
    case SILInstructionKind::TupleInst:
    case SILInstructionKind::IntegerLiteralInst:
    case SILInstructionKind::FloatLiteralInst:
    case SILInstructionKind::ObjectInst:
    case SILInstructionKind::ValueToBridgeObjectInst:
      return true;
    default:
      return false;
  }
}

/// Return whether this variable corresponds to a Clang node.
bool SILGlobalVariable::hasClangNode() const {
  return (VDecl ? VDecl->hasClangNode() : false);
}

/// Return the Clang node associated with this variable if it has one.
ClangNode SILGlobalVariable::getClangNode() const {
  return (VDecl ? VDecl->getClangNode() : ClangNode());
}
const clang::Decl *SILGlobalVariable::getClangDecl() const {
  return (VDecl ? VDecl->getClangDecl() : nullptr);
}

//===----------------------------------------------------------------------===//
// Utilities for verification and optimization.
//===----------------------------------------------------------------------===//

static SILGlobalVariable *getStaticallyInitializedVariable(SILFunction *AddrF) {
  if (AddrF->isExternalDeclaration())
    return nullptr;

  auto *RetInst = cast<ReturnInst>(AddrF->findReturnBB()->getTerminator());
  auto *API = dyn_cast<AddressToPointerInst>(RetInst->getOperand());
  if (!API)
    return nullptr;
  auto *GAI = dyn_cast<GlobalAddrInst>(API->getOperand());
  if (!GAI)
    return nullptr;

  return GAI->getReferencedGlobal();
}

SILGlobalVariable *swift::getVariableOfGlobalInit(SILFunction *AddrF) {
  if (!AddrF->isGlobalInit())
    return nullptr;

  if (auto *SILG = getStaticallyInitializedVariable(AddrF))
    return SILG;

  // If the addressor contains a single "once" call, it calls globalinit_func,
  // and the globalinit_func is called by "once" from a single location,
  // continue; otherwise bail.
  BuiltinInst *CallToOnce;
  auto *InitF = findInitializer(&AddrF->getModule(), AddrF, CallToOnce);

  if (!InitF || !InitF->getName().startswith("globalinit_"))
    return nullptr;

  // If the globalinit_func is trivial, continue; otherwise bail.
  SingleValueInstruction *dummyInitVal;
  auto *SILG = getVariableOfStaticInitializer(InitF, dummyInitVal);

  return SILG;
}

SILFunction *swift::getCalleeOfOnceCall(BuiltinInst *BI) {
  assert(BI->getNumOperands() == 2 && "once call should have 2 operands.");

  auto Callee = BI->getOperand(1);
  assert(Callee->getType().castTo<SILFunctionType>()->getRepresentation()
           == SILFunctionTypeRepresentation::CFunctionPointer &&
         "Expected C function representation!");

  if (auto *FR = dyn_cast<FunctionRefInst>(Callee))
    return FR->getReferencedFunctionOrNull();

  return nullptr;
}

// Find the globalinit_func by analyzing the body of the addressor.
SILFunction *swift::findInitializer(SILModule *Module, SILFunction *AddrF,
                             BuiltinInst *&CallToOnce) {
  // We only handle a single SILBasicBlock for now.
  if (AddrF->size() != 1)
    return nullptr;

  CallToOnce = nullptr;
  SILBasicBlock *BB = &AddrF->front();
  for (auto &I : *BB) {
    // Find the builtin "once" call.
    if (auto *BI = dyn_cast<BuiltinInst>(&I)) {
      const BuiltinInfo &Builtin =
        BI->getModule().getBuiltinInfo(BI->getName());
      if (Builtin.ID != BuiltinValueKind::Once)
        continue;

      // Bail if we have multiple "once" calls in the addressor.
      if (CallToOnce)
        return nullptr;

      CallToOnce = BI;
    }
  }
  if (!CallToOnce)
    return nullptr;
  return getCalleeOfOnceCall(CallToOnce);
}

SILGlobalVariable *
swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
                                      SingleValueInstruction *&InitVal) {
  InitVal = nullptr;
  SILGlobalVariable *GVar = nullptr;
  // We only handle a single SILBasicBlock for now.
  if (InitFunc->size() != 1)
    return nullptr;

  SILBasicBlock *BB = &InitFunc->front();
  GlobalAddrInst *SGA = nullptr;
  bool HasStore = false;
  for (auto &I : *BB) {
    // Make sure we have a single GlobalAddrInst and a single StoreInst.
    // And the StoreInst writes to the GlobalAddrInst.
    if (isa<AllocGlobalInst>(&I) || isa<ReturnInst>(&I)
        || isa<DebugValueInst>(&I)) {
      continue;
    } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
      if (SGA)
        return nullptr;
      SGA = sga;
      GVar = SGA->getReferencedGlobal();
    } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
      if (HasStore || SI->getDest() != SGA)
        return nullptr;
      HasStore = true;
      SILValue value = SI->getSrc();

      // We only handle StructInst and TupleInst being stored to a
      // global variable for now.
      if (!isa<StructInst>(value) && !isa<TupleInst>(value))
        return nullptr;
      InitVal = cast<SingleValueInstruction>(value);
    } else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
                                                             I.getModule())) {
      return nullptr;
    }
  }
  if (!InitVal)
    return nullptr;
  return GVar;
}

SILType
SILGlobalVariable::getLoweredTypeInContext(TypeExpansionContext context) const {
  auto ty = getLoweredType();
  if (!ty.getASTType()->hasOpaqueArchetype() ||
      !context.shouldLookThroughOpaqueTypeArchetypes())
    return ty;
  auto resultTy =
      getModule().Types.getTypeLowering(ty, context).getLoweredType();
  return resultTy.getCategoryType(ty.getCategory());
}
<commit_msg>[SIL] NFC: "Stop being a sop"<commit_after>//===--- SILGlobalVariable.cpp - Defines SILGlobalVariable structure ------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILGlobalVariable.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SIL/SILLinkage.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

SILGlobalVariable *SILGlobalVariable::create(SILModule &M, SILLinkage linkage,
                                             IsSerialized_t isSerialized,
                                             StringRef name,
                                             SILType loweredType,
                                             Optional<SILLocation> loc,
                                             VarDecl *Decl) {
  // Get a StringMapEntry for the variable.
  llvm::StringMapEntry<SILGlobalVariable*> *entry = nullptr;
  assert(!name.empty() && "Name required");

  entry = &*M.GlobalVariableMap.insert(std::make_pair(name, nullptr)).first;
  assert(!entry->getValue() && "global variable already exists");
  name = entry->getKey();

  auto var = new (M) SILGlobalVariable(M, linkage, isSerialized, name,
                                       loweredType, loc, Decl);

  if (entry) entry->setValue(var);
  return var;
}

SILGlobalVariable::SILGlobalVariable(SILModule &Module, SILLinkage Linkage,
                                     IsSerialized_t isSerialized,
                                     StringRef Name, SILType LoweredType,
                                     Optional<SILLocation> Loc, VarDecl *Decl)
  : Module(Module),
    Name(Name),
    LoweredType(LoweredType),
    Location(Loc),
    Linkage(unsigned(Linkage)),
    VDecl(Decl) {
  setSerialized(isSerialized);
  IsDeclaration = isAvailableExternally(Linkage);
  setLet(Decl ? Decl->isLet() : false);
  Module.silGlobals.push_back(this);
}

SILGlobalVariable::~SILGlobalVariable() {
  getModule().GlobalVariableMap.erase(Name);
}

/// Get this global variable's fragile attribute.
IsSerialized_t SILGlobalVariable::isSerialized() const {
  return Serialized ? IsSerialized : IsNotSerialized;
}
void SILGlobalVariable::setSerialized(IsSerialized_t isSerialized) {
  assert(isSerialized != IsSerializable);
  Serialized = isSerialized ? 1 : 0;
}

/// Return the value that is written into the global variable.
SILInstruction *SILGlobalVariable::getStaticInitializerValue() {
  if (StaticInitializerBlock.empty())
    return nullptr;

  return &StaticInitializerBlock.back();
}

BuiltinInst *SILGlobalVariable::getOffsetSubtract(const TupleExtractInst *TE,
                                                  SILModule &M) {

  // Match the pattern:
  // tuple_extract(usub_with_overflow(x, integer_literal, integer_literal 0), 0)

  if (TE->getFieldNo() != 0)
    return nullptr;

  auto *BI = dyn_cast<BuiltinInst>(TE->getOperand());
  if (!BI)
    return nullptr;
  if (M.getBuiltinInfo(BI->getName()).ID != BuiltinValueKind::USubOver)
    return nullptr;

  if (!isa<IntegerLiteralInst>(BI->getArguments()[1]))
    return nullptr;

  auto *overflowFlag = dyn_cast<IntegerLiteralInst>(BI->getArguments()[2]);
  if (!overflowFlag || !overflowFlag->getValue().isNullValue())
    return nullptr;

  return BI;
}

bool SILGlobalVariable::isValidStaticInitializerInst(const SILInstruction *I,
                                                     SILModule &M) {
  switch (I->getKind()) {
    case SILInstructionKind::BuiltinInst: {
      auto *bi = cast<BuiltinInst>(I);
      switch (M.getBuiltinInfo(bi->getName()).ID) {
        case BuiltinValueKind::ZeroInitializer: {
          auto type = bi->getType().getASTType();
          if (auto vector = dyn_cast<BuiltinVectorType>(type))
            type = vector.getElementType();
          return isa<BuiltinIntegerType>(type) || isa<BuiltinFloatType>(type);
        }
        case BuiltinValueKind::PtrToInt:
          if (isa<LiteralInst>(bi->getArguments()[0]))
            return true;
          break;
        case BuiltinValueKind::StringObjectOr:
          // The first operand can be a string literal (i.e. a pointer), but the
          // second operand must be a constant. This enables creating a
          // a pointer+offset relocation.
          // Note that StringObjectOr requires the or'd bits in the first
          // operand to be 0, so the operation is equivalent to an addition.
          if (isa<IntegerLiteralInst>(bi->getArguments()[1]))
            return true;
          break;
        case BuiltinValueKind::ZExtOrBitCast:
          return true;
        case BuiltinValueKind::USubOver: {
          // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
          // This pattern appears in UTF8 String literal construction.
          auto *TE = bi->getSingleUserOfType<TupleExtractInst>();
          return TE && getOffsetSubtract(TE, M);
        }
        default:
          break;
      }
      return false;
    }
    case SILInstructionKind::TupleExtractInst: {
      // Handle StringObjectOr(tuple_extract(usub_with_overflow(x, offset)), bits)
      // This pattern appears in UTF8 String literal construction.
      auto *TE = cast<TupleExtractInst>(I);
      if (!getOffsetSubtract(TE, M))
        return false;
      auto *BI = TE->getSingleUserOfType<BuiltinInst>();
      return BI &&
        M.getBuiltinInfo(BI->getName()).ID == BuiltinValueKind::StringObjectOr;
    }
    case SILInstructionKind::StringLiteralInst:
      switch (cast<StringLiteralInst>(I)->getEncoding()) {
        case StringLiteralInst::Encoding::Bytes:
        case StringLiteralInst::Encoding::UTF8:
        case StringLiteralInst::Encoding::UTF16:
          return true;
        case StringLiteralInst::Encoding::ObjCSelector:
          // Objective-C selector string literals cannot be used in static
          // initializers.
          return false;
      }
      return false;
    case SILInstructionKind::StructInst:
    case SILInstructionKind::TupleInst:
    case SILInstructionKind::IntegerLiteralInst:
    case SILInstructionKind::FloatLiteralInst:
    case SILInstructionKind::ObjectInst:
    case SILInstructionKind::ValueToBridgeObjectInst:
      return true;
    default:
      return false;
  }
}

/// Return whether this variable corresponds to a Clang node.
bool SILGlobalVariable::hasClangNode() const {
  return (VDecl ? VDecl->hasClangNode() : false);
}

/// Return the Clang node associated with this variable if it has one.
ClangNode SILGlobalVariable::getClangNode() const {
  return (VDecl ? VDecl->getClangNode() : ClangNode());
}
const clang::Decl *SILGlobalVariable::getClangDecl() const {
  return (VDecl ? VDecl->getClangDecl() : nullptr);
}

//===----------------------------------------------------------------------===//
// Utilities for verification and optimization.
//===----------------------------------------------------------------------===//

static SILGlobalVariable *getStaticallyInitializedVariable(SILFunction *AddrF) {
  if (AddrF->isExternalDeclaration())
    return nullptr;

  auto *RetInst = cast<ReturnInst>(AddrF->findReturnBB()->getTerminator());
  auto *API = dyn_cast<AddressToPointerInst>(RetInst->getOperand());
  if (!API)
    return nullptr;
  auto *GAI = dyn_cast<GlobalAddrInst>(API->getOperand());
  if (!GAI)
    return nullptr;

  return GAI->getReferencedGlobal();
}

SILGlobalVariable *swift::getVariableOfGlobalInit(SILFunction *AddrF) {
  if (!AddrF->isGlobalInit())
    return nullptr;

  if (auto *SILG = getStaticallyInitializedVariable(AddrF))
    return SILG;

  // If the addressor contains a single "once" call, it calls globalinit_func,
  // and the globalinit_func is called by "once" from a single location,
  // continue; otherwise bail.
  BuiltinInst *CallToOnce;
  auto *InitF = findInitializer(&AddrF->getModule(), AddrF, CallToOnce);

  if (!InitF || !InitF->getName().startswith("globalinit_"))
    return nullptr;

  // If the globalinit_func is trivial, continue; otherwise bail.
  SingleValueInstruction *dummyInitVal;
  auto *SILG = getVariableOfStaticInitializer(InitF, dummyInitVal);

  return SILG;
}

SILFunction *swift::getCalleeOfOnceCall(BuiltinInst *BI) {
  assert(BI->getNumOperands() == 2 && "once call should have 2 operands.");

  auto Callee = BI->getOperand(1);
  assert(Callee->getType().castTo<SILFunctionType>()->getRepresentation()
           == SILFunctionTypeRepresentation::CFunctionPointer &&
         "Expected C function representation!");

  if (auto *FR = dyn_cast<FunctionRefInst>(Callee))
    return FR->getReferencedFunctionOrNull();

  return nullptr;
}

// Find the globalinit_func by analyzing the body of the addressor.
SILFunction *swift::findInitializer(SILModule *Module, SILFunction *AddrF,
                             BuiltinInst *&CallToOnce) {
  // We only handle a single SILBasicBlock for now.
  if (AddrF->size() != 1)
    return nullptr;

  CallToOnce = nullptr;
  SILBasicBlock *BB = &AddrF->front();
  for (auto &I : *BB) {
    // Find the builtin "once" call.
    if (auto *BI = dyn_cast<BuiltinInst>(&I)) {
      const BuiltinInfo &Builtin =
        BI->getModule().getBuiltinInfo(BI->getName());
      if (Builtin.ID != BuiltinValueKind::Once)
        continue;

      // Bail if we have multiple "once" calls in the addressor.
      if (CallToOnce)
        return nullptr;

      CallToOnce = BI;
    }
  }
  if (!CallToOnce)
    return nullptr;
  return getCalleeOfOnceCall(CallToOnce);
}

SILGlobalVariable *
swift::getVariableOfStaticInitializer(SILFunction *InitFunc,
                                      SingleValueInstruction *&InitVal) {
  InitVal = nullptr;
  SILGlobalVariable *GVar = nullptr;
  // We only handle a single SILBasicBlock for now.
  if (InitFunc->size() != 1)
    return nullptr;

  SILBasicBlock *BB = &InitFunc->front();
  GlobalAddrInst *SGA = nullptr;
  bool HasStore = false;
  for (auto &I : *BB) {
    // Make sure we have a single GlobalAddrInst and a single StoreInst.
    // And the StoreInst writes to the GlobalAddrInst.
    if (isa<AllocGlobalInst>(&I) || isa<ReturnInst>(&I)
        || isa<DebugValueInst>(&I)) {
      continue;
    } else if (auto *sga = dyn_cast<GlobalAddrInst>(&I)) {
      if (SGA)
        return nullptr;
      SGA = sga;
      GVar = SGA->getReferencedGlobal();
    } else if (auto *SI = dyn_cast<StoreInst>(&I)) {
      if (HasStore || SI->getDest() != SGA)
        return nullptr;
      HasStore = true;
      SILValue value = SI->getSrc();

      // We only handle StructInst and TupleInst being stored to a
      // global variable for now.
      if (!isa<StructInst>(value) && !isa<TupleInst>(value))
        return nullptr;
      InitVal = cast<SingleValueInstruction>(value);
    } else if (!SILGlobalVariable::isValidStaticInitializerInst(&I,
                                                             I.getModule())) {
      return nullptr;
    }
  }
  if (!InitVal)
    return nullptr;
  return GVar;
}

SILType
SILGlobalVariable::getLoweredTypeInContext(TypeExpansionContext context) const {
  auto ty = getLoweredType();
  if (!ty.getASTType()->hasOpaqueArchetype() ||
      !context.shouldLookThroughOpaqueTypeArchetypes())
    return ty;
  auto resultTy =
      getModule().Types.getTypeLowering(ty, context).getLoweredType();
  return resultTy.getCategoryType(ty.getCategory());
}
<|endoftext|>


<commit_before>// Fill out your copyright notice in the Description page of Project Settings.

// #include "TestCamera.h"
#include "ScriptPluginPrivatePCH.h"
#include "TableUtil.h"
lua_State* UTableUtil::L = nullptr;

TMap<FString, TMap<FString, UProperty*>> UTableUtil::propertyMap;

void UTableUtil::InitClassMap()
{
	for (TObjectIterator<UClass> uClass; uClass; ++uClass)
	{
		UClass* theClass = *uClass;
		FString className = FString::Printf(TEXT("%s%s"), theClass->GetPrefixCPP(), *theClass->GetName());
		TMap<FString, UProperty*> m;
		for (TFieldIterator<UProperty> PropertyIt(theClass); PropertyIt; ++PropertyIt)
		{
			UProperty* Property = *PropertyIt;
			m.Add(Property->GetName(), Property);
		}
		propertyMap.Add(className ,m);
	}
}

UProperty* UTableUtil::GetPropertyByName(FString classname, FString propertyname)
{
	return propertyMap[classname][propertyname];
}

static void* LuaAlloc(void *Ud, void *Ptr, size_t OldSize, size_t NewSize)
{
	if (NewSize != 0)
	{
		return FMemory::Realloc(Ptr, NewSize);
	}
	else
	{
		FMemory::Free(Ptr);
		return NULL;
	}
}

static int32 LuaPanic(lua_State *L)
{
	UTableUtil::log(FString::Printf(TEXT("PANIC: unprotected error in call to Lua API(%s)"), ANSI_TO_TCHAR(lua_tostring(L, -1))));
	return 0;
}

void UTableUtil::init()
{
	InitClassMap();
	if (L != nullptr)
		lua_close(L);
	auto l = lua_newstate(LuaAlloc, nullptr);
	if (l) lua_atpanic(l, &LuaPanic);
	luaL_openlibs(l);
	L = l;
	if (luaL_dofile(l, "G:\\luacode\\main.lua"))
	{
		UTableUtil::log(FString(lua_tostring(L, -1)));
	}
	else
	{
		//set table for index exist userdata
		lua_newtable(L);
		lua_newtable(L);
		lua_pushstring(L, "v");
		lua_setfield(L, -2, "__mode");
		lua_setmetatable(L, -2);
		lua_setfield(L, LUA_REGISTRYINDEX, "_existuserdata");
		//register all function
		LuaRegisterExportedClasses(L);

	}
}
void UTableUtil::shutdown()
{
	if (L != nullptr)
	{
		lua_close(L);
		L = nullptr;
	}
}

int32 indexFunc(lua_State* L)
{
	lua_getmetatable(L, 1);
	lua_pushvalue(L, 2);
	lua_rawget(L,-2);
	if (lua_isnil(L, -1))
	{
		FString property = FString(lua_tostring(L, 2));
		lua_pop(L, 1);
		FString propertyKey = FString::Printf(TEXT("Get_%s"), *property);
		UTableUtil::push(propertyKey);
		lua_rawget(L, -2);
		if (!lua_isnil(L, -1))
		{
			lua_pushvalue(L, 1);
			lua_pcall(L, 1, 1, 0);
		}
	}
	return 1;
}

int32 newindexFunc(lua_State* L)
{
	lua_getmetatable(L, 1);
	FString property = FString(lua_tostring(L, 2));
	FString propertyKey = FString::Printf(TEXT("Set_%s"), *property);
	UTableUtil::push(propertyKey);
	lua_rawget(L, -2);
	if (!lua_isnil(L, -1))
	{
		lua_pushvalue(L, 1);
		lua_pushvalue(L, 3);
		lua_call(L, 2, 1);
	}
	return 0;
}

int32 cast(lua_State* L)
{
	if (lua_isnil(L, 2))
	{
		UTableUtil::log(FString("cast error, nil"));
		return 1;
	}
	lua_pushstring(L, "classname");
	lua_rawget(L, 1);
	luaL_getmetatable(L, lua_tostring(L, -1));
	lua_setmetatable(L, 2);
	lua_pushvalue(L, 2);
	return 1;
}

int32 gcfunc(lua_State *L)
{
	auto u = (void**)lua_touserdata(L, -1);
	if (*u != nullptr)
	{
		FScriptObjectReferencer::Get().RemoveObjectReference((UObject*)(*u));
	}
	lua_getmetatable(L, -1);
	lua_pushstring(L, "Destroy");
	lua_gettable(L, -2);
	if (lua_iscfunction(L, -1))
	{
		lua_remove(L, -2);
		lua_pushvalue(L, 1);
		if (lua_pcall(L, 1, 0, 0))
		{
			UTableUtil::log(FString(lua_tostring(L, -1)));
		}
	}
	else
	{
	}
	return 0;
}

void UTableUtil::initmeta()
{
	lua_pushstring(L, "__index");
	lua_pushcfunction(L, indexFunc);
	lua_rawset(L, -3);
	lua_pushstring(L, "cast");
	lua_pushcfunction(L, cast);
	lua_rawset(L, -3);
	lua_pushstring(L, "__newindex");
	lua_pushcfunction(L, newindexFunc);
	lua_rawset(L, -3);
	lua_pushstring(L, "__gc");
	lua_pushcfunction(L, gcfunc);
	lua_rawset(L, -3);
}

void UTableUtil::addmodule(const char* name)
{
	lua_getglobal(L, name);
	if (lua_istable(L, -1))
	{
		lua_pop(L, 1);
		return;
	}
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	lua_pushstring(L, name);
	luaL_newmetatable(L, name);
	initmeta();
	lua_pushstring(L, "classname");
	lua_pushstring(L, name);
	lua_rawset(L, -3);
	lua_rawset(L, -3);
	lua_pop(L, 2);
}

void UTableUtil::openmodule(const char* name)
{
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	lua_pushstring(L, name);
	lua_rawget(L, -2);
}

void UTableUtil::addfunc(const char* name, luafunc f)
{
	lua_pushstring(L, name);
	lua_pushcfunction(L, f);
	lua_rawset(L, -3);
}

void UTableUtil::closemodule()
{
	lua_pop(L, 2);
}

void* UTableUtil::tousertype(const char* classname, int i)
{
	if (lua_isnil(L, i))
		return nullptr;
	else if (lua_istable(L, i))
	{
		lua_pushstring(L,  "_cppinstance_");
		lua_rawget(L, i);
		if (lua_isnil(L, -1))
		{
			lua_pushstring(L, "suck in tousertype");
			lua_error(L);
			return nullptr;
		}
		else
		{
			lua_replace(L, i);
			return tousertype(classname, i);
		}
	}
	else if (lua_isuserdata(L, i))
	{
		auto u = static_cast<void**>(lua_touserdata(L, i));
		return *u;
	}
	else
		return nullptr;
}

int UTableUtil::toint(int i)
{
	return lua_tointeger(L, i);
}

void UTableUtil::push(const char* classname, void* p, bool bgcrecord)
{
	if (p == nullptr)
	{
		lua_pushnil(L);
		return;
	}
	if (!existdata(p))
	{
		if (bgcrecord)
			FScriptObjectReferencer::Get().AddObjectReference((UObject*)p);
		*(void**)lua_newuserdata(L, sizeof(void *)) = p;

		lua_getfield(L, LUA_REGISTRYINDEX, "_existuserdata");
		lua_pushlightuserdata(L, p);
		lua_pushvalue(L, -3);
		lua_rawset(L, -3);
		lua_pop(L, 1);

		luaL_getmetatable(L, classname);
		if (lua_istable(L, -1))
		{
			lua_setmetatable(L, -2);
		}
		else
		{
			lua_pop(L, 1);
			UTableUtil::addmodule(classname);
			luaL_getmetatable(L, classname);
			lua_setmetatable(L, -2);
		}
	}
}

UTableUtil::UTableUtil()
{

}

void UTableUtil::loadlib(const luaL_Reg funclist[], const char* classname)
{
	int i = 0;
	UTableUtil::addmodule(classname);
	UTableUtil::openmodule(classname);
	while (true)
	{

		luaL_Reg temp = funclist[i];
		if (temp.name == nullptr)
		{
			break;
		}
		else if (temp.func != nullptr)
		{
			UTableUtil::addfunc(temp.name, temp.func);
		}
		i++;
	}
	UTableUtil::closemodule();
	// int j = lua_gettop(L);
	// UE_LOG(LogScriptPlugin, Warning, TEXT("lalala %d"), j);
}

void UTableUtil::setpawn(ADefaultPawn *p)
{
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	lua_pushstring(L, "PawnIns");
	push("ADefaultPawn", (void*)p);
	lua_rawset(L, -3);
	lua_pop(L, 1);
}

void UTableUtil::executeFunc(FString funcName)
{
	int nargs = lua_gettop(L);
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	push(funcName);
	lua_rawget(L, -2);
	for (int i = 1; i <= nargs; i++)
	{
		lua_pushvalue(L, i);
	}
	lua_pcall(L, nargs, 1, 0);
}

void UTableUtil::clearStack()
{
	lua_pop(L, lua_gettop(L));
}
// api for blueprint start:
void UTableUtil::Push_obj(UObject *p)
{
	auto Class = p->StaticClass();
	FString ClassName = FString::Printf(TEXT("%s%s"), Class->GetPrefixCPP(), *Class->GetName());
	push(TCHAR_TO_ANSI(*ClassName), (void*)p, true);
}

void UTableUtil::Push_float(float value)
{
	lua_pushnumber(L, value);
}

void UTableUtil::Push_str(FString value)
{
	push(value);
}

void UTableUtil::Call_void(FString funcName)
{
	executeFunc(funcName);
	clearStack();
	// lua_tinker::call<void>(L, TCHAR_TO_ANSI(*funcName));
}

float UTableUtil::Call_float(FString funcName)
{
	executeFunc(funcName);
	auto result = lua_tonumber(L, -1);
	clearStack();
	return result;
}

UObject* UTableUtil::Call_obj(FString funcName)
{
	executeFunc(funcName);
	auto result = (UObject*)tousertype("", -1);
	clearStack();
	return result;
}

FString UTableUtil::Call_str(FString funcName)
{
	executeFunc(funcName);
	FString result = ANSI_TO_TCHAR(luaL_checkstring(L, -1));
	clearStack();
	return result;
}

bool UTableUtil::existdata(void * p)
{
	lua_getfield(L, LUA_REGISTRYINDEX, "_existuserdata");
	lua_pushlightuserdata(L, p);
	lua_rawget(L, -2);
	if (lua_isnil(L, -1))
	{
		lua_pop(L, 2);
		return false;
	}
	else
	{
		lua_replace(L, 1);
		return true;
	}
}

void UTableUtil::log(FString content)
{
	UE_LOG(LogScriptPlugin, Warning, TEXT("[lua error] %s"), *content);
}
<commit_msg>default delete point<commit_after>// Fill out your copyright notice in the Description page of Project Settings.

// #include "TestCamera.h"
#include "ScriptPluginPrivatePCH.h"
#include "TableUtil.h"
lua_State* UTableUtil::L = nullptr;

TMap<FString, TMap<FString, UProperty*>> UTableUtil::propertyMap;

void UTableUtil::InitClassMap()
{
	for (TObjectIterator<UClass> uClass; uClass; ++uClass)
	{
		UClass* theClass = *uClass;
		FString className = FString::Printf(TEXT("%s%s"), theClass->GetPrefixCPP(), *theClass->GetName());
		TMap<FString, UProperty*> m;
		for (TFieldIterator<UProperty> PropertyIt(theClass); PropertyIt; ++PropertyIt)
		{
			UProperty* Property = *PropertyIt;
			m.Add(Property->GetName(), Property);
		}
		propertyMap.Add(className ,m);
	}
}

UProperty* UTableUtil::GetPropertyByName(FString classname, FString propertyname)
{
	return propertyMap[classname][propertyname];
}

static void* LuaAlloc(void *Ud, void *Ptr, size_t OldSize, size_t NewSize)
{
	if (NewSize != 0)
	{
		return FMemory::Realloc(Ptr, NewSize);
	}
	else
	{
		FMemory::Free(Ptr);
		return NULL;
	}
}

static int32 LuaPanic(lua_State *L)
{
	UTableUtil::log(FString::Printf(TEXT("PANIC: unprotected error in call to Lua API(%s)"), ANSI_TO_TCHAR(lua_tostring(L, -1))));
	return 0;
}

void UTableUtil::init()
{
	InitClassMap();
	if (L != nullptr)
		lua_close(L);
	auto l = lua_newstate(LuaAlloc, nullptr);
	if (l) lua_atpanic(l, &LuaPanic);
	luaL_openlibs(l);
	L = l;
	if (luaL_dofile(l, "G:\\luacode\\main.lua"))
	{
		UTableUtil::log(FString(lua_tostring(L, -1)));
	}
	else
	{
		//set table for index exist userdata
		lua_newtable(L);
		lua_newtable(L);
		lua_pushstring(L, "v");
		lua_setfield(L, -2, "__mode");
		lua_setmetatable(L, -2);
		lua_setfield(L, LUA_REGISTRYINDEX, "_existuserdata");
		//register all function
		LuaRegisterExportedClasses(L);

	}
}
void UTableUtil::shutdown()
{
	if (L != nullptr)
	{
		lua_close(L);
		L = nullptr;
	}
}

int32 indexFunc(lua_State* L)
{
	lua_getmetatable(L, 1);
	lua_pushvalue(L, 2);
	lua_rawget(L,-2);
	if (lua_isnil(L, -1))
	{
		FString property = FString(lua_tostring(L, 2));
		lua_pop(L, 1);
		FString propertyKey = FString::Printf(TEXT("Get_%s"), *property);
		UTableUtil::push(propertyKey);
		lua_rawget(L, -2);
		if (!lua_isnil(L, -1))
		{
			lua_pushvalue(L, 1);
			lua_pcall(L, 1, 1, 0);
		}
	}
	return 1;
}

int32 newindexFunc(lua_State* L)
{
	lua_getmetatable(L, 1);
	FString property = FString(lua_tostring(L, 2));
	FString propertyKey = FString::Printf(TEXT("Set_%s"), *property);
	UTableUtil::push(propertyKey);
	lua_rawget(L, -2);
	if (!lua_isnil(L, -1))
	{
		lua_pushvalue(L, 1);
		lua_pushvalue(L, 3);
		lua_call(L, 2, 1);
	}
	return 0;
}

int32 cast(lua_State* L)
{
	if (lua_isnil(L, 2))
	{
		UTableUtil::log(FString("cast error, nil"));
		return 1;
	}
	lua_pushstring(L, "classname");
	lua_rawget(L, 1);
	luaL_getmetatable(L, lua_tostring(L, -1));
	lua_setmetatable(L, 2);
	lua_pushvalue(L, 2);
	return 1;
}

int32 gcfunc(lua_State *L)
{
	auto u = (void**)lua_touserdata(L, -1);
	if (*u != nullptr)
	{
		FScriptObjectReferencer::Get().RemoveObjectReference((UObject*)(*u));
	}
	lua_getmetatable(L, -1);
	lua_pushstring(L, "Destroy");
	lua_gettable(L, -2);
	if (lua_iscfunction(L, -1))
	{
		lua_remove(L, -2);
		lua_pushvalue(L, 1);
		if (lua_pcall(L, 1, 0, 0))
		{
			UTableUtil::log(FString(lua_tostring(L, -1)));
		}
	}
	else
	{
		delete *u;
	}
	return 0;
}

void UTableUtil::initmeta()
{
	lua_pushstring(L, "__index");
	lua_pushcfunction(L, indexFunc);
	lua_rawset(L, -3);
	lua_pushstring(L, "cast");
	lua_pushcfunction(L, cast);
	lua_rawset(L, -3);
	lua_pushstring(L, "__newindex");
	lua_pushcfunction(L, newindexFunc);
	lua_rawset(L, -3);
	lua_pushstring(L, "__gc");
	lua_pushcfunction(L, gcfunc);
	lua_rawset(L, -3);
}

void UTableUtil::addmodule(const char* name)
{
	lua_getglobal(L, name);
	if (lua_istable(L, -1))
	{
		lua_pop(L, 1);
		return;
	}
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	lua_pushstring(L, name);
	luaL_newmetatable(L, name);
	initmeta();
	lua_pushstring(L, "classname");
	lua_pushstring(L, name);
	lua_rawset(L, -3);
	lua_rawset(L, -3);
	lua_pop(L, 2);
}

void UTableUtil::openmodule(const char* name)
{
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	lua_pushstring(L, name);
	lua_rawget(L, -2);
}

void UTableUtil::addfunc(const char* name, luafunc f)
{
	lua_pushstring(L, name);
	lua_pushcfunction(L, f);
	lua_rawset(L, -3);
}

void UTableUtil::closemodule()
{
	lua_pop(L, 2);
}

void* UTableUtil::tousertype(const char* classname, int i)
{
	if (lua_isnil(L, i))
		return nullptr;
	else if (lua_istable(L, i))
	{
		lua_pushstring(L,  "_cppinstance_");
		lua_rawget(L, i);
		if (lua_isnil(L, -1))
		{
			lua_pushstring(L, "suck in tousertype");
			lua_error(L);
			return nullptr;
		}
		else
		{
			lua_replace(L, i);
			return tousertype(classname, i);
		}
	}
	else if (lua_isuserdata(L, i))
	{
		auto u = static_cast<void**>(lua_touserdata(L, i));
		return *u;
	}
	else
		return nullptr;
}

int UTableUtil::toint(int i)
{
	return lua_tointeger(L, i);
}

void UTableUtil::push(const char* classname, void* p, bool bgcrecord)
{
	if (p == nullptr)
	{
		lua_pushnil(L);
		return;
	}
	if (!existdata(p))
	{
		if (bgcrecord)
			FScriptObjectReferencer::Get().AddObjectReference((UObject*)p);
		*(void**)lua_newuserdata(L, sizeof(void *)) = p;

		lua_getfield(L, LUA_REGISTRYINDEX, "_existuserdata");
		lua_pushlightuserdata(L, p);
		lua_pushvalue(L, -3);
		lua_rawset(L, -3);
		lua_pop(L, 1);

		luaL_getmetatable(L, classname);
		if (lua_istable(L, -1))
		{
			lua_setmetatable(L, -2);
		}
		else
		{
			lua_pop(L, 1);
			UTableUtil::addmodule(classname);
			luaL_getmetatable(L, classname);
			lua_setmetatable(L, -2);
		}
	}
}

UTableUtil::UTableUtil()
{

}

void UTableUtil::loadlib(const luaL_Reg funclist[], const char* classname)
{
	int i = 0;
	UTableUtil::addmodule(classname);
	UTableUtil::openmodule(classname);
	while (true)
	{

		luaL_Reg temp = funclist[i];
		if (temp.name == nullptr)
		{
			break;
		}
		else if (temp.func != nullptr)
		{
			UTableUtil::addfunc(temp.name, temp.func);
		}
		i++;
	}
	UTableUtil::closemodule();
	// int j = lua_gettop(L);
	// UE_LOG(LogScriptPlugin, Warning, TEXT("lalala %d"), j);
}

void UTableUtil::setpawn(ADefaultPawn *p)
{
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	lua_pushstring(L, "PawnIns");
	push("ADefaultPawn", (void*)p);
	lua_rawset(L, -3);
	lua_pop(L, 1);
}

void UTableUtil::executeFunc(FString funcName)
{
	int nargs = lua_gettop(L);
	lua_pushvalue(L, LUA_GLOBALSINDEX);
	push(funcName);
	lua_rawget(L, -2);
	for (int i = 1; i <= nargs; i++)
	{
		lua_pushvalue(L, i);
	}
	lua_pcall(L, nargs, 1, 0);
}

void UTableUtil::clearStack()
{
	lua_pop(L, lua_gettop(L));
}
// api for blueprint start:
void UTableUtil::Push_obj(UObject *p)
{
	auto Class = p->StaticClass();
	FString ClassName = FString::Printf(TEXT("%s%s"), Class->GetPrefixCPP(), *Class->GetName());
	push(TCHAR_TO_ANSI(*ClassName), (void*)p, true);
}

void UTableUtil::Push_float(float value)
{
	lua_pushnumber(L, value);
}

void UTableUtil::Push_str(FString value)
{
	push(value);
}

void UTableUtil::Call_void(FString funcName)
{
	executeFunc(funcName);
	clearStack();
	// lua_tinker::call<void>(L, TCHAR_TO_ANSI(*funcName));
}

float UTableUtil::Call_float(FString funcName)
{
	executeFunc(funcName);
	auto result = lua_tonumber(L, -1);
	clearStack();
	return result;
}

UObject* UTableUtil::Call_obj(FString funcName)
{
	executeFunc(funcName);
	auto result = (UObject*)tousertype("", -1);
	clearStack();
	return result;
}

FString UTableUtil::Call_str(FString funcName)
{
	executeFunc(funcName);
	FString result = ANSI_TO_TCHAR(luaL_checkstring(L, -1));
	clearStack();
	return result;
}

bool UTableUtil::existdata(void * p)
{
	lua_getfield(L, LUA_REGISTRYINDEX, "_existuserdata");
	lua_pushlightuserdata(L, p);
	lua_rawget(L, -2);
	if (lua_isnil(L, -1))
	{
		lua_pop(L, 2);
		return false;
	}
	else
	{
		lua_replace(L, 1);
		return true;
	}
}

void UTableUtil::log(FString content)
{
	UE_LOG(LogScriptPlugin, Warning, TEXT("[lua error] %s"), *content);
}
<|endoftext|>


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

#include <cstdio>
#include <limits>
#include <QMutexLocker>
#include "com/centreon/broker/file/stream.hh"
#include "com/centreon/broker/io/raw.hh"
#include "com/centreon/broker/misc/string.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::file;

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Constructor.
 *
 *  @param[in] file  Splitted file on which the stream will operate.
 */
stream::stream(splitter* file)
  : _file(file),
    _last_read_offset(0),
    _last_time(0),
    _last_write_offset(0) {}

/**
 *  Destructor.
 */
stream::~stream() {}

/**
 *  Read data from the file.
 *
 *  @param[out] d         Bunch of data.
 *  @param[in]  deadline  Timeout.
 *
 *  @return Always true as file never times out.
 */
bool stream::read(
               misc::shared_ptr<io::data>& d,
               time_t deadline) {
  (void)deadline;

  // Lock mutex.
  d.clear();
  QMutexLocker lock(&_mutex);

  // Build data array.
  std::auto_ptr<io::raw> data(new io::raw);
  data->resize(BUFSIZ);

  // Read data.
  long rb(_file->read(data->QByteArray::data(), data->size()));
  if (rb) {
    data->resize(rb);
    d = misc::shared_ptr<io::data>(data.release());
  }

  return (true);
}

/**
 *  Generate statistics about file processing.
 *
 *  @param[out] buffer Output buffer.
 */
void stream::statistics(io::properties& tree) const {
  // Get base properties.
  long max_file_size(_file->get_max_file_size());
  int rid(_file->get_rid());
  long roffset(_file->get_roffset());
  int wid(_file->get_wid());
  long woffset(_file->get_woffset());

  // Easy to print.
  std::ostringstream oss;
  {
    tree.add_property(
           "file_read_path",
           io::property("file_read_path", misc::string::get(rid)));
  }
  {
    tree.add_property(
           "file_read_offset",
           io::property("file_read_offset", misc::string::get(roffset)));
  }
  {
    tree.add_property(
           "file_write_path",
           io::property("file_write_path", misc::string::get(wid)));
  }
  {
    tree.add_property(
           "file_write_offset",
           io::property("file_write_offset", misc::string::get(woffset)));
  }
  {
    tree.add_property(
           "file_max_size",
           io::property(
                 "file_max_size",
                 max_file_size != std::numeric_limits<long>::max()
                 ? misc::string::get(max_file_size)
                 : "unlimited"));
  }

  // Need computation.
  bool write_time_expected(false);
  {
    io::property& p(tree["file_percent_processed"]);
    p.set_name("file_percent_processed");
    oss.str("");
    if (rid != wid
        && max_file_size == std::numeric_limits<long>::max()) {
      oss << "unknown";
    }
    else {
      oss << (roffset * 100.0 + rid * max_file_size) / (woffset + wid * max_file_size)
          << "%";
      write_time_expected = true;
    }
    p.set_value(oss.str());
  }
  if (write_time_expected) {
    time_t now(time(NULL));
    long long froffset(roffset + rid * max_file_size);
    long long fwoffset(woffset + wid * max_file_size);

    if (_last_time && (now != _last_time)) {
      time_t eta(0);
      {
        io::property& p(tree["file_expected_terminated_at"]);
        oss.str("");
        p.set_name("file_expected_terminated_at");

        unsigned long long
          div(froffset + _last_write_offset - _last_read_offset - fwoffset);
        if (div == 0)
          oss << "file not processed fast enough to terminate";
        else {
          eta = now + (fwoffset - froffset) * (now - _last_time) / div;
          oss << eta;
        }
        p.set_value(oss.str());
      }

      if (max_file_size == std::numeric_limits<long>::max()) {
        io::property& p(tree["file_expected_max_size"]);
        oss.str("");
        p.set_name("file_expected_max_size");
        oss << fwoffset
               + (fwoffset - _last_write_offset)
               * (eta - now)
               / (now - _last_time);

        p.set_value(oss.str());
        p.set_graphable(false);
      }
    }

    _last_time = now;
    _last_read_offset = froffset;
    _last_write_offset = fwoffset;
  }

  return ;
}

/**
 *  Write data to the file.
 *
 *  @param[in] d  Data to write.
 *
 *  @return Number of events acknowledged (1).
 */
int stream::write(misc::shared_ptr<io::data> const& d) {
  // Check that data exists.
  if (!validate(d, "file"))
    return (1);

  if (d->type() == io::raw::static_type()) {
    // Lock mutex.
    QMutexLocker lock(&_mutex);

    // Get data.
    char const* memory;
    unsigned int size;
    {
      io::raw* data(static_cast<io::raw*>(d.data()));
      memory = data->QByteArray::data();
      size = data->size();
    }

    // Write data.
    while (size > 0) {
      long wb(_file->write(memory, size));
      size -= wb;
      memory += wb;
    }
  }

  return (1);
}
<commit_msg>core: fix file percent processed in statistics.<commit_after>/*
** Copyright 2011-2017 Centreon
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
**     http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
**
** For more information : contact@centreon.com
*/

#include <cstdio>
#include <limits>
#include <QMutexLocker>
#include "com/centreon/broker/file/stream.hh"
#include "com/centreon/broker/io/raw.hh"
#include "com/centreon/broker/misc/string.hh"

using namespace com::centreon::broker;
using namespace com::centreon::broker::file;

/**************************************
*                                     *
*           Public Methods            *
*                                     *
**************************************/

/**
 *  Constructor.
 *
 *  @param[in] file  Splitted file on which the stream will operate.
 */
stream::stream(splitter* file)
  : _file(file),
    _last_read_offset(0),
    _last_time(0),
    _last_write_offset(0) {}

/**
 *  Destructor.
 */
stream::~stream() {}

/**
 *  Read data from the file.
 *
 *  @param[out] d         Bunch of data.
 *  @param[in]  deadline  Timeout.
 *
 *  @return Always true as file never times out.
 */
bool stream::read(
               misc::shared_ptr<io::data>& d,
               time_t deadline) {
  (void)deadline;

  // Lock mutex.
  d.clear();
  QMutexLocker lock(&_mutex);

  // Build data array.
  std::auto_ptr<io::raw> data(new io::raw);
  data->resize(BUFSIZ);

  // Read data.
  long rb(_file->read(data->QByteArray::data(), data->size()));
  if (rb) {
    data->resize(rb);
    d = misc::shared_ptr<io::data>(data.release());
  }

  return (true);
}

/**
 *  Generate statistics about file processing.
 *
 *  @param[out] buffer Output buffer.
 */
void stream::statistics(io::properties& tree) const {
  // Get base properties.
  long max_file_size(_file->get_max_file_size());
  int rid(_file->get_rid());
  long roffset(_file->get_roffset());
  int wid(_file->get_wid());
  long woffset(_file->get_woffset());

  // Easy to print.
  std::ostringstream oss;
  {
    tree.add_property(
           "file_read_path",
           io::property("file_read_path", misc::string::get(rid)));
  }
  {
    tree.add_property(
           "file_read_offset",
           io::property("file_read_offset", misc::string::get(roffset)));
  }
  {
    tree.add_property(
           "file_write_path",
           io::property("file_write_path", misc::string::get(wid)));
  }
  {
    tree.add_property(
           "file_write_offset",
           io::property("file_write_offset", misc::string::get(woffset)));
  }
  {
    tree.add_property(
           "file_max_size",
           io::property(
                 "file_max_size",
                 max_file_size != std::numeric_limits<long>::max()
                 ? misc::string::get(max_file_size)
                 : "unlimited"));
  }

  // Need computation.
  bool write_time_expected(false);
  long long froffset(roffset + rid * static_cast<long long>(max_file_size));
  long long fwoffset(woffset + wid * static_cast<long long>(max_file_size));
  {
    io::property& p(tree["file_percent_processed"]);
    p.set_name("file_percent_processed");
    oss.str("");
    if (((rid != wid)
         && max_file_size == std::numeric_limits<long>::max())
        || !fwoffset) {
      oss << "unknown";
    }
    else {
      oss << 100.0 * froffset / fwoffset << "%";
      write_time_expected = true;
    }
    p.set_value(oss.str());
  }
  if (write_time_expected) {
    time_t now(time(NULL));

    if (_last_time && (now != _last_time)) {
      time_t eta(0);
      {
        io::property& p(tree["file_expected_terminated_at"]);
        oss.str("");
        p.set_name("file_expected_terminated_at");

        unsigned long long
          div(froffset + _last_write_offset - _last_read_offset - fwoffset);
        if (div == 0)
          oss << "file not processed fast enough to terminate";
        else {
          eta = now + (fwoffset - froffset) * (now - _last_time) / div;
          oss << eta;
        }
        p.set_value(oss.str());
      }

      if (max_file_size == std::numeric_limits<long>::max()) {
        io::property& p(tree["file_expected_max_size"]);
        oss.str("");
        p.set_name("file_expected_max_size");
        oss << fwoffset
               + (fwoffset - _last_write_offset)
               * (eta - now)
               / (now - _last_time);

        p.set_value(oss.str());
        p.set_graphable(false);
      }
    }

    _last_time = now;
    _last_read_offset = froffset;
    _last_write_offset = fwoffset;
  }

  return ;
}

/**
 *  Write data to the file.
 *
 *  @param[in] d  Data to write.
 *
 *  @return Number of events acknowledged (1).
 */
int stream::write(misc::shared_ptr<io::data> const& d) {
  // Check that data exists.
  if (!validate(d, "file"))
    return (1);

  if (d->type() == io::raw::static_type()) {
    // Lock mutex.
    QMutexLocker lock(&_mutex);

    // Get data.
    char const* memory;
    unsigned int size;
    {
      io::raw* data(static_cast<io::raw*>(d.data()));
      memory = data->QByteArray::data();
      size = data->size();
    }

    // Write data.
    while (size > 0) {
      long wb(_file->write(memory, size));
      size -= wb;
      memory += wb;
    }
  }

  return (1);
}
<|endoftext|>