<commit_before>#include "Base.h"
#include "Animation.h"
#include "AnimationController.h"
#include "AnimationClip.h"
#include "AnimationTarget.h"
#include "Game.h"
#include "Transform.h"
#include "Properties.h"

#define ANIMATION_INDEFINITE_STR "INDEFINITE"
#define ANIMATION_DEFAULT_CLIP 0
#define ANIMATION_ROTATE_OFFSET 0
#define ANIMATION_SRT_OFFSET 3

namespace gameplay
{

Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
{
    createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);

    // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
    release();
    GP_ASSERT(getRefCount() == 1);
}

Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
{
    createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
    // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
    release();
    GP_ASSERT(getRefCount() == 1);
}

Animation::Animation(const char* id)
    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
{
}

Animation::~Animation()
{
    _channels.clear();

    if (_defaultClip)
    {
        if (_defaultClip->isClipStateBitSet(AnimationClip::CLIP_IS_PLAYING_BIT))
        {
            GP_ASSERT(_controller);
            _controller->unschedule(_defaultClip);
        }
        SAFE_RELEASE(_defaultClip);
    }

    if (_clips)
    {
        std::vector<AnimationClip*>::iterator clipIter = _clips->begin();

        while (clipIter != _clips->end())
        {
            AnimationClip* clip = *clipIter;
            GP_ASSERT(clip);
            if (clip->isClipStateBitSet(AnimationClip::CLIP_IS_PLAYING_BIT))
            {
                GP_ASSERT(_controller);
                _controller->unschedule(clip);
            }
            SAFE_RELEASE(clip);
            clipIter++;
        }
        _clips->clear();
    }
    SAFE_DELETE(_clips);
}

Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
    : _animation(animation), _target(target), _propertyId(propertyId), _curve(curve), _duration(duration)
{
    GP_ASSERT(_animation);
    GP_ASSERT(_target);
    GP_ASSERT(_curve);

    // get property component count, and ensure the property exists on the AnimationTarget by getting the property component count.
    GP_ASSERT(_target->getAnimationPropertyComponentCount(propertyId));
    _curve->addRef();
    _target->addChannel(this);
    _animation->addRef();
}

Animation::Channel::Channel(const Channel& copy, Animation* animation, AnimationTarget* target)
    : _animation(animation), _target(target), _propertyId(copy._propertyId), _curve(copy._curve), _duration(copy._duration)
{
    GP_ASSERT(_curve);
    GP_ASSERT(_target);
    GP_ASSERT(_animation);

    _curve->addRef();
    _target->addChannel(this);
    _animation->addRef();
}

Animation::Channel::~Channel()
{
    SAFE_RELEASE(_curve);
    SAFE_RELEASE(_animation);
}

Curve* Animation::Channel::getCurve() const
{
    return _curve;
}

const char* Animation::getId() const
{
    return _id.c_str();
}

unsigned long Animation::getDuration() const
{
    return _duration;
}

void Animation::createClips(const char* url)
{
    Properties* properties = Properties::create(url);
    GP_ASSERT(properties);

    Properties* pAnimation = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
    GP_ASSERT(pAnimation);

    int frameCount = pAnimation->getInt("frameCount");
    if (frameCount <= 0)
        GP_ERROR("The animation's frame count must be greater than 0.");

    createClips(pAnimation, (unsigned int)frameCount);

    SAFE_DELETE(properties);
}

AnimationClip* Animation::createClip(const char* id, unsigned long start, unsigned long end)
{
    AnimationClip* clip = new AnimationClip(id, this, start, end);
    addClip(clip);
    return clip;
}

AnimationClip* Animation::getClip(const char* id)
{
    // If id is NULL return the default clip.
    if (id == NULL)
    {
        if (_defaultClip == NULL)
            createDefaultClip();

        return _defaultClip;
    }
    else
    {
        return findClip(id);
    }
}

AnimationClip* Animation::getClip(unsigned int index) const
{
    if (_clips)
        return _clips->at(index);

    return NULL;
}

unsigned int Animation::getClipCount() const
{
    return _clips ? (unsigned int)_clips->size() : 0;
}

void Animation::play(const char* clipId)
{
    // If id is NULL, play the default clip.
    if (clipId == NULL)
    {
        if (_defaultClip == NULL)
            createDefaultClip();

        _defaultClip->play();
    }
    else
    {
        // Find animation clip and play.
        AnimationClip* clip = findClip(clipId);
        if (clip != NULL)
            clip->play();
    }
}

void Animation::stop(const char* clipId)
{
    // If id is NULL, play the default clip.
    if (clipId == NULL)
    {
        if (_defaultClip)
            _defaultClip->stop();
    }
    else
    {
        // Find animation clip and play.
        AnimationClip* clip = findClip(clipId);
        if (clip != NULL)
            clip->stop();
    }
}

void Animation::pause(const char * clipId)
{
    if (clipId == NULL)
    {
        if (_defaultClip)
            _defaultClip->pause();
    }
    else
    {
        AnimationClip* clip = findClip(clipId);
        if (clip != NULL)
            clip->pause();
    }
}

bool Animation::targets(AnimationTarget* target) const
{
    for (std::vector<Animation::Channel*>::const_iterator itr = _channels.begin(); itr != _channels.end(); ++itr)
    {
        GP_ASSERT(*itr);
        if ((*itr)->_target == target)
        {
            return true;
        }
    }
    return false;
}

void Animation::createDefaultClip()
{
    _defaultClip = new AnimationClip("default_clip", this, 0.0f, _duration);
}

void Animation::createClips(Properties* animationProperties, unsigned int frameCount)
{
    GP_ASSERT(animationProperties);

    Properties* pClip = animationProperties->getNextNamespace();

    while (pClip != NULL && std::strcmp(pClip->getNamespace(), "clip") == 0)
    {
        int begin = pClip->getInt("begin");
        int end = pClip->getInt("end");

        AnimationClip* clip = createClip(pClip->getId(), ((float) begin / frameCount) * _duration, ((float) end / frameCount) * _duration);

        const char* repeat = pClip->getString("repeatCount");
        if (repeat)
        {
            if (strcmp(repeat, ANIMATION_INDEFINITE_STR) == 0)
            {
                clip->setRepeatCount(AnimationClip::REPEAT_INDEFINITE);
            }
            else
            {
                float value;
                sscanf(repeat, "%f", &value);
                clip->setRepeatCount(value);
            }
        }

        const char* speed = pClip->getString("speed");
        if (speed)
        {
            float value;
            sscanf(speed, "%f", &value);
            clip->setSpeed(value);
        }

        pClip = animationProperties->getNextNamespace();
    }
}

void Animation::addClip(AnimationClip* clip)
{
    if (_clips == NULL)
        _clips = new std::vector<AnimationClip*>;

    GP_ASSERT(clip);
    _clips->push_back(clip);
}

AnimationClip* Animation::findClip(const char* id) const
{
    if (_clips)
    {
        AnimationClip* clip = NULL;
        size_t clipCount = _clips->size();
        for (size_t i = 0; i < clipCount; i++)
        {
            clip = _clips->at(i);
            GP_ASSERT(clip);
            if (clip->_id.compare(id) == 0)
            {
                return clip;
            }
        }
    }
    return NULL;
}

Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
{
    GP_ASSERT(target);
    GP_ASSERT(keyTimes);
    GP_ASSERT(keyValues);

    unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
    GP_ASSERT(propertyComponentCount > 0);

    Curve* curve = Curve::create(keyCount, propertyComponentCount);
    GP_ASSERT(curve);
    if (target->_targetType == AnimationTarget::TRANSFORM)
        setTransformRotationOffset(curve, propertyId);

    unsigned int lowest = keyTimes[0];
    unsigned long duration = keyTimes[keyCount-1] - lowest;

    float* normalizedKeyTimes = new float[keyCount];

    normalizedKeyTimes[0] = 0.0f;
    curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type);

    unsigned int pointOffset = propertyComponentCount;
    unsigned int i = 1;
    for (; i < keyCount - 1; i++)
    {
        normalizedKeyTimes[i] = (float) (keyTimes[i] - lowest) / (float) duration;
        curve->setPoint(i, normalizedKeyTimes[i], (keyValues + pointOffset), (Curve::InterpolationType) type);
        pointOffset += propertyComponentCount;
    }
    i = keyCount - 1;
    normalizedKeyTimes[i] = 1.0f;
    curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);

    SAFE_DELETE_ARRAY(normalizedKeyTimes);

    Channel* channel = new Channel(this, target, propertyId, curve, duration);
    curve->release();
    addChannel(channel);
    return channel;
}

Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
{
    GP_ASSERT(target);
    GP_ASSERT(keyTimes);
    GP_ASSERT(keyValues);

    unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
    GP_ASSERT(propertyComponentCount > 0);

    Curve* curve = Curve::create(keyCount, propertyComponentCount);
    GP_ASSERT(curve);
    if (target->_targetType == AnimationTarget::TRANSFORM)
        setTransformRotationOffset(curve, propertyId);

    unsigned long lowest = keyTimes[0];
    unsigned long duration = keyTimes[keyCount-1] - lowest;

    float* normalizedKeyTimes = new float[keyCount];

    normalizedKeyTimes[0] = 0.0f;
    curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type, keyInValue, keyOutValue);

    unsigned int pointOffset = propertyComponentCount;
    unsigned int i = 1;
    for (; i < keyCount - 1; i++)
    {
        normalizedKeyTimes[i] = (float) (keyTimes[i] - lowest) / (float) duration;
        curve->setPoint(i, normalizedKeyTimes[i], (keyValues + pointOffset), (Curve::InterpolationType) type, (keyInValue + pointOffset), (keyOutValue + pointOffset));
        pointOffset += propertyComponentCount;
    }
    i = keyCount - 1;
    normalizedKeyTimes[i] = 1.0f;
    curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);

    SAFE_DELETE_ARRAY(normalizedKeyTimes);

    Channel* channel = new Channel(this, target, propertyId, curve, duration);
    curve->release();
    addChannel(channel);
    return channel;
}

void Animation::addChannel(Channel* channel)
{
    GP_ASSERT(channel);
    _channels.push_back(channel);

    if (channel->_duration > _duration)
        _duration = channel->_duration;
}

void Animation::removeChannel(Channel* channel)
{
    std::vector<Animation::Channel*>::iterator itr = _channels.begin();
    while (itr != _channels.end())
    {
        Animation::Channel* chan = *itr;
        if (channel == chan)
        {
            _channels.erase(itr);
            return;
        }
        else
        {
            itr++;
        }
    }
}

void Animation::setTransformRotationOffset(Curve* curve, unsigned int propertyId)
{
    GP_ASSERT(curve);

    switch (propertyId)
    {
    case Transform::ANIMATE_ROTATE:
    case Transform::ANIMATE_ROTATE_TRANSLATE:
        curve->setQuaternionOffset(ANIMATION_ROTATE_OFFSET);
        return;
    case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
        curve->setQuaternionOffset(ANIMATION_SRT_OFFSET);
        return;
    }

    return;
}

