<commit_before>#include "chronotext/texture/TextureAtlas.h"

#include "cinder/Xml.h"

using namespace ci;
using namespace std;

TextureAtlas::TextureAtlas(const string &resourceName, bool useMipmap)
{
    init(InputSource::getResource(resourceName), useMipmap);    
}

TextureAtlas::TextureAtlas(InputSourceRef inputSource, bool useMipmap)
{
    init(inputSource, useMipmap);
}

void TextureAtlas::init(InputSourceRef inputSource, bool useMipmap)
{
    XmlTree doc(inputSource->loadDataSource());
    
    string resourceName = doc.getChild("TextureAtlas").getAttributeValue<string>("imagePath");
    texture = new Texture(InputSource::getResource(resourceName), useMipmap);
    
    float width = texture->getWidth();
    float height = texture->getHeight();
    
    // ---
    
    for (XmlTree::Iter spriteElement = doc.begin("TextureAtlas/sprite"); spriteElement != doc.end(); ++spriteElement)
    {
        string spritePath = spriteElement->getAttributeValue<string>("n");
        
        float x = spriteElement->getAttributeValue<float>("x");
        float y = spriteElement->getAttributeValue<float>("y");
        float w = spriteElement->getAttributeValue<float>("w");
        float h = spriteElement->getAttributeValue<float>("h");
        
        float ox = spriteElement->getAttributeValue<float>("oX", 0);
        float oy = spriteElement->getAttributeValue<float>("oY", 0);
        float ow = spriteElement->getAttributeValue<float>("oW", w);
        float oh = spriteElement->getAttributeValue<float>("oH", h);
        
        bool rotated = spriteElement->hasAttribute("r");
        
        float tx1 = x / width;
        float ty1 = y / height;
        
        float tx2 = (x + w) / width;
        float ty2 = (y + h) / height;
        
        sprites[spritePath] = new Sprite(texture, w, h, ox, oy, ow, oh, rotated, tx1, ty1, tx2, ty2);
    }
}

TextureAtlas::~TextureAtlas()
{
    delete texture;
    
    for (map<string, Sprite*>::iterator it = sprites.begin(); it != sprites.end(); ++it)
    {
        delete it->second;
    }
}

void TextureAtlas::unload()
{
    texture->unload();
}

void TextureAtlas::reload()
{
    texture->reload();
}

Sprite* TextureAtlas::getSprite(const string &path)
{
    map<string, Sprite*>::iterator it = sprites.find(path);
    
    if (it == sprites.end())
    {
        throw runtime_error("SPRITE NOT FOUND: " + path);
    }

    return it->second;
}

vector<Sprite*> TextureAtlas::getAnimationSprites(const string &path) const
{
    vector<Sprite*> animationSprites;
    string pattern = path + "%d";
    
    for (map<string, Sprite*>::const_iterator it = sprites.begin(); it != sprites.end(); ++it)
    {
        int i = -1;
        sscanf((it->first).c_str(), pattern.c_str(), &i);
        
        if (i != -1)
        {
            animationSprites.push_back(it->second);
        }
    }
    
    return animationSprites;<commit_msg>TextureAtlas: getSprite() NOW RETURNS NULL IF SPRITE IS NOT FOUND<commit_after>#include "chronotext/texture/TextureAtlas.h"

#include "cinder/Xml.h"

using namespace ci;
using namespace std;

TextureAtlas::TextureAtlas(const string &resourceName, bool useMipmap)
{
    init(InputSource::getResource(resourceName), useMipmap);    
}

TextureAtlas::TextureAtlas(InputSourceRef inputSource, bool useMipmap)
{
    init(inputSource, useMipmap);
}

void TextureAtlas::init(InputSourceRef inputSource, bool useMipmap)
{
    XmlTree doc(inputSource->loadDataSource());
    
    string resourceName = doc.getChild("TextureAtlas").getAttributeValue<string>("imagePath");
    texture = new Texture(InputSource::getResource(resourceName), useMipmap);
    
    float width = texture->getWidth();
    float height = texture->getHeight();
    
    // ---
    
    for (XmlTree::Iter spriteElement = doc.begin("TextureAtlas/sprite"); spriteElement != doc.end(); ++spriteElement)
    {
        string spritePath = spriteElement->getAttributeValue<string>("n");
        
        float x = spriteElement->getAttributeValue<float>("x");
        float y = spriteElement->getAttributeValue<float>("y");
        float w = spriteElement->getAttributeValue<float>("w");
        float h = spriteElement->getAttributeValue<float>("h");
        
        float ox = spriteElement->getAttributeValue<float>("oX", 0);
        float oy = spriteElement->getAttributeValue<float>("oY", 0);
        float ow = spriteElement->getAttributeValue<float>("oW", w);
        float oh = spriteElement->getAttributeValue<float>("oH", h);
        
        bool rotated = spriteElement->hasAttribute("r");
        
        float tx1 = x / width;
        float ty1 = y / height;
        
        float tx2 = (x + w) / width;
        float ty2 = (y + h) / height;
        
        sprites[spritePath] = new Sprite(texture, w, h, ox, oy, ow, oh, rotated, tx1, ty1, tx2, ty2);
    }
}

TextureAtlas::~TextureAtlas()
{
    delete texture;
    
    for (map<string, Sprite*>::iterator it = sprites.begin(); it != sprites.end(); ++it)
    {
        delete it->second;
    }
}

void TextureAtlas::unload()
{
    texture->unload();
}

void TextureAtlas::reload()
{
    texture->reload();
}

Sprite* TextureAtlas::getSprite(const string &path)
{
    map<string, Sprite*>::iterator it = sprites.find(path);
    
    if (it == sprites.end())
    {
        return NULL;
    }
    else
    {
        return it->second;
    }
}

vector<Sprite*> TextureAtlas::getAnimationSprites(const string &path) const
{
    vector<Sprite*> animationSprites;
    string pattern = path + "%d";
    
    for (map<string, Sprite*>::const_iterator it = sprites.begin(); it != sprites.end(); ++it)
    {
        int i = -1;
        sscanf((it->first).c_str(), pattern.c_str(), &i);
        
        if (i != -1)
        {
            animationSprites.push_back(it->second);
        }
    }
    
    return animationSprites;
{'fraction_non_alphanumeric': 0.14520266803488968, 'fraction_numerical': 0.004104669061056952, 'mean_word_length': 3.0192439862542955, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 71, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5886545', 'n_tokens_mistral': 1870, 'n_tokens_neox': 1854, 'n_words': 374}