<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef CONCURRENT_HPP_
#define CONCURRENT_HPP_

#include "top.hpp"
#include "thread/atomic.hpp"
#include "os/alloc.hpp"

#include <new>

//! \addtogroup Utils

namespace amd {/*@{*/

namespace details {

template <typename T, int N>
struct TaggedPointerHelper
{
    static const uintptr_t TagMask = (1u << N) - 1;

private:
    TaggedPointerHelper();        // Cannot instantiate
    void* operator new(size_t);   // allocate or
    void operator delete(void*);  // delete a TaggedPointerHelper.

public:
    //! Create a tagged pointer.
    static TaggedPointerHelper* make(T* ptr, size_t tag)
    {
        return reinterpret_cast<TaggedPointerHelper*>(
            (reinterpret_cast<uintptr_t>(ptr) & ~TagMask) | (tag & TagMask));
    }

    //! Return the pointer value.
    T* ptr()
    {
        return reinterpret_cast<T*>(
            reinterpret_cast<uintptr_t>(this) & ~TagMask);
    }

    //! Return the tag value.
    size_t tag() const
    {
        return reinterpret_cast<uintptr_t>(this) & TagMask;
    }
};

} // namespace details

/*! \brief An unbounded thread-safe queue.
 *
 * This queue orders elements first-in-first-out. It is based on the algorithm
 * "Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue
 * Algorithms by Maged M. Michael and Michael L. Scott.".
 *
 * FIXME_lmoriche: Implement the new/delete operators for SimplyLinkedNode
 * using thread-local allocation buffers.
 */
template <typename T, int N = 5>
class ConcurrentLinkedQueue : public HeapObject
{
    //! A simply-linked node
    struct Node
    {
        typedef details::TaggedPointerHelper<Node,N> TaggedPointerHelper;
        typedef TaggedPointerHelper* Ptr;

        T value_;          //!< The value stored in that node.
        Atomic<Ptr> next_; //!< Pointer to the next node

        //! Create a Node::Ptr
        static inline Ptr ptr(Node* ptr, size_t counter = 0)
        {
            return TaggedPointerHelper::make(ptr, counter);
        }
    };

private:
    Atomic<typename Node::Ptr> head_; //! Pointer to the oldest element.
    Atomic<typename Node::Ptr> tail_; //! Pointer to the most recent element.

private:
    //! \brief Allocate a free node.
    static inline Node* allocNode()
    {
        return new(AlignedMemory::allocate(sizeof(Node), 1 << N)) Node();
    }

    //! \brief Return a node to the free list.
    static inline void reclaimNode(Node* node)
    {
        AlignedMemory::deallocate(node);
    }

public:
    //! \brief Initialize a new concurrent linked queue.
    ConcurrentLinkedQueue();

    //! \brief Destroy this concurrent linked queue.
    ~ConcurrentLinkedQueue();

    //! \brief Enqueue an element to this queue.
    inline void enqueue(T elem);

    //! \brief Dequeue an element from this queue.
    inline T dequeue();
};

/*@}*/

template <typename T, int N>
inline
ConcurrentLinkedQueue<T,N>::ConcurrentLinkedQueue()
{
    // Create the first "dummy" node.
    Node* dummy = allocNode();
    dummy->next_ = NULL;
    DEBUG_ONLY(dummy->value_ = NULL);

    // Head and tail should now point to it (empty list).
    head_ = tail_ = Node::ptr(dummy);

    // Make sure the instance is fully initialized before it becomes
    // globally visible.
    MemoryOrder::sfence();
}

template <typename T, int N>
inline
ConcurrentLinkedQueue<T,N>::~ConcurrentLinkedQueue()
{
    typename Node::Ptr head = head_;
    typename Node::Ptr tail = tail_;
    while (head->ptr() != tail->ptr()) {
        Node* node = head->ptr();
        head = head->ptr()->next_;
        reclaimNode(node);
    }
    reclaimNode(head->ptr());
}

template <typename T, int N>
inline void
ConcurrentLinkedQueue<T,N>::enqueue(T elem)
{
    Node* node = allocNode();
    node->value_ = elem;
    node->next_ = NULL;

    while (true) {
        typename Node::Ptr tail = tail_;
        typename Node::Ptr next = tail->ptr()->next_;
        MemoryOrder::lfence();
        if (tail == tail_) {
            if (next->ptr() == NULL) {
                if (tail->ptr()->next_.compareAndSet(
                        next, Node::ptr(node, next->tag()+1))) {
                    tail_.compareAndSet(tail, Node::ptr(node, tail->tag()+1));
                    return;
                }
            }
            else {
                tail_.compareAndSet(
                    tail, Node::ptr(next->ptr(), tail->tag()+1));
            }
        }
    }
}

template <typename T, int N>
inline T
ConcurrentLinkedQueue<T,N>::dequeue()
{
    while (true) {
        typename Node::Ptr head = head_;
        typename Node::Ptr tail = tail_;
        typename Node::Ptr next = head->ptr()->next_;
        MemoryOrder::lfence();
        if (head == head_) {
            if (head->ptr() == tail->ptr()) {
                if (next->ptr() == NULL) {
                    return NULL;
                }
                tail_.compareAndSet(
                    tail, Node::ptr(next->ptr(), tail->tag()+1));
            }
            else {
                T value = next->ptr()->value_;
                if (head_.compareAndSet(
                        head, Node::ptr(next->ptr(), head->tag()+1))) {
                    // we can reclaim head now
                    reclaimNode(head->ptr());
                    return value;
                }
            }
        }
    }
}

} // namespace amd

#endif /*CONCURRENT_HPP_*/
<commit_msg>P4 to Git Change 1081826 by lmoriche@lmoriche_opencl_dev on 2014/09/26 18:40:37<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef CONCURRENT_HPP_
#define CONCURRENT_HPP_

#include "top.hpp"
#include "os/alloc.hpp"

#include <atomic>
#include <new>

//! \addtogroup Utils

namespace amd {/*@{*/

namespace details {

template <typename T, int N>
struct TaggedPointerHelper
{
    static const uintptr_t TagMask = (1u << N) - 1;

private:
    TaggedPointerHelper();        // Cannot instantiate
    void* operator new(size_t);   // allocate or
    void operator delete(void*);  // delete a TaggedPointerHelper.

public:
    //! Create a tagged pointer.
    static TaggedPointerHelper* make(T* ptr, size_t tag)
    {
        return reinterpret_cast<TaggedPointerHelper*>(
            (reinterpret_cast<uintptr_t>(ptr) & ~TagMask) | (tag & TagMask));
    }

    //! Return the pointer value.
    T* ptr()
    {
        return reinterpret_cast<T*>(
            reinterpret_cast<uintptr_t>(this) & ~TagMask);
    }

    //! Return the tag value.
    size_t tag() const
    {
        return reinterpret_cast<uintptr_t>(this) & TagMask;
    }
};

} // namespace details

/*! \brief An unbounded thread-safe queue.
 *
 * This queue orders elements first-in-first-out. It is based on the algorithm
 * "Simple, Fast, and Practical Non-Blocking and Blocking Concurrent Queue
 * Algorithms by Maged M. Michael and Michael L. Scott.".
 *
 * FIXME_lmoriche: Implement the new/delete operators for SimplyLinkedNode
 * using thread-local allocation buffers.
 */
template <typename T, int N = 5>
class ConcurrentLinkedQueue : public HeapObject
{
    //! A simply-linked node
    struct Node
    {
        typedef details::TaggedPointerHelper<Node,N> TaggedPointerHelper;
        typedef TaggedPointerHelper* Ptr;

        T value_;               //!< The value stored in that node.
        std::atomic<Ptr> next_; //!< Pointer to the next node

        //! Create a Node::Ptr
        static inline Ptr ptr(Node* ptr, size_t counter = 0)
        {
            return TaggedPointerHelper::make(ptr, counter);
        }
    };

private:
    std::atomic<typename Node::Ptr> head_; //! Pointer to the oldest element.
    std::atomic<typename Node::Ptr> tail_; //! Pointer to the most recent element.

private:
    //! \brief Allocate a free node.
    static inline Node* allocNode()
    {
        return new(AlignedMemory::allocate(sizeof(Node), 1 << N)) Node();
    }

    //! \brief Return a node to the free list.
    static inline void reclaimNode(Node* node)
    {
        AlignedMemory::deallocate(node);
    }

public:
    //! \brief Initialize a new concurrent linked queue.
    ConcurrentLinkedQueue();

    //! \brief Destroy this concurrent linked queue.
    ~ConcurrentLinkedQueue();

    //! \brief Enqueue an element to this queue.
    inline void enqueue(T elem);

    //! \brief Dequeue an element from this queue.
    inline T dequeue();
};

/*@}*/

template <typename T, int N>
inline
ConcurrentLinkedQueue<T,N>::ConcurrentLinkedQueue()
{
    // Create the first "dummy" node.
    Node* dummy = allocNode();
    dummy->next_ = NULL;
    DEBUG_ONLY(dummy->value_ = NULL);

    // Head and tail should now point to it (empty list).
    head_ = tail_ = Node::ptr(dummy);

    // Make sure the instance is fully initialized before it becomes
    // globally visible.
    MemoryOrder::sfence();
}

template <typename T, int N>
inline
ConcurrentLinkedQueue<T,N>::~ConcurrentLinkedQueue()
{
    typename Node::Ptr head = head_;
    typename Node::Ptr tail = tail_;
    while (head->ptr() != tail->ptr()) {
        Node* node = head->ptr();
        head = head->ptr()->next_;
        reclaimNode(node);
    }
    reclaimNode(head->ptr());
}

template <typename T, int N>
inline void
ConcurrentLinkedQueue<T,N>::enqueue(T elem)
{
    Node* node = allocNode();
    node->value_ = elem;
    node->next_ = NULL;

    while (true) {
        typename Node::Ptr tail = tail_.load(std::memory_order_acquire);
        typename Node::Ptr next =
            tail->ptr()->next_.load(std::memory_order_acquire);
        if (tail == tail_.load(std::memory_order_acquire)) {
            if (next->ptr() == NULL) {
                if (tail->ptr()->next_.compare_exchange_weak(
                        next, Node::ptr(node, next->tag()+1),
                        std::memory_order_acq_rel, std::memory_order_acquire)) {
                    tail_.compare_exchange_strong(
                        tail, Node::ptr(node, tail->tag()+1),
                        std::memory_order_acq_rel, std::memory_order_acquire);
                    return;
                }
            }
            else {
                tail_.compare_exchange_strong(
                    tail, Node::ptr(next->ptr(), tail->tag()+1),
                    std::memory_order_acq_rel, std::memory_order_acquire);
            }
        }
    }
}

template <typename T, int N>
inline T
ConcurrentLinkedQueue<T,N>::dequeue()
{
    while (true) {
        typename Node::Ptr head = head_.load(std::memory_order_acquire);
        typename Node::Ptr tail = tail_.load(std::memory_order_acquire);
        typename Node::Ptr next =
            head->ptr()->next_.load(std::memory_order_acquire);
        if (head == head_.load(std::memory_order_acquire)) {
            if (head->ptr() == tail->ptr()) {
                if (next->ptr() == NULL) {
                    return NULL;
                }
                tail_.compare_exchange_strong(
                    tail, Node::ptr(next->ptr(), tail->tag()+1),
                    std::memory_order_acq_rel, std::memory_order_acquire);
            }
            else {
                T value = next->ptr()->value_;
                if (head_.compare_exchange_weak(
                        head, Node::ptr(next->ptr(), head->tag()+1),
                        std::memory_order_acq_rel, std::memory_order_acquire)) {
                    // we can reclaim head now
                    reclaimNode(head->ptr());
                    return value;
                }
            }
        }
    }
}

} // namespace amd