Animation* Animation::clone(Channel* channel, AnimationTarget* target)
{
    GP_ASSERT(channel);

    Animation* animation = new Animation(getId());

    Animation::Channel* channelCopy = new Animation::Channel(*channel, animation, target);
    animation->addChannel(channelCopy);
    // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
    animation->release();
    GP_ASSERT(animation->getRefCount() == 1);

    // Clone the clips
    if (_clips)
    {
        for (std::vector<AnimationClip*>::iterator it = _clips->begin(); it != _clips->end(); ++it)
        {
            AnimationClip* newClip = (*it)->clone(animation);
            animation->addClip(newClip);
        }
    }
    return animation;
}

}
<commit_msg>Renamed some test resource files for consistency.<commit_after>#include "Base.h"
#include "Animation.h"
#include "AnimationController.h"
#include "AnimationClip.h"
#include "AnimationTarget.h"
#include "Game.h"
#include "Transform.h"
#include "Properties.h"

#define ANIMATION_INDEFINITE_STR "INDEFINITE"
#define ANIMATION_DEFAULT_CLIP 0
#define ANIMATION_ROTATE_OFFSET 0
#define ANIMATION_SRT_OFFSET 3

namespace gameplay
{

Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
{
    createChannel(target, propertyId, keyCount, keyTimes, keyValues, type);

    // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
    release();
    GP_ASSERT(getRefCount() == 1);
}

Animation::Animation(const char* id, AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
{
    createChannel(target, propertyId, keyCount, keyTimes, keyValues, keyInValue, keyOutValue, type);
    // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
    release();
    GP_ASSERT(getRefCount() == 1);
}

Animation::Animation(const char* id)
    : _controller(Game::getInstance()->getAnimationController()), _id(id), _duration(0L), _defaultClip(NULL), _clips(NULL)
{
}

Animation::~Animation()
{
    _channels.clear();

    if (_defaultClip)
    {
        if (_defaultClip->isClipStateBitSet(AnimationClip::CLIP_IS_PLAYING_BIT))
        {
            GP_ASSERT(_controller);
            _controller->unschedule(_defaultClip);
        }
        SAFE_RELEASE(_defaultClip);
    }

    if (_clips)
    {
        std::vector<AnimationClip*>::iterator clipIter = _clips->begin();

        while (clipIter != _clips->end())
        {
            AnimationClip* clip = *clipIter;
            GP_ASSERT(clip);
            if (clip->isClipStateBitSet(AnimationClip::CLIP_IS_PLAYING_BIT))
            {
                GP_ASSERT(_controller);
                _controller->unschedule(clip);
            }
            SAFE_RELEASE(clip);
            clipIter++;
        }
        _clips->clear();
    }
    SAFE_DELETE(_clips);
}

Animation::Channel::Channel(Animation* animation, AnimationTarget* target, int propertyId, Curve* curve, unsigned long duration)
    : _animation(animation), _target(target), _propertyId(propertyId), _curve(curve), _duration(duration)
{
    GP_ASSERT(_animation);
    GP_ASSERT(_target);
    GP_ASSERT(_curve);

    // get property component count, and ensure the property exists on the AnimationTarget by getting the property component count.
    GP_ASSERT(_target->getAnimationPropertyComponentCount(propertyId));
    _curve->addRef();
    _target->addChannel(this);
    _animation->addRef();
}

Animation::Channel::Channel(const Channel& copy, Animation* animation, AnimationTarget* target)
    : _animation(animation), _target(target), _propertyId(copy._propertyId), _curve(copy._curve), _duration(copy._duration)
{
    GP_ASSERT(_curve);
    GP_ASSERT(_target);
    GP_ASSERT(_animation);

    _curve->addRef();
    _target->addChannel(this);
    _animation->addRef();
}

Animation::Channel::~Channel()
{
    SAFE_RELEASE(_curve);
    SAFE_RELEASE(_animation);
}

Curve* Animation::Channel::getCurve() const
{
    return _curve;
}

const char* Animation::getId() const
{
    return _id.c_str();
}

unsigned long Animation::getDuration() const
{
    return _duration;
}

void Animation::createClips(const char* url)
{
    Properties* properties = Properties::create(url);
    GP_ASSERT(properties);

    Properties* pAnimation = (strlen(properties->getNamespace()) > 0) ? properties : properties->getNextNamespace();
    GP_ASSERT(pAnimation);

    int frameCount = pAnimation->getInt("frameCount");
    if (frameCount <= 0)
        GP_ERROR("The animation's frame count must be greater than 0.");

    createClips(pAnimation, (unsigned int)frameCount);

    SAFE_DELETE(properties);
}

AnimationClip* Animation::createClip(const char* id, unsigned long start, unsigned long end)
{
    AnimationClip* clip = new AnimationClip(id, this, start, end);
    addClip(clip);
    return clip;
}

AnimationClip* Animation::getClip(const char* id)
{
    // If id is NULL return the default clip.
    if (id == NULL)
    {
        if (_defaultClip == NULL)
            createDefaultClip();

        return _defaultClip;
    }
    else
    {
        return findClip(id);
    }
}

AnimationClip* Animation::getClip(unsigned int index) const
{
    if (_clips)
        return _clips->at(index);

    return NULL;
}

unsigned int Animation::getClipCount() const
{
    return _clips ? (unsigned int)_clips->size() : 0;
}

void Animation::play(const char* clipId)
{
    // If id is NULL, play the default clip.
    if (clipId == NULL)
    {
        if (_defaultClip == NULL)
            createDefaultClip();

        _defaultClip->play();
    }
    else
    {
        // Find animation clip and play.
        AnimationClip* clip = findClip(clipId);
        if (clip != NULL)
            clip->play();
    }
}

void Animation::stop(const char* clipId)
{
    // If id is NULL, play the default clip.
    if (clipId == NULL)
    {
        if (_defaultClip)
            _defaultClip->stop();
    }
    else
    {
        // Find animation clip and play.
        AnimationClip* clip = findClip(clipId);
        if (clip != NULL)
            clip->stop();
    }
}

void Animation::pause(const char * clipId)
{
    if (clipId == NULL)
    {
        if (_defaultClip)
            _defaultClip->pause();
    }
    else
    {
        AnimationClip* clip = findClip(clipId);
        if (clip != NULL)
            clip->pause();
    }
}

bool Animation::targets(AnimationTarget* target) const
{
    for (std::vector<Animation::Channel*>::const_iterator itr = _channels.begin(); itr != _channels.end(); ++itr)
    {
        GP_ASSERT(*itr);
        if ((*itr)->_target == target)
        {
            return true;
        }
    }
    return false;
}

void Animation::createDefaultClip()
{
    _defaultClip = new AnimationClip("default_clip", this, 0.0f, _duration);
}

void Animation::createClips(Properties* animationProperties, unsigned int frameCount)
{
    GP_ASSERT(animationProperties);

    Properties* pClip = animationProperties->getNextNamespace();

    while (pClip != NULL && std::strcmp(pClip->getNamespace(), "clip") == 0)
    {
        int begin = pClip->getInt("begin");
        int end = pClip->getInt("end");

        AnimationClip* clip = createClip(pClip->getId(), ((float) begin / frameCount) * _duration, ((float) end / frameCount) * _duration);

        const char* repeat = pClip->getString("repeatCount");
        if (repeat)
        {
            if (strcmp(repeat, ANIMATION_INDEFINITE_STR) == 0)
            {
                clip->setRepeatCount(AnimationClip::REPEAT_INDEFINITE);
            }
            else
            {
                float value;
                sscanf(repeat, "%f", &value);
                clip->setRepeatCount(value);
            }
        }

        const char* speed = pClip->getString("speed");
        if (speed)
        {
            float value;
            sscanf(speed, "%f", &value);
            clip->setSpeed(value);
        }

        pClip = animationProperties->getNextNamespace();
    }
}

void Animation::addClip(AnimationClip* clip)
{
    if (_clips == NULL)
        _clips = new std::vector<AnimationClip*>;

    GP_ASSERT(clip);
    _clips->push_back(clip);
}

AnimationClip* Animation::findClip(const char* id) const
{
    if (_clips)
    {
        AnimationClip* clip = NULL;
        size_t clipCount = _clips->size();
        for (size_t i = 0; i < clipCount; i++)
        {
            clip = _clips->at(i);
            GP_ASSERT(clip);
            if (clip->_id.compare(id) == 0)
            {
                return clip;
            }
        }
    }
    return NULL;
}

Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, unsigned int type)
{
    GP_ASSERT(target);
    GP_ASSERT(keyTimes);
    GP_ASSERT(keyValues);

    unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
    GP_ASSERT(propertyComponentCount > 0);

    Curve* curve = Curve::create(keyCount, propertyComponentCount);
    GP_ASSERT(curve);
    if (target->_targetType == AnimationTarget::TRANSFORM)
        setTransformRotationOffset(curve, propertyId);

    unsigned int lowest = keyTimes[0];
    unsigned long duration = keyTimes[keyCount-1] - lowest;

    float* normalizedKeyTimes = new float[keyCount];

    normalizedKeyTimes[0] = 0.0f;
    curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type);

    unsigned int pointOffset = propertyComponentCount;
    unsigned int i = 1;
    for (; i < keyCount - 1; i++)
    {
        normalizedKeyTimes[i] = (float) (keyTimes[i] - lowest) / (float) duration;
        curve->setPoint(i, normalizedKeyTimes[i], (keyValues + pointOffset), (Curve::InterpolationType) type);
        pointOffset += propertyComponentCount;
    }
    i = keyCount - 1;
    normalizedKeyTimes[i] = 1.0f;
    curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type);

    SAFE_DELETE_ARRAY(normalizedKeyTimes);

    Channel* channel = new Channel(this, target, propertyId, curve, duration);
    curve->release();
    addChannel(channel);
    return channel;
}

Animation::Channel* Animation::createChannel(AnimationTarget* target, int propertyId, unsigned int keyCount, unsigned int* keyTimes, float* keyValues, float* keyInValue, float* keyOutValue, unsigned int type)
{
    GP_ASSERT(target);
    GP_ASSERT(keyTimes);
    GP_ASSERT(keyValues);

    unsigned int propertyComponentCount = target->getAnimationPropertyComponentCount(propertyId);
    GP_ASSERT(propertyComponentCount > 0);

    Curve* curve = Curve::create(keyCount, propertyComponentCount);
    GP_ASSERT(curve);
    if (target->_targetType == AnimationTarget::TRANSFORM)
        setTransformRotationOffset(curve, propertyId);

    unsigned long lowest = keyTimes[0];
    unsigned long duration = keyTimes[keyCount-1] - lowest;

    float* normalizedKeyTimes = new float[keyCount];

    normalizedKeyTimes[0] = 0.0f;
    curve->setPoint(0, normalizedKeyTimes[0], keyValues, (Curve::InterpolationType) type, keyInValue, keyOutValue);

    unsigned int pointOffset = propertyComponentCount;
    unsigned int i = 1;
    for (; i < keyCount - 1; i++)
    {
        normalizedKeyTimes[i] = (float) (keyTimes[i] - lowest) / (float) duration;
        curve->setPoint(i, normalizedKeyTimes[i], (keyValues + pointOffset), (Curve::InterpolationType) type, (keyInValue + pointOffset), (keyOutValue + pointOffset));
        pointOffset += propertyComponentCount;
    }
    i = keyCount - 1;
    normalizedKeyTimes[i] = 1.0f;
    curve->setPoint(i, normalizedKeyTimes[i], keyValues + pointOffset, (Curve::InterpolationType) type, keyInValue + pointOffset, keyOutValue + pointOffset);

    SAFE_DELETE_ARRAY(normalizedKeyTimes);

    Channel* channel = new Channel(this, target, propertyId, curve, duration);
    curve->release();
    addChannel(channel);
    return channel;
}

