<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <OpenThreads/ScopedLock>
#include <osg/ImageSequence>
#include <osg/Notify>
#include <osg/Camera>
#include <osg/NodeVisitor>
#include <osg/Texture2D>

#include <math.h>

using namespace osg;

ImageSequence::ImageData::ImageData()
{
}

ImageSequence::ImageData::ImageData(const ImageData& id):
    _filename(id._filename),
    _image(id._image),
    _imageRequest(id._imageRequest)
{
}

ImageSequence::ImageData& ImageSequence::ImageData::operator = (const ImageSequence::ImageData& rhs)
{
    if (&rhs!=this)
    {
        _filename = rhs._filename;
        _image = rhs._image;
        _imageRequest = rhs._imageRequest;
    }
    return *this;
}

ImageSequence::ImageSequence()
{
    _referenceTime = DBL_MAX;
    _timeMultiplier = 1.0;

    _mode = PRE_LOAD_ALL_IMAGES;
    _length = 1.0;
    _timePerImage = 1.0;

    _seekTime = 0.0;
    _seekTimeSet = false;

    _previousAppliedImageIndex = -1;
}

ImageSequence::ImageSequence(const ImageSequence& is,const CopyOp& copyop):
    osg::ImageStream(is,copyop),
    _referenceTime(is._referenceTime),
    _timeMultiplier(is._timeMultiplier),
    _mode(is._mode),
    _length(is._length),
    _timePerImage(is._timePerImage)
{
    _seekTime = is._seekTime;
    _seekTimeSet = is._seekTimeSet;

    _previousAppliedImageIndex = -1;
}

int ImageSequence::compare(const Image& rhs) const
{
    return ImageStream::compare(rhs);
}

void ImageSequence::seek(double time)
{
    _seekTime = time;
    _seekTimeSet = true;
}

void ImageSequence::play()
{
    _status=PLAYING;
}

void ImageSequence::pause()
{
    _status=PAUSED;
}

void ImageSequence::rewind()
{
    seek(0.0f);
}

void ImageSequence::setMode(Mode mode)
{
    _mode = mode;
}

void ImageSequence::setLength(double length)
{
    if (length<=0.0)
    {
        OSG_NOTICE<<"ImageSequence::setLength("<<length<<") invalid length value, must be greater than 0."<<std::endl;
        return;
    }

    _length = length;
    computeTimePerImage();
}

void ImageSequence::computeTimePerImage()
{
    if (!_imageDataList.empty()) _timePerImage = _length / double(_imageDataList.size());
    else _timePerImage = _length;
}

void ImageSequence::setImageFile(unsigned int pos, const std::string& fileName)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    if (pos>=_imageDataList.size()) _imageDataList.resize(pos);
    _imageDataList[pos]._filename = fileName;
}

std::string ImageSequence::getImageFile(unsigned int pos) const
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    return pos<_imageDataList.size() ? _imageDataList[pos]._filename : std::string();
}

void ImageSequence::addImageFile(const std::string& fileName)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    _imageDataList.push_back(ImageData());
    _imageDataList.back()._filename = fileName;
    computeTimePerImage();
}

void ImageSequence::setImage(unsigned int pos, osg::Image* image)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    if (pos>=_imageDataList.size()) _imageDataList.resize(pos+1);

    _imageDataList[pos]._image = image;
    _imageDataList[pos]._filename = image->getFileName();
}

Image* ImageSequence::getImage(unsigned int pos)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    return pos<_imageDataList.size() ? _imageDataList[pos]._image.get() : 0;
}

const Image* ImageSequence::getImage(unsigned int pos) const
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    return pos<_imageDataList.size() ? _imageDataList[pos]._image.get() : 0;
}

void ImageSequence::addImage(osg::Image* image)
{
    if (image==0) return;

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    // OSG_NOTICE<<"merging image in order expected : "<<image->getFileName()<<std::endl;
    _imageDataList.push_back(ImageData());
    _imageDataList.back()._image = image;

    computeTimePerImage();

    if (data()==0)
    {
        setImageToChild(_imageDataList.size()-1);
    }
}

void ImageSequence::setImageToChild(int pos)
{

    const osg::Image* image = (pos>=0 && pos<static_cast<int>(_imageDataList.size())) ? _imageDataList[pos]._image.get() : 0;
    if (image==0) return;

    // check to see if data is changing, if not don't apply
    if (image->data() == data())
    {
        return;
    }

    if (_mode==PAGE_AND_DISCARD_USED_IMAGES && _previousAppliedImageIndex>=0)
    {
        if (_previousAppliedImageIndex<pos)
        {
            OSG_INFO<<"Moving forward from "<<_previousAppliedImageIndex<<" to "<<pos<<std::endl;
            while(_previousAppliedImageIndex<pos)
            {
                _imageDataList[_previousAppliedImageIndex]._image = 0;
                OSG_INFO<<"   deleting "<<_previousAppliedImageIndex<<std::endl;
                ++_previousAppliedImageIndex;
            }
        }
        else if (_previousAppliedImageIndex>pos)
        {
            OSG_INFO<<"Moving back from "<<_previousAppliedImageIndex<<" to "<<pos<<std::endl;
            while(_previousAppliedImageIndex>pos)
            {
                _imageDataList[_previousAppliedImageIndex]._image = 0;
                OSG_INFO<<"   deleting "<<_previousAppliedImageIndex<<std::endl;
                --_previousAppliedImageIndex;
            }
        }
    }

    _previousAppliedImageIndex = pos;

    setImage(image->s(),image->t(),image->r(),
             image->getInternalTextureFormat(),
             image->getPixelFormat(),image->getDataType(),
             const_cast<unsigned char*>(image->data()),
             osg::Image::NO_DELETE,
             image->getPacking());
}

void ImageSequence::applyLoopingMode()
{
}

int ImageSequence::imageIndex(double time)
{
    if (getLoopingMode()==LOOPING)
    {
        double positionRatio = time/_length;
        time = (positionRatio - floor(positionRatio))*_length;
    }

    if (time<0.0) return 0;
    int index = int(time/_timePerImage);
    if (index>=int(_imageDataList.size())) return int(_imageDataList.size())-1;
    return index;
}

void ImageSequence::update(osg::NodeVisitor* nv)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    osg::NodeVisitor::ImageRequestHandler* irh = nv->getImageRequestHandler();
    const osg::FrameStamp* fs = nv->getFrameStamp();

    // OSG_NOTICE<<"ImageSequence::update("<<fs<<", "<<irh<<")"<<std::endl;

    if (_referenceTime == DBL_MAX)
    {
        _referenceTime = fs->getSimulationTime();
    }

    bool looping = getLoopingMode()==LOOPING;
    double time = (fs->getSimulationTime() - _referenceTime)*_timeMultiplier;
    bool useDirectTimeRequest = _seekTimeSet;

    if (_seekTimeSet || _status==PAUSED || _status==INVALID)
    {
        time = _seekTime;
        useDirectTimeRequest = true;
        _referenceTime =  fs->getSimulationTime() - time/_timeMultiplier;
    }
    else
    {
        if (looping)
        {
            while (time>_length)
            {
                _referenceTime += _length/_timeMultiplier;
                time -= _length;
            }
        }
        else
        {
            if (time>_length)
            {
                _referenceTime = fs->getSimulationTime() - _length/_timeMultiplier;
                time = _length;
            }
        }
    }

    _seekTime = time;
    _seekTimeSet = false;

    if (irh && _mode==PRE_LOAD_ALL_IMAGES)
    {
        for(ImageDataList::iterator itr = _imageDataList.begin();
            itr != _imageDataList.end();
            ++itr)
        {
            if (!(itr->_image) && !(itr->_filename.empty()))
            {
                itr->_image = irh->readImageFile(itr->_filename);
            }
        }
    }

    int index = int(time/_timePerImage);
    // OSG_NOTICE<<"time= "<<time<<" _timePerImage="<<_timePerImage<<" index="<<index<<" _length="<<_length<<std::endl;

    if (index>=int(_imageDataList.size())) index = int(_imageDataList.size())-1;

    if (index>=0 && index<int(_imageDataList.size()))
    {
        // need to find the nearest relevant change.
        if (!_imageDataList[index]._image)
        {
            if (_previousAppliedImageIndex<index)
            {
                OSG_DEBUG<<"ImageSequence::update(..) Moving forward by "<<index-_previousAppliedImageIndex<<std::endl;
                while (index>=0 && !_imageDataList[index]._image.valid())
                {
                    --index;
                }
            }
            else if (_previousAppliedImageIndex>index)
            {
                OSG_DEBUG<<"ImageSequence::update(..) Moving back by "<<_previousAppliedImageIndex-index<<std::endl;
                while (index<static_cast<int>(_imageDataList.size()) && !_imageDataList[index]._image.valid())
                {
                    ++index;
                }
            }
        }

        if (index>=0 && index!=_previousAppliedImageIndex)
        {
            setImageToChild(index);
        }
    }

    // OSG_NOTICE<<"time = "<<time<<std::endl;

    if (!irh) return;

    if (useDirectTimeRequest)
    {
        int i = int(time/_timePerImage);
        if ((i>=int(_imageDataList.size()) || !_imageDataList[i]._image))
        {
             i = osg::clampTo<int>(i, 0, _imageDataList.size()-1);

             OSG_INFO<<"Requesting file, entry="<<i<<" : _fileNames[i]="<<_imageDataList[i]._filename<<std::endl;
             irh->requestImageFile(_imageDataList[i]._filename, this, i, time, fs, _imageDataList[i]._imageRequest, _readOptions.get());
        }
    }
    else
    {
        double preLoadTime = time + osg::minimum(irh->getPreLoadTime()*_timeMultiplier, _length);

        int startLoadIndex = int(time/_timePerImage);
        if (startLoadIndex>=int(_imageDataList.size())) startLoadIndex = int(_imageDataList.size())-1;
        if (startLoadIndex<0) startLoadIndex = 0;

        int endLoadIndex = int(preLoadTime/_timePerImage);
        if (endLoadIndex>=int(_imageDataList.size()))
        {
            if (looping)
            {
                endLoadIndex -= int(_imageDataList.size());
            }
            else
            {
                endLoadIndex = int(_imageDataList.size())-1;
            }
        }
        if (endLoadIndex<0) endLoadIndex = 0;

        double requestTime = time;

        if (endLoadIndex<startLoadIndex)
        {
            for(int i=startLoadIndex; i<int(_imageDataList.size()); ++i)
            {
                if (!_imageDataList[i]._image)
                {
                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
                }
                requestTime += _timePerImage;
            }

            for(int i=0; i<=endLoadIndex; ++i)
            {
                if (!_imageDataList[i]._image)
                {
                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
                }
                requestTime += _timePerImage;
            }
        }
        else
        {
            for(int i=startLoadIndex; i<=endLoadIndex; ++i)
            {
                if (!_imageDataList[i]._image)
                {
                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
                }
                requestTime += _timePerImage;
            }
        }

    }

}
<commit_msg>Added check to avoid doing update when the imagesequence is empty.<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * OpenSceneGraph Public License for more details.
*/

#include <OpenThreads/ScopedLock>
#include <osg/ImageSequence>
#include <osg/Notify>
#include <osg/Camera>
#include <osg/NodeVisitor>
#include <osg/Texture2D>

#include <math.h>

using namespace osg;

ImageSequence::ImageData::ImageData()
{
}

ImageSequence::ImageData::ImageData(const ImageData& id):
    _filename(id._filename),
    _image(id._image),
    _imageRequest(id._imageRequest)
{
}

ImageSequence::ImageData& ImageSequence::ImageData::operator = (const ImageSequence::ImageData& rhs)
{
    if (&rhs!=this)
    {
        _filename = rhs._filename;
        _image = rhs._image;
        _imageRequest = rhs._imageRequest;
    }
    return *this;
}