#endif /*CONCURRENT_HPP_*/
<|endoftext|>


<commit_before>#include "CCHandler.h"
#include "Midi.h"

CCHandler *activeCCHandler = NULL;

void CCHandlerOnCCCallback(uint8_t *msg) {
  if (activeCCHandler != NULL) {
    activeCCHandler->onCCCallback(msg);
  }
}

void onOutgoingCCCallback(uint8_t *msg) {
  if (activeCCHandler != NULL) {
    activeCCHandler->onOutgoingCC(MIDI_VOICE_CHANNEL(msg[0]), msg[1], msg[2]);
  }
}

void CCHandler::setup() {
  activeCCHandler = this;
  Midi.addOnControlChangeCallback(CCHandlerOnCCCallback);
  MidiUart.addOnControlChangeCallback(onOutgoingCCCallback);
}

void CCHandler::destroy() {
  Midi.removeOnControlChangeCallback(CCHandlerOnCCCallback);
  MidiUart.removeOnControlChangeCallback(onOutgoingCCCallback);
}

void CCHandler::onCCCallback(uint8_t *msg) {
  incoming_cc_t cc;
  cc.channel = MIDI_VOICE_CHANNEL(msg[0]);
  cc.cc = msg[1];
  cc.value = msg[2];

  bool found = false;
  for (int i = 0; i < incomingCCs.size(); i++) {
    incoming_cc_t *cc2 = incomingCCs.getp(i);
    if (cc2->channel == cc.channel && cc2->cc == cc.cc) {
      cc2->value = cc.value;
      found = true;
      break;
    }
  }
  if (!found)
    incomingCCs.putp(&cc);

  if (midiLearnEnc != NULL) {
    midiLearnEnc->initCCEncoder(cc.channel, cc.cc);
    midiLearnEnc->setValue(cc.value);
    if (callback != NULL)
      callback(midiLearnEnc);
    midiLearnEnc = NULL;
  }

  for (int i = 0; i < encoders.size; i++) {
    if (encoders.arr[i] != NULL) {
      if (encoders.arr[i]->getChannel() == cc.channel &&
	  encoders.arr[i]->getCC() == cc.cc) {
	encoders.arr[i]->setValue(cc.value);
      }
    }
  }
}

void CCHandler::onOutgoingCC(uint8_t channel, uint8_t cc, uint8_t value) {
  for (int i = 0; i < encoders.size; i++) {
    if (encoders.arr[i] != NULL) {
      if (encoders.arr[i]->getChannel() == channel &&
	  encoders.arr[i]->getCC() == cc) {
	encoders.arr[i]->setValue(value);
      }
    }
  }
}
<commit_msg>add correct recognition and shifting (ahem) of incoming ccs<commit_after>#include "CCHandler.h"
#include "Midi.h"

CCHandler *activeCCHandler = NULL;

void CCHandlerOnCCCallback(uint8_t *msg) {
  if (activeCCHandler != NULL) {
    activeCCHandler->onCCCallback(msg);
  }
}

void onOutgoingCCCallback(uint8_t *msg) {
  if (activeCCHandler != NULL) {
    activeCCHandler->onOutgoingCC(MIDI_VOICE_CHANNEL(msg[0]), msg[1], msg[2]);
  }
}

void CCHandler::setup() {
  activeCCHandler = this;
  Midi.addOnControlChangeCallback(CCHandlerOnCCCallback);
  MidiUart.addOnControlChangeCallback(onOutgoingCCCallback);
}

void CCHandler::destroy() {
  Midi.removeOnControlChangeCallback(CCHandlerOnCCCallback);
  MidiUart.removeOnControlChangeCallback(onOutgoingCCCallback);
}

void CCHandler::onCCCallback(uint8_t *msg) {
  incoming_cc_t cc;
  cc.channel = MIDI_VOICE_CHANNEL(msg[0]);
  cc.cc = msg[1];
  cc.value = msg[2];

  bool found = false;
  for (int i = 0; i < incomingCCs.size(); i++) {
    incoming_cc_t *cc2 = incomingCCs.getp(i);
    if (cc2->channel == cc.channel && cc2->cc == cc.cc) {
      //      cc2->value = cc.value;
      found = true;

      /* swap to top */
      //      incoming_cc_t *topcc = incomingCCs.getp(incomingCCs.size() - 1);
      for (int j = i; j < incomingCCs.size() - 1; j++) {
	incoming_cc_t *botcc = incomingCCs.getp(j);
	incoming_cc_t *topcc = incomingCCs.getp(j+1);
	botcc->value = topcc->value;
	botcc->channel = topcc->channel;
	botcc->cc = topcc->cc;
	topcc->value = cc.value;
	topcc->cc = cc.cc;
	topcc->channel = cc.channel;
      }
      break;
    }
  }
  if (!found)
    incomingCCs.putp(&cc);

  if (midiLearnEnc != NULL) {
    midiLearnEnc->initCCEncoder(cc.channel, cc.cc);
    midiLearnEnc->setValue(cc.value);
    if (callback != NULL)
      callback(midiLearnEnc);
    midiLearnEnc = NULL;
  }

  for (int i = 0; i < encoders.size; i++) {
    if (encoders.arr[i] != NULL) {
      if (encoders.arr[i]->getChannel() == cc.channel &&
	  encoders.arr[i]->getCC() == cc.cc) {
	encoders.arr[i]->setValue(cc.value);
      }
    }
  }
}

void CCHandler::onOutgoingCC(uint8_t channel, uint8_t cc, uint8_t value) {
  for (int i = 0; i < encoders.size; i++) {
    if (encoders.arr[i] != NULL) {
      if (encoders.arr[i]->getChannel() == channel &&
	  encoders.arr[i]->getCC() == cc) {
	encoders.arr[i]->setValue(value);
      }
    }
  }
}
<|endoftext|>


<commit_before>#include "pixelboost/file/fileHelpers.h"

#include "pixelboost/graphics/device/device.h"
#include "pixelboost/graphics/device/indexBuffer.h"
#include "pixelboost/graphics/device/texture.h"
#include "pixelboost/graphics/device/vertexBuffer.h"
#include "pixelboost/graphics/helper/screenHelpers.h"
#include "pixelboost/graphics/render/font/fontRenderer.h"

using namespace pixelboost;

FontRenderer::FontRenderer(int maxCharacters)
    : _MaxCharacters(maxCharacters)
{
    _IndexBuffer = GraphicsDevice::Instance()->CreateIndexBuffer(kBufferFormatStatic, _MaxCharacters*6);
    _VertexBuffer = GraphicsDevice::Instance()->CreateVertexBuffer(kBufferFormatStatic, kVertexFormat_P_XYZ_UV, _MaxCharacters*4);

    _IndexBuffer->Lock();

    unsigned short* indices = _IndexBuffer->GetData();
    for (int i=0; i<_MaxCharacters; i++)
    {
        indices[0] = (i*4);
        indices[1] = (i*4)+1;
        indices[2] = (i*4)+2;
        indices[3] = (i*4);
        indices[4] = (i*4)+2;
        indices[5] = (i*4)+3;
        indices += 6;
    }

    _IndexBuffer->Unlock();
}

FontRenderer::~FontRenderer()
{
    GraphicsDevice::Instance()->DestroyIndexBuffer(_IndexBuffer);
    GraphicsDevice::Instance()->DestroyVertexBuffer(_VertexBuffer);

    for (FontMap::iterator it = _Fonts.begin(); it != _Fonts.end(); ++it)
    {
        delete it->second;
    }
}

void FontRenderer::AddCharacter(Vertex_PXYZ_UV* buffer, const Font::Character& character, float offset, float baseline)
{
    float xOffset = character.xOffset;
    float yOffset = -character.yOffset + baseline;

    buffer[0].position[0] = offset + xOffset;
    buffer[0].position[1] = yOffset - character.height;
    buffer[0].uv[0] = character.uvx;
    buffer[0].uv[1] = character.uvy + character.uvv;
    buffer[1].position[0] = offset + xOffset;
    buffer[1].position[1] = yOffset;
    buffer[1].uv[0] = character.uvx;
    buffer[1].uv[1] = character.uvy;
    buffer[2].position[0] = offset + character.width + xOffset;
    buffer[2].position[1] = yOffset;
    buffer[2].uv[0] = character.uvx + character.uvu;
    buffer[2].uv[1] = character.uvy;
    buffer[3].position[0] = offset + character.width + xOffset;
    buffer[3].position[1] = yOffset - character.height;
    buffer[3].uv[0] = character.uvx + character.uvu;
    buffer[3].uv[1] = character.uvy + character.uvv;
}