void Animation::addChannel(Channel* channel)
{
    GP_ASSERT(channel);
    _channels.push_back(channel);

    if (channel->_duration > _duration)
        _duration = channel->_duration;
}

void Animation::removeChannel(Channel* channel)
{
    std::vector<Animation::Channel*>::iterator itr = _channels.begin();
    while (itr != _channels.end())
    {
        Animation::Channel* chan = *itr;
        if (channel == chan)
        {
            _channels.erase(itr);
            return;
        }
        else
        {
            itr++;
        }
    }
}

void Animation::setTransformRotationOffset(Curve* curve, unsigned int propertyId)
{
    GP_ASSERT(curve);

    switch (propertyId)
    {
    case Transform::ANIMATE_ROTATE:
    case Transform::ANIMATE_ROTATE_TRANSLATE:
        curve->setQuaternionOffset(ANIMATION_ROTATE_OFFSET);
        return;
    case Transform::ANIMATE_SCALE_ROTATE_TRANSLATE:
        curve->setQuaternionOffset(ANIMATION_SRT_OFFSET);
        return;
    }

    return;
}

Animation* Animation::clone(Channel* channel, AnimationTarget* target)
{
    GP_ASSERT(channel);

    Animation* animation = new Animation(getId());

    Animation::Channel* channelCopy = new Animation::Channel(*channel, animation, target);
    animation->addChannel(channelCopy);
    // Release the animation because a newly created animation has a ref count of 1 and the channels hold the ref to animation.
    animation->release();
    GP_ASSERT(animation->getRefCount() == 1);

    // Clone the clips
    if (_clips)
    {
        for (std::vector<AnimationClip*>::iterator it = _clips->begin(); it != _clips->end(); ++it)
        {
            AnimationClip* newClip = (*it)->clone(animation);
            animation->addClip(newClip);
        }
    }
    return animation;
}

}
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"

#include <string>

#include "base/bind.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros_settings.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/proxy_config_service_impl.h"
#include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/prefs/pref_set_observer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "content/browser/user_metrics.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"

namespace chromeos {

namespace {

// Create a settings value with "managed" and "disabled" property.
// "managed" property is true if the setting is managed by administrator.
// "disabled" property is true if the UI for the setting should be disabled.
base::Value* CreateSettingsValue(base::Value *value,
                                 bool managed,
                                 bool disabled) {
  DictionaryValue* dict = new DictionaryValue;
  dict->Set("value", value);
  dict->Set("managed", base::Value::CreateBooleanValue(managed));
  dict->Set("disabled", base::Value::CreateBooleanValue(disabled));
  return dict;
}

// Returns true if |username| is the logged-in owner.
bool IsLoggedInOwner(const std::string& username) {
  UserManager* user_manager = UserManager::Get();
  return user_manager->current_user_is_owner() &&
      user_manager->logged_in_user().email() == username;
}

// Creates a user info dictionary to be stored in the |ListValue| that is
// passed to Javascript for the |kAccountsPrefUsers| preference.
base::DictionaryValue* CreateUserInfo(const std::string& username,
                                      const std::string& display_email,
                                      const std::string& display_name) {
  base::DictionaryValue* user_dict = new DictionaryValue;
  user_dict->SetString("username", username);
  user_dict->SetString("name", display_email);
  user_dict->SetString("email", display_name);
  user_dict->SetBoolean("owner", IsLoggedInOwner(username));
  return user_dict;
}

// This function decorates the bare list of emails with some more information
// needed by the UI to properly display the Accounts page.
base::Value* CreateUsersWhitelist(const base::Value *pref_value) {
  const base::ListValue* list_value =
      static_cast<const base::ListValue*>(pref_value);
  base::ListValue* user_list = new base::ListValue();
  UserManager* user_manager = UserManager::Get();

  for (base::ListValue::const_iterator i = list_value->begin();
       i != list_value->end(); ++i) {
    std::string email;
    if ((*i)->GetAsString(&email)) {
      // Translate email to the display email.
      std::string display_email = user_manager->GetUserDisplayEmail(email);
      // TODO(ivankr): fetch display name for existing users.
      user_list->Append(CreateUserInfo(email, display_email, std::string()));
    }
  }
  return user_list;
}

}  // namespace

CoreChromeOSOptionsHandler::CoreChromeOSOptionsHandler()
    : handling_change_(false),
      pointer_factory_(this) {
}

CoreChromeOSOptionsHandler::~CoreChromeOSOptionsHandler() {
  PrefProxyConfigTracker* proxy_tracker =
      Profile::FromWebUI(web_ui_)->GetProxyConfigTracker();
  proxy_tracker->RemoveNotificationCallback(
      base::Bind(&CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged,
                 pointer_factory_.GetWeakPtr()));
}

void CoreChromeOSOptionsHandler::Initialize() {
  proxy_prefs_.reset(PrefSetObserver::CreateProxyPrefSetObserver(
    Profile::FromWebUI(web_ui_)->GetPrefs(), this));
  // Observe the chromeos::ProxyConfigServiceImpl for changes from the UI.
  PrefProxyConfigTracker* proxy_tracker =
      Profile::FromWebUI(web_ui_)->GetProxyConfigTracker();
  proxy_tracker->AddNotificationCallback(
      base::Bind(&CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged,
                 pointer_factory_.GetWeakPtr()));
}

base::Value* CoreChromeOSOptionsHandler::FetchPref(
    const std::string& pref_name) {
  if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
    base::Value *value = NULL;
    proxy_cros_settings_parser::GetProxyPrefValue(Profile::FromWebUI(web_ui_),
                                                  pref_name, &value);
    if (!value)
      return base::Value::CreateNullValue();

    return value;
  }
  if (!CrosSettings::IsCrosSettings(pref_name)) {
    // Specially handle kUseSharedProxies because kProxy controls it to
    // determine if it's managed by policy/extension.
    if (pref_name == prefs::kUseSharedProxies) {
      PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs();
      const PrefService::Preference* pref =
          pref_service->FindPreference(prefs::kUseSharedProxies);
      if (!pref)
        return base::Value::CreateNullValue();
      const PrefService::Preference* controlling_pref =
          pref_service->FindPreference(prefs::kProxy);
      return CreateValueForPref(pref, controlling_pref);
    }
    return ::CoreOptionsHandler::FetchPref(pref_name);
  }

  const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name);
  if (!pref_value)
    return base::Value::CreateNullValue();

  // Lists don't get the standard pref decoration.
  if (pref_value->GetType() == base::Value::TYPE_LIST) {
    if (pref_name == kAccountsPrefUsers)
      return CreateUsersWhitelist(pref_value);
    // Return a copy because the UI will take ownership of this object.
    return pref_value->DeepCopy();
  }
  // All other prefs are decorated the same way.
  return CreateSettingsValue(
      pref_value->DeepCopy(),  // The copy will be owned by the dictionary.
      g_browser_process->browser_policy_connector()->IsEnterpriseManaged(),
      !UserManager::Get()->current_user_is_owner());
}

void CoreChromeOSOptionsHandler::ObservePref(const std::string& pref_name) {
  if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
    // We observe those all the time.
    return;
  }
  if (!CrosSettings::IsCrosSettings(pref_name))
    return ::CoreOptionsHandler::ObservePref(pref_name);
  CrosSettings::Get()->AddSettingsObserver(pref_name.c_str(), this);
}

void CoreChromeOSOptionsHandler::SetPref(const std::string& pref_name,
                                         const base::Value* value,
                                         const std::string& metric) {
  if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
    proxy_cros_settings_parser::SetProxyPrefValue(Profile::FromWebUI(web_ui_),
                                                  pref_name, value);
    ProcessUserMetric(value, metric);
    return;
  }
  if (!CrosSettings::IsCrosSettings(pref_name))
    return ::CoreOptionsHandler::SetPref(pref_name, value, metric);
  handling_change_ = true;
  CrosSettings::Get()->Set(pref_name, *value);
  handling_change_ = false;

  ProcessUserMetric(value, metric);
}

void CoreChromeOSOptionsHandler::StopObservingPref(const std::string& path) {
  if (proxy_cros_settings_parser::IsProxyPref(path))
    return;  // We unregister those in the destructor.
  // Unregister this instance from observing prefs of chrome os settings.
  if (CrosSettings::IsCrosSettings(path))
    CrosSettings::Get()->RemoveSettingsObserver(path.c_str(), this);
  else  // Call base class to handle regular preferences.
    ::CoreOptionsHandler::StopObservingPref(path);
}

void CoreChromeOSOptionsHandler::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  // Ignore the notification if this instance had caused it.
  if (handling_change_)
    return;
  if (type == chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED) {
    NotifySettingsChanged(content::Details<std::string>(details).ptr());
    return;
  }
  // Special handling for preferences kUseSharedProxies and kProxy, the latter
  // controls the former and decides if it's managed by policy/extension.
  if (type == chrome::NOTIFICATION_PREF_CHANGED) {
    const PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs();
    std::string* pref_name = content::Details<std::string>(details).ptr();
    if (content::Source<PrefService>(source).ptr() == pref_service &&
        (proxy_prefs_->IsObserved(*pref_name) ||
         *pref_name == prefs::kUseSharedProxies)) {
      NotifyPrefChanged(prefs::kUseSharedProxies, prefs::kProxy);
      return;
    }
  }
  ::CoreOptionsHandler::Observe(type, source, details);
}

void CoreChromeOSOptionsHandler::NotifySettingsChanged(
    const std::string* setting_name) {
  DCHECK(web_ui_);
  DCHECK(CrosSettings::Get()->IsCrosSettings(*setting_name));
  const base::Value* value = FetchPref(*setting_name);
  if (!value) {
    NOTREACHED();
    return;
  }
  for (PreferenceCallbackMap::const_iterator iter =
      pref_callback_map_.find(*setting_name);
      iter != pref_callback_map_.end(); ++iter) {
    const std::wstring& callback_function = iter->second;
    ListValue result_value;
    result_value.Append(base::Value::CreateStringValue(setting_name->c_str()));
    result_value.Append(value->DeepCopy());
    web_ui_->CallJavascriptFunction(WideToASCII(callback_function),
                                    result_value);
  }
  if (value)
    delete value;
}

void CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged() {
  DCHECK(web_ui_);
  for (size_t i = 0; i < kProxySettingsCount; ++i) {
    base::Value* value = NULL;
    proxy_cros_settings_parser::GetProxyPrefValue(
        Profile::FromWebUI(web_ui_), kProxySettings[i], &value);
    DCHECK(value);
    PreferenceCallbackMap::const_iterator iter =
        pref_callback_map_.find(kProxySettings[i]);
    for (; iter != pref_callback_map_.end(); ++iter) {
      const std::wstring& callback_function = iter->second;
      ListValue result_value;
      result_value.Append(base::Value::CreateStringValue(kProxySettings[i]));
      result_value.Append(value->DeepCopy());
      web_ui_->CallJavascriptFunction(WideToASCII(callback_function),
                                      result_value);
    }
    if (value)
      delete value;
  }
}

}  // namespace chromeos
<commit_msg>[cros] System setting change is correctly reported to a single JS callback.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/webui/options/chromeos/core_chromeos_options_handler.h"