ImageSequence::ImageSequence()
{
    _referenceTime = DBL_MAX;
    _timeMultiplier = 1.0;

    _mode = PRE_LOAD_ALL_IMAGES;
    _length = 1.0;
    _timePerImage = 1.0;

    _seekTime = 0.0;
    _seekTimeSet = false;

    _previousAppliedImageIndex = -1;
}

ImageSequence::ImageSequence(const ImageSequence& is,const CopyOp& copyop):
    osg::ImageStream(is,copyop),
    _referenceTime(is._referenceTime),
    _timeMultiplier(is._timeMultiplier),
    _mode(is._mode),
    _length(is._length),
    _timePerImage(is._timePerImage)
{
    _seekTime = is._seekTime;
    _seekTimeSet = is._seekTimeSet;

    _previousAppliedImageIndex = -1;
}

int ImageSequence::compare(const Image& rhs) const
{
    return ImageStream::compare(rhs);
}

void ImageSequence::seek(double time)
{
    _seekTime = time;
    _seekTimeSet = true;
}

void ImageSequence::play()
{
    _status=PLAYING;
}

void ImageSequence::pause()
{
    _status=PAUSED;
}

void ImageSequence::rewind()
{
    seek(0.0f);
}

void ImageSequence::setMode(Mode mode)
{
    _mode = mode;
}

void ImageSequence::setLength(double length)
{
    if (length<=0.0)
    {
        OSG_NOTICE<<"ImageSequence::setLength("<<length<<") invalid length value, must be greater than 0."<<std::endl;
        return;
    }

    _length = length;
    computeTimePerImage();
}

void ImageSequence::computeTimePerImage()
{
    if (!_imageDataList.empty()) _timePerImage = _length / double(_imageDataList.size());
    else _timePerImage = _length;
}

void ImageSequence::setImageFile(unsigned int pos, const std::string& fileName)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    if (pos>=_imageDataList.size()) _imageDataList.resize(pos);
    _imageDataList[pos]._filename = fileName;
}

std::string ImageSequence::getImageFile(unsigned int pos) const
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    return pos<_imageDataList.size() ? _imageDataList[pos]._filename : std::string();
}

void ImageSequence::addImageFile(const std::string& fileName)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    _imageDataList.push_back(ImageData());
    _imageDataList.back()._filename = fileName;
    computeTimePerImage();
}

void ImageSequence::setImage(unsigned int pos, osg::Image* image)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    if (pos>=_imageDataList.size()) _imageDataList.resize(pos+1);

    _imageDataList[pos]._image = image;
    _imageDataList[pos]._filename = image->getFileName();
}

Image* ImageSequence::getImage(unsigned int pos)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    return pos<_imageDataList.size() ? _imageDataList[pos]._image.get() : 0;
}

const Image* ImageSequence::getImage(unsigned int pos) const
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
    return pos<_imageDataList.size() ? _imageDataList[pos]._image.get() : 0;
}

void ImageSequence::addImage(osg::Image* image)
{
    if (image==0) return;

    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    // OSG_NOTICE<<"merging image in order expected : "<<image->getFileName()<<std::endl;
    _imageDataList.push_back(ImageData());
    _imageDataList.back()._image = image;

    computeTimePerImage();

    if (data()==0)
    {
        setImageToChild(_imageDataList.size()-1);
    }
}

void ImageSequence::setImageToChild(int pos)
{

    const osg::Image* image = (pos>=0 && pos<static_cast<int>(_imageDataList.size())) ? _imageDataList[pos]._image.get() : 0;
    if (image==0) return;

    // check to see if data is changing, if not don't apply
    if (image->data() == data())
    {
        return;
    }

    if (_mode==PAGE_AND_DISCARD_USED_IMAGES && _previousAppliedImageIndex>=0)
    {
        if (_previousAppliedImageIndex<pos)
        {
            OSG_INFO<<"Moving forward from "<<_previousAppliedImageIndex<<" to "<<pos<<std::endl;
            while(_previousAppliedImageIndex<pos)
            {
                _imageDataList[_previousAppliedImageIndex]._image = 0;
                OSG_INFO<<"   deleting "<<_previousAppliedImageIndex<<std::endl;
                ++_previousAppliedImageIndex;
            }
        }
        else if (_previousAppliedImageIndex>pos)
        {
            OSG_INFO<<"Moving back from "<<_previousAppliedImageIndex<<" to "<<pos<<std::endl;
            while(_previousAppliedImageIndex>pos)
            {
                _imageDataList[_previousAppliedImageIndex]._image = 0;
                OSG_INFO<<"   deleting "<<_previousAppliedImageIndex<<std::endl;
                --_previousAppliedImageIndex;
            }
        }
    }

    _previousAppliedImageIndex = pos;

    setImage(image->s(),image->t(),image->r(),
             image->getInternalTextureFormat(),
             image->getPixelFormat(),image->getDataType(),
             const_cast<unsigned char*>(image->data()),
             osg::Image::NO_DELETE,
             image->getPacking());
}

void ImageSequence::applyLoopingMode()
{
}

int ImageSequence::imageIndex(double time)
{
    if (getLoopingMode()==LOOPING)
    {
        double positionRatio = time/_length;
        time = (positionRatio - floor(positionRatio))*_length;
    }

    if (time<0.0) return 0;
    int index = int(time/_timePerImage);
    if (index>=int(_imageDataList.size())) return int(_imageDataList.size())-1;
    return index;
}

void ImageSequence::update(osg::NodeVisitor* nv)
{
    OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);

    // if imageDataList is empty then there is nothing update can do.
    if (_imageDataList.empty()) return;

    osg::NodeVisitor::ImageRequestHandler* irh = nv->getImageRequestHandler();
    const osg::FrameStamp* fs = nv->getFrameStamp();

    // OSG_NOTICE<<"ImageSequence::update("<<fs<<", "<<irh<<")"<<std::endl;

    if (_referenceTime == DBL_MAX)
    {
        _referenceTime = fs->getSimulationTime();
    }

    bool looping = getLoopingMode()==LOOPING;
    double time = (fs->getSimulationTime() - _referenceTime)*_timeMultiplier;
    bool useDirectTimeRequest = _seekTimeSet;

    if (_seekTimeSet || _status==PAUSED || _status==INVALID)
    {
        time = _seekTime;
        useDirectTimeRequest = true;
        _referenceTime =  fs->getSimulationTime() - time/_timeMultiplier;
    }
    else
    {
        if (looping)
        {
            while (time>_length)
            {
                _referenceTime += _length/_timeMultiplier;
                time -= _length;
            }
        }
        else
        {
            if (time>_length)
            {
                _referenceTime = fs->getSimulationTime() - _length/_timeMultiplier;
                time = _length;
            }
        }
    }

    _seekTime = time;
    _seekTimeSet = false;

    if (irh && _mode==PRE_LOAD_ALL_IMAGES)
    {
        for(ImageDataList::iterator itr = _imageDataList.begin();
            itr != _imageDataList.end();
            ++itr)
        {
            if (!(itr->_image) && !(itr->_filename.empty()))
            {
                itr->_image = irh->readImageFile(itr->_filename);
            }
        }
    }

    int index = int(time/_timePerImage);
    // OSG_NOTICE<<"time= "<<time<<" _timePerImage="<<_timePerImage<<" index="<<index<<" _length="<<_length<<std::endl;

    if (index>=int(_imageDataList.size())) index = int(_imageDataList.size())-1;

    if (index>=0 && index<int(_imageDataList.size()))
    {
        // need to find the nearest relevant change.
        if (!_imageDataList[index]._image)
        {
            if (_previousAppliedImageIndex<index)
            {
                OSG_DEBUG<<"ImageSequence::update(..) Moving forward by "<<index-_previousAppliedImageIndex<<std::endl;
                while (index>=0 && !_imageDataList[index]._image.valid())
                {
                    --index;
                }
            }
            else if (_previousAppliedImageIndex>index)
            {
                OSG_DEBUG<<"ImageSequence::update(..) Moving back by "<<_previousAppliedImageIndex-index<<std::endl;
                while (index<static_cast<int>(_imageDataList.size()) && !_imageDataList[index]._image.valid())
                {
                    ++index;
                }
            }
        }

        if (index>=0 && index!=_previousAppliedImageIndex)
        {
            setImageToChild(index);
        }
    }

    // OSG_NOTICE<<"time = "<<time<<std::endl;

    if (!irh) return;

    if (useDirectTimeRequest)
    {
        int i = int(time/_timePerImage);
        if ((i>=int(_imageDataList.size()) || !_imageDataList[i]._image))
        {
             i = osg::clampTo<int>(i, 0, _imageDataList.size()-1);

             OSG_INFO<<"Requesting file, entry="<<i<<" : _fileNames[i]="<<_imageDataList[i]._filename<<std::endl;
             irh->requestImageFile(_imageDataList[i]._filename, this, i, time, fs, _imageDataList[i]._imageRequest, _readOptions.get());
        }
    }
    else
    {
        double preLoadTime = time + osg::minimum(irh->getPreLoadTime()*_timeMultiplier, _length);

        int startLoadIndex = int(time/_timePerImage);
        if (startLoadIndex>=int(_imageDataList.size())) startLoadIndex = int(_imageDataList.size())-1;
        if (startLoadIndex<0) startLoadIndex = 0;

        int endLoadIndex = int(preLoadTime/_timePerImage);
        if (endLoadIndex>=int(_imageDataList.size()))
        {
            if (looping)
            {
                endLoadIndex -= int(_imageDataList.size());
            }
            else
            {
                endLoadIndex = int(_imageDataList.size())-1;
            }
        }
        if (endLoadIndex<0) endLoadIndex = 0;

        double requestTime = time;

        if (endLoadIndex<startLoadIndex)
        {
            for(int i=startLoadIndex; i<int(_imageDataList.size()); ++i)
            {
                if (!_imageDataList[i]._image)
                {
                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
                }
                requestTime += _timePerImage;
            }

            for(int i=0; i<=endLoadIndex; ++i)
            {
                if (!_imageDataList[i]._image)
                {
                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
                }
                requestTime += _timePerImage;
            }
        }
        else
        {
            for(int i=startLoadIndex; i<=endLoadIndex; ++i)
            {
                if (!_imageDataList[i]._image)
                {
                    irh->requestImageFile(_imageDataList[i]._filename, this, i, requestTime, fs, _imageDataList[i]._imageRequest, _readOptions.get());
                }
                requestTime += _timePerImage;
            }
        }

    }

}
<|endoftext|>


<commit_before>// Author: Jingyue
//
// Checks whether a specified call graph is sound by comparing it with another
// call graph generated on DynamicAliasAnalysis

#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"

#include "common/typedefs.h"

#include "dyn-aa/DynamicAliasAnalysis.h"

using namespace llvm;
using namespace rcs;
using namespace dyn_aa;

namespace dyn_aa {
struct AliasAnalysisChecker: public ModulePass {
  static char ID;

  AliasAnalysisChecker(): ModulePass(ID) {}
  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  virtual bool runOnModule(Module &M);

 private:
  static void PrintValue(raw_ostream &O, const Value *V);
};
}

static RegisterPass<AliasAnalysisChecker> X(
    "check-aa",
    "Check whether the alias analysis is sound",
    false, // Is CFG Only?
    true); // Is Analysis?

char AliasAnalysisChecker::ID = 0;

void AliasAnalysisChecker::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  // Note that DynamicAliasAnalysis is not registered to the
  // AliasAnalysis group.
  AU.addRequired<DynamicAliasAnalysis>();
  AU.addRequired<AliasAnalysis>();
}