void FontRenderer::LoadFont(const std::string& name)
{
    if (_Fonts.find(name) != _Fonts.end())
        return;

    Font* font = new Font();

    std::string fileRoot = FileHelpers::GetRootPath();

    std::string fntFilename = fileRoot + "/data/fonts/" + name + (ScreenHelpers::IsHighResolution() ? "-hd" : "") + ".fnt";

    std::string fontContents = FileHelpers::FileToString(fntFilename);

    std::vector<std::string> lines;
    SplitString(fontContents, '\n', lines);

    for (std::vector<std::string>::iterator line = lines.begin(); line != lines.end(); ++line)
    {
        std::vector<std::string> elements;
        SplitString(*line, ' ', elements);

        if (elements.size() < 1 )
            continue;

        std::map<std::string, std::string> data;
        for (std::vector<std::string>::iterator element = elements.begin(); element != elements.end(); ++element)
        {
            data[element->substr(0, element->find('='))] = element->substr(element->find('=')+1);
        }

        std::string elementType = elements[0];

        Vec2 texSize;

        if (elementType == "info")
        {
            int size = (int)atoi(data["size"].c_str());

            font->size = size;
        } else if (elementType == "common")
        {
            int lineHeight = (int)atoi(data["lineHeight"].c_str());
            int base = (int)atoi(data["base"].c_str());
            int scaleW = (int)atoi(data["scaleW"].c_str());
            int scaleH = (int)atoi(data["scaleH"].c_str());

            font->base = (float)base/(float)font->size;
            font->lineHeight = (float)lineHeight / (float)scaleH;
            texSize = Vec2(scaleW, scaleH);
        } else if (elementType == "page")
        {
            std::string texFilename = fileRoot + "/data/fonts/" + data["file"].substr(1, data["file"].find('"', 1)-1);
            font->texture = GraphicsDevice::Instance()->CreateTexture();
            font->texture->Load(texFilename, true);
        } else if (elementType == "char")
        {
            Font::Character character;

            char charCode = (char)atoi(data["id"].c_str());
            int x = (int)atoi(data["x"].c_str());
            int y = (int)atoi(data["y"].c_str());
            int width = (int)atoi(data["width"].c_str());
            int height = (int)atoi(data["height"].c_str());
            int xoffset = (int)atoi(data["xoffset"].c_str());
            int yoffset = (int)atoi(data["yoffset"].c_str());
            int xadvance = (int)atoi(data["xadvance"].c_str());

            character.width = width/(float)font->size;
            character.height = height/(float)font->size;
            character.uvx = x/texSize[0];
            character.uvy = y/texSize[1];
            character.uvu = width/texSize[0];
            character.uvv = height/texSize[1];
            character.xOffset = xoffset/(float)font->size;
            character.yOffset = yoffset/(float)font->size;
            character.xAdvance = xadvance/(float)font->size;

            font->chars[charCode] = character;
        } else if (elementType == "kerning")
        {
            char charOne = (char)atoi(data["first"].c_str());
            char charTwo = (char)atoi(data["second"].c_str());
            int amount = (int)atoi(data["amount"].c_str());

            font->kerning[std::pair<char, char>(charOne, charTwo)] = amount/texSize[0];
        }
    }

    _Fonts[name] = font;
}

void FontRenderer::Update(float time)
{
    _Instances.clear();
}

void FontRenderer::Render(RenderLayer* layer)
{
    InstanceList& instances = _Instances[layer];

    if (instances.size() == 0)
        return;

    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glEnable(GL_TEXTURE_2D);

#ifndef PIXELBOOST_GRAPHICS_PREMULTIPLIED_ALPHA
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#else
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
#endif

    glDisableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    _IndexBuffer->Bind();

    for (InstanceList::iterator it = instances.begin(); it != instances.end(); ++it)
    {
        Font* font;

        FontMap::iterator fontIt = _Fonts.find(it->_Font);
        if (fontIt == _Fonts.end())
            continue;

        font = fontIt->second;

        _VertexBuffer->Lock();

        Vertex_PXYZ_UV* vertexBuffer = static_cast<Vertex_PXYZ_UV*>(_VertexBuffer->GetData());

        float offset = 0.f;
        for (int i=0; i<it->_String.length(); i++)
        {
            std::map<char, Font::Character>::iterator charIt = font->chars.find(it->_String[i]);

            if (charIt == font->chars.end())
                continue;

            AddCharacter(vertexBuffer, charIt->second, offset, font->base);

            vertexBuffer += 4;

            offset += charIt->second.xAdvance;

            if (i<it->_String.length()-1)
            {
                std::map<std::pair<char, char>, float>::iterator kerningIt = font->kerning.find(std::pair<char, char>(it->_String[i], it->_String[i+1]));

                if (kerningIt != font->kerning.end())
                    offset += kerningIt->second;
            }
        }

        _VertexBuffer->Unlock(it->_String.length()*4);

        _VertexBuffer->Bind();

        font->texture->Bind(0);

        glPushMatrix();

        glTranslatef(it->_Position[0], it->_Position[1], 0.f);

        glRotatef(it->_Rotation, 0, 0, 1);

        glScalef(it->_Size, it->_Size, 1.f);

        switch (it->_Alignment) {
            case kFontAlignLeft:
                break;
            case kFontAlignCenter:
                glTranslatef(-offset/2.f, 0, 0);
                break;
            case kFontAlignRight:
                glTranslatef(-offset, 0, 0);
                break;
        }

        GraphicsDevice::Instance()->DrawElements(GraphicsDevice::kElementTriangles, it->_String.length()*6);

        glPopMatrix();
    }

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    GraphicsDevice::Instance()->BindIndexBuffer(0);
    GraphicsDevice::Instance()->BindVertexBuffer(0);

    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);
}

bool FontRenderer::AttachToRenderer(RenderLayer* layer, const std::string& fontName, const std::string& string, Vec2 position, FontAlign alignment, float size, float rotation, Vec4 color)
{
    FontInstance instance;

    instance._Font = fontName;
    instance._String = string;
    instance._Position = position;
    instance._Alignment = alignment;
    instance._Rotation = rotation;
    instance._Size = size;
    instance._Color = color;

    _Instances[layer].push_back(instance);

    return true;
}

void FontRenderer::SplitString(const std::string& string, char seperator, std::vector<std::string>& output)
{
    std::string item;

    for (int i=0; i<string.length(); i++)
    {
        char ch=string[i];

        if (ch == seperator)
        {
            if (!item.empty())
            {
                output.push_back(item);
            }
            item = "";
        }
        else
        {
            item += ch;
        }
    }
    if (!item.empty())
    {
        output.push_back(item);
    }
}
<commit_msg>Add temp color implementation to font renderer<commit_after>#include "pixelboost/file/fileHelpers.h"

#include "pixelboost/graphics/device/device.h"
#include "pixelboost/graphics/device/indexBuffer.h"
#include "pixelboost/graphics/device/texture.h"
#include "pixelboost/graphics/device/vertexBuffer.h"
#include "pixelboost/graphics/helper/screenHelpers.h"
#include "pixelboost/graphics/render/font/fontRenderer.h"

using namespace pixelboost;

FontRenderer::FontRenderer(int maxCharacters)
    : _MaxCharacters(maxCharacters)
{
    _IndexBuffer = GraphicsDevice::Instance()->CreateIndexBuffer(kBufferFormatStatic, _MaxCharacters*6);
    _VertexBuffer = GraphicsDevice::Instance()->CreateVertexBuffer(kBufferFormatStatic, kVertexFormat_P_XYZ_UV, _MaxCharacters*4);

    _IndexBuffer->Lock();

    unsigned short* indices = _IndexBuffer->GetData();
    for (int i=0; i<_MaxCharacters; i++)
    {
        indices[0] = (i*4);
        indices[1] = (i*4)+1;
        indices[2] = (i*4)+2;
        indices[3] = (i*4);
        indices[4] = (i*4)+2;
        indices[5] = (i*4)+3;
        indices += 6;
    }

    _IndexBuffer->Unlock();
}

FontRenderer::~FontRenderer()
{
    GraphicsDevice::Instance()->DestroyIndexBuffer(_IndexBuffer);
    GraphicsDevice::Instance()->DestroyVertexBuffer(_VertexBuffer);

    for (FontMap::iterator it = _Fonts.begin(); it != _Fonts.end(); ++it)
    {
        delete it->second;
    }
}

void FontRenderer::AddCharacter(Vertex_PXYZ_UV* buffer, const Font::Character& character, float offset, float baseline)
{
    float xOffset = character.xOffset;
    float yOffset = -character.yOffset + baseline;

    buffer[0].position[0] = offset + xOffset;
    buffer[0].position[1] = yOffset - character.height;
    buffer[0].uv[0] = character.uvx;
    buffer[0].uv[1] = character.uvy + character.uvv;
    buffer[1].position[0] = offset + xOffset;
    buffer[1].position[1] = yOffset;
    buffer[1].uv[0] = character.uvx;
    buffer[1].uv[1] = character.uvy;
    buffer[2].position[0] = offset + character.width + xOffset;
    buffer[2].position[1] = yOffset;
    buffer[2].uv[0] = character.uvx + character.uvu;
    buffer[2].uv[1] = character.uvy;
    buffer[3].position[0] = offset + character.width + xOffset;
    buffer[3].position[1] = yOffset - character.height;
    buffer[3].uv[0] = character.uvx + character.uvu;
    buffer[3].uv[1] = character.uvy + character.uvv;
}