#include <string>

#include "base/bind.h"
#include "base/string_number_conversions.h"
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/cros_settings.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/proxy_config_service_impl.h"
#include "chrome/browser/chromeos/proxy_cros_settings_parser.h"
#include "chrome/browser/policy/browser_policy_connector.h"
#include "chrome/browser/prefs/pref_set_observer.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/webui/options/chromeos/accounts_options_handler.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/pref_names.h"
#include "content/browser/user_metrics.h"
#include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_source.h"

namespace chromeos {

namespace {

// Create a settings value with "managed" and "disabled" property.
// "managed" property is true if the setting is managed by administrator.
// "disabled" property is true if the UI for the setting should be disabled.
base::Value* CreateSettingsValue(base::Value *value,
                                 bool managed,
                                 bool disabled) {
  DictionaryValue* dict = new DictionaryValue;
  dict->Set("value", value);
  dict->Set("managed", base::Value::CreateBooleanValue(managed));
  dict->Set("disabled", base::Value::CreateBooleanValue(disabled));
  return dict;
}

// Returns true if |username| is the logged-in owner.
bool IsLoggedInOwner(const std::string& username) {
  UserManager* user_manager = UserManager::Get();
  return user_manager->current_user_is_owner() &&
      user_manager->logged_in_user().email() == username;
}

// Creates a user info dictionary to be stored in the |ListValue| that is
// passed to Javascript for the |kAccountsPrefUsers| preference.
base::DictionaryValue* CreateUserInfo(const std::string& username,
                                      const std::string& display_email,
                                      const std::string& display_name) {
  base::DictionaryValue* user_dict = new DictionaryValue;
  user_dict->SetString("username", username);
  user_dict->SetString("name", display_email);
  user_dict->SetString("email", display_name);
  user_dict->SetBoolean("owner", IsLoggedInOwner(username));
  return user_dict;
}

// This function decorates the bare list of emails with some more information
// needed by the UI to properly display the Accounts page.
base::Value* CreateUsersWhitelist(const base::Value *pref_value) {
  const base::ListValue* list_value =
      static_cast<const base::ListValue*>(pref_value);
  base::ListValue* user_list = new base::ListValue();
  UserManager* user_manager = UserManager::Get();

  for (base::ListValue::const_iterator i = list_value->begin();
       i != list_value->end(); ++i) {
    std::string email;
    if ((*i)->GetAsString(&email)) {
      // Translate email to the display email.
      std::string display_email = user_manager->GetUserDisplayEmail(email);
      // TODO(ivankr): fetch display name for existing users.
      user_list->Append(CreateUserInfo(email, display_email, std::string()));
    }
  }
  return user_list;
}

}  // namespace

CoreChromeOSOptionsHandler::CoreChromeOSOptionsHandler()
    : handling_change_(false),
      pointer_factory_(this) {
}

CoreChromeOSOptionsHandler::~CoreChromeOSOptionsHandler() {
  PrefProxyConfigTracker* proxy_tracker =
      Profile::FromWebUI(web_ui_)->GetProxyConfigTracker();
  proxy_tracker->RemoveNotificationCallback(
      base::Bind(&CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged,
                 pointer_factory_.GetWeakPtr()));
}

void CoreChromeOSOptionsHandler::Initialize() {
  proxy_prefs_.reset(PrefSetObserver::CreateProxyPrefSetObserver(
    Profile::FromWebUI(web_ui_)->GetPrefs(), this));
  // Observe the chromeos::ProxyConfigServiceImpl for changes from the UI.
  PrefProxyConfigTracker* proxy_tracker =
      Profile::FromWebUI(web_ui_)->GetProxyConfigTracker();
  proxy_tracker->AddNotificationCallback(
      base::Bind(&CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged,
                 pointer_factory_.GetWeakPtr()));
}

base::Value* CoreChromeOSOptionsHandler::FetchPref(
    const std::string& pref_name) {
  if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
    base::Value *value = NULL;
    proxy_cros_settings_parser::GetProxyPrefValue(Profile::FromWebUI(web_ui_),
                                                  pref_name, &value);
    if (!value)
      return base::Value::CreateNullValue();

    return value;
  }
  if (!CrosSettings::IsCrosSettings(pref_name)) {
    // Specially handle kUseSharedProxies because kProxy controls it to
    // determine if it's managed by policy/extension.
    if (pref_name == prefs::kUseSharedProxies) {
      PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs();
      const PrefService::Preference* pref =
          pref_service->FindPreference(prefs::kUseSharedProxies);
      if (!pref)
        return base::Value::CreateNullValue();
      const PrefService::Preference* controlling_pref =
          pref_service->FindPreference(prefs::kProxy);
      return CreateValueForPref(pref, controlling_pref);
    }
    return ::CoreOptionsHandler::FetchPref(pref_name);
  }

  const base::Value* pref_value = CrosSettings::Get()->GetPref(pref_name);
  if (!pref_value)
    return base::Value::CreateNullValue();

  // Lists don't get the standard pref decoration.
  if (pref_value->GetType() == base::Value::TYPE_LIST) {
    if (pref_name == kAccountsPrefUsers)
      return CreateUsersWhitelist(pref_value);
    // Return a copy because the UI will take ownership of this object.
    return pref_value->DeepCopy();
  }
  // All other prefs are decorated the same way.
  return CreateSettingsValue(
      pref_value->DeepCopy(),  // The copy will be owned by the dictionary.
      g_browser_process->browser_policy_connector()->IsEnterpriseManaged(),
      !UserManager::Get()->current_user_is_owner());
}

void CoreChromeOSOptionsHandler::ObservePref(const std::string& pref_name) {
  if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
    // We observe those all the time.
    return;
  }
  if (!CrosSettings::IsCrosSettings(pref_name))
    return ::CoreOptionsHandler::ObservePref(pref_name);
  CrosSettings::Get()->AddSettingsObserver(pref_name.c_str(), this);
}

void CoreChromeOSOptionsHandler::SetPref(const std::string& pref_name,
                                         const base::Value* value,
                                         const std::string& metric) {
  if (proxy_cros_settings_parser::IsProxyPref(pref_name)) {
    proxy_cros_settings_parser::SetProxyPrefValue(Profile::FromWebUI(web_ui_),
                                                  pref_name, value);
    ProcessUserMetric(value, metric);
    return;
  }
  if (!CrosSettings::IsCrosSettings(pref_name))
    return ::CoreOptionsHandler::SetPref(pref_name, value, metric);
  handling_change_ = true;
  CrosSettings::Get()->Set(pref_name, *value);
  handling_change_ = false;

  ProcessUserMetric(value, metric);
}

void CoreChromeOSOptionsHandler::StopObservingPref(const std::string& path) {
  if (proxy_cros_settings_parser::IsProxyPref(path))
    return;  // We unregister those in the destructor.
  // Unregister this instance from observing prefs of chrome os settings.
  if (CrosSettings::IsCrosSettings(path))
    CrosSettings::Get()->RemoveSettingsObserver(path.c_str(), this);
  else  // Call base class to handle regular preferences.
    ::CoreOptionsHandler::StopObservingPref(path);
}

void CoreChromeOSOptionsHandler::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
  // Ignore the notification if this instance had caused it.
  if (handling_change_)
    return;
  if (type == chrome::NOTIFICATION_SYSTEM_SETTING_CHANGED) {
    NotifySettingsChanged(content::Details<std::string>(details).ptr());
    return;
  }
  // Special handling for preferences kUseSharedProxies and kProxy, the latter
  // controls the former and decides if it's managed by policy/extension.
  if (type == chrome::NOTIFICATION_PREF_CHANGED) {
    const PrefService* pref_service = Profile::FromWebUI(web_ui_)->GetPrefs();
    std::string* pref_name = content::Details<std::string>(details).ptr();
    if (content::Source<PrefService>(source).ptr() == pref_service &&
        (proxy_prefs_->IsObserved(*pref_name) ||
         *pref_name == prefs::kUseSharedProxies)) {
      NotifyPrefChanged(prefs::kUseSharedProxies, prefs::kProxy);
      return;
    }
  }
  ::CoreOptionsHandler::Observe(type, source, details);
}

void CoreChromeOSOptionsHandler::NotifySettingsChanged(
    const std::string* setting_name) {
  DCHECK(web_ui_);
  DCHECK(CrosSettings::Get()->IsCrosSettings(*setting_name));
  const base::Value* value = FetchPref(*setting_name);
  if (!value) {
    NOTREACHED();
    return;
  }
  std::pair<PreferenceCallbackMap::const_iterator,
            PreferenceCallbackMap::const_iterator> range =
      pref_callback_map_.equal_range(*setting_name);
  for (PreferenceCallbackMap::const_iterator iter = range.first;
      iter != range.second; ++iter) {
    const std::wstring& callback_function = iter->second;
    ListValue result_value;
    result_value.Append(base::Value::CreateStringValue(setting_name->c_str()));
    result_value.Append(value->DeepCopy());
    web_ui_->CallJavascriptFunction(WideToASCII(callback_function),
                                    result_value);
  }
  if (value)
    delete value;
}

void CoreChromeOSOptionsHandler::NotifyProxyPrefsChanged() {
  DCHECK(web_ui_);
  for (size_t i = 0; i < kProxySettingsCount; ++i) {
    base::Value* value = NULL;
    proxy_cros_settings_parser::GetProxyPrefValue(
        Profile::FromWebUI(web_ui_), kProxySettings[i], &value);
    DCHECK(value);
    PreferenceCallbackMap::const_iterator iter =
        pref_callback_map_.find(kProxySettings[i]);
    for (; iter != pref_callback_map_.end(); ++iter) {
      const std::wstring& callback_function = iter->second;
      ListValue result_value;
      result_value.Append(base::Value::CreateStringValue(kProxySettings[i]));
      result_value.Append(value->DeepCopy());
      web_ui_->CallJavascriptFunction(WideToASCII(callback_function),
                                      result_value);
    }
    if (value)
      delete value;
  }
}

}  // namespace chromeos
<|endoftext|>


<commit_before>#include <cassert>
#include <chrono>
#include "Noise/CurlNoise.h"

#define ASSERT(e) assert(e)
//#define ASSERT(e) if (!(e)) printf("assert failed.\n");

using namespace Effekseer;

void Test_Turbulence()
{
	using namespace std::chrono;

	const uint32_t IterationCount = 10;

	printf("Turbulence Test\n");

	CurlNoise noise(0);
	noise.Octave = 1.0f;
	noise.Scale = 1.0f;

	Vec3f position{0.0f, 0.0f, 0.0f};
	for (uint32_t iteration = 0; iteration < IterationCount; iteration++) {
		position = noise.Get(position);
		printf("- (%f, %f, %f)\n", position.GetX(), position.GetY(), position.GetZ());
	}
}