bool AliasAnalysisChecker::runOnModule(Module &M) {
  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
  AliasAnalysis &DAA = getAnalysis<DynamicAliasAnalysis>();

  // We don't want to include all pointers yet.
  // For now, we include all pointers used as a pointer operand of
  // a Load/Store instruction.
  ValueSet PointerOperands;
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
      for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
        if (StoreInst *SI = dyn_cast<StoreInst>(Ins))
          PointerOperands.insert(SI->getPointerOperand());
        if (LoadInst *LI = dyn_cast<LoadInst>(Ins))
          PointerOperands.insert(LI->getPointerOperand());
      }
    }
  }
  errs() << "# of pointer operands to process = "
      << PointerOperands.size() << "\n";

  unsigned NumMissingAliases = 0;
  for (ValueSet::iterator I = PointerOperands.begin();
       I != PointerOperands.end(); ++I) {
    Value *V1 = *I;
    ValueSet::iterator J = I;
    for (++J; J != PointerOperands.end(); ++J) {
      Value *V2 = *J;
      if (AA.alias(V1, V2) == AliasAnalysis::NoAlias &&
          DAA.alias(V1, V2) != AliasAnalysis::NoAlias) {
        ++NumMissingAliases;
        errs().changeColor(raw_ostream::RED);
        errs() << "Missing alias:\n";
        errs().resetColor();
        PrintValue(errs(), V1); errs() << "\n";
        PrintValue(errs(), V2); errs() << "\n";
      }
    }
  }

  if (NumMissingAliases == 0) {
    errs().changeColor(raw_ostream::GREEN, true);
    errs() << "Congrats! You passed all the tests.\n";
    errs().resetColor();
  } else {
    errs().changeColor(raw_ostream::RED, true);
    errs() << "Detected " << NumMissingAliases << " missing aliases.\n";
    errs().resetColor();
  }

  return false;
}

void AliasAnalysisChecker::PrintValue(raw_ostream &O, const Value *V) {
  if (isa<Function>(V)) {
    O << V->getName();
  } else if (const Argument *Arg = dyn_cast<Argument>(V)) {
    O << Arg->getParent()->getName() << ":  " << *Arg;
  } else if (const Instruction *Ins = dyn_cast<Instruction>(V)) {
    O << Ins->getParent()->getParent()->getName();
    O << "." << Ins->getParent()->getName() << ":";
    O << *Ins;
  } else {
    O << *V;
  }
}
<commit_msg>New features:<commit_after>// Author: Jingyue
//
// Checks whether a specified call graph is sound by comparing it with another
// call graph generated on DynamicAliasAnalysis

#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"

#include "common/typedefs.h"

#include "dyn-aa/DynamicAliasAnalysis.h"

using namespace llvm;
using namespace rcs;
using namespace dyn_aa;

namespace dyn_aa {
struct AliasAnalysisChecker: public ModulePass {
  static char ID;

  AliasAnalysisChecker(): ModulePass(ID) {}
  virtual void getAnalysisUsage(AnalysisUsage &AU) const;
  virtual bool runOnModule(Module &M);

 private:
  static void PrintValue(raw_ostream &O, const Value *V);
  static bool isIntraProcQuery(const Value *V1, const Value *V2);
  static const Function *getContainingFunction(const Value *V);
};
}

static cl::opt<bool> IntraProc(
    "intra",
    cl::desc("Whether the checked AA supports intra-procedural queries only"));

static RegisterPass<AliasAnalysisChecker> X(
    "check-aa",
    "Check whether the alias analysis is sound",
    false, // Is CFG Only?
    true); // Is Analysis?

char AliasAnalysisChecker::ID = 0;

void AliasAnalysisChecker::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.setPreservesAll();
  // Note that DynamicAliasAnalysis is not registered to the
  // AliasAnalysis group.
  AU.addRequired<DynamicAliasAnalysis>();
  AU.addRequired<AliasAnalysis>();
}

bool AliasAnalysisChecker::runOnModule(Module &M) {
  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
  AliasAnalysis &DAA = getAnalysis<DynamicAliasAnalysis>();

  // We don't want to include all pointers yet.
  // For now, we include all pointers used as a pointer operand of
  // a Load/Store instruction.
  ValueSet PointerOperands;
  for (Module::iterator F = M.begin(); F != M.end(); ++F) {
    for (Function::iterator BB = F->begin(); BB != F->end(); ++BB) {
      for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) {
        if (StoreInst *SI = dyn_cast<StoreInst>(Ins))
          PointerOperands.insert(SI->getPointerOperand());
        if (LoadInst *LI = dyn_cast<LoadInst>(Ins))
          PointerOperands.insert(LI->getPointerOperand());
      }
    }
  }
  errs() << "# of pointer operands to process = "
      << PointerOperands.size() << "\n";

  unsigned NumMissingAliases = 0;
  for (ValueSet::iterator I = PointerOperands.begin();
       I != PointerOperands.end(); ++I) {
    Value *V1 = *I;
    ValueSet::iterator J = I;
    for (++J; J != PointerOperands.end(); ++J) {
      Value *V2 = *J;
      // If the checked AA supports only intra-procedural queries,
      // and V1 and V2 belong to different functions, skip this query.
      if (IntraProc && !isIntraProcQuery(V1, V2))
        continue;
      if (AA.alias(V1, V2) == AliasAnalysis::NoAlias &&
          DAA.alias(V1, V2) != AliasAnalysis::NoAlias) {
        ++NumMissingAliases;
        errs().changeColor(raw_ostream::RED);
        errs() << "Missing alias:\n";
        errs().resetColor();
        PrintValue(errs(), V1); errs() << "\n";
        PrintValue(errs(), V2); errs() << "\n";
      }
    }
  }

  if (NumMissingAliases == 0) {
    errs().changeColor(raw_ostream::GREEN, true);
    errs() << "Congrats! You passed all the tests.\n";
    errs().resetColor();
  } else {
    errs().changeColor(raw_ostream::RED, true);
    errs() << "Detected " << NumMissingAliases << " missing aliases.\n";
    errs().resetColor();
  }

  return false;
}

void AliasAnalysisChecker::PrintValue(raw_ostream &O, const Value *V) {
  if (isa<Function>(V)) {
    O << V->getName();
  } else if (const Argument *Arg = dyn_cast<Argument>(V)) {
    O << Arg->getParent()->getName() << ":  " << *Arg;
  } else if (const Instruction *Ins = dyn_cast<Instruction>(V)) {
    O << Ins->getParent()->getParent()->getName();
    O << "." << Ins->getParent()->getName() << ":";
    O << *Ins;
  } else {
    O << *V;
  }
}

bool AliasAnalysisChecker::isIntraProcQuery(const Value *V1, const Value *V2) {
  assert(V1->getType()->isPointerTy() && V2->getType()->isPointerTy());
  const Function *F1 = getContainingFunction(V1);
  const Function *F2 = getContainingFunction(V2);
  return F1 == NULL || F2 == NULL || F1 == F2;
}

const Function *AliasAnalysisChecker::getContainingFunction(const Value *V) {
  if (const Instruction *Ins = dyn_cast<Instruction>(V))
    return Ins->getParent()->getParent();
  if (const Argument *Arg = dyn_cast<Argument>(V))
    return Arg->getParent();
  return NULL;
}
<|endoftext|>


<commit_before>80669d9c-4b02-11e5-97d0-28cfe9171a43<commit_msg>Did a thing<commit_after>8072c8ba-4b02-11e5-8b0f-28cfe9171a43<|endoftext|>


<commit_before>9c0e4c14-4b02-11e5-be6c-28cfe9171a43<commit_msg>Tuesday, turns out it was tuesday<commit_after>9c19bc35-4b02-11e5-b8e2-28cfe9171a43<|endoftext|>


<commit_before>#include "../include/string.h"

#include <algorithm>

using std::string;

string myto_string(long long a) {
	string w;
	bool minus = false;
	if (a < 0) {
		minus = true;
		a = -a;
	}
	while (a > 0) {
		w += static_cast<char>(a % 10 + '0');
		a /= 10;
	}
	if (minus)
		w += "-";
	if (w.empty())
		w = "0";
	else
		std::reverse(w.begin(), w.end());
return w;
}

string myto_string(size_t a) {
	string w;
	while (a > 0) {
		w += static_cast<char>(a % 10 + '0');
		a /= 10;
	}
	if (w.empty())
		w = "0";
	else
		std::reverse(w.begin(), w.end());
return w;
}

size_t strtosize_t(const string& s) {
	size_t res = 0;
	for (size_t i = 0; i < s.size(); ++i)
		res = res * 10 + s[i] - '0';
	return res;
}

int strtosize_t(size_t& x, const string& s, size_t beg, size_t end) {
	if (end > s.size())
		end = s.size();
	if (beg > end)
		beg = end;

	x = 0;
	for (size_t i = beg; i < end; ++i) {
		if (isdigit(s[i]))
			x = x * 10 + s[i] - '0';
		else
			return -1;
	}
	return end - beg;
}

int strtonum(string& x, const string& s, size_t beg, size_t end) {
	if (end > s.size())
		end = s.size();
	if (beg > end)
		beg = end;

	for (size_t i = beg; i < end; ++i)
		if (!isdigit(s[i]))
			return -1;
	s.substr(beg, end - beg).swap(x);
	return end - beg;
}

size_t find(const string& str, char c, size_t beg, size_t end) {
	if (end > str.size())
		end = str.size();
	for (; beg < end; ++beg)
		if (str[beg] == c)
			return beg;
	return string::npos;
}

string encodeURI(const string& str, size_t beg, size_t end) {
	// a-z A-Z 0-9 - _ . ~
	static bool is_safe[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
		0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1};
	if (end > str.size())
		end = str.size();
	string ret;
	for (; beg < end; ++beg) {
		unsigned char c = str[beg];
		if (is_safe[c])
			ret += c;
		else {
			ret += '%';
			ret += dectohex(c >> 4);
			ret += dectohex(c & 15);
		}
	}
	return ret;
}

string decodeURI(const string& str, size_t beg, size_t end) {
	if (end > str.size())
		end = str.size();
	string ret;
	for (; beg < end; ++beg) {
		if (str[beg] == '%' && beg + 2 < end) {
			ret += static_cast<char>((hextodec(str[beg+1]) << 4) + hextodec(str[beg+2]));
			beg += 2;
		} else if (str[beg] == '+')
			ret += ' ';
		else
			ret += str[beg];
	}
	return ret;
}

string tolower(string str) {
	for (size_t i = 0, s = str.size(); i < s; ++i)
		str[i] = tolower(str[i]);
	return str;
}

string abspath(const string& path, size_t beg, size_t end, string root) {
	if (end > path.size())
		end = path.size();
	while (beg < end) {
		while (beg < end && path[beg] == '/')
			++beg;
		size_t next_slash = std::min(end, find(path, '/', beg, end));
		// If [beg, next_slash) == ("." or "..")
		if ((next_slash - beg == 1 && path[beg] == '.') ||
				(next_slash - beg == 2 && path[beg] == '.' &&
				path[beg + 1] == '.')) {
			beg = next_slash;
			continue;
		}
		if (*--root.end() != '/')
			root += '/';
		root.append(path, beg, next_slash - beg);
		beg = next_slash;
	}
	return root;
}