void FontRenderer::LoadFont(const std::string& name)
{
    if (_Fonts.find(name) != _Fonts.end())
        return;

    Font* font = new Font();

    std::string fileRoot = FileHelpers::GetRootPath();

    std::string fntFilename = fileRoot + "/data/fonts/" + name + (ScreenHelpers::IsHighResolution() ? "-hd" : "") + ".fnt";

    std::string fontContents = FileHelpers::FileToString(fntFilename);

    std::vector<std::string> lines;
    SplitString(fontContents, '\n', lines);

    for (std::vector<std::string>::iterator line = lines.begin(); line != lines.end(); ++line)
    {
        std::vector<std::string> elements;
        SplitString(*line, ' ', elements);

        if (elements.size() < 1 )
            continue;

        std::map<std::string, std::string> data;
        for (std::vector<std::string>::iterator element = elements.begin(); element != elements.end(); ++element)
        {
            data[element->substr(0, element->find('='))] = element->substr(element->find('=')+1);
        }

        std::string elementType = elements[0];

        Vec2 texSize;

        if (elementType == "info")
        {
            int size = (int)atoi(data["size"].c_str());

            font->size = size;
        } else if (elementType == "common")
        {
            int lineHeight = (int)atoi(data["lineHeight"].c_str());
            int base = (int)atoi(data["base"].c_str());
            int scaleW = (int)atoi(data["scaleW"].c_str());
            int scaleH = (int)atoi(data["scaleH"].c_str());

            font->base = (float)base/(float)font->size;
            font->lineHeight = (float)lineHeight / (float)scaleH;
            texSize = Vec2(scaleW, scaleH);
        } else if (elementType == "page")
        {
            std::string texFilename = fileRoot + "/data/fonts/" + data["file"].substr(1, data["file"].find('"', 1)-1);
            font->texture = GraphicsDevice::Instance()->CreateTexture();
            font->texture->Load(texFilename, true);
        } else if (elementType == "char")
        {
            Font::Character character;

            char charCode = (char)atoi(data["id"].c_str());
            int x = (int)atoi(data["x"].c_str());
            int y = (int)atoi(data["y"].c_str());
            int width = (int)atoi(data["width"].c_str());
            int height = (int)atoi(data["height"].c_str());
            int xoffset = (int)atoi(data["xoffset"].c_str());
            int yoffset = (int)atoi(data["yoffset"].c_str());
            int xadvance = (int)atoi(data["xadvance"].c_str());

            character.width = width/(float)font->size;
            character.height = height/(float)font->size;
            character.uvx = x/texSize[0];
            character.uvy = y/texSize[1];
            character.uvu = width/texSize[0];
            character.uvv = height/texSize[1];
            character.xOffset = xoffset/(float)font->size;
            character.yOffset = yoffset/(float)font->size;
            character.xAdvance = xadvance/(float)font->size;

            font->chars[charCode] = character;
        } else if (elementType == "kerning")
        {
            char charOne = (char)atoi(data["first"].c_str());
            char charTwo = (char)atoi(data["second"].c_str());
            int amount = (int)atoi(data["amount"].c_str());

            font->kerning[std::pair<char, char>(charOne, charTwo)] = amount/texSize[0];
        }
    }

    _Fonts[name] = font;
}

void FontRenderer::Update(float time)
{
    _Instances.clear();
}

void FontRenderer::Render(RenderLayer* layer)
{
    InstanceList& instances = _Instances[layer];

    if (instances.size() == 0)
        return;

    glDisable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glEnable(GL_TEXTURE_2D);

#ifndef PIXELBOOST_GRAPHICS_PREMULTIPLIED_ALPHA
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#else
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
#endif

    glDisableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    _IndexBuffer->Bind();

    for (InstanceList::iterator it = instances.begin(); it != instances.end(); ++it)
    {
        Font* font;

        FontMap::iterator fontIt = _Fonts.find(it->_Font);
        if (fontIt == _Fonts.end())
            continue;

        font = fontIt->second;

        _VertexBuffer->Lock();

        Vertex_PXYZ_UV* vertexBuffer = static_cast<Vertex_PXYZ_UV*>(_VertexBuffer->GetData());

        float offset = 0.f;
        for (int i=0; i<it->_String.length(); i++)
        {
            std::map<char, Font::Character>::iterator charIt = font->chars.find(it->_String[i]);

            if (charIt == font->chars.end())
                continue;

            AddCharacter(vertexBuffer, charIt->second, offset, font->base);

            vertexBuffer += 4;

            offset += charIt->second.xAdvance;

            if (i<it->_String.length()-1)
            {
                std::map<std::pair<char, char>, float>::iterator kerningIt = font->kerning.find(std::pair<char, char>(it->_String[i], it->_String[i+1]));

                if (kerningIt != font->kerning.end())
                    offset += kerningIt->second;
            }
        }

        _VertexBuffer->Unlock(it->_String.length()*4);

        _VertexBuffer->Bind();

        font->texture->Bind(0);

        glPushMatrix();

        glTranslatef(it->_Position[0], it->_Position[1], 0.f);

        glRotatef(it->_Rotation, 0, 0, 1);

        glScalef(it->_Size, it->_Size, 1.f);

        switch (it->_Alignment) {
            case kFontAlignLeft:
                break;
            case kFontAlignCenter:
                glTranslatef(-offset/2.f, 0, 0);
                break;
            case kFontAlignRight:
                glTranslatef(-offset, 0, 0);
                break;
        }

        glColor4f(it->_Color[0], it->_Color[1], it->_Color[2], it->_Color[3]);

        GraphicsDevice::Instance()->DrawElements(GraphicsDevice::kElementTriangles, it->_String.length()*6);

        glColor4f(1, 1, 1, 1);

        glPopMatrix();
    }

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    GraphicsDevice::Instance()->BindIndexBuffer(0);
    GraphicsDevice::Instance()->BindVertexBuffer(0);

    glDisable(GL_BLEND);
    glDisable(GL_TEXTURE_2D);
}

bool FontRenderer::AttachToRenderer(RenderLayer* layer, const std::string& fontName, const std::string& string, Vec2 position, FontAlign alignment, float size, float rotation, Vec4 color)
{
    FontInstance instance;

    instance._Font = fontName;
    instance._String = string;
    instance._Position = position;
    instance._Alignment = alignment;
    instance._Rotation = rotation;
    instance._Size = size;
    instance._Color = color;

    _Instances[layer].push_back(instance);

    return true;
}

void FontRenderer::SplitString(const std::string& string, char seperator, std::vector<std::string>& output)
{
    std::string item;

    for (int i=0; i<string.length(); i++)
    {
        char ch=string[i];

        if (ch == seperator)
        {
            if (!item.empty())
            {
                output.push_back(item);
            }
            item = "";
        }
        else
        {
            item += ch;
        }
    }
    if (!item.empty())
    {
        output.push_back(item);
    }
}
<|endoftext|>