void MeasurePerformance_Turbulence()
{
	using namespace std::chrono;

	const uint32_t IterationCount = 10;
	const uint32_t CallCount = 100;
	const uint32_t InstanceCount = 1000;

	std::vector<std::unique_ptr<CurlNoise>> noise;
	for (uint32_t instanceIndex = 0; instanceIndex < InstanceCount; instanceIndex++) {
		noise.emplace_back(new CurlNoise(instanceIndex));
		noise[instanceIndex]->Octave = 1.0f;
		noise[instanceIndex]->Scale = 1.0f;
	}

	printf("Turbulence Performance - Calls=%u, Instances:%u\n", CallCount, InstanceCount);

	for (uint32_t iteration = 0; iteration < IterationCount; iteration++) {
		auto t0 = high_resolution_clock::now();

		for (size_t calling = 0; calling < CallCount; calling++) {
			for (size_t instanceIndex = 0; instanceIndex < InstanceCount; instanceIndex++) {
				noise[instanceIndex]->Get(Vec3f(0.0f, 0.0f, 0.0f));
			}
		}

		auto t1 = high_resolution_clock::now();

		printf("- elapsed: %lld[usec]\n", duration_cast<microseconds>(t1 - t0).count());
	}
}

int main(int argc, char *argv[])
{
	Test_Turbulence();
	MeasurePerformance_Turbulence();

	return 0;
}
<commit_msg>fix warning<commit_after>#include <cassert>
#include <chrono>
#include "Noise/CurlNoise.h"

#define ASSERT(e) assert(e)
//#define ASSERT(e) if (!(e)) printf("assert failed.\n");

using namespace Effekseer;

void Test_Turbulence()
{
	using namespace std::chrono;

	const uint32_t IterationCount = 10;

	printf("Turbulence Test\n");

	CurlNoise noise(0);
	noise.Octave = 1;
	noise.Scale = 1;

	Vec3f position{0.0f, 0.0f, 0.0f};
	for (uint32_t iteration = 0; iteration < IterationCount; iteration++) {
		position = noise.Get(position);
		printf("- (%f, %f, %f)\n", position.GetX(), position.GetY(), position.GetZ());
	}
}

void MeasurePerformance_Turbulence()
{
	using namespace std::chrono;

	const uint32_t IterationCount = 10;
	const uint32_t CallCount = 100;
	const uint32_t InstanceCount = 1000;

	std::vector<std::unique_ptr<CurlNoise>> noise;
	for (uint32_t instanceIndex = 0; instanceIndex < InstanceCount; instanceIndex++) {
		noise.emplace_back(new CurlNoise(instanceIndex));
		noise[instanceIndex]->Octave = 1.0f;
		noise[instanceIndex]->Scale = 1.0f;
	}

	printf("Turbulence Performance - Calls=%u, Instances:%u\n", CallCount, InstanceCount);

	for (uint32_t iteration = 0; iteration < IterationCount; iteration++) {
		auto t0 = high_resolution_clock::now();

		for (size_t calling = 0; calling < CallCount; calling++) {
			for (size_t instanceIndex = 0; instanceIndex < InstanceCount; instanceIndex++) {
				noise[instanceIndex]->Get(Vec3f(0.0f, 0.0f, 0.0f));
			}
		}

		auto t1 = high_resolution_clock::now();

		printf("- elapsed: %lld[usec]\n", duration_cast<microseconds>(t1 - t0).count());
	}
}