string htmlSpecialChars(const string& s) {
	string res;
	for (size_t i = 0; i < s.size(); ++i)
		switch (s[i]) {
			case '&': res += "&";
			case '"': res += """;
			case '\'': res += "'";
			case '<': res += "<";
			case '>': res += ">";
			default: res += s[i];
		}
	return res;
}
<commit_msg>Fix bug in htmlSpecialChars, improve forms (CSS, add FormValidator)<commit_after>#include "../include/string.h"
#include "../include/debug.h"

#include <algorithm>

using std::string;

string myto_string(long long a) {
	string w;
	bool minus = false;
	if (a < 0) {
		minus = true;
		a = -a;
	}
	while (a > 0) {
		w += static_cast<char>(a % 10 + '0');
		a /= 10;
	}
	if (minus)
		w += "-";
	if (w.empty())
		w = "0";
	else
		std::reverse(w.begin(), w.end());
return w;
}

string myto_string(size_t a) {
	string w;
	while (a > 0) {
		w += static_cast<char>(a % 10 + '0');
		a /= 10;
	}
	if (w.empty())
		w = "0";
	else
		std::reverse(w.begin(), w.end());
return w;
}

size_t strtosize_t(const string& s) {
	size_t res = 0;
	for (size_t i = 0; i < s.size(); ++i)
		res = res * 10 + s[i] - '0';
	return res;
}

int strtosize_t(size_t& x, const string& s, size_t beg, size_t end) {
	if (end > s.size())
		end = s.size();
	if (beg > end)
		beg = end;

	x = 0;
	for (size_t i = beg; i < end; ++i) {
		if (isdigit(s[i]))
			x = x * 10 + s[i] - '0';
		else
			return -1;
	}
	return end - beg;
}

int strtonum(string& x, const string& s, size_t beg, size_t end) {
	if (end > s.size())
		end = s.size();
	if (beg > end)
		beg = end;

	for (size_t i = beg; i < end; ++i)
		if (!isdigit(s[i]))
			return -1;
	s.substr(beg, end - beg).swap(x);
	return end - beg;
}

size_t find(const string& str, char c, size_t beg, size_t end) {
	if (end > str.size())
		end = str.size();
	for (; beg < end; ++beg)
		if (str[beg] == c)
			return beg;
	return string::npos;
}

string encodeURI(const string& str, size_t beg, size_t end) {
	// a-z A-Z 0-9 - _ . ~
	static bool is_safe[256] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
		0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0,
		0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
		1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1};
	if (end > str.size())
		end = str.size();
	string ret;
	for (; beg < end; ++beg) {
		unsigned char c = str[beg];
		if (is_safe[c])
			ret += c;
		else {
			ret += '%';
			ret += dectohex(c >> 4);
			ret += dectohex(c & 15);
		}
	}
	return ret;
}

string decodeURI(const string& str, size_t beg, size_t end) {
	if (end > str.size())
		end = str.size();
	string ret;
	for (; beg < end; ++beg) {
		if (str[beg] == '%' && beg + 2 < end) {
			ret += static_cast<char>((hextodec(str[beg+1]) << 4) + hextodec(str[beg+2]));
			beg += 2;
		} else if (str[beg] == '+')
			ret += ' ';
		else
			ret += str[beg];
	}
	return ret;
}

string tolower(string str) {
	for (size_t i = 0, s = str.size(); i < s; ++i)
		str[i] = tolower(str[i]);
	return str;
}

string abspath(const string& path, size_t beg, size_t end, string root) {
	if (end > path.size())
		end = path.size();
	while (beg < end) {
		while (beg < end && path[beg] == '/')
			++beg;
		size_t next_slash = std::min(end, find(path, '/', beg, end));
		// If [beg, next_slash) == ("." or "..")
		if ((next_slash - beg == 1 && path[beg] == '.') ||
				(next_slash - beg == 2 && path[beg] == '.' &&
				path[beg + 1] == '.')) {
			beg = next_slash;
			continue;
		}
		if (*--root.end() != '/')
			root += '/';
		root.append(path, beg, next_slash - beg);
		beg = next_slash;
	}
	return root;
}

string htmlSpecialChars(const string& s) {
	string res;
	for (size_t i = 0; i < s.size(); ++i)
		switch (s[i]) {
			case '&': res += "&"; break;
			case '"': res += """; break;
			case '\'': res += "'"; break;
			case '<': res += "<"; break;
			case '>': res += ">"; break;
			default: res += s[i];
		}
	return res;
}
<|endoftext|>


<commit_before>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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.
==============================================================================*/

#include <vector>

#include "tensorflow/core/util/command_line_flags.h"
#include "tensorflow/lite/testing/kernel_test/diff_analyzer.h"

int main(int argc, char** argv) {
  std::string base, test, output;
  std::vector<tensorflow::Flag> flag_list = {
      tensorflow::Flag("base", &base, "Path to the base serialized tensor."),
      tensorflow::Flag("test", &test, "Path to the test serialized tensor."),
      tensorflow::Flag("output", &output, "Path to the output file."),
  };
  tensorflow::Flags::Parse(&argc, argv, flag_list);

  tflite::testing::DiffAnalyzer diff_analyzer;
  diff_analyzer.ReadFiles(base, test);
  diff_analyzer.WriteReport(output);
  return 0;
}
<commit_msg>Update generate_diff_report.cc<commit_after>/* Copyright 2019 The TensorFlow Authors. All Rights Reserved.

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.
==============================================================================*/
#include <string>
#include <vector>

#include "tensorflow/core/util/command_line_flags.h"
#include "tensorflow/lite/testing/kernel_test/diff_analyzer.h"

int main(int argc, char** argv) {
  std::string base, test, output;
  std::vector<tensorflow::Flag> flag_list = {
      tensorflow::Flag("base", &base, "Path to the base serialized tensor."),
      tensorflow::Flag("test", &test, "Path to the test serialized tensor."),
      tensorflow::Flag("output", &output, "Path to the output file."),
  };
  tensorflow::Flags::Parse(&argc, argv, flag_list);

  tflite::testing::DiffAnalyzer diff_analyzer;
  diff_analyzer.ReadFiles(base, test);
  diff_analyzer.WriteReport(output);
  return 0;
}
<|endoftext|>


<commit_before>b3056833-ad5a-11e7-94b1-ac87a332f658<commit_msg>That didn't fix it<commit_after>b385f11e-ad5a-11e7-883d-ac87a332f658<|endoftext|>


<commit_before>bcdffb07-4b02-11e5-a7b5-28cfe9171a43<commit_msg>My Life for Auir<commit_after>bcec00b8-4b02-11e5-9b61-28cfe9171a43<|endoftext|>


<commit_before>//===-- WebAssemblyRegColoring.cpp - Register coloring --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a virtual register coloring pass.
///
/// WebAssembly doesn't have a fixed number of registers, but it is still
/// desirable to minimize the total number of registers used in each function.
///
/// This code is modeled after lib/CodeGen/StackSlotColoring.cpp.
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-reg-coloring"

namespace {
class WebAssemblyRegColoring final : public MachineFunctionPass {
public:
  static char ID; // Pass identification, replacement for typeid
  WebAssemblyRegColoring() : MachineFunctionPass(ID) {}

  const char *getPassName() const override {
    return "WebAssembly Register Coloring";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    AU.addRequired<LiveIntervals>();
    AU.addRequired<MachineBlockFrequencyInfo>();
    AU.addPreserved<MachineBlockFrequencyInfo>();
    AU.addPreservedID(MachineDominatorsID);
    AU.addRequired<SlotIndexes>(); // for ARGUMENT fixups
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  bool runOnMachineFunction(MachineFunction &MF) override;

private:
};
} // end anonymous namespace

char WebAssemblyRegColoring::ID = 0;
FunctionPass *llvm::createWebAssemblyRegColoring() {
  return new WebAssemblyRegColoring();
}

// Compute the total spill weight for VReg.
static float computeWeight(const MachineRegisterInfo *MRI,
                           const MachineBlockFrequencyInfo *MBFI,
                           unsigned VReg) {
  float weight = 0.0f;
  for (MachineOperand &MO : MRI->reg_nodbg_operands(VReg))
    weight += LiveIntervals::getSpillWeight(MO.isDef(), MO.isUse(), MBFI,
                                            MO.getParent());
  return weight;
}

bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
  DEBUG({
    dbgs() << "********** Register Coloring **********\n"
           << "********** Function: " << MF.getName() << '\n';
  });

  // If there are calls to setjmp or sigsetjmp, don't perform coloring. Virtual
  // registers could be modified before the longjmp is executed, resulting in
  // the wrong value being used afterwards. (See <rdar://problem/8007500>.)
  // TODO: Does WebAssembly need to care about setjmp for register coloring?
  if (MF.exposesReturnsTwice())
    return false;

  MachineRegisterInfo *MRI = &MF.getRegInfo();
  LiveIntervals *Liveness = &getAnalysis<LiveIntervals>();
  const MachineBlockFrequencyInfo *MBFI =
      &getAnalysis<MachineBlockFrequencyInfo>();
  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();

  // Gather all register intervals into a list and sort them.
  unsigned NumVRegs = MRI->getNumVirtRegs();
  SmallVector<LiveInterval *, 0> SortedIntervals;
  SortedIntervals.reserve(NumVRegs);

  // FIXME: If scheduling has moved an ARGUMENT virtual register, move it back,
  // and recompute liveness. This is a temporary hack.
  bool SawNonArg = false;
  bool MovedArg = false;
  MachineBasicBlock &EntryMBB = MF.front();
  for (auto MII = EntryMBB.begin(); MII != EntryMBB.end(); ) {
    MachineInstr *MI = &*MII++;
    if (MI->getOpcode() == WebAssembly::ARGUMENT_I32 ||
        MI->getOpcode() == WebAssembly::ARGUMENT_I64 ||
        MI->getOpcode() == WebAssembly::ARGUMENT_F32 ||
        MI->getOpcode() == WebAssembly::ARGUMENT_F64) {
      EntryMBB.insert(EntryMBB.begin(), MI->removeFromParent());
      if (SawNonArg)
        MovedArg = true;
    } else {
      SawNonArg = true;
    }
  }
  if (MovedArg) {
    SlotIndexes &Slots = getAnalysis<SlotIndexes>();
    Liveness->releaseMemory();
    Slots.releaseMemory();
    Slots.runOnMachineFunction(MF);
    Liveness->runOnMachineFunction(MF);
  }

  DEBUG(dbgs() << "Interesting register intervals:\n");
  for (unsigned i = 0; i < NumVRegs; ++i) {
    unsigned VReg = TargetRegisterInfo::index2VirtReg(i);
    if (MFI.isVRegStackified(VReg))
      continue;

    LiveInterval *LI = &Liveness->getInterval(VReg);
    assert(LI->weight == 0.0f);
    LI->weight = computeWeight(MRI, MBFI, VReg);
    DEBUG(LI->dump());
    SortedIntervals.push_back(LI);
  }
  DEBUG(dbgs() << '\n');

  // Sort them to put arguments first (since we don't want to rename live-in
  // registers), by weight next, and then by position.
  // TODO: Investigate more intelligent sorting heuristics. For starters, we
  // should try to coalesce adjacent live intervals before non-adjacent ones.
  std::sort(SortedIntervals.begin(), SortedIntervals.end(),
            [MRI](LiveInterval *LHS, LiveInterval *RHS) {
              if (MRI->isLiveIn(LHS->reg) != MRI->isLiveIn(RHS->reg))
                return MRI->isLiveIn(LHS->reg);
              if (LHS->weight != RHS->weight)
                return LHS->weight > RHS->weight;
              if (LHS->empty() || RHS->empty())
                return !LHS->empty() && RHS->empty();
              return *LHS < *RHS;
            });