<commit_before>/******************************************************************************\
* File:          appl.cpp
* Purpose:       Implementation of sample classes for wxextension
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009, Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/aboutdlg.h>
#include <wx/busyinfo.h>
#include <wx/numdlg.h>
#include <wx/stdpaths.h>
#include <wx/textfile.h>
#include <wx/extension/renderer.h>
#include "appl.h"
#include "appl.xpm"

enum
{
  ID_FIRST = 15000,
  ID_CONFIG_DLG,
  ID_CONFIG_DLG_READONLY,
  ID_PRINT_SPECIAL,
  ID_LOCALE_SHOW_DIR,
  ID_STATISTICS_CLEAR,
  ID_STATISTICS_SHOW,
  ID_STC_CONFIG_DLG,
  ID_STC_FLAGS,
  ID_STC_GOTO,
  ID_STC_SPLIT,
  ID_STC_LEXER,
  ID_LAST,
};

BEGIN_EVENT_TABLE(exSampleFrame, exFrame)
  EVT_MENU_RANGE(wxID_LOWEST, wxID_HIGHEST, exSampleFrame::OnCommand)
  EVT_MENU_RANGE(ID_FIRST, ID_LAST, exSampleFrame::OnCommand)
  EVT_MENU(ID_SHELL_COMMAND, exSampleFrame::OnCommand)
END_EVENT_TABLE()

IMPLEMENT_APP(exSampleApp)

bool exSampleApp::OnInit()
{
  SetAppName("exSample");
  SetLogging();

  exApp::OnInit();

  exSampleFrame *frame = new exSampleFrame("exSample");
  frame->Show(true);

  SetTopWindow(frame);

  return true;
}

#if wxUSE_GRID
exSampleDir::exSampleDir(const wxString& fullpath, const wxString& findfiles, exGrid* grid)
  : exDir(fullpath, findfiles)
  , m_Grid(grid)
{
}

void exSampleDir::OnFile(const wxString& file)
{
  m_Grid->AppendRows(1);
  const int no = m_Grid->GetNumberRows() - 1;
  m_Grid->SetCellValue(no, 0, wxString::Format("cell%d", no));
  m_Grid->SetCellValue(no, 1, file);

  exRenderer* renderer = new exRenderer(exRenderer::CELL_CROSS, *wxGREEN_PEN, *wxRED_PEN);
  m_Grid->SetCellRenderer(no, 0, renderer);

  // Let's make these cells readonly and colour them, so we can test
  // things like cutting and dropping is forbidden.
  m_Grid->SetReadOnly(no, 1);
  m_Grid->SetCellBackgroundColour(no, 1, *wxLIGHT_GREY);
}
#endif

exSampleFrame::exSampleFrame(const wxString& title)
  : exManagedFrame(NULL, wxID_ANY, title)
  , m_FlagsSTC(0)
{
  SetIcon(appl_xpm);

  exMenu* menuFile = new exMenu;
  menuFile->Append(wxID_OPEN);
  menuFile->AppendSeparator();
  menuFile->AppendPrint();
  menuFile->AppendSeparator();
  menuFile->Append(ID_PRINT_SPECIAL, _("Print Test")); // test to print without a window
  menuFile->AppendSeparator();
  menuFile->Append(ID_LOCALE_SHOW_DIR, _("Show Locale Dir"));
  menuFile->AppendSeparator();
  menuFile->Append(ID_STATISTICS_SHOW, _("Show Statistics"));
  menuFile->Append(ID_STATISTICS_CLEAR, _("Clear Statistics"));
  menuFile->AppendSeparator();
  menuFile->Append(wxID_EXIT);

  exMenu* menuConfig = new exMenu;
  menuConfig->Append(ID_CONFIG_DLG, exEllipsed(_("Config Dialog")));
  menuConfig->Append(ID_CONFIG_DLG_READONLY, exEllipsed(_("Config Dialog Readonly")));
  menuConfig->AppendSeparator();

  exMenu* menuSTC = new exMenu;
  menuSTC->Append(ID_STC_FLAGS, exEllipsed(_("Open Flag")));
  menuSTC->AppendSeparator();
  menuSTC->Append(ID_STC_CONFIG_DLG, exEllipsed(_("Config Dialog")));
  menuSTC->Append(ID_STC_GOTO, exEllipsed(_("Goto Dialog")));
  menuSTC->Append(ID_STC_LEXER, exEllipsed(_("Lexer Dialog")));
  menuSTC->AppendSeparator();
  menuSTC->Append(ID_STC_SPLIT, _("Split"));
  menuSTC->AppendSeparator();
  menuSTC->Append(ID_EDIT_MACRO_START_RECORD, _("Start Record"));
  menuSTC->Append(ID_EDIT_MACRO_STOP_RECORD, _("Stop Record"));
  menuSTC->Append(ID_EDIT_MACRO_PLAYBACK, _("Playback"));

  exMenu* menuHelp = new exMenu;
  menuHelp->Append(wxID_ABOUT);

  wxMenuBar *menubar = new wxMenuBar;
  menubar->Append(menuFile, _("&File"));
  menubar->Append(menuSTC, _("&STC"));
  menubar->Append(menuConfig, _("&Config"));
  menubar->Append(menuHelp, _("&Help"));
  SetMenuBar(menubar);

  m_Notebook = new exNotebook(this, NULL);
#if wxUSE_GRID
  m_Grid = new exGrid(m_Notebook);
#endif
  m_ListView = new exListView(m_Notebook);
  m_STC = new exSTC(this);
  m_STCShell = new exSTCShell(this, ">", wxTextFile::GetEOL(), true, 10);

  GetManager().AddPane(m_STC, wxAuiPaneInfo().CenterPane().CloseButton(false).MaximizeButton(true).Name("exSTC"));
  GetManager().AddPane(m_STCShell, wxAuiPaneInfo().Bottom().MinSize(wxSize(250, 250)));
  GetManager().AddPane(m_Notebook, wxAuiPaneInfo().Left().MinSize(wxSize(250, 250)));
  GetManager().Update();

  assert(exApp::GetLexers());

  exSTC* st = new exSTC(this, exApp::GetLexers()->GetFileName().GetFullPath());
  m_Notebook->AddPage(st, exApp::GetLexers()->GetFileName().GetFullName());
  m_Notebook->AddPage(m_ListView, "exListView");

#if wxUSE_GRID
  m_Notebook->AddPage(m_Grid, "exGrid");
  m_Grid->CreateGrid(0, 0);
  m_Grid->AppendCols(2);
  exSampleDir dir(wxGetCwd(), "appl.*", m_Grid);
  dir.FindFiles();
  m_Grid->AutoSizeColumns();
#endif

  m_ListView->SetSingleStyle(wxLC_REPORT); // wxLC_ICON);
  m_ListView->InsertColumn("String", exColumn::COL_STRING);
  m_ListView->InsertColumn("Number", exColumn::COL_INT);
  m_ListView->InsertColumn("Float", exColumn::COL_FLOAT);
  m_ListView->InsertColumn("Date", exColumn::COL_DATE);

  const int items = 50;

  for (int i = 0; i < items; i++)
  {
    exListItem item(m_ListView, wxString::Format("item%d", i));
    item.Insert();
    item.SetColumnText(1, wxString::Format("%d", i));
    item.SetColumnText(2, wxString::Format("%f", (float)i / 2.0));
    item.SetColumnText(3, wxDateTime::Now().Format());

    // Set some images.
    if      (i == 0) item.SetImage(wxART_CDROM);
    else if (i == 1) item.SetImage(wxART_REMOVABLE);
    else if (i == 2) item.SetImage(wxART_FOLDER);
    else if (i == 3) item.SetImage(wxART_FOLDER_OPEN);
    else if (i == 4) item.SetImage(wxART_GO_DIR_UP);
    else if (i == 5) item.SetImage(wxART_EXECUTABLE_FILE);
    else if (i == 6) item.SetImage(wxART_NORMAL_FILE);
    else             item.SetImage(wxART_TICK_MARK);
  }

  std::vector<exPane> panes;
  panes.push_back(exPane("PaneText", -3));
  panes.push_back(exPane("PaneFileType", 50, _("File type")));
  panes.push_back(exPane("PaneCells", 60, _("Cells")));
  panes.push_back(exPane("PaneItems", 60, _("Items")));
  panes.push_back(exPane("PaneLines", 100, _("Lines")));
  panes.push_back(exPane("PaneLexer", 60, _("Lexer")));
  SetupStatusBar(panes);

  CreateToolBar();
  m_ToolBar->AddTool(wxID_OPEN);
  m_ToolBar->AddTool(wxID_SAVE);
  m_ToolBar->AddTool(wxID_PRINT);
  m_ToolBar->AddTool(wxID_EXIT);
  m_ToolBar->Realize();
}

void exSampleFrame::ConfigDialogApplied(wxWindowID id)
{
  m_STC->ConfigGet();
  m_STCShell->ConfigGet();
}

void exSampleFrame::OnCommand(wxCommandEvent& event)
{
  m_Statistics.Inc(wxString::Format("%d", event.GetId()));

  switch (event.GetId())
  {
  case wxID_ABOUT:
    {
    wxAboutDialogInfo info;
    info.SetIcon(GetIcon());
    info.SetVersion(EX_LIB_VERSION);
    info.AddDeveloper(wxVERSION_STRING);
    info.SetCopyright(_("(c) 1998-2009 Anton van Wezenbeek."));
    wxAboutBox(info);
    }
    break;
  case wxID_EXIT: Close(true); break;
  case wxID_OPEN:
    {
    wxFileDialog dlg(this,
      _("Select File"),
      wxEmptyString,
      wxEmptyString,
      wxFileSelectorDefaultWildcardStr,
      wxFD_OPEN | wxFD_CHANGE_DIR);

    if (m_STC->AskFileOpen(dlg) == wxID_CANCEL) return;

    wxStopWatch sw;
    m_STC->Open(dlg.GetPath(), 0, wxEmptyString, m_FlagsSTC);
    const long stop = sw.Time();

    StatusText(wxString::Format("exSTC::Open:%ld milliseconds, %d bytes", stop, m_STC->GetTextLength()));
    }
    break;

  case wxID_PREVIEW: m_ListView->PrintPreview(); break;
  case wxID_PRINT: m_ListView->Print(); break;
  case wxID_PRINT_SETUP: exApp::GetPrinter()->PageSetup(); break;

  case wxID_SAVE:
    m_STC->FileSave();

    if (m_STC->GetFileName().GetFullPath() == exApp::GetLexers()->GetFileName().GetFullPath())
    {
      if (exApp::GetLexers()->Read())
      {
        wxLogMessage("file contains: %d lexers", exApp::GetLexers()->Get().size());
        m_STC->SetLexer();
        // As the lexer might have changed, update status bar field as well.
        m_STC->UpdateStatusBar("PaneLexer");
      }
    }
    break;

  case ID_CONFIG_DLG:
    {
    std::vector<exConfigItem> v;

    for (size_t h = 1; h <= 25; h++)
    {
      v.push_back(exConfigItem(wxString::Format(_("check%d"), h), CONFIG_CHECKBOX, "Checkboxes"));
    }

    for (size_t i = 1; i <= 25; i++)
    {
      v.push_back(exConfigItem(wxString::Format(_("colour%d"), i), CONFIG_COLOUR, "Colours"));
    }

    for (size_t j = 1; j <= 10; j++)
    {
      v.push_back(exConfigItem(wxString::Format(_("integer%d"), j), CONFIG_INT, "Integers", true));
    }

    for (size_t k = 1; k <= 10; k++)
    {
      v.push_back(exConfigItem(wxString::Format(_("spin%d"), k), 1, k, wxString("Spin controls")));
    }

    for (size_t l = 1; l <= 10; l++)
    {
      v.push_back(exConfigItem(wxString::Format(_("string%d"), l), CONFIG_STRING, "Strings"));
    }

    for (size_t m = 1; m <= 10; m++)
    {
      v.push_back(exConfigItem(wxString::Format(_("combobox%d"), m), CONFIG_COMBOBOX, "Comboboxes"));
    }

    v.push_back(exConfigItem(_("dirpicker"), CONFIG_DIRPICKERCTRL, "Pickers"));
    v.push_back(exConfigItem(_("filepicker"), CONFIG_FILEPICKERCTRL, "Pickers"));

    exConfigDialog* dlg = new exConfigDialog(
      this,
      v,
      _("Config Dialog"),
      wxEmptyString,
      5,
      6,
      wxAPPLY | wxCANCEL,
      wxID_ANY,
      wxDefaultPosition,
      wxSize(400,300));

      dlg->Show();

      // Dialog is not placed nicely.
      //GetManager().GetPane("NOTEBOOK"));
      //GetManager().Update();
    }
    break;

  case ID_CONFIG_DLG_READONLY:
    {
    std::vector<exConfigItem> v;

    v.push_back(exConfigItem(_("filepicker"), CONFIG_FILEPICKERCTRL));

    for (size_t j = 1; j <= 10; j++)
    {
      v.push_back(exConfigItem(wxString::Format(_("integer%d"), j), CONFIG_INT));
    }

    exConfigDialog* dlg = new exConfigDialog(
      this,
      v,
      _("Config Dialog Readonly"),
      wxEmptyString,
      2,
      2,
      wxCANCEL);

      dlg->Show();
    }
    break;

  case ID_PRINT_SPECIAL:
    {
    wxHtmlEasyPrinting* print = exApp::GetPrinter();

    wxPrintDialogData printDialogData(*print->GetPrintData());
    wxPrinter printer(&printDialogData);

    wxHtmlPrintout printout;
    printout.SetHtmlFile("appl.xpm");
    printer.Print(this, &printout, false);

    /*
    // This is the simplest, but
    // asks for printing always (in lib source).
    print->PrintFile("mondrian.xpm");
    */

    /*
    // This could be made better, immediately hide etc.
    exSTC* stc = new exSTC(this, "mondrian.xpm");
    stc->Hide();
    stc->Print(false);// however stc->Print(false) does not print
    delete stc;
    */
    }
    break;

  case ID_LOCALE_SHOW_DIR:
    wxLogMessage(exApp::GetCatalogDir());
    break;

  case ID_SHELL_COMMAND:
      m_STCShell->AppendText("\nHello '" + event.GetString() + "' from the shell"),
      m_STCShell->Prompt();
    break;

  case ID_STATISTICS_SHOW:
    m_Notebook->AddPage(m_Statistics.Show(m_Notebook), "Statistics");
    break;
  case ID_STATISTICS_CLEAR:
    m_Statistics.Clear();
    break;

  case ID_STC_CONFIG_DLG:
    exSTC::ConfigDialog(
      _("Editor Options"),
      exSTC::STC_CONFIG_MODELESS | exSTC::STC_CONFIG_WITH_APPLY);
    break;
  case ID_STC_FLAGS:
    {
    long value = wxGetNumberFromUser(
      "Input:",
      wxEmptyString,
      "STC Open Flag",
      m_FlagsSTC,
      0,
      2 * exSTC::STC_OPEN_FROM_URL);

    if (value != -1)
    {
      m_FlagsSTC = value;
    }
    }
    break;
  case ID_STC_GOTO: m_STC->GotoDialog(); break;
  case ID_STC_LEXER: m_STC->LexerDialog(); break;
  case ID_STC_SPLIT:
    {
    exSTC* stc = new exSTC(*m_STC);
    m_Notebook->AddPage(
      stc,
      wxString::Format("stc%d", stc->GetId()),
      m_STC->GetFileName().GetFullName());
    stc->SetDocPointer(m_STC->GetDocPointer());
    }
    break;
  }
}
<commit_msg>removed unnecessary separator<commit_after>/******************************************************************************\
* File:          appl.cpp
* Purpose:       Implementation of sample classes for wxextension
* Author:        Anton van Wezenbeek
* RCS-ID:        $Id$
*
* Copyright (c) 1998-2009, Anton van Wezenbeek
* All rights are reserved. Reproduction in whole or part is prohibited
* without the written consent of the copyright owner.
\******************************************************************************/