int main(int argc, char *argv[])
{
	Test_Turbulence();
	MeasurePerformance_Turbulence();

	return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/thread_local.h"

#include <pthread.h>

#include "base/logging.h"

namespace base {

// static
void ThreadLocalPlatform::AllocateSlot(SlotType& slot) {
  int error = pthread_key_create(&slot, NULL);
  CHECK(error == 0);
}

// static
void ThreadLocalPlatform::FreeSlot(SlotType& slot) {
  int error = pthread_key_delete(slot);
  DCHECK(error == 0);
}

// static
void* ThreadLocalPlatform::GetValueFromSlot(SlotType& slot) {
  return pthread_getspecific(slot_);
}

// static
void ThreadLocalPlatform::SetValueInSlot(SlotType& slot, void* value) {
  int error = pthread_setspecific(slot, value);
  CHECK(error == 0);
}

}  // namespace base
<commit_msg>Fix a typo that broke the posix build.<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/thread_local.h"

#include <pthread.h>

#include "base/logging.h"

namespace base {

// static
void ThreadLocalPlatform::AllocateSlot(SlotType& slot) {
  int error = pthread_key_create(&slot, NULL);
  CHECK(error == 0);
}

// static
void ThreadLocalPlatform::FreeSlot(SlotType& slot) {
  int error = pthread_key_delete(slot);
  DCHECK(error == 0);
}

// static
void* ThreadLocalPlatform::GetValueFromSlot(SlotType& slot) {
  return pthread_getspecific(slot);
}

// static
void ThreadLocalPlatform::SetValueInSlot(SlotType& slot, void* value) {
  int error = pthread_setspecific(slot, value);
  CHECK(error == 0);
}

}  // namespace base
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/render_widget_host_view_base.h"

#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/port/browser/smooth_scroll_gesture.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"

#if defined(TOOLKIT_GTK)
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

#include "content/browser/renderer_host/gtk_window_utils.h"
#endif

namespace content {

// How long a smooth scroll gesture should run when it is a near scroll.
static const double kDurationOfNearScrollGestureSec = 0.15;

// How long a smooth scroll gesture should run when it is a far scroll.
static const double kDurationOfFarScrollGestureSec = 0.5;

// static
RenderWidgetHostViewPort* RenderWidgetHostViewPort::FromRWHV(
    RenderWidgetHostView* rwhv) {
  return static_cast<RenderWidgetHostViewPort*>(rwhv);
}

// static
RenderWidgetHostViewPort* RenderWidgetHostViewPort::CreateViewForWidget(
    content::RenderWidgetHost* widget) {
  return FromRWHV(RenderWidgetHostView::CreateViewForWidget(widget));
}

RenderWidgetHostViewBase::RenderWidgetHostViewBase()
    : popup_type_(WebKit::WebPopupTypeNone),
      mouse_locked_(false),
      showing_context_menu_(false),
      selection_text_offset_(0),
      selection_range_(ui::Range::InvalidRange()),
      current_device_scale_factor_(0) {
}

RenderWidgetHostViewBase::~RenderWidgetHostViewBase() {
  DCHECK(!mouse_locked_);
}

void RenderWidgetHostViewBase::SetBackground(const SkBitmap& background) {
  background_ = background;
}

const SkBitmap& RenderWidgetHostViewBase::GetBackground() {
  return background_;
}

void RenderWidgetHostViewBase::SelectionChanged(const string16& text,
                                                size_t offset,
                                                const ui::Range& range) {
  selection_text_ = text;
  selection_text_offset_ = offset;
  selection_range_.set_start(range.start());
  selection_range_.set_end(range.end());
}

bool RenderWidgetHostViewBase::IsShowingContextMenu() const {
  return showing_context_menu_;
}

void RenderWidgetHostViewBase::SetShowingContextMenu(bool showing) {
  DCHECK_NE(showing_context_menu_, showing);
  showing_context_menu_ = showing;
}

bool RenderWidgetHostViewBase::IsMouseLocked() {
  return mouse_locked_;
}

void RenderWidgetHostViewBase::UnhandledWheelEvent(
    const WebKit::WebMouseWheelEvent& event) {
  // Most implementations don't need to do anything here.
}

void RenderWidgetHostViewBase::SetPopupType(WebKit::WebPopupType popup_type) {
  popup_type_ = popup_type;
}

WebKit::WebPopupType RenderWidgetHostViewBase::GetPopupType() {
  return popup_type_;
}

BrowserAccessibilityManager*
    RenderWidgetHostViewBase::GetBrowserAccessibilityManager() const {
  return browser_accessibility_manager_.get();
}

void RenderWidgetHostViewBase::SetBrowserAccessibilityManager(
    BrowserAccessibilityManager* manager) {
  browser_accessibility_manager_.reset(manager);
}

void RenderWidgetHostViewBase::UpdateScreenInfo() {
  gfx::Display display = gfx::Screen::GetDisplayNearestPoint(
      GetViewBounds().origin());
  if (current_display_area_ == display.bounds() &&
      current_device_scale_factor_ == display.device_scale_factor())
    return;
  current_display_area_ = display.bounds();
  current_device_scale_factor_ = display.device_scale_factor();
  if (GetRenderWidgetHost()) {
    RenderWidgetHostImpl* impl =
        RenderWidgetHostImpl::From(GetRenderWidgetHost());
    impl->NotifyScreenInfoChanged();
  }
}

class BasicMouseWheelSmoothScrollGesture
    : public SmoothScrollGesture {
 public:
  BasicMouseWheelSmoothScrollGesture(bool scroll_down, bool scroll_far)
      : start_time_(base::TimeTicks::HighResNow()),
        scroll_down_(scroll_down),
        scroll_far_(scroll_far) { }

  virtual bool ForwardInputEvents(base::TimeTicks now,
                                  RenderWidgetHost* host) OVERRIDE {
    double duration_in_seconds;
    if (scroll_far_)
      duration_in_seconds = kDurationOfFarScrollGestureSec;
    else
      duration_in_seconds = kDurationOfNearScrollGestureSec;

    if (now - start_time_ > base::TimeDelta::FromSeconds(duration_in_seconds))
      return false;

    WebKit::WebMouseWheelEvent event;
    event.type = WebKit::WebInputEvent::MouseWheel;
    // TODO(nduca): Figure out plausible value.
    event.deltaY = scroll_down_ ? -10 : 10;
    event.wheelTicksY = scroll_down_ ? 1 : -1;
    event.modifiers = 0;

    // TODO(nduca): Figure out plausible x and y values.
    event.globalX = 0;
    event.globalY = 0;
    event.x = 0;
    event.y = 0;
    event.windowX = event.x;
    event.windowY = event.y;
    host->ForwardWheelEvent(event);
    return true;
  }

 private:
  base::TimeTicks start_time_;
  bool scroll_down_;
  bool scroll_far_;
};

SmoothScrollGesture* RenderWidgetHostViewBase::CreateSmoothScrollGesture(
    bool scroll_down, bool scroll_far) {
  return new BasicMouseWheelSmoothScrollGesture(scroll_down, scroll_far);
}

}  // namespace content
<commit_msg>beginSmoothScroll tries to do a simple animation for a given length in seconds, specified as a double. To do a half-second animation, it did base::TimeDelta::FromSeconds(0.5). base::TimeDelta::FromSeconds takes an in64, so this silently converts to FromSeconds(0) causing the smooth scroll to do exactly one step and stop.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/render_widget_host_view_base.h"

#include "base/logging.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/port/browser/smooth_scroll_gesture.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebScreenInfo.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"

#if defined(TOOLKIT_GTK)
#include <gdk/gdkx.h>
#include <gtk/gtk.h>

#include "content/browser/renderer_host/gtk_window_utils.h"
#endif

namespace content {

// How long a smooth scroll gesture should run when it is a near scroll.
static const int64 kDurationOfNearScrollGestureMs = 150;

// How long a smooth scroll gesture should run when it is a far scroll.
static const int64 kDurationOfFarScrollGestureMs = 500;

// static
RenderWidgetHostViewPort* RenderWidgetHostViewPort::FromRWHV(
    RenderWidgetHostView* rwhv) {
  return static_cast<RenderWidgetHostViewPort*>(rwhv);
}

// static
RenderWidgetHostViewPort* RenderWidgetHostViewPort::CreateViewForWidget(
    content::RenderWidgetHost* widget) {
  return FromRWHV(RenderWidgetHostView::CreateViewForWidget(widget));
}

RenderWidgetHostViewBase::RenderWidgetHostViewBase()
    : popup_type_(WebKit::WebPopupTypeNone),
      mouse_locked_(false),
      showing_context_menu_(false),
      selection_text_offset_(0),
      selection_range_(ui::Range::InvalidRange()),
      current_device_scale_factor_(0) {
}

RenderWidgetHostViewBase::~RenderWidgetHostViewBase() {
  DCHECK(!mouse_locked_);
}

void RenderWidgetHostViewBase::SetBackground(const SkBitmap& background) {
  background_ = background;
}

const SkBitmap& RenderWidgetHostViewBase::GetBackground() {
  return background_;
}

void RenderWidgetHostViewBase::SelectionChanged(const string16& text,
                                                size_t offset,
                                                const ui::Range& range) {
  selection_text_ = text;
  selection_text_offset_ = offset;
  selection_range_.set_start(range.start());
  selection_range_.set_end(range.end());
}

bool RenderWidgetHostViewBase::IsShowingContextMenu() const {
  return showing_context_menu_;
}

void RenderWidgetHostViewBase::SetShowingContextMenu(bool showing) {
  DCHECK_NE(showing_context_menu_, showing);
  showing_context_menu_ = showing;
}

bool RenderWidgetHostViewBase::IsMouseLocked() {
  return mouse_locked_;
}

void RenderWidgetHostViewBase::UnhandledWheelEvent(
    const WebKit::WebMouseWheelEvent& event) {
  // Most implementations don't need to do anything here.
}

void RenderWidgetHostViewBase::SetPopupType(WebKit::WebPopupType popup_type) {
  popup_type_ = popup_type;
}

WebKit::WebPopupType RenderWidgetHostViewBase::GetPopupType() {
  return popup_type_;
}

BrowserAccessibilityManager*
    RenderWidgetHostViewBase::GetBrowserAccessibilityManager() const {
  return browser_accessibility_manager_.get();
}

void RenderWidgetHostViewBase::SetBrowserAccessibilityManager(
    BrowserAccessibilityManager* manager) {
  browser_accessibility_manager_.reset(manager);
}

void RenderWidgetHostViewBase::UpdateScreenInfo() {
  gfx::Display display = gfx::Screen::GetDisplayNearestPoint(
      GetViewBounds().origin());
  if (current_display_area_ == display.bounds() &&
      current_device_scale_factor_ == display.device_scale_factor())
    return;
  current_display_area_ = display.bounds();
  current_device_scale_factor_ = display.device_scale_factor();
  if (GetRenderWidgetHost()) {
    RenderWidgetHostImpl* impl =
        RenderWidgetHostImpl::From(GetRenderWidgetHost());
    impl->NotifyScreenInfoChanged();
  }
}

class BasicMouseWheelSmoothScrollGesture
    : public SmoothScrollGesture {
 public:
  BasicMouseWheelSmoothScrollGesture(bool scroll_down, bool scroll_far)
      : start_time_(base::TimeTicks::HighResNow()),
        scroll_down_(scroll_down),
        scroll_far_(scroll_far) { }

  virtual bool ForwardInputEvents(base::TimeTicks now,
                                  RenderWidgetHost* host) OVERRIDE {
    int64 duration_in_ms;
    if (scroll_far_)
      duration_in_ms = kDurationOfFarScrollGestureMs;
    else
      duration_in_ms = kDurationOfNearScrollGestureMs;

    if (now - start_time_ > base::TimeDelta::FromMilliseconds(duration_in_ms))
      return false;

    WebKit::WebMouseWheelEvent event;
    event.type = WebKit::WebInputEvent::MouseWheel;
    // TODO(nduca): Figure out plausible value.
    event.deltaY = scroll_down_ ? -10 : 10;
    event.wheelTicksY = scroll_down_ ? 1 : -1;
    event.modifiers = 0;

    // TODO(nduca): Figure out plausible x and y values.
    event.globalX = 0;
    event.globalY = 0;
    event.x = 0;
    event.y = 0;
    event.windowX = event.x;
    event.windowY = event.y;
    host->ForwardWheelEvent(event);
    return true;
  }

 private:
  base::TimeTicks start_time_;
  bool scroll_down_;
  bool scroll_far_;
};

SmoothScrollGesture* RenderWidgetHostViewBase::CreateSmoothScrollGesture(
    bool scroll_down, bool scroll_far) {
  return new BasicMouseWheelSmoothScrollGesture(scroll_down, scroll_far);
}

}  // namespace content
<|endoftext|>


<commit_before>//==================================================================================================
// FileSystemProxyMock.cpp
//
//     This file contains the definitions for the file system proxy classes for the file system
//     proxy mock object.
//
// _________________________________________________________________________________________________
// MIT License
//
// Copyright  2017 Steve Hollasch
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//==================================================================================================

#include "FileSystemProxyMock.h"
#include <stdlib.h>
#include <string>

using namespace std;
using namespace FileSystemProxy;

MockDirectoryIterator::MockDirectoryIterator (const string path) {
    // Not yet implemented.
}

MockDirectoryIterator::~MockDirectoryIterator() {
    // Not yet implemented.
}

bool MockDirectoryIterator::next() {
    // Not yet implemented.
    return false;
}

bool MockDirectoryIterator::isDirectory() const {
    // Not yet implemented.
    return false;
}

bool MockDirectoryIterator::isFile() const {
    // Not yet implemented.
    return false;
}

const string MockDirectoryIterator::name() const {
    // Not yet implemented.
    return string("<nyi>");
}

MockFS::MockFS (const string mockDirFileName, const string startingDirectory) {
    // Not Yet Implemented

    // This should be validated.
    m_currentDir = startingDirectory;
}

MockFS::~MockFS() {
}

size_t MockFS::maxPathLength() const {
    return 0;   // Indicate unlimited path length.
}

DirectoryIterator* MockFS::newDirectoryIterator (const string path) const
{
    // Not Yet Implemented
    return new MockDirectoryIterator(path);
}

bool MockFS::setCurrentDirectory (const string path)
{
    // Sets the current working directory. Returns true if the directory is valid.
    m_currentDir = path;

    // NOT YET IMPLEMENTED: For now, just always accept the directory.
    return true;
}
<commit_msg>Add base initialization for MockDirectoryIterator<commit_after>//==================================================================================================
// FileSystemProxyMock.cpp
//
//     This file contains the definitions for the file system proxy classes for the file system
//     proxy mock object.
//
// _________________________________________________________________________________________________
// MIT License
//
// Copyright  2017 Steve Hollasch
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//==================================================================================================

#include "FileSystemProxyMock.h"
#include <stdlib.h>
#include <string>

using namespace std;
using namespace FileSystemProxy;

MockDirectoryIterator::MockDirectoryIterator (const string path)
    : DirectoryIterator(path) {

    // Not yet implemented.
}

MockDirectoryIterator::~MockDirectoryIterator() {
    // Not yet implemented.
}

bool MockDirectoryIterator::next() {
    // Not yet implemented.
    return false;
}

bool MockDirectoryIterator::isDirectory() const {
    // Not yet implemented.
    return false;
}

bool MockDirectoryIterator::isFile() const {
    // Not yet implemented.
    return false;
}

const string MockDirectoryIterator::name() const {
    // Not yet implemented.
    return string("<nyi>");
}

MockFS::MockFS (const string mockDirFileName, const string startingDirectory) {
    // Not Yet Implemented

    // This should be validated.
    m_currentDir = startingDirectory;
}

MockFS::~MockFS() {
}

size_t MockFS::maxPathLength() const {
    return 0;   // Indicate unlimited path length.
}

DirectoryIterator* MockFS::newDirectoryIterator (const string path) const
{
    // Not Yet Implemented
    return new MockDirectoryIterator(path);
}

bool MockFS::setCurrentDirectory (const string path)
{
    // Sets the current working directory. Returns true if the directory is valid.
    m_currentDir = path;

    // NOT YET IMPLEMENTED: For now, just always accept the directory.
    return true;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <algorithm>
#include <iostream>

using namespace std;

struct point
{
	int x, y;
};

int points, pa, dp[105][105][105], maxim, xs[3000005], tp;

point pbyx[105], pbyy[105], cler[105];

bool hp1(point i, point j)
{
	return i.x<j.x;
}

bool hp2(point i, point j)
{
    if(i.y!=j.y)
        return i.y<j.y;
    return i.x<j.x;
}

int dper(int x1, int x2, int y)
{
	if(pbyx[x2].x==pbyx[x1].x)
		return 1;
    //Not so sure about this one
	if(dp[x1][x2][y]!=-1)
		return dp[x1][x2][y];
	int m1=1000000, mint=1000000, newy=y, curh=pa/(pbyx[x2].x-pbyx[x1].x), nx1, nx2;
	for(int i=x1; i<x2; i++)
	{
		mint=dper(x1, i, y)+dper(i+1, x2, y);
		if(mint<m1)
			m1=mint;
	}
	for(newy=y; (pbyy[newy].y<=curh || pbyy[newy].x<pbyx[x1].x || pbyy[newy].x>pbyx[x2].x) && newy<=points; newy++){}
	for(nx1=x1; pbyx[nx1].y<=curh && nx1<=points; nx1++){}
	for(nx2=x2; pbyx[nx2].y<=curh && nx2; nx2--){}
    if(pbyx[nx2].x<pbyx[nx1].x && newy!=points+1)
    {
        //cout<<x1<<" "<<x2<<endl;
        //cout<<pbyx[x1].x<<" "<<pbyx[x2].x<<" "<<curh<<" "<<pbyy[newy].x<<" "<<pbyy[newy].y;
        //cout<<endl;
        //cout<<nx1<<" "<<nx2<<endl;
    }
	if(newy==y)
		dp[x1][x2][y]=100000;
	else if(newy==points+1)
		dp[x1][x2][y]=1;
	else
		dp[x1][x2][y]=dper(nx1, nx2, newy)+1;
    //printf("%d ", dp[x1][x2][y]);
	if(dp[x1][x2][y]>m1)
		dp[x1][x2][y]=m1;
    //printf("%d\n", m1);
	//printf("%d %d %d %d %d %d %d\n", nx1, nx2, newy, curh, x1, x2, y);
	return dp[x1][x2][y];
}

int main()
{
	scanf("%d%d", &points, &pa);
    if(points==0)
    {
        printf("0\n");
        return 0;
    }
	for(int i=0; i<=points; i++)
	{
		for(int j=0; j<=points; j++)
		{
			for(int k=0; k<=points; k++)
			{
				dp[i][j][k]=-1;
			}
		}
	}
	for(int i=1; i<=points; i++)
	{
		scanf("%d%d", &pbyx[i].x, &pbyx[i].y);
        if(pbyx[i].y>xs[pbyx[i].x])
            xs[pbyx[i].x]=pbyx[i].y;
	}
	sort(pbyx+1, pbyx+1+points, hp1);
    if(pbyx[points].x-1==pbyx[points-1].x)
        points--;
    for(int i=1; i<=points; i++)
    {
        if(pbyx[i].x==pbyx[i+1].x)
        {
            pbyx[i].y=xs[pbyx[i].x];
        }
        cler[i]=pbyx[i];
    }
    for(int i=1; i<=points; i++)
    {
        if(cler[i].x!=cler[i+1].x || cler[i].y!=cler[i+1].y)
        {
            tp++;
            pbyx[tp]=cler[i];
            pbyy[tp]=pbyx[i];
        }
    }
    points=tp;
    sort(pbyx+1, pbyx+1+points, hp1);
	sort(pbyy+1, pbyy+1+points, hp2);
	printf("%d\n", dper(1, points, 1));
	return 0;
}
<commit_msg>Update Freddy-el-Humano.cpp<commit_after>//https://omegaup.com/arena/problem/Freddy-el-Humano#

#include <cstdio>
#include <algorithm>
#include <iostream>

using namespace std;

struct point
{
	int x, y;
};

int points, pa, dp[105][105][105], maxim, xs[3000005], tp;

point pbyx[105], pbyy[105], cler[105];

bool hp1(point i, point j)
{
	return i.x<j.x;
}

bool hp2(point i, point j)
{
    if(i.y!=j.y)
        return i.y<j.y;
    return i.x<j.x;
}

int dper(int x1, int x2, int y)
{
	if(pbyx[x2].x==pbyx[x1].x)
		return 1;
    //Not so sure about this one
	if(dp[x1][x2][y]!=-1)
		return dp[x1][x2][y];
	int m1=1000000, mint=1000000, newy=y, curh=pa/(pbyx[x2].x-pbyx[x1].x), nx1, nx2;
	for(int i=x1; i<x2; i++)
	{
		mint=dper(x1, i, y)+dper(i+1, x2, y);
		if(mint<m1)
			m1=mint;
	}
	for(newy=y; (pbyy[newy].y<=curh || pbyy[newy].x<pbyx[x1].x || pbyy[newy].x>pbyx[x2].x) && newy<=points; newy++){}
	for(nx1=x1; pbyx[nx1].y<=curh && nx1<=points; nx1++){}
	for(nx2=x2; pbyx[nx2].y<=curh && nx2; nx2--){}
    if(pbyx[nx2].x<pbyx[nx1].x && newy!=points+1)
    {
        //cout<<x1<<" "<<x2<<endl;
        //cout<<pbyx[x1].x<<" "<<pbyx[x2].x<<" "<<curh<<" "<<pbyy[newy].x<<" "<<pbyy[newy].y;
        //cout<<endl;
        //cout<<nx1<<" "<<nx2<<endl;
    }
	if(newy==y)
		dp[x1][x2][y]=100000;
	else if(newy==points+1)
		dp[x1][x2][y]=1;
	else
		dp[x1][x2][y]=dper(nx1, nx2, newy)+1;
    //printf("%d ", dp[x1][x2][y]);
	if(dp[x1][x2][y]>m1)
		dp[x1][x2][y]=m1;
    //printf("%d\n", m1);
	//printf("%d %d %d %d %d %d %d\n", nx1, nx2, newy, curh, x1, x2, y);
	return dp[x1][x2][y];
}

int main()
{
	scanf("%d%d", &points, &pa);
    if(points==0)
    {
        printf("0\n");
        return 0;
    }
	for(int i=0; i<=points; i++)
	{
		for(int j=0; j<=points; j++)
		{
			for(int k=0; k<=points; k++)
			{
				dp[i][j][k]=-1;
			}
		}
	}
	for(int i=1; i<=points; i++)
	{
		scanf("%d%d", &pbyx[i].x, &pbyx[i].y);
        if(pbyx[i].y>xs[pbyx[i].x])
            xs[pbyx[i].x]=pbyx[i].y;
	}
	sort(pbyx+1, pbyx+1+points, hp1);
    if(pbyx[points].x-1==pbyx[points-1].x)
        points--;
    for(int i=1; i<=points; i++)
    {
        if(pbyx[i].x==pbyx[i+1].x)
        {
            pbyx[i].y=xs[pbyx[i].x];
        }
        cler[i]=pbyx[i];
    }
    for(int i=1; i<=points; i++)
    {
        if(cler[i].x!=cler[i+1].x || cler[i].y!=cler[i+1].y)
        {
            tp++;
            pbyx[tp]=cler[i];
            pbyy[tp]=pbyx[i];
        }
    }
    points=tp;
    sort(pbyx+1, pbyx+1+points, hp1);
	sort(pbyy+1, pbyy+1+points, hp2);
	printf("%d\n", dper(1, points, 1));
	return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS HEADER
#include <dali/internal/accessibility/bridge/bridge-object.h>

// EXTERNAL INCLUDES
#include <iostream>
#include <string>

using namespace Dali::Accessibility;

namespace
{
inline std::string GetAccessiblePath(Accessible* accessible)
{
  auto address = accessible->GetAddress();
  return address ? ATSPI_PREFIX_PATH + address.GetPath() : ATSPI_NULL_PATH;
}
} // namespace

BridgeObject::BridgeObject()
{
}

void BridgeObject::RegisterInterfaces()
{
  // DBus::DBusInterfaceDescription desc{ AtspiDbusInterfaceEventObject };
  // mStateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
  // mDbusServer.addInterface("/", desc, true);
}

void BridgeObject::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
{
  if(!IsUp()) return;
  auto index = child->GetIndexInParent();

  mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<Address>, Address>(
    GetAccessiblePath(obj),
    AtspiDbusInterfaceEventObject,
    "ActiveDescendantChanged",
    "",
    index,
    0,
    {child->GetAddress()},
    {"", "root"});
}

void BridgeObject::Emit(Accessible* obj, Dali::Accessibility::ObjectPropertyChangeEvent event)
{
  if(!IsUp()) return;
  const char* name = nullptr;

  switch(event)
  {
    case ObjectPropertyChangeEvent::NAME:
    {
      name = "accessible-name";
      break;
    }
    case ObjectPropertyChangeEvent::DESCRIPTION:
    {
      name = "accessible-description";
      break;
    }
    case ObjectPropertyChangeEvent::VALUE:
    {
      name = "accessible-value";
      break;
    }
    case ObjectPropertyChangeEvent::PARENT:
    {
      name = "accessible-parent";
      break;
    }
    case ObjectPropertyChangeEvent::ROLE:
    {
      name = "accessible-role";
      break;
    }
  }

  if(name)
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "PropertyChange",
      name,
      0,
      0,
      {0},
      {"", "root"});
  }
}

void BridgeObject::Emit(Accessible* obj, WindowEvent event, unsigned int detail)
{
  if(!IsUp()) return;
  const char* name = nullptr;

  switch(event)
  {
    case WindowEvent::PROPERTY_CHANGE:
    {
      name = "PropertyChange";
      break;
    }
    case WindowEvent::MINIMIZE:
    {
      name = "Minimize";
      break;
    }
    case WindowEvent::MAXIMIZE:
    {
      name = "Maximize";
      break;
    }
    case WindowEvent::RESTORE:
    {
      name = "Restore";
      break;
    }
    case WindowEvent::CLOSE:
    {
      name = "Close";
      break;
    }
    case WindowEvent::CREATE:
    {
      name = "Create";
      break;
    }
    case WindowEvent::REPARENT:
    {
      name = "Reparent";
      break;
    }
    case WindowEvent::DESKTOP_CREATE:
    {
      name = "DesktopCreate";
      break;
    }
    case WindowEvent::DESKTOP_DESTROY:
    {
      name = "DesktopDestroy";
      break;
    }
    case WindowEvent::DESTROY:
    {
      name = "Destroy";
      break;
    }
    case WindowEvent::ACTIVATE:
    {
      name = "Activate";
      break;
    }
    case WindowEvent::DEACTIVATE:
    {
      name = "Deactivate";
      break;
    }
    case WindowEvent::RAISE:
    {
      name = "Raise";
      break;
    }
    case WindowEvent::LOWER:
    {
      name = "Lower";
      break;
    }
    case WindowEvent::MOVE:
    {
      name = "Move";
      break;
    }
    case WindowEvent::RESIZE:
    {
      name = "Resize";
      break;
    }
    case WindowEvent::SHADE:
    {
      name = "Shade";
      break;
    }
    case WindowEvent::UU_SHADE:
    {
      name = "uUshade";
      break;
    }
    case WindowEvent::RESTYLE:
    {
      name = "Restyle";
      break;
    }
  }

  if(name)
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventWindow,
      name,
      "",
      detail,
      0,
      {0},
      {"", "root"});
  }
}