  DEBUG(dbgs() << "Coloring register intervals:\n");
  SmallVector<unsigned, 16> SlotMapping(SortedIntervals.size(), -1u);
  SmallVector<SmallVector<LiveInterval *, 4>, 16> Assignments(
      SortedIntervals.size());
  BitVector UsedColors(SortedIntervals.size());
  bool Changed = false;
  for (size_t i = 0, e = SortedIntervals.size(); i < e; ++i) {
    LiveInterval *LI = SortedIntervals[i];
    unsigned Old = LI->reg;
    size_t Color = i;
    const TargetRegisterClass *RC = MRI->getRegClass(Old);

    // Check if it's possible to reuse any of the used colors.
    if (!MRI->isLiveIn(Old))
      for (int C(UsedColors.find_first()); C != -1;
           C = UsedColors.find_next(C)) {
        if (MRI->getRegClass(SortedIntervals[C]->reg) != RC)
          continue;
        for (LiveInterval *OtherLI : Assignments[C])
          if (!OtherLI->empty() && OtherLI->overlaps(*LI))
            goto continue_outer;
        Color = C;
        break;
      continue_outer:;
      }

    unsigned New = SortedIntervals[Color]->reg;
    SlotMapping[i] = New;
    Changed |= Old != New;
    UsedColors.set(Color);
    Assignments[Color].push_back(LI);
    DEBUG(dbgs() << "Assigning vreg"
                 << TargetRegisterInfo::virtReg2Index(LI->reg) << " to vreg"
                 << TargetRegisterInfo::virtReg2Index(New) << "\n");
  }
  if (!Changed)
    return false;

  // Rewrite register operands.
  for (size_t i = 0, e = SortedIntervals.size(); i < e; ++i) {
    unsigned Old = SortedIntervals[i]->reg;
    unsigned New = SlotMapping[i];
    if (Old != New)
      MRI->replaceRegWith(Old, New);
  }
  return true;
}
<commit_msg>Split the argument unscheduling loop in the WebAssembly register coloring pass. Turn the logic into "look for an insert point and then move things past the insert point".<commit_after>//===-- WebAssemblyRegColoring.cpp - Register coloring --------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief This file implements a virtual register coloring pass.
///
/// WebAssembly doesn't have a fixed number of registers, but it is still
/// desirable to minimize the total number of registers used in each function.
///
/// This code is modeled after lib/CodeGen/StackSlotColoring.cpp.
///
//===----------------------------------------------------------------------===//

#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h" // for WebAssembly::ARGUMENT_*
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
#include "llvm/CodeGen/MachineBlockFrequencyInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "wasm-reg-coloring"

namespace {
class WebAssemblyRegColoring final : public MachineFunctionPass {
public:
  static char ID; // Pass identification, replacement for typeid
  WebAssemblyRegColoring() : MachineFunctionPass(ID) {}

  const char *getPassName() const override {
    return "WebAssembly Register Coloring";
  }

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesCFG();
    AU.addRequired<LiveIntervals>();
    AU.addRequired<MachineBlockFrequencyInfo>();
    AU.addPreserved<MachineBlockFrequencyInfo>();
    AU.addPreservedID(MachineDominatorsID);
    AU.addRequired<SlotIndexes>(); // for ARGUMENT fixups
    MachineFunctionPass::getAnalysisUsage(AU);
  }

  bool runOnMachineFunction(MachineFunction &MF) override;

private:
};
} // end anonymous namespace

char WebAssemblyRegColoring::ID = 0;
FunctionPass *llvm::createWebAssemblyRegColoring() {
  return new WebAssemblyRegColoring();
}

// Compute the total spill weight for VReg.
static float computeWeight(const MachineRegisterInfo *MRI,
                           const MachineBlockFrequencyInfo *MBFI,
                           unsigned VReg) {
  float weight = 0.0f;
  for (MachineOperand &MO : MRI->reg_nodbg_operands(VReg))
    weight += LiveIntervals::getSpillWeight(MO.isDef(), MO.isUse(), MBFI,
                                            MO.getParent());
  return weight;
}

bool WebAssemblyRegColoring::runOnMachineFunction(MachineFunction &MF) {
  DEBUG({
    dbgs() << "********** Register Coloring **********\n"
           << "********** Function: " << MF.getName() << '\n';
  });

  // If there are calls to setjmp or sigsetjmp, don't perform coloring. Virtual
  // registers could be modified before the longjmp is executed, resulting in
  // the wrong value being used afterwards. (See <rdar://problem/8007500>.)
  // TODO: Does WebAssembly need to care about setjmp for register coloring?
  if (MF.exposesReturnsTwice())
    return false;

  MachineRegisterInfo *MRI = &MF.getRegInfo();
  LiveIntervals *Liveness = &getAnalysis<LiveIntervals>();
  const MachineBlockFrequencyInfo *MBFI =
      &getAnalysis<MachineBlockFrequencyInfo>();
  WebAssemblyFunctionInfo &MFI = *MF.getInfo<WebAssemblyFunctionInfo>();

  // Gather all register intervals into a list and sort them.
  unsigned NumVRegs = MRI->getNumVirtRegs();
  SmallVector<LiveInterval *, 0> SortedIntervals;
  SortedIntervals.reserve(NumVRegs);

  // FIXME: If scheduling has moved an ARGUMENT virtual register, move it back,
  // and recompute liveness. This is a temporary hack.
  bool MovedArg = false;
  MachineBasicBlock &EntryMBB = MF.front();
  MachineBasicBlock::iterator InsertPt = EntryMBB.end();
  // Look for the first NonArg instruction.
  for (auto MII = EntryMBB.begin(), MIE = EntryMBB.end(); MII != MIE; ++MII) {
    MachineInstr *MI = MII;
    if (MI->getOpcode() != WebAssembly::ARGUMENT_I32 &&
        MI->getOpcode() != WebAssembly::ARGUMENT_I64 &&
        MI->getOpcode() != WebAssembly::ARGUMENT_F32 &&
        MI->getOpcode() != WebAssembly::ARGUMENT_F64) {
      InsertPt = MII;
      break;
    }
  }
  // Now move any argument instructions later in the block
  // to before our first NonArg instruction.
  for (auto I = InsertPt, E = EntryMBB.end(); I != E; ++I) {
    MachineInstr *MI = I;
    if (MI->getOpcode() == WebAssembly::ARGUMENT_I32 ||
        MI->getOpcode() == WebAssembly::ARGUMENT_I64 ||
        MI->getOpcode() == WebAssembly::ARGUMENT_F32 ||
        MI->getOpcode() == WebAssembly::ARGUMENT_F64) {
      EntryMBB.insert(InsertPt, MI->removeFromParent());
      MovedArg = true;
    }
  }
  if (MovedArg) {
    SlotIndexes &Slots = getAnalysis<SlotIndexes>();
    Liveness->releaseMemory();
    Slots.releaseMemory();
    Slots.runOnMachineFunction(MF);
    Liveness->runOnMachineFunction(MF);
  }

  DEBUG(dbgs() << "Interesting register intervals:\n");
  for (unsigned i = 0; i < NumVRegs; ++i) {
    unsigned VReg = TargetRegisterInfo::index2VirtReg(i);
    if (MFI.isVRegStackified(VReg))
      continue;

    LiveInterval *LI = &Liveness->getInterval(VReg);
    assert(LI->weight == 0.0f);
    LI->weight = computeWeight(MRI, MBFI, VReg);
    DEBUG(LI->dump());
    SortedIntervals.push_back(LI);
  }
  DEBUG(dbgs() << '\n');

  // Sort them to put arguments first (since we don't want to rename live-in
  // registers), by weight next, and then by position.
  // TODO: Investigate more intelligent sorting heuristics. For starters, we
  // should try to coalesce adjacent live intervals before non-adjacent ones.
  std::sort(SortedIntervals.begin(), SortedIntervals.end(),
            [MRI](LiveInterval *LHS, LiveInterval *RHS) {
              if (MRI->isLiveIn(LHS->reg) != MRI->isLiveIn(RHS->reg))
                return MRI->isLiveIn(LHS->reg);
              if (LHS->weight != RHS->weight)
                return LHS->weight > RHS->weight;
              if (LHS->empty() || RHS->empty())
                return !LHS->empty() && RHS->empty();
              return *LHS < *RHS;
            });

  DEBUG(dbgs() << "Coloring register intervals:\n");
  SmallVector<unsigned, 16> SlotMapping(SortedIntervals.size(), -1u);
  SmallVector<SmallVector<LiveInterval *, 4>, 16> Assignments(
      SortedIntervals.size());
  BitVector UsedColors(SortedIntervals.size());
  bool Changed = false;
  for (size_t i = 0, e = SortedIntervals.size(); i < e; ++i) {
    LiveInterval *LI = SortedIntervals[i];
    unsigned Old = LI->reg;
    size_t Color = i;
    const TargetRegisterClass *RC = MRI->getRegClass(Old);

    // Check if it's possible to reuse any of the used colors.
    if (!MRI->isLiveIn(Old))
      for (int C(UsedColors.find_first()); C != -1;
           C = UsedColors.find_next(C)) {
        if (MRI->getRegClass(SortedIntervals[C]->reg) != RC)
          continue;
        for (LiveInterval *OtherLI : Assignments[C])
          if (!OtherLI->empty() && OtherLI->overlaps(*LI))
            goto continue_outer;
        Color = C;
        break;
      continue_outer:;
      }

    unsigned New = SortedIntervals[Color]->reg;
    SlotMapping[i] = New;
    Changed |= Old != New;
    UsedColors.set(Color);
    Assignments[Color].push_back(LI);
    DEBUG(dbgs() << "Assigning vreg"
                 << TargetRegisterInfo::virtReg2Index(LI->reg) << " to vreg"
                 << TargetRegisterInfo::virtReg2Index(New) << "\n");
  }
  if (!Changed)
    return false;

  // Rewrite register operands.
  for (size_t i = 0, e = SortedIntervals.size(); i < e; ++i) {
    unsigned Old = SortedIntervals[i]->reg;
    unsigned New = SlotMapping[i];
    if (Old != New)
      MRI->replaceRegWith(Old, New);
  }
  return true;
}
<|endoftext|>


<commit_before>
#include "Globals.h"
#include "ItemHandler.h"
#include "../Item.h"
#include "../World.h"
#include "../Player.h"

//Handler
#include "ItemCloth.h"
#include "ItemHoe.h"
#include "ItemSlab.h"
#include "ItemWood.h"
#include "ItemShears.h"
#include "ItemLeaves.h"
#include "ItemSapling.h"
#include "ItemBucket.h"
#include "ItemLighter.h"
#include "ItemRedstoneDust.h"
#include "ItemRedstoneRepeater.h"
#include "ItemSeeds.h"
#include "ItemDye.h"
#include "ItemSugarcane.h"
#include "ItemPickaxe.h"
#include "ItemShovel.h"
#include "ItemSword.h"
#include "ItemDoor.h"
#include "ItemFood.h"
#include "ItemSign.h"
#include "ItemBed.h"
#include "ItemSpawnEgg.h"

#include "../Blocks/BlockHandler.h"

bool cItemHandler::m_HandlerInitialized = false;
cItemHandler * cItemHandler::m_ItemHandler[2266];

cItemHandler *cItemHandler::GetItemHandler(int a_ItemType)
{
	if(a_ItemType < 0) a_ItemType = 0;

	if(!m_HandlerInitialized)
	{	//We have to initialize
		memset(m_ItemHandler, 0, sizeof(m_ItemHandler));
		m_HandlerInitialized = true;
	}
	if(m_ItemHandler[a_ItemType])
		return m_ItemHandler[a_ItemType];
	m_ItemHandler[a_ItemType] = CreateItemHandler(a_ItemType);
	return m_ItemHandler[a_ItemType];
}

cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
{
	switch(a_ItemType)
	{
		default:                       return new cItemHandler(a_ItemType);

		// Single item per handler, alphabetically sorted:
		case E_ITEM_BED:               return new cItemBedHandler(a_ItemType);
		case E_ITEM_DYE:               return new cItemDyeHandler(a_ItemType);
		case E_ITEM_FLINT_AND_STEEL:   return new cItemLighterHandler(a_ItemType);
		case E_ITEM_LEAVES:            return new cItemLeavesHandler(a_ItemType);
		case E_ITEM_REDSTONE_DUST:     return new cItemRedstoneDustHandler(a_ItemType);
		case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
		case E_ITEM_SAPLING:           return new cItemSaplingHandler(a_ItemType);
		case E_ITEM_SHEARS:            return new cItemShearsHandler(a_ItemType);
		case E_ITEM_SIGN:              return new cItemSignHandler(a_ItemType);
		case E_ITEM_SPAWN_EGG:         return new cItemSpawnEggHandler(a_ItemType);
		case E_ITEM_SUGARCANE:         return new cItemSugarcaneHandler(a_ItemType);
		case E_ITEM_WOOL:              return new cItemClothHandler(a_ItemType);

		case E_ITEM_WOODEN_HOE:
		case E_ITEM_STONE_HOE:
		case E_ITEM_IRON_HOE:
		case E_ITEM_GOLD_HOE:
		case E_ITEM_DIAMOND_HOE:
		{
			return new cItemHoeHandler(a_ItemType);
		}

		case E_ITEM_WOODEN_PICKAXE:
		case E_ITEM_STONE_PICKAXE:
		case E_ITEM_IRON_PICKAXE:
		case E_ITEM_GOLD_PICKAXE:
		case E_ITEM_DIAMOND_PICKAXE:
		{
			return new cItemPickaxeHandler(a_ItemType);
		}

		case E_ITEM_WOODEN_SHOVEL:
		case E_ITEM_STONE_SHOVEL:
		case E_ITEM_IRON_SHOVEL:
		case E_ITEM_GOLD_SHOVEL:
		case E_ITEM_DIAMOND_SHOVEL:
		{
			return new cItemShovelHandler(a_ItemType);
		}

		case E_ITEM_WOODEN_SWORD:
		case E_ITEM_STONE_SWORD:
		case E_ITEM_IRON_SWORD:
		case E_ITEM_GOLD_SWORD:
		case E_ITEM_DIAMOND_SWORD:
		{
			return new cItemSwordHandler(a_ItemType);
		}

		case E_ITEM_STONE_SLAB:
		case E_ITEM_WOODEN_SLAB:
		{
			return new cItemSlabHandler(a_ItemType);
		}

		case E_ITEM_LOG:
		case E_ITEM_PLANKS:
		{
			return new cItemWoodHandler(a_ItemType);
		}

		case E_ITEM_BUCKET:
		case E_ITEM_WATER_BUCKET:
		case E_ITEM_LAVA_BUCKET:
		{
			return new cItemBucketHandler(a_ItemType);
		}

		case E_ITEM_PUMPKIN_SEEDS:
		case E_ITEM_MELON_SEEDS:
		case E_ITEM_SEEDS:
		{
			return new cItemSeedsHandler(a_ItemType);
		}

		case E_ITEM_IRON_DOOR:
		case E_ITEM_WOODEN_DOOR:
		{
			return new cItemDoorHandler(a_ItemType);
		}

		// Food:
		case E_ITEM_BREAD:
		case E_ITEM_COOKIE:
		case E_ITEM_MELON_SLICE:
		case E_ITEM_RAW_CHICKEN:
		case E_ITEM_COOKED_CHICKEN:
		case E_ITEM_RAW_BEEF:
		case E_ITEM_RAW_MEAT:
		case E_ITEM_STEAK:
		case E_ITEM_COOKED_MEAT:
		case E_ITEM_RAW_FISH:
		case E_ITEM_COOKED_FISH:
		case E_ITEM_RED_APPLE:
		case E_ITEM_GOLDEN_APPLE:
		case E_ITEM_ROTTEN_FLESH:
		case E_ITEM_SPIDER_EYE:
		{
			return new cItemFoodHandler(a_ItemType);
		}
	}
}

void cItemHandler::Deinit()
{
	for(int i = 0; i < 2266; i++)
	{
		delete m_ItemHandler[i];
	}
	m_HandlerInitialized = false;
}

cItemHandler::cItemHandler(int a_ItemType)
{
	m_ItemType = a_ItemType;
}

bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	return false;
}

bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	return false;
}

void cItemHandler::OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z)
{
	char Block = a_World->GetBlock(a_X, a_Y, a_Z);
	cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);

	if(a_Player->GetGameMode() == eGameMode_Survival)
	{
		if(!BlockRequiresSpecialTool(Block) || CanHarvestBlock(Block))
		{
			Handler->DropBlock(a_World, a_X, a_Y, a_Z);
		}
	}

	a_Player->UseEquippedItem();
}

void cItemHandler::OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item)
{

}

char cItemHandler::GetMaxStackSize(void)
{
	if (m_ItemType < 256)
	{
		// All blocks can stack up to 64
		return 64;
	}

	switch (m_ItemType)
	{
		case E_ITEM_APPLE:           return 64;
		case E_ITEM_ARROW:           return 64;
		case E_ITEM_BLAZE_POWDER:    return 64;
		case E_ITEM_BLAZE_ROD:       return 64;
		case E_ITEM_BONE:            return 64;
		case E_ITEM_BOOK:            return 64;
		case E_ITEM_BOWL:            return 64;
		case E_ITEM_BREAD:           return 64;
		case E_ITEM_BROWN_MUSHROOM:  return 64;
		case E_ITEM_BUCKET:          return 1;  // TODO: change this to 16 when turning compatibility to 1.3
		case E_ITEM_COAL:            return 64;
		case E_ITEM_COOKED_CHICKEN:  return 64;
		case E_ITEM_COOKED_FISH:     return 64;
		case E_ITEM_COOKED_PORKCHOP: return 64;
		case E_ITEM_DIAMOND:         return 64;
		case E_ITEM_FEATHER:         return 64;
		case E_ITEM_FLINT:           return 64;
		case E_ITEM_GOLD:            return 64;
		case E_ITEM_GUNPOWDER:       return 64;
		case E_ITEM_IRON:            return 64;
		case E_ITEM_RAW_PORKCHOP:    return 64;
		case E_ITEM_SEEDS:           return 64;
		case E_ITEM_STICK:           return 64;
		case E_ITEM_STRING:          return 64;
		case E_ITEM_WHEAT:           return 64;
	}
	// By default items don't stack:
	return 1;
}

bool cItemHandler::IsTool()
{
	return
		   (m_ItemType >= 256 && m_ItemType <= 259)
		|| (m_ItemType == 261)
		|| (m_ItemType >= 267 && m_ItemType <= 279)
		|| (m_ItemType >= 283 && m_ItemType <= 286)
		|| (m_ItemType >= 290 && m_ItemType <= 294)
		|| (m_ItemType >= 256 && m_ItemType <= 259)
		|| (m_ItemType == 325)
		|| (m_ItemType == 346);
}

bool cItemHandler::IsFood()
{
	return
		   (m_ItemType == 260)
		|| (m_ItemType == 282)
		|| (m_ItemType == 297)
		|| (m_ItemType >= 319 && m_ItemType <= 320)
		|| (m_ItemType == 335)
		|| (m_ItemType >= 349 && m_ItemType <= 350)
		|| (m_ItemType == 357)
		|| (m_ItemType == 360)
		|| (m_ItemType >= 363 && m_ItemType <= 366);
}

bool cItemHandler::IsPlaceable()
{
	return m_ItemType >= 1 && m_ItemType <= 136;
}

bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
{
	return false;
}

BLOCKTYPE cItemHandler::GetBlockType()
{
	ASSERT(m_ItemType < 256);  // Items with IDs above 255 should all be handled by specific handlers

	#ifdef _DEBUG
	if (m_ItemType > 256)
	{
		LOGERROR("Item %d has no valid block!", m_ItemType);
	}
	#endif  // _DEBUG

	return (BLOCKTYPE) m_ItemType;
}

NIBBLETYPE cItemHandler::GetBlockMeta(short a_ItemDamage)
{
	return (NIBBLETYPE)a_ItemDamage & 0x0f;  // This keeps most textures. The few other items have to override this
}

void cItemHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	BLOCKTYPE Block = GetBlockType();
	cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);
	Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_BlockX, a_BlockY, a_BlockZ, a_Dir);
	if(a_Player->GetGameMode() == eGameMode_Survival)
	{
		cItem Item(a_Item->m_ItemType, 1);
		a_Player->GetInventory().RemoveItem(Item);
	}
}

bool cItemHandler::EatItem(cPlayer *a_Player, cItem *a_Item)
{
	FoodInfo Info = GetFoodInfo();

	if(Info.FoodLevel > 0 || Info.Saturation > 0.f)
	{
		bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation);
		if(Success && Info.PoisionChance > 0)
		{
			MTRand r1;
			if((r1.randInt(100) - Info.PoisionChance) <= 0)
			{	//Unlucky guy :D
				//TODO: Make player ill
			}
		}

		return Success;
	}

	return false;
}

cItemHandler::FoodInfo cItemHandler::GetFoodInfo()
{
	return FoodInfo(0, 0.f);
}

<commit_msg>Added more item stacking sizes (patch contributed by Hanfer)<commit_after>
#include "Globals.h"
#include "ItemHandler.h"
#include "../Item.h"
#include "../World.h"
#include "../Player.h"

//Handler
#include "ItemCloth.h"
#include "ItemHoe.h"
#include "ItemSlab.h"
#include "ItemWood.h"
#include "ItemShears.h"
#include "ItemLeaves.h"
#include "ItemSapling.h"
#include "ItemBucket.h"
#include "ItemLighter.h"
#include "ItemRedstoneDust.h"
#include "ItemRedstoneRepeater.h"
#include "ItemSeeds.h"
#include "ItemDye.h"
#include "ItemSugarcane.h"
#include "ItemPickaxe.h"
#include "ItemShovel.h"
#include "ItemSword.h"
#include "ItemDoor.h"
#include "ItemFood.h"
#include "ItemSign.h"
#include "ItemBed.h"
#include "ItemSpawnEgg.h"

#include "../Blocks/BlockHandler.h"

bool cItemHandler::m_HandlerInitialized = false;
cItemHandler * cItemHandler::m_ItemHandler[2266];

cItemHandler *cItemHandler::GetItemHandler(int a_ItemType)
{
	if(a_ItemType < 0) a_ItemType = 0;

	if(!m_HandlerInitialized)
	{	//We have to initialize
		memset(m_ItemHandler, 0, sizeof(m_ItemHandler));
		m_HandlerInitialized = true;
	}
	if(m_ItemHandler[a_ItemType])
		return m_ItemHandler[a_ItemType];
	m_ItemHandler[a_ItemType] = CreateItemHandler(a_ItemType);
	return m_ItemHandler[a_ItemType];
}