#include <wx/aboutdlg.h>
#include <wx/busyinfo.h>
#include <wx/numdlg.h>
#include <wx/stdpaths.h>
#include <wx/textfile.h>
#include <wx/extension/renderer.h>
#include "appl.h"
#include "appl.xpm"

enum
{
  ID_FIRST = 15000,
  ID_CONFIG_DLG,
  ID_CONFIG_DLG_READONLY,
  ID_PRINT_SPECIAL,
  ID_LOCALE_SHOW_DIR,
  ID_STATISTICS_CLEAR,
  ID_STATISTICS_SHOW,
  ID_STC_CONFIG_DLG,
  ID_STC_FLAGS,
  ID_STC_GOTO,
  ID_STC_SPLIT,
  ID_STC_LEXER,
  ID_LAST,
};

BEGIN_EVENT_TABLE(exSampleFrame, exFrame)
  EVT_MENU_RANGE(wxID_LOWEST, wxID_HIGHEST, exSampleFrame::OnCommand)
  EVT_MENU_RANGE(ID_FIRST, ID_LAST, exSampleFrame::OnCommand)
  EVT_MENU(ID_SHELL_COMMAND, exSampleFrame::OnCommand)
END_EVENT_TABLE()

IMPLEMENT_APP(exSampleApp)

bool exSampleApp::OnInit()
{
  SetAppName("exSample");
  SetLogging();

  exApp::OnInit();

  exSampleFrame *frame = new exSampleFrame("exSample");
  frame->Show(true);

  SetTopWindow(frame);

  return true;
}

#if wxUSE_GRID
exSampleDir::exSampleDir(const wxString& fullpath, const wxString& findfiles, exGrid* grid)
  : exDir(fullpath, findfiles)
  , m_Grid(grid)
{
}

void exSampleDir::OnFile(const wxString& file)
{
  m_Grid->AppendRows(1);
  const int no = m_Grid->GetNumberRows() - 1;
  m_Grid->SetCellValue(no, 0, wxString::Format("cell%d", no));
  m_Grid->SetCellValue(no, 1, file);

  exRenderer* renderer = new exRenderer(exRenderer::CELL_CROSS, *wxGREEN_PEN, *wxRED_PEN);
  m_Grid->SetCellRenderer(no, 0, renderer);

  // Let's make these cells readonly and colour them, so we can test
  // things like cutting and dropping is forbidden.
  m_Grid->SetReadOnly(no, 1);
  m_Grid->SetCellBackgroundColour(no, 1, *wxLIGHT_GREY);
}
#endif

exSampleFrame::exSampleFrame(const wxString& title)
  : exManagedFrame(NULL, wxID_ANY, title)
  , m_FlagsSTC(0)
{
  SetIcon(appl_xpm);

  exMenu* menuFile = new exMenu;
  menuFile->Append(wxID_OPEN);
  menuFile->AppendSeparator();
  menuFile->AppendPrint();
  menuFile->AppendSeparator();
  menuFile->Append(ID_PRINT_SPECIAL, _("Print Test")); // test to print without a window
  menuFile->AppendSeparator();
  menuFile->Append(ID_LOCALE_SHOW_DIR, _("Show Locale Dir"));
  menuFile->AppendSeparator();
  menuFile->Append(ID_STATISTICS_SHOW, _("Show Statistics"));
  menuFile->Append(ID_STATISTICS_CLEAR, _("Clear Statistics"));
  menuFile->AppendSeparator();
  menuFile->Append(wxID_EXIT);

  exMenu* menuConfig = new exMenu;
  menuConfig->Append(ID_CONFIG_DLG, exEllipsed(_("Config Dialog")));
  menuConfig->Append(ID_CONFIG_DLG_READONLY, exEllipsed(_("Config Dialog Readonly")));

  exMenu* menuSTC = new exMenu;
  menuSTC->Append(ID_STC_FLAGS, exEllipsed(_("Open Flag")));
  menuSTC->AppendSeparator();
  menuSTC->Append(ID_STC_CONFIG_DLG, exEllipsed(_("Config Dialog")));
  menuSTC->Append(ID_STC_GOTO, exEllipsed(_("Goto Dialog")));
  menuSTC->Append(ID_STC_LEXER, exEllipsed(_("Lexer Dialog")));
  menuSTC->AppendSeparator();
  menuSTC->Append(ID_STC_SPLIT, _("Split"));
  menuSTC->AppendSeparator();
  menuSTC->Append(ID_EDIT_MACRO_START_RECORD, _("Start Record"));
  menuSTC->Append(ID_EDIT_MACRO_STOP_RECORD, _("Stop Record"));
  menuSTC->Append(ID_EDIT_MACRO_PLAYBACK, _("Playback"));

  exMenu* menuHelp = new exMenu;
  menuHelp->Append(wxID_ABOUT);

  wxMenuBar *menubar = new wxMenuBar;
  menubar->Append(menuFile, _("&File"));
  menubar->Append(menuSTC, _("&STC"));
  menubar->Append(menuConfig, _("&Config"));
  menubar->Append(menuHelp, _("&Help"));
  SetMenuBar(menubar);

  m_Notebook = new exNotebook(this, NULL);
#if wxUSE_GRID
  m_Grid = new exGrid(m_Notebook);
#endif
  m_ListView = new exListView(m_Notebook);
  m_STC = new exSTC(this);
  m_STCShell = new exSTCShell(this, ">", wxTextFile::GetEOL(), true, 10);

  GetManager().AddPane(m_STC, wxAuiPaneInfo().CenterPane().CloseButton(false).MaximizeButton(true).Name("exSTC"));
  GetManager().AddPane(m_STCShell, wxAuiPaneInfo().Bottom().MinSize(wxSize(250, 250)));
  GetManager().AddPane(m_Notebook, wxAuiPaneInfo().Left().MinSize(wxSize(250, 250)));
  GetManager().Update();

  assert(exApp::GetLexers());

  exSTC* st = new exSTC(this, exApp::GetLexers()->GetFileName().GetFullPath());
  m_Notebook->AddPage(st, exApp::GetLexers()->GetFileName().GetFullName());
  m_Notebook->AddPage(m_ListView, "exListView");

#if wxUSE_GRID
  m_Notebook->AddPage(m_Grid, "exGrid");
  m_Grid->CreateGrid(0, 0);
  m_Grid->AppendCols(2);
  exSampleDir dir(wxGetCwd(), "appl.*", m_Grid);
  dir.FindFiles();
  m_Grid->AutoSizeColumns();
#endif

  m_ListView->SetSingleStyle(wxLC_REPORT); // wxLC_ICON);
  m_ListView->InsertColumn("String", exColumn::COL_STRING);
  m_ListView->InsertColumn("Number", exColumn::COL_INT);
  m_ListView->InsertColumn("Float", exColumn::COL_FLOAT);
  m_ListView->InsertColumn("Date", exColumn::COL_DATE);

  const int items = 50;

  for (int i = 0; i < items; i++)
  {
    exListItem item(m_ListView, wxString::Format("item%d", i));
    item.Insert();
    item.SetColumnText(1, wxString::Format("%d", i));
    item.SetColumnText(2, wxString::Format("%f", (float)i / 2.0));
    item.SetColumnText(3, wxDateTime::Now().Format());

    // Set some images.
    if      (i == 0) item.SetImage(wxART_CDROM);
    else if (i == 1) item.SetImage(wxART_REMOVABLE);
    else if (i == 2) item.SetImage(wxART_FOLDER);
    else if (i == 3) item.SetImage(wxART_FOLDER_OPEN);
    else if (i == 4) item.SetImage(wxART_GO_DIR_UP);
    else if (i == 5) item.SetImage(wxART_EXECUTABLE_FILE);
    else if (i == 6) item.SetImage(wxART_NORMAL_FILE);
    else             item.SetImage(wxART_TICK_MARK);
  }

  std::vector<exPane> panes;
  panes.push_back(exPane("PaneText", -3));
  panes.push_back(exPane("PaneFileType", 50, _("File type")));
  panes.push_back(exPane("PaneCells", 60, _("Cells")));
  panes.push_back(exPane("PaneItems", 60, _("Items")));
  panes.push_back(exPane("PaneLines", 100, _("Lines")));
  panes.push_back(exPane("PaneLexer", 60, _("Lexer")));
  SetupStatusBar(panes);

  CreateToolBar();
  m_ToolBar->AddTool(wxID_OPEN);
  m_ToolBar->AddTool(wxID_SAVE);
  m_ToolBar->AddTool(wxID_PRINT);
  m_ToolBar->AddTool(wxID_EXIT);
  m_ToolBar->Realize();
}

void exSampleFrame::ConfigDialogApplied(wxWindowID id)
{
  m_STC->ConfigGet();
  m_STCShell->ConfigGet();
}