void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue, int reserved)
{
  if(!IsUp()) return;
  const char* stateName = nullptr;

  switch(state)
  {
    case State::INVALID:
    {
      stateName = "invalid";
      break;
    }
    case State::ACTIVE:
    {
      stateName = "active";
      break;
    }
    case State::ARMED:
    {
      stateName = "armed";
      break;
    }
    case State::BUSY:
    {
      stateName = "busy";
      break;
    }
    case State::CHECKED:
    {
      stateName = "checked";
      break;
    }
    case State::COLLAPSED:
    {
      stateName = "collapsed";
      break;
    }
    case State::DEFUNCT:
    {
      stateName = "defunct";
      break;
    }
    case State::EDITABLE:
    {
      stateName = "editable";
      break;
    }
    case State::ENABLED:
    {
      stateName = "enabled";
      break;
    }
    case State::EXPANDABLE:
    {
      stateName = "expandable";
      break;
    }
    case State::EXPANDED:
    {
      stateName = "expanded";
      break;
    }
    case State::FOCUSABLE:
    {
      stateName = "focusable";
      break;
    }
    case State::FOCUSED:
    {
      stateName = "focused";
      break;
    }
    case State::HAS_TOOLTIP:
    {
      stateName = "has-tooltip";
      break;
    }
    case State::HORIZONTAL:
    {
      stateName = "horizontal";
      break;
    }
    case State::ICONIFIED:
    {
      stateName = "iconified";
      break;
    }
    case State::MODAL:
    {
      stateName = "modal";
      break;
    }
    case State::MULTI_LINE:
    {
      stateName = "multi-line";
      break;
    }
    case State::MULTI_SELECTABLE:
    {
      stateName = "multiselectable";
      break;
    }
    case State::OPAQUE:
    {
      stateName = "opaque";
      break;
    }
    case State::PRESSED:
    {
      stateName = "pressed";
      break;
    }
    case State::RESIZEABLE:
    {
      stateName = "resizable";
      break;
    }
    case State::SELECTABLE:
    {
      stateName = "selectable";
      break;
    }
    case State::SELECTED:
    {
      stateName = "selected";
      break;
    }
    case State::SENSITIVE:
    {
      stateName = "sensitive";
      break;
    }
    case State::SHOWING:
    {
      stateName = "showing";
      break;
    }
    case State::SINGLE_LINE:
    {
      stateName = "single-line";
      break;
    }
    case State::STALE:
    {
      stateName = "stale";
      break;
    }
    case State::TRANSIENT:
    {
      stateName = "transient";
      break;
    }
    case State::VERTICAL:
    {
      stateName = "vertical";
      break;
    }
    case State::VISIBLE:
    {
      stateName = "visible";
      break;
    }
    case State::MANAGES_DESCENDANTS:
    {
      stateName = "manages-descendants";
      break;
    }
    case State::INDETERMINATE:
    {
      stateName = "indeterminate";
      break;
    }
    case State::REQUIRED:
    {
      stateName = "required";
      break;
    }
    case State::TRUNCATED:
    {
      stateName = "truncated";
      break;
    }
    case State::ANIMATED:
    {
      stateName = "animated";
      break;
    }
    case State::INVALID_ENTRY:
    {
      stateName = "invalid-entry";
      break;
    }
    case State::SUPPORTS_AUTOCOMPLETION:
    {
      stateName = "supports-autocompletion";
      break;
    }
    case State::SELECTABLE_TEXT:
    {
      stateName = "selectable-text";
      break;
    }
    case State::IS_DEFAULT:
    {
      stateName = "is-default";
      break;
    }
    case State::VISITED:
    {
      stateName = "visited";
      break;
    }
    case State::CHECKABLE:
    {
      stateName = "checkable";
      break;
    }
    case State::HAS_POPUP:
    {
      stateName = "has-popup";
      break;
    }
    case State::READ_ONLY:
    {
      stateName = "read-only";
      break;
    }
    case State::HIGHLIGHTED:
    {
      stateName = "highlighted";
      break;
    }
    case State::HIGHLIGHTABLE:
    {
      stateName = "highlightable";
      break;
    }
    case State::MAX_COUNT:
    {
      break;
    }
  }

  if(stateName)
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "StateChanged",
      stateName,
      newValue,
      reserved,
      {0},
      {"", "root"});
  }
}