cItemHandler *cItemHandler::CreateItemHandler(int a_ItemType)
{
	switch(a_ItemType)
	{
		default:                       return new cItemHandler(a_ItemType);

		// Single item per handler, alphabetically sorted:
		case E_ITEM_BED:               return new cItemBedHandler(a_ItemType);
		case E_ITEM_DYE:               return new cItemDyeHandler(a_ItemType);
		case E_ITEM_FLINT_AND_STEEL:   return new cItemLighterHandler(a_ItemType);
		case E_ITEM_LEAVES:            return new cItemLeavesHandler(a_ItemType);
		case E_ITEM_REDSTONE_DUST:     return new cItemRedstoneDustHandler(a_ItemType);
		case E_ITEM_REDSTONE_REPEATER: return new cItemRedstoneRepeaterHandler(a_ItemType);
		case E_ITEM_SAPLING:           return new cItemSaplingHandler(a_ItemType);
		case E_ITEM_SHEARS:            return new cItemShearsHandler(a_ItemType);
		case E_ITEM_SIGN:              return new cItemSignHandler(a_ItemType);
		case E_ITEM_SPAWN_EGG:         return new cItemSpawnEggHandler(a_ItemType);
		case E_ITEM_SUGARCANE:         return new cItemSugarcaneHandler(a_ItemType);
		case E_ITEM_WOOL:              return new cItemClothHandler(a_ItemType);

		case E_ITEM_WOODEN_HOE:
		case E_ITEM_STONE_HOE:
		case E_ITEM_IRON_HOE:
		case E_ITEM_GOLD_HOE:
		case E_ITEM_DIAMOND_HOE:
		{
			return new cItemHoeHandler(a_ItemType);
		}

		case E_ITEM_WOODEN_PICKAXE:
		case E_ITEM_STONE_PICKAXE:
		case E_ITEM_IRON_PICKAXE:
		case E_ITEM_GOLD_PICKAXE:
		case E_ITEM_DIAMOND_PICKAXE:
		{
			return new cItemPickaxeHandler(a_ItemType);
		}

		case E_ITEM_WOODEN_SHOVEL:
		case E_ITEM_STONE_SHOVEL:
		case E_ITEM_IRON_SHOVEL:
		case E_ITEM_GOLD_SHOVEL:
		case E_ITEM_DIAMOND_SHOVEL:
		{
			return new cItemShovelHandler(a_ItemType);
		}

		case E_ITEM_WOODEN_SWORD:
		case E_ITEM_STONE_SWORD:
		case E_ITEM_IRON_SWORD:
		case E_ITEM_GOLD_SWORD:
		case E_ITEM_DIAMOND_SWORD:
		{
			return new cItemSwordHandler(a_ItemType);
		}

		case E_ITEM_STONE_SLAB:
		case E_ITEM_WOODEN_SLAB:
		{
			return new cItemSlabHandler(a_ItemType);
		}

		case E_ITEM_LOG:
		case E_ITEM_PLANKS:
		{
			return new cItemWoodHandler(a_ItemType);
		}

		case E_ITEM_BUCKET:
		case E_ITEM_WATER_BUCKET:
		case E_ITEM_LAVA_BUCKET:
		{
			return new cItemBucketHandler(a_ItemType);
		}

		case E_ITEM_PUMPKIN_SEEDS:
		case E_ITEM_MELON_SEEDS:
		case E_ITEM_SEEDS:
		{
			return new cItemSeedsHandler(a_ItemType);
		}

		case E_ITEM_IRON_DOOR:
		case E_ITEM_WOODEN_DOOR:
		{
			return new cItemDoorHandler(a_ItemType);
		}

		// Food:
		case E_ITEM_BREAD:
		case E_ITEM_COOKIE:
		case E_ITEM_MELON_SLICE:
		case E_ITEM_RAW_CHICKEN:
		case E_ITEM_COOKED_CHICKEN:
		case E_ITEM_RAW_BEEF:
		case E_ITEM_RAW_MEAT:
		case E_ITEM_STEAK:
		case E_ITEM_COOKED_MEAT:
		case E_ITEM_RAW_FISH:
		case E_ITEM_COOKED_FISH:
		case E_ITEM_RED_APPLE:
		case E_ITEM_GOLDEN_APPLE:
		case E_ITEM_ROTTEN_FLESH:
		case E_ITEM_SPIDER_EYE:
		{
			return new cItemFoodHandler(a_ItemType);
		}
	}
}

void cItemHandler::Deinit()
{
	for(int i = 0; i < 2266; i++)
	{
		delete m_ItemHandler[i];
	}
	m_HandlerInitialized = false;
}

cItemHandler::cItemHandler(int a_ItemType)
{
	m_ItemType = a_ItemType;
}

bool cItemHandler::OnItemUse(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	return false;
}

bool cItemHandler::OnDiggingBlock(cWorld * a_World, cPlayer * a_Player, cItem * a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	return false;
}

void cItemHandler::OnBlockDestroyed(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_X, int a_Y, int a_Z)
{
	char Block = a_World->GetBlock(a_X, a_Y, a_Z);
	cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);

	if(a_Player->GetGameMode() == eGameMode_Survival)
	{
		if(!BlockRequiresSpecialTool(Block) || CanHarvestBlock(Block))
		{
			Handler->DropBlock(a_World, a_X, a_Y, a_Z);
		}
	}

	a_Player->UseEquippedItem();
}

void cItemHandler::OnFoodEaten(cWorld *a_World, cPlayer *a_Player, cItem *a_Item)
{

}

char cItemHandler::GetMaxStackSize(void)
{
	if (m_ItemType < 256)
	{
		// All blocks can stack up to 64
		return 64;
	}

	switch (m_ItemType) //sorted by id
	{
		case E_ITEM_APPLE:                return 64;
		case E_ITEM_ARROW:                return 64;
		case E_ITEM_BLAZE_POWDER:         return 64;
		case E_ITEM_BLAZE_ROD:            return 64;
		case E_ITEM_BONE:                 return 64;
		case E_ITEM_BOOK:                 return 64;
		case E_ITEM_BOTTLE_O_ENCHANTING:  return 64;
		case E_ITEM_BOWL:                 return 64;
		case E_ITEM_BREAD:                return 64;
		case E_ITEM_BREWING_STAND:        return 64;
		case E_ITEM_BUCKET:               return 1;  // TODO: change this to 16 when turning compatibility to 1.3
		case E_ITEM_CLAY:                 return 64;
		case E_ITEM_CLAY_BRICK:           return 64;
		case E_ITEM_CLOCK:                return 64;
		case E_ITEM_COAL:                 return 64;
		case E_ITEM_COMPASS:              return 64;
		case E_ITEM_COOKED_CHICKEN:       return 64;
		case E_ITEM_COOKED_FISH:          return 64;
		case E_ITEM_COOKED_PORKCHOP:      return 64;
		case E_ITEM_COOKIE:               return 64;
		case E_ITEM_DIAMOND:              return 64;
		case E_ITEM_DYE:                  return 64;
		case E_ITEM_EGG:                  return 16;
		case E_ITEM_EMERALD:              return 64;
		case E_ITEM_ENDER_PEARL:          return 16;
		case E_ITEM_EYE_OF_ENDER:         return 64;
		case E_ITEM_FEATHER:              return 64;
		case E_ITEM_FERMENTED_SPIDER_EYE: return 64;
		case E_ITEM_FIRE_CHARGE:          return 64;
		case E_ITEM_FLINT:                return 64;
		case E_ITEM_GHAST_TEAR:           return 64;
		case E_ITEM_GLASS_BOTTLE:         return 64;
		case E_ITEM_GLISTERING_MELON:     return 64;
		case E_ITEM_GLOWSTONE_DUST:       return 64;
		case E_ITEM_GOLD:                 return 64;
		case E_ITEM_GOLDEN_APPLE:         return 64;
		case E_ITEM_GOLD_NUGGET:          return 64;
		case E_ITEM_GUNPOWDER:            return 64;
		case E_ITEM_IRON:                 return 64;
		case E_ITEM_LEATHER:              return 64;
		case E_ITEM_MAGMA_CREAM:          return 64;
		case E_ITEM_MELON_SEEDS:          return 64;
		case E_ITEM_MELON_SLICE:          return 64;
		case E_ITEM_PAINTINGS:            return 64;
		case E_ITEM_PAPER:                return 64;
		case E_ITEM_PUMPKIN_SEEDS:        return 64;
		case E_ITEM_RAW_BEEF:             return 64;
		case E_ITEM_RAW_CHICKEN:          return 64;
		case E_ITEM_RAW_FISH:             return 64;
		case E_ITEM_RAW_PORKCHOP:         return 64;
		case E_ITEM_REDSTONE_DUST:        return 64;
		case E_ITEM_REDSTONE_REPEATER:    return 64;
		case E_ITEM_ROTTEN_FLESH:         return 64;
		case E_ITEM_SEEDS:                return 64;
		case E_ITEM_SIGN:                 return 16;
		case E_ITEM_SLIMEBALL:            return 64;
		case E_ITEM_SNOWBALL:             return 16;
		case E_ITEM_SPIDER_EYE:           return 64;
		case E_ITEM_STEAK:                return 64;
		case E_ITEM_STICK:                return 64;
		case E_ITEM_STRING:               return 64;
		case E_ITEM_SUGAR:                return 64;
		case E_ITEM_SUGAR_CANE:           return 64;
		case E_ITEM_WHEAT:                return 64;
	}
	// By default items don't stack:
	return 1;
}

bool cItemHandler::IsTool()
{
	return
		   (m_ItemType >= 256 && m_ItemType <= 259)
		|| (m_ItemType == 261)
		|| (m_ItemType >= 267 && m_ItemType <= 279)
		|| (m_ItemType >= 283 && m_ItemType <= 286)
		|| (m_ItemType >= 290 && m_ItemType <= 294)
		|| (m_ItemType >= 256 && m_ItemType <= 259)
		|| (m_ItemType == 325)
		|| (m_ItemType == 346);
}

bool cItemHandler::IsFood()
{
	return
		   (m_ItemType == 260)
		|| (m_ItemType == 282)
		|| (m_ItemType == 297)
		|| (m_ItemType >= 319 && m_ItemType <= 320)
		|| (m_ItemType == 335)
		|| (m_ItemType >= 349 && m_ItemType <= 350)
		|| (m_ItemType == 357)
		|| (m_ItemType == 360)
		|| (m_ItemType >= 363 && m_ItemType <= 366);
}

bool cItemHandler::IsPlaceable()
{
	return m_ItemType >= 1 && m_ItemType <= 136;
}

bool cItemHandler::CanHarvestBlock(BLOCKTYPE a_BlockType)
{
	return false;
}

BLOCKTYPE cItemHandler::GetBlockType()
{
	ASSERT(m_ItemType < 256);  // Items with IDs above 255 should all be handled by specific handlers

	#ifdef _DEBUG
	if (m_ItemType > 256)
	{
		LOGERROR("Item %d has no valid block!", m_ItemType);
	}
	#endif  // _DEBUG

	return (BLOCKTYPE) m_ItemType;
}

NIBBLETYPE cItemHandler::GetBlockMeta(short a_ItemDamage)
{
	return (NIBBLETYPE)a_ItemDamage & 0x0f;  // This keeps most textures. The few other items have to override this
}

void cItemHandler::PlaceBlock(cWorld *a_World, cPlayer *a_Player, cItem *a_Item, int a_BlockX, int a_BlockY, int a_BlockZ, char a_Dir)
{
	BLOCKTYPE Block = GetBlockType();
	cBlockHandler *Handler = cBlockHandler::GetBlockHandler(Block);
	Handler->PlaceBlock(a_World, a_Player, GetBlockMeta(a_Item->m_ItemHealth), a_BlockX, a_BlockY, a_BlockZ, a_Dir);
	if(a_Player->GetGameMode() == eGameMode_Survival)
	{
		cItem Item(a_Item->m_ItemType, 1);
		a_Player->GetInventory().RemoveItem(Item);
	}
}

bool cItemHandler::EatItem(cPlayer *a_Player, cItem *a_Item)
{
	FoodInfo Info = GetFoodInfo();

	if(Info.FoodLevel > 0 || Info.Saturation > 0.f)
	{
		bool Success = a_Player->Feed(Info.FoodLevel, Info.Saturation);
		if(Success && Info.PoisionChance > 0)
		{
			MTRand r1;
			if((r1.randInt(100) - Info.PoisionChance) <= 0)
			{	//Unlucky guy :D
				//TODO: Make player ill
			}
		}

		return Success;
	}

	return false;
}

cItemHandler::FoodInfo cItemHandler::GetFoodInfo()
{
	return FoodInfo(0, 0.f);
}

<|endoftext|>


<commit_before>#include "ServerPeer.h"
#include "Parameter.h"
#include "MessageDecoder.h"

using namespace std;

ServerPeer::ServerPeer(char* _listen_hostname, int _listen_port):Server(_listen_hostname, _listen_port){
}

ServerPeer::~ServerPeer(){

}

std::vector<std::string> ServerPeer::getListofImages(std::string token, std::string userID){
	//TODO: AUTHENTICATE WITH SERVER DISCOVERY
	return imageList;
}