void exSampleFrame::OnCommand(wxCommandEvent& event)
{
  m_Statistics.Inc(wxString::Format("%d", event.GetId()));

  switch (event.GetId())
  {
  case wxID_ABOUT:
    {
    wxAboutDialogInfo info;
    info.SetIcon(GetIcon());
    info.SetVersion(EX_LIB_VERSION);
    info.AddDeveloper(wxVERSION_STRING);
    info.SetCopyright(_("(c) 1998-2009 Anton van Wezenbeek."));
    wxAboutBox(info);
    }
    break;
  case wxID_EXIT: Close(true); break;
  case wxID_OPEN:
    {
    wxFileDialog dlg(this,
      _("Select File"),
      wxEmptyString,
      wxEmptyString,
      wxFileSelectorDefaultWildcardStr,
      wxFD_OPEN | wxFD_CHANGE_DIR);

    if (m_STC->AskFileOpen(dlg) == wxID_CANCEL) return;

    wxStopWatch sw;
    m_STC->Open(dlg.GetPath(), 0, wxEmptyString, m_FlagsSTC);
    const long stop = sw.Time();

    StatusText(wxString::Format("exSTC::Open:%ld milliseconds, %d bytes", stop, m_STC->GetTextLength()));
    }
    break;

  case wxID_PREVIEW: m_ListView->PrintPreview(); break;
  case wxID_PRINT: m_ListView->Print(); break;
  case wxID_PRINT_SETUP: exApp::GetPrinter()->PageSetup(); break;

  case wxID_SAVE:
    m_STC->FileSave();

    if (m_STC->GetFileName().GetFullPath() == exApp::GetLexers()->GetFileName().GetFullPath())
    {
      if (exApp::GetLexers()->Read())
      {
        wxLogMessage("file contains: %d lexers", exApp::GetLexers()->Get().size());
        m_STC->SetLexer();
        // As the lexer might have changed, update status bar field as well.
        m_STC->UpdateStatusBar("PaneLexer");
      }
    }
    break;

  case ID_CONFIG_DLG:
    {
    std::vector<exConfigItem> v;

    for (size_t h = 1; h <= 25; h++)
    {
      v.push_back(exConfigItem(wxString::Format(_("check%d"), h), CONFIG_CHECKBOX, "Checkboxes"));
    }

    for (size_t i = 1; i <= 25; i++)
    {
      v.push_back(exConfigItem(wxString::Format(_("colour%d"), i), CONFIG_COLOUR, "Colours"));
    }

    for (size_t j = 1; j <= 10; j++)
    {
      v.push_back(exConfigItem(wxString::Format(_("integer%d"), j), CONFIG_INT, "Integers", true));
    }

    for (size_t k = 1; k <= 10; k++)
    {
      v.push_back(exConfigItem(wxString::Format(_("spin%d"), k), 1, k, wxString("Spin controls")));
    }

    for (size_t l = 1; l <= 10; l++)
    {
      v.push_back(exConfigItem(wxString::Format(_("string%d"), l), CONFIG_STRING, "Strings"));
    }

    for (size_t m = 1; m <= 10; m++)
    {
      v.push_back(exConfigItem(wxString::Format(_("combobox%d"), m), CONFIG_COMBOBOX, "Comboboxes"));
    }

    v.push_back(exConfigItem(_("dirpicker"), CONFIG_DIRPICKERCTRL, "Pickers"));
    v.push_back(exConfigItem(_("filepicker"), CONFIG_FILEPICKERCTRL, "Pickers"));

    exConfigDialog* dlg = new exConfigDialog(
      this,
      v,
      _("Config Dialog"),
      wxEmptyString,
      5,
      6,
      wxAPPLY | wxCANCEL,
      wxID_ANY,
      wxDefaultPosition,
      wxSize(400,300));

      dlg->Show();

      // Dialog is not placed nicely.
      //GetManager().GetPane("NOTEBOOK"));
      //GetManager().Update();
    }
    break;

  case ID_CONFIG_DLG_READONLY:
    {
    std::vector<exConfigItem> v;

    v.push_back(exConfigItem(_("filepicker"), CONFIG_FILEPICKERCTRL));

    for (size_t j = 1; j <= 10; j++)
    {
      v.push_back(exConfigItem(wxString::Format(_("integer%d"), j), CONFIG_INT));
    }

    exConfigDialog* dlg = new exConfigDialog(
      this,
      v,
      _("Config Dialog Readonly"),
      wxEmptyString,
      2,
      2,
      wxCANCEL);

      dlg->Show();
    }
    break;

  case ID_PRINT_SPECIAL:
    {
    wxHtmlEasyPrinting* print = exApp::GetPrinter();

    wxPrintDialogData printDialogData(*print->GetPrintData());
    wxPrinter printer(&printDialogData);

    wxHtmlPrintout printout;
    printout.SetHtmlFile("appl.xpm");
    printer.Print(this, &printout, false);

    /*
    // This is the simplest, but
    // asks for printing always (in lib source).
    print->PrintFile("mondrian.xpm");
    */

    /*
    // This could be made better, immediately hide etc.
    exSTC* stc = new exSTC(this, "mondrian.xpm");
    stc->Hide();
    stc->Print(false);// however stc->Print(false) does not print
    delete stc;
    */
    }
    break;

  case ID_LOCALE_SHOW_DIR:
    wxLogMessage(exApp::GetCatalogDir());
    break;

  case ID_SHELL_COMMAND:
      m_STCShell->AppendText("\nHello '" + event.GetString() + "' from the shell"),
      m_STCShell->Prompt();
    break;

  case ID_STATISTICS_SHOW:
    m_Notebook->AddPage(m_Statistics.Show(m_Notebook), "Statistics");
    break;
  case ID_STATISTICS_CLEAR:
    m_Statistics.Clear();
    break;

  case ID_STC_CONFIG_DLG:
    exSTC::ConfigDialog(
      _("Editor Options"),
      exSTC::STC_CONFIG_MODELESS | exSTC::STC_CONFIG_WITH_APPLY);
    break;
  case ID_STC_FLAGS:
    {
    long value = wxGetNumberFromUser(
      "Input:",
      wxEmptyString,
      "STC Open Flag",
      m_FlagsSTC,
      0,
      2 * exSTC::STC_OPEN_FROM_URL);

    if (value != -1)
    {
      m_FlagsSTC = value;
    }
    }
    break;
  case ID_STC_GOTO: m_STC->GotoDialog(); break;
  case ID_STC_LEXER: m_STC->LexerDialog(); break;
  case ID_STC_SPLIT:
    {
    exSTC* stc = new exSTC(*m_STC);
    m_Notebook->AddPage(
      stc,
      wxString::Format("stc%d", stc->GetId()),
      m_STC->GetFileName().GetFullName());
    stc->SetDocPointer(m_STC->GetDocPointer());
    }
    break;
  }
}
<|endoftext|>


<commit_before>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <google/protobuf/compiler/javanano/javanano_params.h>
#include <google/protobuf/compiler/javanano/javanano_generator.h>
#include <google/protobuf/compiler/javanano/javanano_file.h>
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace javanano {

namespace {

string TrimString(const string& s) {
  string::size_type start = s.find_first_not_of(" \n\r\t");
  if (start == string::npos) {
    return "";
  }
  string::size_type end = s.find_last_not_of(" \n\r\t") + 1;
  return s.substr(start, end - start);
}

} // namespace

void UpdateParamsRecursively(Params& params,
    const FileDescriptor* file) {
  // Add any parameters for this file
  if (file->options().has_java_outer_classname()) {
    params.set_java_outer_classname(
      file->name(), file->options().java_outer_classname());
  }
  if (file->options().has_java_package()) {
    params.set_java_package(
      file->name(), file->options().java_package());
  }
  if (file->options().has_java_multiple_files()) {
    params.set_java_multiple_files(
      file->name(), file->options().java_multiple_files());
  }

  // Loop through all dependent files recursively
  // adding dep
  for (int i = 0; i < file->dependency_count(); i++) {
    UpdateParamsRecursively(params, file->dependency(i));
  }
}

JavaNanoGenerator::JavaNanoGenerator() {}
JavaNanoGenerator::~JavaNanoGenerator() {}

bool JavaNanoGenerator::Generate(const FileDescriptor* file,
                             const string& parameter,
                             GeneratorContext* output_directory,
                             string* error) const {
  vector<pair<string, string> > options;

  ParseGeneratorParameter(parameter, &options);

  // -----------------------------------------------------------------
  // parse generator options

  // Name a file where we will write a list of generated file names, one
  // per line.
  string output_list_file;
  Params params(file->name());

  // Update per file params
  UpdateParamsRecursively(params, file);

  // Replace any existing options with ones from command line
  for (int i = 0; i < options.size(); i++) {
    string option_name = TrimString(options[i].first);
    string option_value = TrimString(options[i].second);
    if (option_name == "output_list_file") {
      output_list_file = option_value;
    } else if (option_name == "java_package") {
        vector<string> parts;
        SplitStringUsing(option_value, "|", &parts);
        if (parts.size() != 2) {
          *error = "Bad java_package, expecting filename|PackageName found '"
            + option_value + "'";
          return false;
        }
        params.set_java_package(parts[0], parts[1]);
    } else if (option_name == "java_outer_classname") {
        vector<string> parts;
        SplitStringUsing(option_value, "|", &parts);
        if (parts.size() != 2) {
          *error = "Bad java_outer_classname, "
                   "expecting filename|ClassName found '"
                   + option_value + "'";
          return false;
        }
        params.set_java_outer_classname(parts[0], parts[1]);
    } else if (option_name == "store_unknown_fields") {
      params.set_store_unknown_fields(option_value == "true");
    } else if (option_name == "java_multiple_files") {
      params.set_override_java_multiple_files(option_value == "true");
    } else if (option_name == "java_nano_generate_has") {
      params.set_generate_has(option_value == "true");
    } else if (option_name == "enum_style") {
      params.set_java_enum_style(option_value == "java");
    } else if (option_name == "optional_field_style") {
      params.set_optional_field_accessors(option_value == "accessors");
      params.set_use_reference_types_for_primitives(option_value == "reftypes"
          || option_value == "reftypes_compat_mode");
      params.set_reftypes_primitive_enums(
          option_value == "reftypes_compat_mode");
      if (option_value == "reftypes_compat_mode") {
        params.set_generate_clear(false);
      }
    } else if (option_name == "generate_equals") {
      params.set_generate_equals(option_value == "true");
    } else if (option_name == "ignore_services") {
      params.set_ignore_services(option_value == "true");
    } else if (option_name == "parcelable_messages") {
      params.set_parcelable_messages(option_value == "true");
    } else if (option_name == "generate_clone") {
      params.set_generate_clone(option_value == "true");
    } else if (option_name == "generate_intdefs") {
      params.set_generate_intdefs(option_value == "true");
    } else {
      *error = "Ignore unknown javanano generator option: " + option_name;
    }
  }

  // Check illegal parameter combinations
  // Note: the enum-like optional_field_style generator param ensures
  // that we can never have illegal combinations of field styles
  // (e.g. reftypes and accessors can't be on at the same time).
  if (params.generate_has()
      && (params.optional_field_accessors()
          || params.use_reference_types_for_primitives())) {
    error->assign("java_nano_generate_has=true cannot be used in conjunction"
        " with optional_field_style=accessors or optional_field_style=reftypes");
    return false;
  }

  // -----------------------------------------------------------------

  FileGenerator file_generator(file, params);
  if (!file_generator.Validate(error)) {
    return false;
  }

  string package_dir =
    StringReplace(file_generator.java_package(), ".", "/", true);
  if (!package_dir.empty()) package_dir += "/";

  vector<string> all_files;

  if (IsOuterClassNeeded(params, file)) {
    string java_filename = package_dir;
    java_filename += file_generator.classname();
    java_filename += ".java";
    all_files.push_back(java_filename);

    // Generate main java file.
    scoped_ptr<io::ZeroCopyOutputStream> output(
      output_directory->Open(java_filename));
    io::Printer printer(output.get(), '$');
    file_generator.Generate(&printer);
  }

  // Generate sibling files.
  file_generator.GenerateSiblings(package_dir, output_directory, &all_files);

  // Generate output list if requested.
  if (!output_list_file.empty()) {
    // Generate output list.  This is just a simple text file placed in a
    // deterministic location which lists the .java files being generated.
    scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
      output_directory->Open(output_list_file));
    io::Printer srclist_printer(srclist_raw_output.get(), '$');
    for (int i = 0; i < all_files.size(); i++) {
      srclist_printer.Print("$filename$\n", "filename", all_files[i]);
    }
  }

  return true;
}

}  // namespace java
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
<commit_msg>Expose generate_clear as an option.<commit_after>// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// http://code.google.com/p/protobuf/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Author: kenton@google.com (Kenton Varda)
//  Based on original Protocol Buffers design by
//  Sanjay Ghemawat, Jeff Dean, and others.