void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
{
  if(!IsBoundsChangedEventAllowed) return;

  DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
    std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};

  AddFilteredEvent(FilteredEvents::BOUNDS_CHANGED, obj, 1.0f, [=]() {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "BoundsChanged",
      "",
      0,
      0,
      tmp,
      {"", "root"});
  });
}

void BridgeObject::EmitCursorMoved(Accessible* obj, unsigned int cursorPosition)
{
  mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
    GetAccessiblePath(obj),
    AtspiDbusInterfaceEventObject,
    "TextCaretMoved",
    "",
    cursorPosition,
    0,
    {0},
    {"", "root"});
}

void BridgeObject::EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content)
{
  const char* stateName = nullptr;
  switch(state)
  {
    case TextChangedState::INSERTED:
    {
      stateName = "insert";
      break;
    }
    case TextChangedState::DELETED:
    {
      stateName = "delete";
      break;
    }
    case TextChangedState::MAX_COUNT:
    {
      break;
    }
  }

  if(stateName)
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::string>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "TextChanged",
      stateName,
      position,
      length,
      {content},
      {"", "root"});
  }
}

void BridgeObject::EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type)
{
  mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
    GetAccessiblePath(obj),
    AtspiDbusInterfaceEventObject,
    "MoveOuted",
    "",
    static_cast<int>(type),
    0,
    {0},
    {"", "root"});
}
<commit_msg>[AT-SPI] Clean up event emission code for BridgeObject<commit_after>/*
 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
 *
 * 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.
 *
 */

// CLASS HEADER
#include <dali/internal/accessibility/bridge/bridge-object.h>

// EXTERNAL INCLUDES
#include <iostream>
#include <string>
#include <string_view>
#include <unordered_map>

using namespace Dali::Accessibility;

namespace
{
inline std::string GetAccessiblePath(Accessible* accessible)
{
  auto address = accessible->GetAddress();
  return address ? ATSPI_PREFIX_PATH + address.GetPath() : ATSPI_NULL_PATH;
}
} // namespace

BridgeObject::BridgeObject()
{
}

void BridgeObject::RegisterInterfaces()
{
  // DBus::DBusInterfaceDescription desc{ AtspiDbusInterfaceEventObject };
  // mStateChanged = addSignal<std::string, int, int, DBus::EldbusVariant<int>, Accessible*>(desc, "StateChanged");
  // mDbusServer.addInterface("/", desc, true);
}

void BridgeObject::EmitActiveDescendantChanged(Accessible* obj, Accessible* child)
{
  if(!IsUp() || obj->IsHidden() || child->IsHidden())
  {
    return;
  }

  auto index = child->GetIndexInParent();

  mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<Address>, Address>(
    GetAccessiblePath(obj),
    AtspiDbusInterfaceEventObject,
    "ActiveDescendantChanged",
    "",
    index,
    0,
    {child->GetAddress()},
    {"", "root"});
}

void BridgeObject::Emit(Accessible* obj, ObjectPropertyChangeEvent event)
{
  static const std::unordered_map<ObjectPropertyChangeEvent, std::string_view> eventMap{
    {ObjectPropertyChangeEvent::NAME, "accessible-name"},
    {ObjectPropertyChangeEvent::DESCRIPTION, "accessible-description"},
    {ObjectPropertyChangeEvent::VALUE, "accessible-value"},
    {ObjectPropertyChangeEvent::PARENT, "accessible-parent"},
    {ObjectPropertyChangeEvent::ROLE, "accessible-role"},
  };

  if(!IsUp() || obj->IsHidden())
  {
    return;
  }

  auto eventName = eventMap.find(event);

  if(eventName != eventMap.end())
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "PropertyChange",
      std::string{eventName->second},
      0,
      0,
      {0},
      {"", "root"});
  }
}

void BridgeObject::Emit(Accessible* obj, WindowEvent event, unsigned int detail)
{
  static const std::unordered_map<WindowEvent, std::string_view> eventMap{
    {WindowEvent::PROPERTY_CHANGE, "PropertyChange"},
    {WindowEvent::MINIMIZE, "Minimize"},
    {WindowEvent::MAXIMIZE, "Maximize"},
    {WindowEvent::RESTORE, "Restore"},
    {WindowEvent::CLOSE, "Close"},
    {WindowEvent::CREATE, "Create"},
    {WindowEvent::REPARENT, "Reparent"},
    {WindowEvent::DESKTOP_CREATE, "DesktopCreate"},
    {WindowEvent::DESKTOP_DESTROY, "DesktopDestroy"},
    {WindowEvent::DESTROY, "Destroy"},
    {WindowEvent::ACTIVATE, "Activate"},
    {WindowEvent::DEACTIVATE, "Deactivate"},
    {WindowEvent::RAISE, "Raise"},
    {WindowEvent::LOWER, "Lower"},
    {WindowEvent::MOVE, "Move"},
    {WindowEvent::RESIZE, "Resize"},
    {WindowEvent::SHADE, "Shade"},
    {WindowEvent::UU_SHADE, "uUshade"},
    {WindowEvent::RESTYLE, "Restyle"},
  };

  if(!IsUp() || obj->IsHidden())
  {
    return;
  }

  auto eventName = eventMap.find(event);

  if(eventName != eventMap.end())
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventWindow,
      std::string{eventName->second},
      "",
      detail,
      0,
      {0},
      {"", "root"});
  }
}

void BridgeObject::EmitStateChanged(Accessible* obj, State state, int newValue, int reserved)
{
  static const std::unordered_map<State, std::string_view> stateMap{
    {State::INVALID, "invalid"},
    {State::ACTIVE, "active"},
    {State::ARMED, "armed"},
    {State::BUSY, "busy"},
    {State::CHECKED, "checked"},
    {State::COLLAPSED, "collapsed"},
    {State::DEFUNCT, "defunct"},
    {State::EDITABLE, "editable"},
    {State::ENABLED, "enabled"},
    {State::EXPANDABLE, "expandable"},
    {State::EXPANDED, "expanded"},
    {State::FOCUSABLE, "focusable"},
    {State::FOCUSED, "focused"},
    {State::HAS_TOOLTIP, "has-tooltip"},
    {State::HORIZONTAL, "horizontal"},
    {State::ICONIFIED, "iconified"},
    {State::MODAL, "modal"},
    {State::MULTI_LINE, "multi-line"},
    {State::MULTI_SELECTABLE, "multiselectable"},
    {State::OPAQUE, "opaque"},
    {State::PRESSED, "pressed"},
    {State::RESIZEABLE, "resizable"},
    {State::SELECTABLE, "selectable"},
    {State::SELECTED, "selected"},
    {State::SENSITIVE, "sensitive"},
    {State::SHOWING, "showing"},
    {State::SINGLE_LINE, "single-line"},
    {State::STALE, "stale"},
    {State::TRANSIENT, "transient"},
    {State::VERTICAL, "vertical"},
    {State::VISIBLE, "visible"},
    {State::MANAGES_DESCENDANTS, "manages-descendants"},
    {State::INDETERMINATE, "indeterminate"},
    {State::REQUIRED, "required"},
    {State::TRUNCATED, "truncated"},
    {State::ANIMATED, "animated"},
    {State::INVALID_ENTRY, "invalid-entry"},
    {State::SUPPORTS_AUTOCOMPLETION, "supports-autocompletion"},
    {State::SELECTABLE_TEXT, "selectable-text"},
    {State::IS_DEFAULT, "is-default"},
    {State::VISITED, "visited"},
    {State::CHECKABLE, "checkable"},
    {State::HAS_POPUP, "has-popup"},
    {State::READ_ONLY, "read-only"},
    {State::HIGHLIGHTED, "highlighted"},
    {State::HIGHLIGHTABLE, "highlightable"},
  };

  if(!IsUp() || obj->IsHidden())
  {
    return;
  }

  auto stateName = stateMap.find(state);

  if(stateName != stateMap.end())
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "StateChanged",
      std::string{stateName->second},
      newValue,
      reserved,
      {0},
      {"", "root"});
  }
}

void BridgeObject::EmitBoundsChanged(Accessible* obj, Dali::Rect<> rect)
{
  if(!IsUp() || !IsBoundsChangedEventAllowed || obj->IsHidden())
  {
    return;
  }

  DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> > tmp{
    std::tuple<int32_t, int32_t, int32_t, int32_t>{rect.x, rect.y, rect.width, rect.height}};

  AddFilteredEvent(FilteredEvents::BOUNDS_CHANGED, obj, 1.0f, [=]() {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::tuple<int32_t, int32_t, int32_t, int32_t> >, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "BoundsChanged",
      "",
      0,
      0,
      tmp,
      {"", "root"});
  });
}

void BridgeObject::EmitCursorMoved(Accessible* obj, unsigned int cursorPosition)
{
  if(!IsUp() || obj->IsHidden())
  {
    return;
  }

  mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
    GetAccessiblePath(obj),
    AtspiDbusInterfaceEventObject,
    "TextCaretMoved",
    "",
    cursorPosition,
    0,
    {0},
    {"", "root"});
}

void BridgeObject::EmitTextChanged(Accessible* obj, TextChangedState state, unsigned int position, unsigned int length, const std::string& content)
{
  static const std::unordered_map<TextChangedState, std::string_view> stateMap{
    {TextChangedState::INSERTED, "insert"},
    {TextChangedState::DELETED, "delete"},
  };

  if(!IsUp() || obj->IsHidden())
  {
    return;
  }

  auto stateName = stateMap.find(state);

  if(stateName != stateMap.end())
  {
    mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<std::string>, Address>(
      GetAccessiblePath(obj),
      AtspiDbusInterfaceEventObject,
      "TextChanged",
      std::string{stateName->second},
      position,
      length,
      {content},
      {"", "root"});
  }
}

void BridgeObject::EmitMovedOutOfScreen(Accessible* obj, ScreenRelativeMoveType type)
{
  if(!IsUp() || obj->IsHidden())
  {
    return;
  }

  mDbusServer.emit2<std::string, int, int, DBus::EldbusVariant<int>, Address>(
    GetAccessiblePath(obj),
    AtspiDbusInterfaceEventObject,
    "MoveOuted",
    "",
    static_cast<int>(type),
    0,
    {0},
    {"", "root"});
}
<|endoftext|>