std::string ServerPeer::getImage(std::string token, std::string userID, std::string imageID){
	//TODO: LOAD IMAGES
}

void ServerPeer::updateViews(std::string token, std::string userID, int count){

}

void ServerPeer::revokeViews(std::string token, std::string userID){

}

Message* ServerPeer::doOperation(Message* _message){
	Message reply_message(Reply);

    vector<Parameter> args;
    vector<Parameter> reply_args;

    int operation = _message->getOperation();
    MessageType = _message->getMessageType();

    MessageDecoder::decode(_message, args);

    switch(operation){
    case 7:
    	break;
    case 8:
    	break;
    case 9:
    	break;
    }

	MessageDecoder::encode(reply_message, reply_args, operation, Reply);
    return reply_message;
}
<commit_msg>Implemented Image functions of Peer Server<commit_after>#include "ServerPeer.h"
#include "Parameter.h"
#include "MessageDecoder.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

ServerPeer::ServerPeer(char* _listen_hostname, int _listen_port):Server(_listen_hostname, _listen_port){
	system("mkdir MyImages");
	system("mkdir LoadedImages");
}

ServerPeer::~ServerPeer(){

}

std::vector<std::string> ServerPeer::getListofImages(std::string token, std::string userID){
	//TODO: AUTHENTICATE WITH SERVER DISCOVERY
	return imageList;
}

std::string ServerPeer::getImage(std::string token, std::string userID, std::string imageID){
	//TODO: AUTHENTICATE WITH SERVER DISCOVERY
	streampos size;
	char * memblock;

	ifstream file (imageID, ios::in|ios::binary|ios::ate);
	if (file.is_open()){
		size = file.tellg();
		memblock = new char [size];
		file.seekg (0, ios::beg);
		file.read (memblock, size);
		file.close();
		string image(memblock, size);
		delete[] memblock;
		return image;
	}
	else return NULL;
}

void ServerPeer::updateViews(std::string token, std::string userID, int count){

}

void ServerPeer::revokeViews(std::string token, std::string userID){

}

Message* ServerPeer::doOperation(Message* _message){
	Message reply_message(Reply);

    vector<Parameter> args;
    vector<Parameter> reply_args;

    int operation = _message->getOperation();
    MessageType = _message->getMessageType();

    MessageDecoder::decode(_message, args);

    switch(operation){
    case 7:{
    	std::vector<std::string> imageList = getListofImages(args[0].getString(), args[1].getString());
    	Parameter arg1;
		arg1.setVectorString(imageList);
		reply_args.push_back(arg1);
    }
    	break;
    case 8:{
    	string image = getImage(args[0].getString(), args[1].getString(), args[2].getString());
    	Parameter arg1;
    	arg1.setString(image);
    	reply_args.push_back(arg1);
    }
    	break;
    case 9:{

    }
    	break;
    }

	MessageDecoder::encode(reply_message, reply_args, operation, Reply);
    return reply_message;
}
<|endoftext|>


<commit_before>/**
*	2-D Steady State Conduction without Heat Generation | main.cpp
*
*	@libs	[Nodes.a, NodesHelper.a]
*	@header	[Nodes.h, NodesHelper.h]
*
*	@author Samuel0Paul <paulsamuelvishesh@live.com>
**/

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstdint>
#include <chrono>
#include <thread>
#include <atomic>

#include "header/Nodes.h"
#include "header/NodesHelper.h"

#include "test/test.cpp"

using std::cout;	using std::endl;
using std::clog;
using std::cin;
using std::make_pair;

using prec_t = long double;

int main(int argc, char const *argv[])
{
	cout << std::nounitbuf;
	cout << std::setprecision(4) << std::fixed << std::boolalpha;
	cout << "############################ HMT Assignment ##########################" << endl
		 << " 2-D Steady State Conduction with and withour Heat Generation" << endl << endl
		 << " Author: Samuel Paul Vishesh [UR11ME145] <paulsamuelvishesh@live.com>" << endl
		 << "######################################################################" << endl << endl;

	/*HMT::NodesHelper<prec_t> nodes;
	nodes.init();
	nodes.canUseThreads(false);
	nodes.calculate();
	cout << nodes;
	cout << "Time taken: " << nodes.getDuration<std::chrono::nanoseconds>().count() << "ns" << endl;*/

	test::NodesWithoutHeatSrc<prec_t> testNodesWOHSrcTE{12, 12,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, true};
	testNodesWOHSrcTE.test();
	test::NodesWithoutHeatSrc<prec_t> testNodesWOHSrcWTE{12, 12,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, false};
	testNodesWOHSrcWTE.test();

	std::vector<std::pair<std::pair<uint64_t, uint64_t>, prec_t>> heatSrcs = {
		make_pair(make_pair(2, 2), 300.0f),
		make_pair(make_pair(5, 5), -1000.0f)
	};
	test::NodesWithHeatSrc<prec_t> testNodesWHSrcTE{12, 12,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, false,
		heatSrcs};
	testNodesWHSrcTE.test();
	test::NodesWithHeatSrc<prec_t> testNodesWHSrcWTE{12, 12,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, true,
		heatSrcs};
	testNodesWHSrcWTE.test();

	return 0;
}<commit_msg>some changes and code refactor<commit_after>/**
*	2-D Steady State Conduction without Heat Generation | main.cpp
*
*	@libs	[Nodes.a, NodesHelper.a]
*	@header	[Nodes.h, NodesHelper.h]
*
*	@author Samuel0Paul <paulsamuelvishesh@live.com>
**/

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstdint>
#include <chrono>
#include <thread>
#include <atomic>

#include "header/Nodes.h"
#include "header/NodesHelper.h"

#include "test/test.cpp"

using std::cout;	using std::endl;
using std::clog;
using std::cin;
using std::make_pair;

using prec_t = long double;

void runTest(void)
{
	test::NodesWithoutHeatSrc<prec_t> testNodesWOHSrcTE{12, 30,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, true};
	testNodesWOHSrcTE.test();
	test::NodesWithoutHeatSrc<prec_t> testNodesWOHSrcWTE{12, 30,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, false};
	testNodesWOHSrcWTE.test();

	std::vector<std::pair<std::pair<uint64_t, uint64_t>, prec_t>> heatSrcs = {
		make_pair(make_pair(2, 2), 300.0f),
		make_pair(make_pair(5, 5), -1000.0f)
	};
	test::NodesWithHeatSrc<prec_t> testNodesWHSrcTE{12, 30,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, false,
		heatSrcs};
	testNodesWHSrcTE.test();
	test::NodesWithHeatSrc<prec_t> testNodesWHSrcWTE{12, 30,
		500.0f, 100.0f, 100.0f, 100.0f, 0.0000001f, true,
		heatSrcs};
	testNodesWHSrcWTE.test();
}

int main(int argc, char const *argv[])
{
	cout << std::nounitbuf;
	cout << std::setprecision(4) << std::fixed << std::boolalpha;
	cout << "############################ HMT Assignment ##########################" << endl
		 << " 2-D Steady State Conduction with and withour Heat Generation" << endl << endl
		 << " Author: Samuel Paul Vishesh [UR11ME145] <paulsamuelvishesh@live.com>" << endl
		 << "######################################################################" << endl << endl;

	/*HMT::NodesHelper<prec_t> nodes;
	nodes.init();
	nodes.canUseThreads(false);
	nodes.calculate();
	cout << nodes;
	cout << "Time taken: " << nodes.getDuration<std::chrono::nanoseconds>().count() << "ns" << endl;*/

	runTest();

	return 0;
}<|endoftext|>


<commit_before>#include "ewa_base/testing/test.h"
#include "ewa_base/ipc.h"
#include <iostream>

using namespace ew;

TEST_DEFINE(TEST_Shm)
{

	SharedMem sm1,sm2;

	String filetext="helloworld";

	// create a file and write some text
	TEST_ASSERT(sm1.OpenFile("shm_sample.txt",1024,FLAG_FILE_RW|FLAG_FILE_CR));
	if(sm1.data())
	{
		strcpy(sm1.data(),filetext.c_str());
	}
	sm1.Close();
	TEST_ASSERT(sm1.data()==NULL);

	// open the file and read the text
	TEST_ASSERT(sm2.OpenFile("shm_sample.txt",0,FLAG_FILE_RD));
	if(sm1.data() && sm2.data())
	{
		TEST_ASSERT(strcmp(sm2.data(),filetext.c_str())==0);
	}
	sm2.Close();

	// open SharedMem with a name;

	TEST_ASSERT_MSG(sm1.Open("local_shm",1024,FLAG_FILE_RD|FLAG_FILE_WR|FLAG_FILE_CR),"ShmOpen");
	TEST_ASSERT_MSG(sm2.Open("local_shm",1024,FLAG_FILE_RD|FLAG_FILE_WR),"ShmOpen");
	char* p1=sm1.data();
	char* p2=sm2.data();

	if(p1 && p2)
	{
		TEST_ASSERT(p1!=p2);
		int *p=(int*)p1;
		for(size_t i=0; i<sm1.size()/sizeof(int); i++)
		{
			p[i]=rand();
		}

		TEST_ASSERT(memcmp(p1,p2,1024)==0);
	}
	else
	{
		TEST_ASSERT_MSG(false,"ShmOpen");
	}

	// open SharedMem without a name;
	TEST_ASSERT_MSG(sm2.Alloc(4096*8),"ShmOpen");

	p1=sm2.data();
	TEST_ASSERT_MSG(p1!=NULL,"SharedMem::Alloc failed");
	if(p1)
	{
		memset(p1,1,4096*8);
	}

	sm1.Close();
	sm2.Close();

}

<commit_msg>update<commit_after>#include "ewa_base/testing/test.h"
#include "ewa_base/ipc.h"
#include <iostream>

using namespace ew;

TEST_DEFINE(TEST_Shm)
{

	SharedMem sm1,sm2;

	String filetext="helloworld";

	// create a file and write some text
	TEST_ASSERT(sm1.OpenFile("shm_sample.txt",1024,FLAG_FILE_RW|FLAG_FILE_CR));
	if(sm1.data())
	{
		strcpy(sm1.data(),filetext.c_str());
	}
	sm1.Close();
	TEST_ASSERT(sm1.data()==NULL);

	// open the file and read the text
	TEST_ASSERT(sm2.OpenFile("shm_sample.txt",0,FLAG_FILE_RD));
	if(sm2.data())
	{
		TEST_ASSERT(strcmp(sm2.data(),filetext.c_str())==0);
	}
	sm2.Close();

	// open SharedMem with a name;

	TEST_ASSERT_MSG(sm1.Open("local_shm",1024,FLAG_FILE_RD|FLAG_FILE_WR|FLAG_FILE_CR),"ShmOpen");
	TEST_ASSERT_MSG(sm2.Open("local_shm",1024,FLAG_FILE_RD|FLAG_FILE_WR),"ShmOpen");
	char* p1=sm1.data();
	char* p2=sm2.data();

	if(p1 && p2)
	{
		TEST_ASSERT(p1!=p2);
		int *p=(int*)p1;
		for(size_t i=0; i<sm1.size()/sizeof(int); i++)
		{
			p[i]=rand();
		}

		TEST_ASSERT(memcmp(p1,p2,1024)==0);
	}
	else
	{
		TEST_ASSERT_MSG(false,"ShmOpen");
	}

	// open SharedMem without a name;
	TEST_ASSERT_MSG(sm2.Alloc(4096*8),"ShmOpen");

	p1=sm2.data();
	TEST_ASSERT_MSG(p1!=NULL,"SharedMem::Alloc failed");
	if(p1)
	{
		memset(p1,1,4096*8);
	}

	sm1.Close();
	sm2.Close();

}

<|endoftext|>