#include <google/protobuf/compiler/javanano/javanano_params.h>
#include <google/protobuf/compiler/javanano/javanano_generator.h>
#include <google/protobuf/compiler/javanano/javanano_file.h>
#include <google/protobuf/compiler/javanano/javanano_helpers.h>
#include <google/protobuf/io/printer.h>
#include <google/protobuf/io/zero_copy_stream.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/stubs/strutil.h>

namespace google {
namespace protobuf {
namespace compiler {
namespace javanano {

namespace {

string TrimString(const string& s) {
  string::size_type start = s.find_first_not_of(" \n\r\t");
  if (start == string::npos) {
    return "";
  }
  string::size_type end = s.find_last_not_of(" \n\r\t") + 1;
  return s.substr(start, end - start);
}

} // namespace

void UpdateParamsRecursively(Params& params,
    const FileDescriptor* file) {
  // Add any parameters for this file
  if (file->options().has_java_outer_classname()) {
    params.set_java_outer_classname(
      file->name(), file->options().java_outer_classname());
  }
  if (file->options().has_java_package()) {
    params.set_java_package(
      file->name(), file->options().java_package());
  }
  if (file->options().has_java_multiple_files()) {
    params.set_java_multiple_files(
      file->name(), file->options().java_multiple_files());
  }

  // Loop through all dependent files recursively
  // adding dep
  for (int i = 0; i < file->dependency_count(); i++) {
    UpdateParamsRecursively(params, file->dependency(i));
  }
}

JavaNanoGenerator::JavaNanoGenerator() {}
JavaNanoGenerator::~JavaNanoGenerator() {}

bool JavaNanoGenerator::Generate(const FileDescriptor* file,
                             const string& parameter,
                             GeneratorContext* output_directory,
                             string* error) const {
  vector<pair<string, string> > options;

  ParseGeneratorParameter(parameter, &options);

  // -----------------------------------------------------------------
  // parse generator options

  // Name a file where we will write a list of generated file names, one
  // per line.
  string output_list_file;
  Params params(file->name());

  // Update per file params
  UpdateParamsRecursively(params, file);

  // Replace any existing options with ones from command line
  for (int i = 0; i < options.size(); i++) {
    string option_name = TrimString(options[i].first);
    string option_value = TrimString(options[i].second);
    if (option_name == "output_list_file") {
      output_list_file = option_value;
    } else if (option_name == "java_package") {
        vector<string> parts;
        SplitStringUsing(option_value, "|", &parts);
        if (parts.size() != 2) {
          *error = "Bad java_package, expecting filename|PackageName found '"
            + option_value + "'";
          return false;
        }
        params.set_java_package(parts[0], parts[1]);
    } else if (option_name == "java_outer_classname") {
        vector<string> parts;
        SplitStringUsing(option_value, "|", &parts);
        if (parts.size() != 2) {
          *error = "Bad java_outer_classname, "
                   "expecting filename|ClassName found '"
                   + option_value + "'";
          return false;
        }
        params.set_java_outer_classname(parts[0], parts[1]);
    } else if (option_name == "store_unknown_fields") {
      params.set_store_unknown_fields(option_value == "true");
    } else if (option_name == "java_multiple_files") {
      params.set_override_java_multiple_files(option_value == "true");
    } else if (option_name == "java_nano_generate_has") {
      params.set_generate_has(option_value == "true");
    } else if (option_name == "enum_style") {
      params.set_java_enum_style(option_value == "java");
    } else if (option_name == "optional_field_style") {
      params.set_optional_field_accessors(option_value == "accessors");
      params.set_use_reference_types_for_primitives(option_value == "reftypes"
          || option_value == "reftypes_compat_mode");
      params.set_reftypes_primitive_enums(
          option_value == "reftypes_compat_mode");
      if (option_value == "reftypes_compat_mode") {
        params.set_generate_clear(false);
      }
    } else if (option_name == "generate_equals") {
      params.set_generate_equals(option_value == "true");
    } else if (option_name == "ignore_services") {
      params.set_ignore_services(option_value == "true");
    } else if (option_name == "parcelable_messages") {
      params.set_parcelable_messages(option_value == "true");
    } else if (option_name == "generate_clone") {
      params.set_generate_clone(option_value == "true");
    } else if (option_name == "generate_intdefs") {
      params.set_generate_intdefs(option_value == "true");
    } else if (option_name == "generate_clear") {
      params.set_generate_clear(option_value == "true");
    } else {
      *error = "Ignore unknown javanano generator option: " + option_name;
    }
  }

  // Check illegal parameter combinations
  // Note: the enum-like optional_field_style generator param ensures
  // that we can never have illegal combinations of field styles
  // (e.g. reftypes and accessors can't be on at the same time).
  if (params.generate_has()
      && (params.optional_field_accessors()
          || params.use_reference_types_for_primitives())) {
    error->assign("java_nano_generate_has=true cannot be used in conjunction"
        " with optional_field_style=accessors or optional_field_style=reftypes");
    return false;
  }

  // -----------------------------------------------------------------

  FileGenerator file_generator(file, params);
  if (!file_generator.Validate(error)) {
    return false;
  }

  string package_dir =
    StringReplace(file_generator.java_package(), ".", "/", true);
  if (!package_dir.empty()) package_dir += "/";

  vector<string> all_files;

  if (IsOuterClassNeeded(params, file)) {
    string java_filename = package_dir;
    java_filename += file_generator.classname();
    java_filename += ".java";
    all_files.push_back(java_filename);

    // Generate main java file.
    scoped_ptr<io::ZeroCopyOutputStream> output(
      output_directory->Open(java_filename));
    io::Printer printer(output.get(), '$');
    file_generator.Generate(&printer);
  }

  // Generate sibling files.
  file_generator.GenerateSiblings(package_dir, output_directory, &all_files);

  // Generate output list if requested.
  if (!output_list_file.empty()) {
    // Generate output list.  This is just a simple text file placed in a
    // deterministic location which lists the .java files being generated.
    scoped_ptr<io::ZeroCopyOutputStream> srclist_raw_output(
      output_directory->Open(output_list_file));
    io::Printer srclist_printer(srclist_raw_output.get(), '$');
    for (int i = 0; i < all_files.size(); i++) {
      srclist_printer.Print("$filename$\n", "filename", all_files[i]);
    }
  }

  return true;
}

}  // namespace java
}  // namespace compiler
}  // namespace protobuf
}  // namespace google
<|endoftext|>


<commit_before>/// \file
/// \ingroup graphics
/// Show how to shade an area between two graphs
///
/// \macro_image
/// \macro_code
///
/// \author Rene Brun

void graphShade() {
   TCanvas *c1 = new TCanvas("c1",
      "A Simple Graph Example",200,10,700,500);

   c1->SetGrid();
   c1->DrawFrame(0,0,2.2,12);

   const Int_t n = 20;
   Double_t x[n], y[n],ymin[n], ymax[n];
   Int_t i;
   for (i=0;i<n;i++) {
     x[i] = 0.1+i*0.1;
     ymax[i] = 10*sin(x[i]+0.2);
     ymin[i] = 8*sin(x[i]+0.1);
     y[i] = 9*sin(x[i]+0.15);
   }
   TGraph *grmin = new TGraph(n,x,ymin);
   TGraph *grmax = new TGraph(n,x,ymax);
   TGraph *gr    = new TGraph(n,x,y);
   TGraph *grshade = new TGraph(2*n);
   for (i=0;i<n;i++) {
      grshade->SetPoint(i,x[i],ymax[i]);
      grshade->SetPoint(n+i,x[n-i-1],ymin[n-i-1]);
   }
   grshade->SetFillStyle(3013);
   grshade->SetFillColor(16);
   grshade->Draw("f");
   grmin->Draw("l");
   grmax->Draw("l");
   gr->SetLineWidth(4);
   gr->SetMarkerColor(4);
   gr->SetMarkerStyle(21);
   gr->Draw("CP");
}
<commit_msg>Move this Macro to "graphs"<commit_after><|endoftext|>