<commit_before>/*
  Copyright 2017 Barcelona Supercomputing Center (www.bsc.es)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
#include "persistent_cache.h"

static int cached_object_init(cached_object* self,
  PyObject *args, PyObject *kwds) {
    return 0;
}

static void cached_object_dealloc(cached_object* self) {
  Py_DECREF(self->obj);
  Py_XDECREF(self->comparison_function);
}

bool _default_comparison_function(const cached_object& a,  const cached_object& b) {
  if(a.hit_count != b.hit_count) {
    return a.hit_count < b.hit_count;
  }
  if(a.last_hit_time != b.last_hit_time) {
    return a.last_hit_time < b.last_hit_time;
  }
  return a.id < b.id;
}

static PyObject* default_comparison_function(PyObject* self, PyObject* args) {
  PyObject* a;
  PyObject* b;
  if(!Py_BuildValue("OO", &a, &b)) {
    return NULL;
  }
  cached_object* _a = (cached_object*)a;
  cached_object* _b = (cached_object*)b;
  return PyBool_FromLong(_default_comparison_function(*_a, *_b));
}

static PyObject*
cached_object_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
  cached_object* self = (cached_object*)type->tp_alloc(type, 0);
  const char* object_id;

  if(!PyArg_ParseTuple(args, "sOlOl", &object_id, &self->obj, &self->object_size,
  &self->comparison_function, &self->last_hit_time)) {
    return NULL;
  }
  Py_INCREF(self->obj);
  Py_XINCREF(self->comparison_function);
  self->id = std::string(object_id);
  return (PyObject*)self;
}

static PyObject* cached_object_get_id(PyObject* self, PyObject* args) {
  cached_object* _self = (cached_object*)self;
  return PyString_FromStringAndSize(_self->id.c_str(), _self->id.size());
}

static PyObject* cached_object_get_obj(PyObject* self, PyObject* args) {
  cached_object* _self = (cached_object*)self;
  return _self->obj;
}

void _delete_element(Cache* c, cached_object* obj) {
  c->current_size -= obj->object_size;
  c->H->erase(obj->id);
  Py_DECREF(obj->obj);
  Py_XDECREF(obj->comparison_function);
  c->S->erase(*obj);
}

void _delete_first_element(Cache* c) {
  cached_object* first_element = (cached_object*)&*(c->S->begin());
  _delete_element(c, first_element);
}

static void Cache_dealloc(Cache* self) {
  while(!self->S->empty()) _delete_first_element(self);
  delete(self->S);
  delete(self->H);
  Py_XDECREF(self->comparator);
}

static int Cache_init(Cache* self, PyObject* args, PyObject* kwds) {
  return 0;
}

static PyObject* Cache_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
  Cache* self = (Cache*)type->tp_alloc(type, 0);
  self->S = new std::set< cached_object, cached_object_comparator >();
  self->H = new std::map< std::string, cached_object >();
  self->current_time = 0ll;
  self->size_limit = 1024*1024*1024ll;
  static char* kwlist[] = {(char*)"size_limit", (char*)"comparison_function"};
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|lO", kwlist, &self->size_limit,
  &self->comparator)) {
         return NULL;
  }
  Py_XINCREF(self->comparator);
  return (PyObject*)self;
}

static PyObject* Cache_add(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  const char* object_id;
  PyObject* obj_to_add;
  long long object_size = -1ll;
  if(!PyArg_ParseTuple(args, "sO|l", &object_id, &obj_to_add, &object_size)) {
    return NULL;
  }
  cached_object to_add = *(new cached_object());
  to_add.id = std::string(object_id);
  if(_self->H->count(to_add.id)) {
    std::string err_msg = "Object with id " + to_add.id + " is\
    already cached!";
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  to_add.obj = obj_to_add;
  if(object_size == -1ll) {
    // rough approximation to the object's size (only invoked when obj size is
    // not given by the user)
    object_size = sizeof(*obj_to_add);
  }
  // Delete the object with least priority until cache is empty or
  // the total used space is less or equal than the limit
  // Note that this operation can delete the most recent object
  // depending on the comparison function
  while(!_self->S->empty() && _self->current_size >= _self->size_limit) {
    _delete_first_element(_self);
  }
  // Does this object fit on cache?
  // If yes, add it and then update the total used cache space
  if(_self->current_size + object_size <= _self->size_limit) {
    to_add.object_size = object_size;
    to_add.hit_count = 1;
    to_add.last_hit_time = _self->current_time;
    to_add.comparison_function = _self->comparator;
    Py_XINCREF(_self->comparator);
    Py_INCREF(to_add.obj);
    _self->current_size += to_add.object_size;
    std::map< std::string, cached_object >& map_ref = *_self->H;
    map_ref[to_add.id] = to_add;
    _self->S->insert(map_ref[to_add.id]);
  }
  ++_self->current_time;
  Py_RETURN_NONE;
}

bool _has_object(Cache* self, std::string id) {
  return self->H->count(id);
}

static PyObject* Cache_has_object(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  return PyBool_FromLong(_has_object(_self, std::string(to_query)));
}

static PyObject* Cache_hit(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*) self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  std::string object_id(to_query);
  if(!_has_object(_self, object_id)) {
    std::string err_msg = "Cache does not contain object with id " +
    object_id;
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  std::map< std::string, cached_object >& map_ref = *_self->H;
  cached_object& cached_friend = map_ref[object_id];
  // As a remark: an std::set cannot know when some of its objects changes in
  // such a way that its ordering also does, so it must be removed and then
  // re-added in order to ensure that it is in a proper place inside the set
  _self->S->erase(cached_friend);
  ++cached_friend.hit_count;
  cached_friend.last_hit_time = _self->current_time;
  _self->S->insert(cached_friend);
  ++_self->current_time;
  Py_RETURN_NONE;
}

static PyObject* Cache_get(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  std::string id(to_query);
  if(!_has_object(_self, id)) {
    std::string err_msg = "Cache does not contain object with id " +
    id;
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  std::map< std::string, cached_object >& map_ref = *_self->H;
  PyObject* ret = map_ref[id].obj;
  // Returning a PyObject means to "transfer" the object's responsibility
  // to the "demanding person". This transfer is implemented a decreffing
  // the object when returned
  // Py_INCREF(ret);
  return ret;
}

static PyObject* Cache_delete(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*) self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  std::string id(to_query);
  if(!_has_object(_self, id)) {
    std::string err_msg = "Cache does not contain object with id " +
    id;
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  std::map< std::string, cached_object >& map_ref = *_self->H;
  cached_object& cached_friend = map_ref[id];
  _delete_element(_self, &cached_friend);
  Py_RETURN_NONE;
}

static PyObject* Cache_get_last(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  cached_object ret = *_self->S->begin();
  Py_INCREF((PyObject*)&ret);
  return ret.obj;
}

static PyObject* Cache_is_empty(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  return PyBool_FromLong(_self->S->empty());
}

PyMODINIT_FUNC initpersistent_cache(void) {
    PyObject* m;
    m = Py_InitModule("persistent_cache", module_methods);

    if (PyType_Ready(&cached_objectType) < 0)
        return;
    Py_INCREF(&cached_objectType);
    PyModule_AddObject(m, "cached_object", (PyObject*)&cached_objectType);

    if (PyType_Ready(&CacheType) < 0)
        return;
    Py_INCREF(&CacheType);
    PyModule_AddObject(m, "Cache", (PyObject*)&CacheType);
}
<commit_msg>fix missing INCREF<commit_after>/*
  Copyright 2017 Barcelona Supercomputing Center (www.bsc.es)

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
*/
#include "persistent_cache.h"

static int cached_object_init(cached_object* self,
  PyObject *args, PyObject *kwds) {
    return 0;
}

static void cached_object_dealloc(cached_object* self) {
  Py_DECREF(self->obj);
  Py_XDECREF(self->comparison_function);
}

bool _default_comparison_function(const cached_object& a,  const cached_object& b) {
  if(a.hit_count != b.hit_count) {
    return a.hit_count < b.hit_count;
  }
  if(a.last_hit_time != b.last_hit_time) {
    return a.last_hit_time < b.last_hit_time;
  }
  return a.id < b.id;
}

static PyObject* default_comparison_function(PyObject* self, PyObject* args) {
  PyObject* a;
  PyObject* b;
  if(!Py_BuildValue("OO", &a, &b)) {
    return NULL;
  }
  cached_object* _a = (cached_object*)a;
  cached_object* _b = (cached_object*)b;
  return PyBool_FromLong(_default_comparison_function(*_a, *_b));
}

static PyObject*
cached_object_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
  cached_object* self = (cached_object*)type->tp_alloc(type, 0);
  const char* object_id;

  if(!PyArg_ParseTuple(args, "sOlOl", &object_id, &self->obj, &self->object_size,
  &self->comparison_function, &self->last_hit_time)) {
    return NULL;
  }
  Py_INCREF(self->obj);
  Py_XINCREF(self->comparison_function);
  self->id = std::string(object_id);
  return (PyObject*)self;
}

static PyObject* cached_object_get_id(PyObject* self, PyObject* args) {
  cached_object* _self = (cached_object*)self;
  return PyString_FromStringAndSize(_self->id.c_str(), _self->id.size());
}

static PyObject* cached_object_get_obj(PyObject* self, PyObject* args) {
  cached_object* _self = (cached_object*)self;
  return _self->obj;
}

void _delete_element(Cache* c, cached_object* obj) {
  c->current_size -= obj->object_size;
  c->H->erase(obj->id);
  Py_DECREF(obj->obj);
  Py_XDECREF(obj->comparison_function);
  c->S->erase(*obj);
}

void _delete_first_element(Cache* c) {
  cached_object* first_element = (cached_object*)&*(c->S->begin());
  _delete_element(c, first_element);
}

static void Cache_dealloc(Cache* self) {
  while(!self->S->empty()) _delete_first_element(self);
  delete(self->S);
  delete(self->H);
  Py_XDECREF(self->comparator);
}

static int Cache_init(Cache* self, PyObject* args, PyObject* kwds) {
  return 0;
}

static PyObject* Cache_new(PyTypeObject* type, PyObject* args, PyObject* kwds) {
  Cache* self = (Cache*)type->tp_alloc(type, 0);
  self->S = new std::set< cached_object, cached_object_comparator >();
  self->H = new std::map< std::string, cached_object >();
  self->current_time = 0ll;
  self->size_limit = 1024*1024*1024ll;
  static char* kwlist[] = {(char*)"size_limit", (char*)"comparison_function"};
  if (!PyArg_ParseTupleAndKeywords(args, kwds, "|lO", kwlist, &self->size_limit,
  &self->comparator)) {
         return NULL;
  }
  Py_XINCREF(self->comparator);
  return (PyObject*)self;
}

static PyObject* Cache_add(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  const char* object_id;
  PyObject* obj_to_add;
  long long object_size = -1ll;
  if(!PyArg_ParseTuple(args, "sO|l", &object_id, &obj_to_add, &object_size)) {
    return NULL;
  }
  cached_object to_add = *(new cached_object());
  to_add.id = std::string(object_id);
  if(_self->H->count(to_add.id)) {
    std::string err_msg = "Object with id " + to_add.id + " is\
    already cached!";
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  to_add.obj = obj_to_add;
  if(object_size == -1ll) {
    // rough approximation to the object's size (only invoked when obj size is
    // not given by the user)
    object_size = sizeof(*obj_to_add);
  }
  // Delete the object with least priority until cache is empty or
  // the total used space is less or equal than the limit
  // Note that this operation can delete the most recent object
  // depending on the comparison function
  while(!_self->S->empty() && _self->current_size >= _self->size_limit) {
    _delete_first_element(_self);
  }
  // Does this object fit on cache?
  // If yes, add it and then update the total used cache space
  if(_self->current_size + object_size <= _self->size_limit) {
    to_add.object_size = object_size;
    to_add.hit_count = 1;
    to_add.last_hit_time = _self->current_time;
    to_add.comparison_function = _self->comparator;
    Py_XINCREF(_self->comparator);
    Py_INCREF(to_add.obj);
    _self->current_size += to_add.object_size;
    std::map< std::string, cached_object >& map_ref = *_self->H;
    map_ref[to_add.id] = to_add;
    _self->S->insert(map_ref[to_add.id]);
  }
  ++_self->current_time;
  Py_RETURN_NONE;
}

bool _has_object(Cache* self, std::string id) {
  return self->H->count(id);
}

static PyObject* Cache_has_object(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  return PyBool_FromLong(_has_object(_self, std::string(to_query)));
}

static PyObject* Cache_hit(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*) self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  std::string object_id(to_query);
  if(!_has_object(_self, object_id)) {
    std::string err_msg = "Cache does not contain object with id " +
    object_id;
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  std::map< std::string, cached_object >& map_ref = *_self->H;
  cached_object& cached_friend = map_ref[object_id];
  // As a remark: an std::set cannot know when some of its objects changes in
  // such a way that its ordering also does, so it must be removed and then
  // re-added in order to ensure that it is in a proper place inside the set
  _self->S->erase(cached_friend);
  ++cached_friend.hit_count;
  cached_friend.last_hit_time = _self->current_time;
  _self->S->insert(cached_friend);
  ++_self->current_time;
  Py_RETURN_NONE;
}

static PyObject* Cache_get(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  std::string id(to_query);
  if(!_has_object(_self, id)) {
    std::string err_msg = "Cache does not contain object with id " +
    id;
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  std::map< std::string, cached_object >& map_ref = *_self->H;
  PyObject* ret = map_ref[id].obj;
  Py_INCREF(ret);
  return ret;
}

static PyObject* Cache_delete(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*) self;
  const char* to_query;
  if(!PyArg_ParseTuple(args, "s", &to_query)) {
    return NULL;
  }
  std::string id(to_query);
  if(!_has_object(_self, id)) {
    std::string err_msg = "Cache does not contain object with id " +
    id;
    PyErr_SetString(PyExc_KeyError, err_msg.c_str());
    return NULL;
  }
  std::map< std::string, cached_object >& map_ref = *_self->H;
  cached_object& cached_friend = map_ref[id];
  _delete_element(_self, &cached_friend);
  Py_RETURN_NONE;
}

static PyObject* Cache_get_last(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  cached_object ret = *_self->S->begin();
  return ret.obj;
}

static PyObject* Cache_is_empty(PyObject* self, PyObject* args) {
  Cache* _self = (Cache*)self;
  return PyBool_FromLong(_self->S->empty());
}

PyMODINIT_FUNC initpersistent_cache(void) {
    PyObject* m;
    m = Py_InitModule("persistent_cache", module_methods);

    if (PyType_Ready(&cached_objectType) < 0)
        return;
    Py_INCREF(&cached_objectType);
    PyModule_AddObject(m, "cached_object", (PyObject*)&cached_objectType);

    if (PyType_Ready(&CacheType) < 0)
        return;
    Py_INCREF(&CacheType);
    PyModule_AddObject(m, "Cache", (PyObject*)&CacheType);
}
<|endoftext|>


<commit_before><commit_msg>fix select state type<commit_after><|endoftext|>


<commit_before><commit_msg>Add PoissonStructure::Type enum<commit_after><|endoftext|>


<commit_before>#include "base.h"

#ifdef WIN32
    #include <windows.h>
#endif

#include <string.h>

#define KEY_TAB 9
#define KEY_ESC 27
#define KEY_DEL 127
#define KEY_SPACE 32

GLint width  = 400,
      height = 400;

GLfloat ortho2D_minX = -400.0f,
        ortho2D_maxX =  400.0f,
        ortho2D_minY = -400.0f,
        ortho2D_maxY =  400.0f;

bool selectionMode = false;

PWorld world;
int currentObj = -1;
bool isMouseDown = false;

void resize(int width, int height)
{

}

void DrawText(int x, int y, char *s)
{
    int len, i;
    glColor3f(1.0f, 0.0f, 0.0f);
    glRasterPos2f(x, y);
    len = (int) strlen(s);

    for (i = 0; i < len; i++)
    {
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, s[i]);
    }
}

/**
    Converte o espaço X do mouse, para o espaço X do Ortho.
**/
int convertXSpace(int x)
{
    return (x * 2) - width;
}

/**
    Converte o espaço Y do mouse, para o espaço Y do Ortho.
**/
int convertYSpace(int y)
{
    return (y * -2) + height;
}

void drawMode()
{
    DrawText(ortho2D_minX + 4, ortho2D_minY + 4, (char*)(selectionMode ? "Selecao (Tab)" : "Edicao (Tab)"));
}

void display()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(ortho2D_minX, ortho2D_maxX, ortho2D_minY, ortho2D_maxY);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    drawMode();
    world->Draw();

    glutSwapBuffers();
}

void keyPress(unsigned char key, int x, int y)
{
    switch (key)
    {
        case KEY_ESC:
            exit(0);
        break;
        case KEY_TAB:
            selectionMode = !selectionMode;
            glutPostRedisplay();
        break;
        case KEY_DEL:
            // Deleta o ponto ou poligono se for seleção.
            // Limpa a tela se for edição.
            if (selectionMode)
            {

            }
            else
            {
                currentObj = -1;
                world->Objects.clear();
                glutPostRedisplay();
            }
        break;
        case KEY_SPACE:
            if (currentObj != -1)
            {
                world->Objects[currentObj]->ChangePrimitive();
                glutPostRedisplay();
            }
        break;
        case 'P':
        case 'p':
            // Seleciona um poligono.
            if (selectionMode && world->Objects.size() > 0)
            {
                if (currentObj == -1)
                {
                    currentObj = 0;
                }
                else
                {
                    currentObj += 1;

                    if (currentObj >= world->Objects.size())
                    {
                        currentObj = 0;
                    }
                }

                for (size_t i = 0; i < world->Objects.size(); i++)
                {
                    world->Objects[i]->SetSelected(false);
                }

                world->Objects[currentObj]->SetSelected(true);
                glutPostRedisplay();
            }
        break;
        default:
            cout << key << "\n";
        break;
    }
}

void specialKeyPress(int key, int x, int y)
{

}

void mouseMove(int x, int y)
{
    //cout << "Current Obj = " << currentObj << "\n";
    //cout << "Mouse is Down = " << isMouseDown << "\n";

    if (isMouseDown && currentObj != -1)
    {
        //cout << "x = " << x << " y = " << y << "\n";

        Point& pe = world->Objects[currentObj]->Points.back();
        pe.x = convertXSpace(x);
        pe.y = convertYSpace(y);

        glutPostRedisplay();
    }
}

void mouseEvent(int button, int state, int x, int y)
{
    // button  GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, or GLUT_RIGHT_BUTTON
    // state GLUT_UP or GLUT_DOWN
    //cout << "x = " << x << " y = " << y << "\n";

    if (selectionMode)
    {

    }
    else
    {
        if (button == GLUT_LEFT_BUTTON)
        {
            if (state == GLUT_DOWN)
            {
                isMouseDown = true;

                // É um novo
                if (currentObj == -1)
                {
                    world->Objects.push_back(new GraphicObject());
                    currentObj = world->Objects.size() - 1;
                }

                Point ps;
                ps.x = convertXSpace(x);
                ps.y = convertYSpace(y);

                world->Objects[currentObj]->Points.push_back(ps);
                world->Objects[currentObj]->Points.push_back(ps);

                world->Objects[currentObj]->CalculateBBox();
            }
            else if (state == GLUT_UP)
            {
                isMouseDown = false;

                if (currentObj != -1)
                {
                    Point& pe = world->Objects[currentObj]->Points.back();
                    pe.x = convertXSpace(x);
                    pe.y = convertYSpace(y);
                    world->Objects[currentObj]->CalculateBBox();
                }
            }

            //cout << "Current Obj = " << currentObj << "\n";
            //cout << "Mouse is Down = " << isMouseDown << "\n";
        }
        else
        {
            currentObj = -1;
        }
    }

    glutPostRedisplay();
}

void createScene()
{
    /*GraphicObject o1;
    o1.Draw();

    GraphicObject* o2 = new GraphicObject();
    o2->Draw();*/
}

void init(void)
{
    /*glClearColor(1.0f,1.0f,1.0f,1.0);

    createScene();*/

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_LIGHTING);

    glClearColor(0.8f, 0.8f, 1.0f, 1.0f);

    world = new World();
/*
    // Draw line test.
    auto o = new GraphicObject();
    Point p1;
    p1.x = -200;
    p1.y = 0;
    Point p2;
    p2.x = 200;
    p2.y = 0;
    o->Points.push_back(p1);
    o->Points.push_back(p2);
    world->Objects.push_back(o);
*/
}

int main(int argc, const char * argv[])
{
    glutInit(&argc, (char **)argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowPosition(300, 250);
    glutInitWindowSize(height, width);

    glutCreateWindow("N3");

    glutReshapeFunc(resize);
    glutDisplayFunc(display);
    glutKeyboardFunc(keyPress);
    glutSpecialFunc(specialKeyPress);
    glutMotionFunc(mouseMove);
    glutMouseFunc(mouseEvent);

    init();
    glutMainLoop();

    return 0;
}<commit_msg>Remove selected polygin with del key.<commit_after>#include "base.h"

#ifdef WIN32
    #include <windows.h>
#endif

#include <string.h>

#define KEY_TAB 9
#define KEY_ESC 27
#define KEY_DEL 127
#define KEY_SPACE 32

GLint width  = 400,
      height = 400;

GLfloat ortho2D_minX = -400.0f,
        ortho2D_maxX =  400.0f,
        ortho2D_minY = -400.0f,
        ortho2D_maxY =  400.0f;

bool selectionMode = false;

PWorld world;
int currentObj = -1;
bool isMouseDown = false;

void resize(int width, int height)
{

}

void DrawText(int x, int y, char *s)
{
    int len, i;
    glColor3f(1.0f, 0.0f, 0.0f);
    glRasterPos2f(x, y);
    len = (int) strlen(s);

    for (i = 0; i < len; i++)
    {
        glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12, s[i]);
    }
}

/**
    Converte o espaço X do mouse, para o espaço X do Ortho.
**/
int convertXSpace(int x)
{
    return (x * 2) - width;
}

/**
    Converte o espaço Y do mouse, para o espaço Y do Ortho.
**/
int convertYSpace(int y)
{
    return (y * -2) + height;
}

void drawMode()
{
    DrawText(ortho2D_minX + 4, ortho2D_minY + 4, (char*)(selectionMode ? "Selecao (Tab)" : "Edicao (Tab)"));
}

void display()
{
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluOrtho2D(ortho2D_minX, ortho2D_maxX, ortho2D_minY, ortho2D_maxY);

    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    drawMode();
    world->Draw();

    glutSwapBuffers();
}

void keyPress(unsigned char key, int x, int y)
{
    switch (key)
    {
        case KEY_ESC:
            exit(0);
        break;
        case KEY_TAB:
            selectionMode = !selectionMode;
            glutPostRedisplay();
        break;
        case KEY_DEL:
            // Deleta o ponto ou poligono se for seleção.
            // Limpa a tela se for edição.
            if (selectionMode)
            {
                if (currentObj != -1)
                {
                    world->Objects.erase(world->Objects.begin() + currentObj);
                    currentObj = -1;
                    glutPostRedisplay();
                }
            }
            else
            {
                currentObj = -1;
                world->Objects.clear();
                glutPostRedisplay();
            }
        break;
        case KEY_SPACE:
            if (currentObj != -1)
            {
                world->Objects[currentObj]->ChangePrimitive();
                glutPostRedisplay();
            }
        break;
        case 'P':
        case 'p':
            // Seleciona um poligono.
            if (selectionMode && world->Objects.size() > 0)
            {
                if (currentObj == -1)
                {
                    currentObj = 0;
                }
                else
                {
                    currentObj += 1;

                    if (currentObj >= world->Objects.size())
                    {
                        currentObj = 0;
                    }
                }

                for (size_t i = 0; i < world->Objects.size(); i++)
                {
                    world->Objects[i]->SetSelected(false);
                }

                world->Objects[currentObj]->SetSelected(true);
                glutPostRedisplay();
            }
        break;
        default:
            cout << key << "\n";
        break;
    }
}

void specialKeyPress(int key, int x, int y)
{

}

void mouseMove(int x, int y)
{
    //cout << "Current Obj = " << currentObj << "\n";
    //cout << "Mouse is Down = " << isMouseDown << "\n";

    if (isMouseDown && currentObj != -1)
    {
        //cout << "x = " << x << " y = " << y << "\n";

        Point& pe = world->Objects[currentObj]->Points.back();
        pe.x = convertXSpace(x);
        pe.y = convertYSpace(y);

        glutPostRedisplay();
    }
}

void mouseEvent(int button, int state, int x, int y)
{
    // button  GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON, or GLUT_RIGHT_BUTTON
    // state GLUT_UP or GLUT_DOWN
    //cout << "x = " << x << " y = " << y << "\n";

    if (selectionMode)
    {

    }
    else
    {
        if (button == GLUT_LEFT_BUTTON)
        {
            if (state == GLUT_DOWN)
            {
                isMouseDown = true;

                // É um novo
                if (currentObj == -1)
                {
                    world->Objects.push_back(new GraphicObject());
                    currentObj = world->Objects.size() - 1;
                }

                Point ps;
                ps.x = convertXSpace(x);
                ps.y = convertYSpace(y);

                world->Objects[currentObj]->Points.push_back(ps);
                world->Objects[currentObj]->Points.push_back(ps);

                world->Objects[currentObj]->CalculateBBox();
            }
            else if (state == GLUT_UP)
            {
                isMouseDown = false;

                if (currentObj != -1)
                {
                    Point& pe = world->Objects[currentObj]->Points.back();
                    pe.x = convertXSpace(x);
                    pe.y = convertYSpace(y);
                    world->Objects[currentObj]->CalculateBBox();
                }
            }

            //cout << "Current Obj = " << currentObj << "\n";
            //cout << "Mouse is Down = " << isMouseDown << "\n";
        }
        else
        {
            currentObj = -1;
        }
    }

    glutPostRedisplay();
}

void createScene()
{
    /*GraphicObject o1;
    o1.Draw();

    GraphicObject* o2 = new GraphicObject();
    o2->Draw();*/
}

void init(void)
{
    /*glClearColor(1.0f,1.0f,1.0f,1.0);

    createScene();*/

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_LIGHTING);

    glClearColor(0.8f, 0.8f, 1.0f, 1.0f);

    world = new World();
/*
    // Draw line test.
    auto o = new GraphicObject();
    Point p1;
    p1.x = -200;
    p1.y = 0;
    Point p2;
    p2.x = 200;
    p2.y = 0;
    o->Points.push_back(p1);
    o->Points.push_back(p2);
    world->Objects.push_back(o);
*/
}

int main(int argc, const char * argv[])
{
    glutInit(&argc, (char **)argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
    glutInitWindowPosition(300, 250);
    glutInitWindowSize(height, width);

    glutCreateWindow("N3");

    glutReshapeFunc(resize);
    glutDisplayFunc(display);
    glutKeyboardFunc(keyPress);
    glutSpecialFunc(specialKeyPress);
    glutMotionFunc(mouseMove);
    glutMouseFunc(mouseEvent);

    init();
    glutMainLoop();

    return 0;
}<|endoftext|>


<commit_before>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 * 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.
 *
 *  @file TaskC.cpp
 */

#include <iostream>
#include <JPetWriter/JPetWriter.h>
#include <JPetAnalysisTools/JPetAnalysisTools.h>
#include "TaskC.h"
#include <algorithm>

using namespace std;

TaskC::TaskC(const char* name, const char* description): JPetTask(name, description) {}
TaskC::~TaskC() {}

void TaskC::init(const JPetTaskInterface::Options& opts)
{
}

void TaskC::exec()
{
  //getting the data from event in propriate format
  if (auto currSignal = dynamic_cast<const JPetRawSignal* const>(getEvent())) {
    getStatistics().getCounter("No. initial signals")++;
    if (fSignals.empty()) {
      fSignals.push_back(*currSignal);
    } else {
      if (fSignals[0].getTimeWindowIndex() == currSignal->getTimeWindowIndex()) {
        fSignals.push_back(*currSignal);
      } else {

        vector<JPetHit> hits = createHits(fSignals);
        hits = JPetAnalysisTools::getHitsOrderedByTime(hits);
        // uncomment this in order to fill histograms
        // of time differences for subsequent hist
        studyTimeWindow(hits);
        saveHits(hits);

        fSignals.clear();
        fSignals.push_back(*currSignal);
      }
    }
  }
}

vector<JPetHit> TaskC::createHits(const vector<JPetRawSignal>& signals)
{
  vector<JPetHit> hits;
  for (auto i = signals.begin(); i != signals.end(); ++i) {
    for (auto j = i; ++j != signals.end();) {
      if (i->getPM().getScin() == j->getPM().getScin()) {
        // found 2 signals from the same scintillator
        // wrap the RawSignal objects into RecoSignal and PhysSignal
        // for now this is just wrapping opne object into another
        // in the future analyses it will involve more logic like
        // reconstructing the signal's shape, charge, amplitude etc.
        JPetRecoSignal recoSignalA;
        JPetRecoSignal recoSignalB;
        JPetPhysSignal physSignalA;
        JPetPhysSignal physSignalB;
        // assign sides A and B properly
        if (
          (i->getPM().getSide() == JPetPM::SideA)
          && (j->getPM().getSide() == JPetPM::SideB)
        ) {
          recoSignalA.setRawSignal(*i);
          recoSignalB.setRawSignal(*j);
        } else if (
          (j->getPM().getSide() == JPetPM::SideA)
          && (i->getPM().getSide() == JPetPM::SideB)
        ) {
          recoSignalA.setRawSignal(*j);
          recoSignalB.setRawSignal(*i);
        } else {
          // if two hits on the same side, ignore
          WARNING("TWO hits on the same scintillator side we ignore it");
          continue;
        }

        if ( recoSignalA.getRawSignal().getNumberOfPoints(JPetSigCh::Leading) < 4 ) continue;
        if ( recoSignalB.getRawSignal().getNumberOfPoints(JPetSigCh::Leading) < 4 ) continue;

        bool thresholds_ok = true;
        for (int i = 1; i <= 4; ++i) {
          if ( recoSignalA.getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).count(i) < 1 ) {
            thresholds_ok = false;
          }
          if ( recoSignalB.getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).count(i) < 1 ) {
            thresholds_ok = false;
          }
        }
        if (thresholds_ok == false) {
          continue;
        }

        physSignalA.setRecoSignal(recoSignalA);
        physSignalB.setRecoSignal(recoSignalB);
        auto leading_points_a = physSignalA.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading);
        auto leading_points_b = physSignalB.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading);

        //skip signals with no information on 1st threshold
        if (leading_points_a.count(1) == 0) continue;
        if (leading_points_b.count(1) == 0) continue;

        physSignalA.setTime(leading_points_a.at(1));
        physSignalB.setTime(leading_points_b.at(1));

        JPetHit hit;
        hit.setSignalA(physSignalA);
        hit.setSignalB(physSignalB);
        hit.setScintillator(i->getPM().getScin());
        hit.setBarrelSlot(i->getPM().getScin().getBarrelSlot());

        physSignalA.setTime(physSignalA.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(1));
        physSignalB.setTime(physSignalB.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(1));

        hit.setTime( 0.5 * ( hit.getSignalA().getTime() + hit.getSignalB().getTime()) );
        hits.push_back(hit);
        getStatistics().getCounter("No. found hits")++;
      }
    }
  }
  return hits;
}

void TaskC::terminate()
{
  //	saveHits(createHits(fSignals)); //if there is something left
  INFO( Form("From %d initial signals %d hits were paired.",
             static_cast<int>(getStatistics().getCounter("No. initial signals")),
             static_cast<int>(getStatistics().getCounter("No. found hits")) )
      );
}

void TaskC::studyTimeWindow(const vector<JPetHit>& hits)
{
    // make sure the hits are really sorted
    // assert(hits.at(i-1).getTime() <= hits.at(i).getTime());

    // double dt = hits.at(i).getTime() - hits.at(i-1).getTime();

    // getStatistics().getHisto1D("timeSepSmall").Fill(dt / 1000.); // we fill the histo in [ns]
    // getStatistics().getHisto1D("timeSepLarge").Fill(dt / 1000.); // we fill the histo in [ns]

    for(int k=1;k<=4;++k){

      double t2 = 0.5*(hits.at(i).getSignalA().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k) + hits.at(i).getSignalB().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k));

      double t1 = 0.5*(hits.at(i-1).getSignalA().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k) + hits.at(i-1).getSignalB().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k));

      double dt = t2 - t1;

      getStatistics().getHisto1D(Form("timeSepSmall_thr_%d", k)).Fill(dt / 1000.); // we fill the histo in [ns]
      getStatistics().getHisto1D(Form("timeSepLarge_thr_%d", k)).Fill(dt / 1000.); // we fill the histo in [ns]

    }

  }

  getStatistics().getHisto1D("timeSepSmall").Fill(dt / 1000.); // we fill the histo in [ns]
  getStatistics().getHisto1D("timeSepLarge").Fill(dt / 1000.); // we fill the histo in [ns]
}

void TaskC::saveHits(const vector<JPetHit>& hits)
{
  assert(fWriter);
  for (auto hit : hits) {
    // here one can impose any conditions on hits that should be
    // saved or skipped
    // for now, all hits are written to the output file
    // without checking anything
    fWriter->write(hit);
  }
}
<commit_msg>Use hit sorting from framework library<commit_after>/**
 *  @copyright Copyright 2016 The J-PET Framework Authors. All rights reserved.
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may find a copy of the License in the LICENCE file.
 *
 * 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.
 *
 *  @file TaskC.cpp
 */

#include <iostream>
#include <JPetWriter/JPetWriter.h>
#include <JPetAnalysisTools/JPetAnalysisTools.h>
#include "TaskC.h"
#include <algorithm>

using namespace std;

TaskC::TaskC(const char* name, const char* description): JPetTask(name, description) {}
TaskC::~TaskC() {}

void TaskC::init(const JPetTaskInterface::Options& opts)
{
}

void TaskC::exec()
{
  //getting the data from event in propriate format
  if (auto currSignal = dynamic_cast<const JPetRawSignal* const>(getEvent())) {
    getStatistics().getCounter("No. initial signals")++;
    if (fSignals.empty()) {
      fSignals.push_back(*currSignal);
    } else {
      if (fSignals[0].getTimeWindowIndex() == currSignal->getTimeWindowIndex()) {
        fSignals.push_back(*currSignal);
      } else {

        vector<JPetHit> hits = createHits(fSignals);
        hits = JPetAnalysisTools::getHitsOrderedByTime(hits);
        // uncomment this in order to fill histograms
        // of time differences for subsequent hist
        studyTimeWindow(hits);
        saveHits(hits);

        fSignals.clear();
        fSignals.push_back(*currSignal);
      }
    }
  }
}

void TaskC::exec()
{
  //getting the data from event in propriate format
  if (auto currSignal = dynamic_cast<const JPetRawSignal* const>(getEvent())) {
    getStatistics().getCounter("No. initial signals")++;
    if (fSignals.empty()) {
      fSignals.push_back(*currSignal);
    } else {
      if (fSignals[0].getTimeWindowIndex() == currSignal->getTimeWindowIndex()) {
        fSignals.push_back(*currSignal);
      } else {

        vector<JPetHit> hits = createHits(fSignals);
        hits = JPetAnalysisTools::getHitsOrderedByTime(hits);
        // uncomment this in order to fill histograms
        // of time differences for subsequent hist
        studyTimeWindow(hits);

        saveHits(hits);

        fSignals.clear();
        fSignals.push_back(*currSignal);
      }
    }
  }
}
vector<JPetHit> TaskC::createHits(const vector<JPetRawSignal>& signals)
{
  vector<JPetHit> hits;
  for (auto i = signals.begin(); i != signals.end(); ++i) {
    for (auto j = i; ++j != signals.end();) {
      if (i->getPM().getScin() == j->getPM().getScin()) {
        // found 2 signals from the same scintillator
        // wrap the RawSignal objects into RecoSignal and PhysSignal
        // for now this is just wrapping opne object into another
        // in the future analyses it will involve more logic like
        // reconstructing the signal's shape, charge, amplitude etc.
        JPetRecoSignal recoSignalA;
        JPetRecoSignal recoSignalB;
        JPetPhysSignal physSignalA;
        JPetPhysSignal physSignalB;
        // assign sides A and B properly
        if (
          (i->getPM().getSide() == JPetPM::SideA)
          && (j->getPM().getSide() == JPetPM::SideB)
        ) {
          recoSignalA.setRawSignal(*i);
          recoSignalB.setRawSignal(*j);
        } else if (
          (j->getPM().getSide() == JPetPM::SideA)
          && (i->getPM().getSide() == JPetPM::SideB)
        ) {
          recoSignalA.setRawSignal(*j);
          recoSignalB.setRawSignal(*i);
        } else {
          // if two hits on the same side, ignore
          WARNING("TWO hits on the same scintillator side we ignore it");
          continue;
        }

        if ( recoSignalA.getRawSignal().getNumberOfPoints(JPetSigCh::Leading) < 4 ) continue;
        if ( recoSignalB.getRawSignal().getNumberOfPoints(JPetSigCh::Leading) < 4 ) continue;

        bool thresholds_ok = true;
        for (int i = 1; i <= 4; ++i) {
          if ( recoSignalA.getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).count(i) < 1 ) {
            thresholds_ok = false;
          }
          if ( recoSignalB.getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).count(i) < 1 ) {
            thresholds_ok = false;
          }
        }
        if (thresholds_ok == false) {
          continue;
        }

        physSignalA.setRecoSignal(recoSignalA);
        physSignalB.setRecoSignal(recoSignalB);
        auto leading_points_a = physSignalA.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading);
        auto leading_points_b = physSignalB.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading);

        //skip signals with no information on 1st threshold
        // if(leading_points_a.count(1) == 0) continue;
        // if(leading_points_b.count(1) == 0) continue;

        physSignalA.setTime(leading_points_a.at(1));
        physSignalB.setTime(leading_points_b.at(1));

        JPetHit hit;
        hit.setSignalA(physSignalA);
        hit.setSignalB(physSignalB);
        hit.setScintillator(i->getPM().getScin());
        hit.setBarrelSlot(i->getPM().getScin().getBarrelSlot());

        physSignalA.setTime(physSignalA.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(1));
        physSignalB.setTime(physSignalB.getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(1));

        hit.setTime( 0.5 * ( hit.getSignalA().getTime() + hit.getSignalB().getTime()) );

        hits.push_back(hit);
        getStatistics().getCounter("No. found hits")++;
      }
    }
  }
  return hits;
}

void TaskC::terminate()
{
  //	saveHits(createHits(fSignals)); //if there is something left
  INFO( Form("From %d initial signals %d hits were paired.",
             static_cast<int>(getStatistics().getCounter("No. initial signals")),
             static_cast<int>(getStatistics().getCounter("No. found hits")) )
      );
}

void TaskC::studyTimeWindow(const vector<JPetHit>& hits)
{

  // plot time differences for subsequent hits at each threshold separately
  for (int i = 1; i < hits.size(); ++i) {
    >>> >>> > Use hit sorting from framework library
    for (int k = 1; k <= 4; ++k) {
      double t2 = 0.5 * (hits.at(i).getSignalA().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k) + hits.at(i).getSignalB().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k));
      double t1 = 0.5 * (hits.at(i - 1).getSignalA().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k) + hits.at(i - 1).getSignalB().getRecoSignal().getRawSignal().getTimesVsThresholdNumber(JPetSigCh::Leading).at(k));
      double dt = t2 - t1;
      getStatistics().getHisto1D(Form("timeSepSmall_thr_%d", k)).Fill(dt / 1000.); // we fill the histo in [ns]
      getStatistics().getHisto1D(Form("timeSepLarge_thr_%d", k)).Fill(dt / 1000.); // we fill the histo in [ns]
    }
  }
}

void TaskC::saveHits(const vector<JPetHit>& hits)
{
  assert(fWriter);
  for (auto hit : hits) {
    // here one can impose any conditions on hits that should be
    // saved or skipped
    // for now, all hits are written to the output file
    // without checking anything
    fWriter->write(hit);
  }
}
<|endoftext|>


<commit_before>#ifndef UDPSocket_impl_hpp
#define UDPSocket_impl_hpp

#include <iostream>

namespace uvpp {
	namespace internal {
		inline void allocBuffer(uv_handle_t*, size_t suggested_size, uv_buf_t* buf) {
  		buf->base = new char[suggested_size];
			buf->len = suggested_size;
		}

		inline void onRead(uv_udp_t *udp_socket, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
			if(udp_socket->data == nullptr) {
				return;
			}

			UDPSocket *socket = (UDPSocket*) udp_socket->data;
			if(nread < 0){
				socket->_is_listening = false;
				if(socket->_on_error) socket->_on_error(nread, uv_err_name(nread));
        socket->unbind();
			}else{
				if(nread != 0){
					char ip[64];
        	uv_inet_ntop(AF_INET, &((sockaddr_in*)addr)->sin_addr, ip, sizeof(ip));
        	int port = ((sockaddr_in*)addr)->sin_port;
					if(socket->_on_data) socket->_on_data(std::string((char*)buf->base, (size_t) nread), ip, port);
				}
			}

			if(buf != nullptr) delete[] buf->base;
		}
	}

  inline UDPSocket::UDPSocket() :
    _is_listening(false), _udp_socket(nullptr), _listening_on_port(0), _on_data(nullptr), _on_error(nullptr) { }

	inline UDPSocket::UDPSocket(uv_loop_t* loop, int bind_listen_port,
			const OnDataCallback& on_data, const OnErrorCallback& on_error) :
	_is_listening(false), _running_loop(loop), _udp_socket(nullptr), _listening_on_port(bind_listen_port),
	_on_data(on_data), _on_error(on_error) {
    uv_bind_and_listen();
	}

	inline UDPSocket::~UDPSocket() {
		unbind();
	}

  inline UDPSocket::UDPSocket(UDPSocket&& other) :
    _is_listening(false), _udp_socket(nullptr), _listening_on_port(0), _on_data(nullptr), _on_error(nullptr) {
    swap(other);
  }

  inline UDPSocket& UDPSocket::operator=(UDPSocket&& other) {
    if (_is_listening) {
      unbind();
    }
    swap(other);
    return *this;
  }

	inline void UDPSocket::send(const std::string& send_host, int send_port, const std::string& data) {
    if (_is_listening) {
      uv_udp_send_t* send_req = new uv_udp_send_t();

    	char * msg = new char[data.size() + 1];
      std::copy(data.begin(), data.end(), msg);
      uv_buf_t buf = uv_buf_init(msg, data.size());

    	struct sockaddr_in send_addr;
    	uv_ip4_addr(send_host.c_str(), send_port, &send_addr);
    	uv_udp_send(send_req, _udp_socket, &buf, 1, (const struct sockaddr *)&send_addr,
    		[](uv_udp_send_t* req, int status){ delete req; });
    }
	}

	inline void UDPSocket::bind(uv_loop_t* loop, int bind_listen_port,
						const OnDataCallback& on_data, const OnErrorCallback& on_error) {
		_running_loop = loop;
		_listening_on_port = bind_listen_port;
		_on_data = on_data;
		_on_error = on_error;
		uv_bind_and_listen();
	}

	inline void UDPSocket::unbind() {
    if (_udp_socket) {
      _udp_socket->data = nullptr;
      uv_close((uv_handle_t*)_udp_socket, [](uv_handle_t* udp_socket) {
        delete udp_socket;
      });
      _udp_socket = nullptr;
    }
    _is_listening = false;
    _listening_on_port = 0;
    _on_data = nullptr;
    _on_error = nullptr;
	}

	inline bool UDPSocket::isListening() const {
		return _is_listening;
	}

	inline int UDPSocket::listening_on_port() const {
		return _listening_on_port;
	}

	inline void UDPSocket::setOnDataCallback(const OnDataCallback& on_data) {
		_on_data = on_data;
	}

	inline void UDPSocket::setOnErrorCallback(const OnErrorCallback& on_error) {
		_on_error = on_error;
	}

  // Swap with another instance of UDPSocket for move construction
  inline void UDPSocket::swap(UDPSocket& other) {
    std::swap(_running_loop, other._running_loop);
    std::swap(_udp_socket, other._udp_socket);
    if (other._is_listening) {
      _udp_socket->data = this;
    }
    if (_is_listening) {
      other._udp_socket->data = &other;
    }

    std::swap(_is_listening, other._is_listening);

    std::swap(_listening_on_port, other._listening_on_port);

    std::swap(_on_data, other._on_data);
    std::swap(_on_error, other._on_error);
  }

	inline void UDPSocket::uv_bind_and_listen() {
  	_udp_socket = new uv_udp_t();
  	uv_udp_init(_running_loop, _udp_socket);
  	_udp_socket->data = this;
    struct sockaddr_in recv_addr;
    uv_ip4_addr("0.0.0.0", _listening_on_port, &recv_addr);
    uv_udp_bind(_udp_socket, (const struct sockaddr *)&recv_addr, UV_UDP_REUSEADDR);
    uv_udp_recv_start(_udp_socket, internal::allocBuffer, internal::onRead);
	}
}

#endif /* UDPSocket_impl_hpp */
<commit_msg>Port number wasn't correctly read, which caused issues when attempting to reply to messages<commit_after>#ifndef UDPSocket_impl_hpp
#define UDPSocket_impl_hpp

namespace uvpp {
	namespace internal {
		inline void allocBuffer(uv_handle_t*, size_t suggested_size, uv_buf_t* buf) {
  		buf->base = new char[suggested_size];
			buf->len = suggested_size;
		}

		inline void onRead(uv_udp_t *udp_socket, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
			if(udp_socket->data == nullptr) {
				return;
			}

			UDPSocket *socket = (UDPSocket*) udp_socket->data;
			if(nread < 0){
				socket->_is_listening = false;
				if(socket->_on_error) socket->_on_error(nread, uv_err_name(nread));
        socket->unbind();
			}else{
				if(nread != 0){
					char ip[64];
        	uv_inet_ntop(AF_INET, &((sockaddr_in*)addr)->sin_addr, ip, sizeof(ip));
        	auto port = ntohs(((sockaddr_in*)addr)->sin_port);
					if(socket->_on_data) socket->_on_data(std::string((char*)buf->base, (size_t) nread), ip, port);
				}
			}

			if(buf != nullptr) delete[] buf->base;
		}
	}

  inline UDPSocket::UDPSocket() :
    _is_listening(false), _udp_socket(nullptr), _listening_on_port(0), _on_data(nullptr), _on_error(nullptr) { }

	inline UDPSocket::UDPSocket(uv_loop_t* loop, int bind_listen_port,
			const OnDataCallback& on_data, const OnErrorCallback& on_error) :
	_is_listening(false), _running_loop(loop), _udp_socket(nullptr), _listening_on_port(bind_listen_port),
	_on_data(on_data), _on_error(on_error) {
    uv_bind_and_listen();
	}

	inline UDPSocket::~UDPSocket() {
		unbind();
	}

  inline UDPSocket::UDPSocket(UDPSocket&& other) :
    _is_listening(false), _udp_socket(nullptr), _listening_on_port(0), _on_data(nullptr), _on_error(nullptr) {
    swap(other);
  }

  inline UDPSocket& UDPSocket::operator=(UDPSocket&& other) {
    if (_is_listening) {
      unbind();
    }
    swap(other);
    return *this;
  }

	inline void UDPSocket::send(const std::string& send_host, int send_port, const std::string& data) {
    if (_is_listening) {
      uv_udp_send_t* send_req = new uv_udp_send_t();

    	char * msg = new char[data.size() + 1];
      std::copy(data.begin(), data.end(), msg);
      uv_buf_t buf = uv_buf_init(msg, data.size());

    	struct sockaddr_in send_addr;
    	uv_ip4_addr(send_host.c_str(), send_port, &send_addr);
    	uv_udp_send(send_req, _udp_socket, &buf, 1, (const struct sockaddr *)&send_addr,
    		[](uv_udp_send_t* req, int status){ delete req; });
    }
	}

	inline void UDPSocket::bind(uv_loop_t* loop, int bind_listen_port,
						const OnDataCallback& on_data, const OnErrorCallback& on_error) {
		_running_loop = loop;
		_listening_on_port = bind_listen_port;
		_on_data = on_data;
		_on_error = on_error;
		uv_bind_and_listen();
	}

	inline void UDPSocket::unbind() {
    if (_udp_socket) {
      _udp_socket->data = nullptr;
      uv_close((uv_handle_t*)_udp_socket, [](uv_handle_t* udp_socket) {
        delete udp_socket;
      });
      _udp_socket = nullptr;
    }
    _is_listening = false;
    _listening_on_port = 0;
    _on_data = nullptr;
    _on_error = nullptr;
	}

	inline bool UDPSocket::isListening() const {
		return _is_listening;
	}

	inline int UDPSocket::listening_on_port() const {
		return _listening_on_port;
	}

	inline void UDPSocket::setOnDataCallback(const OnDataCallback& on_data) {
		_on_data = on_data;
	}

	inline void UDPSocket::setOnErrorCallback(const OnErrorCallback& on_error) {
		_on_error = on_error;
	}

  // Swap with another instance of UDPSocket for move construction
  inline void UDPSocket::swap(UDPSocket& other) {
    std::swap(_running_loop, other._running_loop);
    std::swap(_udp_socket, other._udp_socket);
    if (other._is_listening) {
      _udp_socket->data = this;
    }
    if (_is_listening) {
      other._udp_socket->data = &other;
    }

    std::swap(_is_listening, other._is_listening);

    std::swap(_listening_on_port, other._listening_on_port);

    std::swap(_on_data, other._on_data);
    std::swap(_on_error, other._on_error);
  }

	inline void UDPSocket::uv_bind_and_listen() {
  	_udp_socket = new uv_udp_t();
  	uv_udp_init(_running_loop, _udp_socket);
  	_udp_socket->data = this;
    struct sockaddr_in recv_addr;
    uv_ip4_addr("0.0.0.0", _listening_on_port, &recv_addr);
    uv_udp_bind(_udp_socket, (const struct sockaddr *)&recv_addr, UV_UDP_REUSEADDR);
    uv_udp_recv_start(_udp_socket, internal::allocBuffer, internal::onRead);
    _is_listening = true;
	}
}

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


<commit_before>
#include "../../include/A2DExtLibs.h"
#include "../../include/A2DQuadFactory.h"

A2DQuadFactory::A2DQuadFactory(ID3D10Device ** xDXDevice, A2DDims * xWindowDims) : aDXDevice(xDXDevice), aWindowDims(xWindowDims){}

A2DQuadFactory::~A2DQuadFactory(){}

void  A2DQuadFactory::x_aligned_memcpy_sse2(void* dest, const void* src, const unsigned long size_t)
{
	__asm
	{
		mov esi, src;    //src pointer
		mov edi, dest;   //dest pointer

		mov ebx, size_t; //ebx is our counter
		shr ebx, 7;      //divide by 128 (8 * 128bit registers)

	loop_copy:
		prefetchnta 128[ESI]; //SSE2 prefetch
		prefetchnta 160[ESI];
		prefetchnta 192[ESI];
		prefetchnta 224[ESI];

		movdqa xmm0, 0[ESI]; //move data from src to registers
		movdqa xmm1, 16[ESI];
		movdqa xmm2, 32[ESI];
		movdqa xmm3, 48[ESI];
		movdqa xmm4, 64[ESI];
		movdqa xmm5, 80[ESI];
		movdqa xmm6, 96[ESI];
		movdqa xmm7, 112[ESI];

		movntdq 0[EDI], xmm0; //move data from registers to dest
		movntdq 16[EDI], xmm1;
		movntdq 32[EDI], xmm2;
		movntdq 48[EDI], xmm3;
		movntdq 64[EDI], xmm4;
		movntdq 80[EDI], xmm5;
		movntdq 96[EDI], xmm6;
		movntdq 112[EDI], xmm7;

		add esi, 128;
		add edi, 128;
		dec ebx;

		jnz loop_copy; //loop please
	}
}

bool A2DQuadFactory::setConstraints(A2DQuadData * aQuadData, A2DRect * xContraints)
{

	memcpy(&aConstraints, xContraints, sizeof(A2DRect));
	// WHy store contraints into every QuadData
//	if (memcmp(&aQuadData->aPreviousContraints, xContraints, sizeof(A2DRect)) != 0)
//	{
//		x_aligned_memcpy_sse2(&aQuadData->aPreviousContraints, xContraints, sizeof(A2DRect));
//		return aContraintsChanged = true;
//	}
//	else
//	{
//		return aContraintsChanged = false;
//	}

	return true;
}

HRESULT A2DQuadFactory::updateVertexBuffer(A2DQuadData * aQuadData, A2DRect * xRect, A2DRect * xTextureClip,
					A2DDims * xTextureDims, A2DImageProperties * xImageProperties)
{
	HRESULT hr = S_OK;

	A2DRect& contraints = aConstraints;

	int textureDimsChange = 0;
	int textureClipChange = 0;
	int rectChange = 0;
	int imagePropertiesChange = 0;

	float rectX = xRect->aX;
	float rectY = xRect->aY;
	float rectWidth = xRect->aWidth;
	float rectHeight = xRect->aHeight;

	if (rectX >= contraints.aWidth || rectY >= contraints.aHeight)	return hr;

	/*
	// Compare using built in accelerated-function
	rectChange = memcmp(&aQuadData->aPreviousRect, xRect, sizeof(A2DRect));
	imagePropertiesChange = memcmp(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DImageProperties));
	imagePropertiesChange = memcmp(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DImageProperties));

	if (!(rectChange | imagePropertiesChange) && !aContraintsChanged)	return hr;

	// Transfer all previous contraints over using accelerated functions
	x_aligned_memcpy_sse2(&aQuadData->aPreviousRect, xRect, sizeof(A2DRect));
	x_aligned_memcpy_sse2(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DRect));
	x_aligned_memcpy_sse2(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DRect));
		*/

	float realX, realY;
	float textureX = xTextureClip->aX;
	float textureY = xTextureClip->aY;
	float textureWidth = xTextureClip->aWidth;
	float textureHeight = xTextureClip->aHeight;

	float realWidth, realHeight, calcWidth, calcHeight;
	float consOffsetX, consOffsetY;
	float realTWidth, realTHeight, calcTX, calcTY;
	float tWidthOffset, tHeightOffset;

	float left;
	float right;
	float top;
	float bottom;
	float leftTex;
	float rightTex;
	float topTex;
	float bottomTex;

	byte index = 0;
	A2DVertexData * vertices = aQuadData->aVertices;
	void * mappedVertices = 0;

	// Bitmap mapping calculations.
	realX = rectX < 0 ? contraints.aX : contraints.aX + rectX;
	realY = rectY < 0 ? contraints.aY : contraints.aY + rectY;

	calcWidth = rectX < 0 ? rectWidth - abs(rectX) : rectWidth;
	calcHeight = rectY < 0 ? rectHeight - abs(rectY) : rectHeight;

	consOffsetX = rectX < 0 ? 0 : rectX;
	consOffsetY = rectY < 0 ? 0 : rectY;

	realWidth = rectX + calcWidth > contraints.aWidth ? contraints.aWidth - consOffsetX : calcWidth;
	realHeight = rectY + calcHeight > contraints.aHeight ? contraints.aHeight - consOffsetY : calcHeight;

	// Handle negative constraint dimensions.
	if (realWidth < 0)
	{
		realWidth = realWidth + rectX > 0 ? realWidth + rectX : 0;
	}
	if (realHeight < 0)
	{
		realHeight = realHeight + rectY > 0 ? realHeight + rectY : 0;
	}

	// Texture mapping calculations.
	calcTX = rectX < 0 ? rectX + (rectWidth * abs(rectX)) / contraints.aWidth : rectX;
	calcTY = rectX < 0 ? rectY + (rectHeight * abs(rectY)) / contraints.aHeight : rectY;

	calcTX += textureX;
	calcTY += textureY;

	// Calculate offset for x and y constraints.
	tWidthOffset = rectX + calcWidth > contraints.aWidth || rectX < 0 ? (rectWidth * abs(rectX)) / contraints.aWidth : 0;
	realTWidth = rectWidth - tWidthOffset;

	realTWidth = textureWidth - realTWidth < 0 ? textureWidth : realTWidth;

	tHeightOffset = rectY + calcHeight > contraints.aHeight || rectY < 0 ? (rectHeight * abs(rectY)) / contraints.aHeight : 0;
	realTHeight = rectHeight - tHeightOffset;

	realTHeight = textureHeight - realTHeight < 0 ? textureHeight : realTHeight;

	// Calculate offset for dimension constraints.
	realTWidth -= rectWidth < contraints.aWidth ? (rectWidth * (contraints.aWidth - rectWidth)) / contraints.aWidth : 0;
	realTHeight -= rectHeight < contraints.aHeight ? (rectHeight * (contraints.aHeight - rectHeight)) / contraints.aHeight : 0;

	// Calculate the screen coordinates of the left side of the bitmap.
	left = ((aWindowDims->aWidth / 2) * -1) + realX;

	// Calculate the screen coordinates of the right side of the bitmap.
	right = left + realWidth;

	// Calculate the screen coordinates of the top of the bitmap.
	top = (aWindowDims->aHeight / 2) - realY;

	// Calculate the screen coordinates of the bottom of the bitmap.
	bottom = top - realHeight;

	// Calculate desired texture mapping.
	leftTex = calcTX / xTextureDims->aWidth;
	rightTex = (calcTX + realTWidth) / xTextureDims->aWidth;;
	topTex = calcTY / xTextureDims->aWidth;
	bottomTex = (calcTY + realTHeight) / xTextureDims->aHeight;

	// Load the vertex array with data.
	vertices[index].position = D3DXVECTOR3(left, top, 0.0f);  // Top left.
	vertices[index++].texture = D3DXVECTOR2(leftTex, topTex);

	vertices[index].position = D3DXVECTOR3(right, bottom, 0.0f);  // Bottom right.
	vertices[index++].texture = D3DXVECTOR2(rightTex, bottomTex);

	vertices[index].position = D3DXVECTOR3(left, bottom, 0.0f);  // Bottom left.
	vertices[index++].texture = D3DXVECTOR2(leftTex, bottomTex);

	// Second triangle.
	vertices[index].position = D3DXVECTOR3(left, top, 0.0f);  // Top left.
	vertices[index++].texture = D3DXVECTOR2(leftTex, topTex);

	vertices[index].position = D3DXVECTOR3(right, top, 0.0f);  // Top right.
	vertices[index++].texture = D3DXVECTOR2(rightTex, topTex);

	vertices[index].position = D3DXVECTOR3(right, bottom, 0.0f);  // Bottom right.
	vertices[index++].texture = D3DXVECTOR2(rightTex, bottomTex);

	// Lock the vertex buffer.
	hr = aQuadData->aVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&mappedVertices);
	if (FAILED(hr))	return hr;

	// Copy the data into the vertex buffer.
	memcpy(mappedVertices, (void*)vertices, (sizeof(A2DVertexData)* 6));

	// Unlock the vertex buffer.
	aQuadData->aVertexBuffer->Unmap();

	return hr;

}

unsigned int A2DQuadFactory::aStride = sizeof(A2DVertexData);
unsigned int A2DQuadFactory::aOffset = 0;

void A2DQuadFactory::RenderQuad(A2DQuadData * aQuadData)
{
	ID3D10Device  *	device = *aDXDevice;

	// Set the vertex buffer to active in the input
	// assembler so it can be rendered.
	device->IASetVertexBuffers(0, 1, &aQuadData->aVertexBuffer, &aStride, &aOffset);

	// Set the index buffer to active in the input
	// assembler so it can be rendered.
	device->IASetIndexBuffer(aIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

	// Set the type of primitive that should be
	// rendered from this vertex buffer, in this case triangles.
	device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	return;
}

HRESULT A2DQuadFactory::Initialize()
{
	HRESULT hr = S_OK;

	hr = A2DDXShapeUtils::CreateDefaultDynamicVertexBuffer<A2DVertexData>(*aDXDevice, &aVertexBuffer, 6);
	if (FAILED(hr))	return hr;

	hr = A2DDXShapeUtils::CreateDefaultIndexBuffer(*aDXDevice, &aIndexBuffer, 6);
	if (FAILED(hr))	return hr;

	return hr;
}

void A2DQuadFactory::Deinitialize()
{
	if (aVertexBuffer)
	{
		aVertexBuffer->Release();
		delete aVertexBuffer;
		aVertexBuffer = 0;
	}

	if (aIndexBuffer)
	{
		aIndexBuffer->Release();
		delete aIndexBuffer;
		aIndexBuffer = 0;
	}
}

LPCWSTR A2DQuadFactory::GetClass()
{
	return L"A2DQuadFactory";
}

LPCWSTR A2DQuadFactory::ToString()
{
	return L"A2DQuadFactory";
}

bool A2DQuadFactory::operator==(A2DAbstract * A2DAbstract)
{
	return false;
}

<commit_msg>Added assembly move A2DRect<commit_after>
#include "../../include/A2DExtLibs.h"
#include "../../include/A2DQuadFactory.h"

A2DQuadFactory::A2DQuadFactory(ID3D10Device ** xDXDevice, A2DDims * xWindowDims) : aDXDevice(xDXDevice), aWindowDims(xWindowDims){}

A2DQuadFactory::~A2DQuadFactory(){}

void  A2DQuadFactory::x_aligned_memcpy_sse2(void* dest, const void* src, const unsigned long size_t)
{
	__asm
	{
		mov esi, src;
		mov edi, dest;

		movdqu xmm1, [ESI];
		movdqu[EDI], xmm1;
	}
}

bool A2DQuadFactory::setConstraints(A2DQuadData * aQuadData, A2DRect * xContraints)
{

	x_aligned_memcpy_sse2(&aConstraints, xContraints, sizeof(A2DRect));

	// WHy store contraints into every QuadData
//	if (memcmp(&aQuadData->aPreviousContraints, xContraints, sizeof(A2DRect)) != 0)
//	{
//		x_aligned_memcpy_sse2(&aQuadData->aPreviousContraints, xContraints, sizeof(A2DRect));
//		return aContraintsChanged = true;
//	}
//	else
//	{
//		return aContraintsChanged = false;
//	}

	return true;
}

HRESULT A2DQuadFactory::updateVertexBuffer(A2DQuadData * aQuadData, A2DRect * xRect, A2DRect * xTextureClip,
					A2DDims * xTextureDims, A2DImageProperties * xImageProperties)
{
	HRESULT hr = S_OK;

	A2DRect& contraints = aConstraints;

	int textureDimsChange = 0;
	int textureClipChange = 0;
	int rectChange = 0;
	int imagePropertiesChange = 0;

	float rectX = xRect->aX;
	float rectY = xRect->aY;
	float rectWidth = xRect->aWidth;
	float rectHeight = xRect->aHeight;

	if (rectX >= contraints.aWidth || rectY >= contraints.aHeight)	return hr;

	/*
	// Compare using built in accelerated-function
	rectChange = memcmp(&aQuadData->aPreviousRect, xRect, sizeof(A2DRect));
	imagePropertiesChange = memcmp(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DImageProperties));
	imagePropertiesChange = memcmp(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DImageProperties));

	if (!(rectChange | imagePropertiesChange) && !aContraintsChanged)	return hr;

	// Transfer all previous contraints over using accelerated functions
	x_aligned_memcpy_sse2(&aQuadData->aPreviousRect, xRect, sizeof(A2DRect));
	x_aligned_memcpy_sse2(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DRect));
	x_aligned_memcpy_sse2(&aQuadData->aPreviousImageProperties, xImageProperties, sizeof(A2DRect));
		*/

	float realX, realY;
	float textureX = xTextureClip->aX;
	float textureY = xTextureClip->aY;
	float textureWidth = xTextureClip->aWidth;
	float textureHeight = xTextureClip->aHeight;

	float realWidth, realHeight, calcWidth, calcHeight;
	float consOffsetX, consOffsetY;
	float realTWidth, realTHeight, calcTX, calcTY;
	float tWidthOffset, tHeightOffset;

	float left;
	float right;
	float top;
	float bottom;
	float leftTex;
	float rightTex;
	float topTex;
	float bottomTex;

	byte index = 0;
	A2DVertexData * vertices = aQuadData->aVertices;
	void * mappedVertices = 0;

	// Bitmap mapping calculations.
	realX = rectX < 0 ? contraints.aX : contraints.aX + rectX;
	realY = rectY < 0 ? contraints.aY : contraints.aY + rectY;

	calcWidth = rectX < 0 ? rectWidth - abs(rectX) : rectWidth;
	calcHeight = rectY < 0 ? rectHeight - abs(rectY) : rectHeight;

	consOffsetX = rectX < 0 ? 0 : rectX;
	consOffsetY = rectY < 0 ? 0 : rectY;

	realWidth = rectX + calcWidth > contraints.aWidth ? contraints.aWidth - consOffsetX : calcWidth;
	realHeight = rectY + calcHeight > contraints.aHeight ? contraints.aHeight - consOffsetY : calcHeight;

	// Handle negative constraint dimensions.
	if (realWidth < 0)
	{
		realWidth = realWidth + rectX > 0 ? realWidth + rectX : 0;
	}
	if (realHeight < 0)
	{
		realHeight = realHeight + rectY > 0 ? realHeight + rectY : 0;
	}

	// Texture mapping calculations.
	calcTX = rectX < 0 ? rectX + (rectWidth * abs(rectX)) / contraints.aWidth : rectX;
	calcTY = rectX < 0 ? rectY + (rectHeight * abs(rectY)) / contraints.aHeight : rectY;

	calcTX += textureX;
	calcTY += textureY;

	// Calculate offset for x and y constraints.
	tWidthOffset = rectX + calcWidth > contraints.aWidth || rectX < 0 ? (rectWidth * abs(rectX)) / contraints.aWidth : 0;
	realTWidth = rectWidth - tWidthOffset;

	realTWidth = textureWidth - realTWidth < 0 ? textureWidth : realTWidth;

	tHeightOffset = rectY + calcHeight > contraints.aHeight || rectY < 0 ? (rectHeight * abs(rectY)) / contraints.aHeight : 0;
	realTHeight = rectHeight - tHeightOffset;

	realTHeight = textureHeight - realTHeight < 0 ? textureHeight : realTHeight;

	// Calculate offset for dimension constraints.
	realTWidth -= rectWidth < contraints.aWidth ? (rectWidth * (contraints.aWidth - rectWidth)) / contraints.aWidth : 0;
	realTHeight -= rectHeight < contraints.aHeight ? (rectHeight * (contraints.aHeight - rectHeight)) / contraints.aHeight : 0;

	// Calculate the screen coordinates of the left side of the bitmap.
	left = ((aWindowDims->aWidth / 2) * -1) + realX;

	// Calculate the screen coordinates of the right side of the bitmap.
	right = left + realWidth;

	// Calculate the screen coordinates of the top of the bitmap.
	top = (aWindowDims->aHeight / 2) - realY;

	// Calculate the screen coordinates of the bottom of the bitmap.
	bottom = top - realHeight;

	// Calculate desired texture mapping.
	leftTex = calcTX / xTextureDims->aWidth;
	rightTex = (calcTX + realTWidth) / xTextureDims->aWidth;;
	topTex = calcTY / xTextureDims->aWidth;
	bottomTex = (calcTY + realTHeight) / xTextureDims->aHeight;

	// Load the vertex array with data.
	vertices[index].position = D3DXVECTOR3(left, top, 0.0f);  // Top left.
	vertices[index++].texture = D3DXVECTOR2(leftTex, topTex);

	vertices[index].position = D3DXVECTOR3(right, bottom, 0.0f);  // Bottom right.
	vertices[index++].texture = D3DXVECTOR2(rightTex, bottomTex);

	vertices[index].position = D3DXVECTOR3(left, bottom, 0.0f);  // Bottom left.
	vertices[index++].texture = D3DXVECTOR2(leftTex, bottomTex);

	// Second triangle.
	vertices[index].position = D3DXVECTOR3(left, top, 0.0f);  // Top left.
	vertices[index++].texture = D3DXVECTOR2(leftTex, topTex);

	vertices[index].position = D3DXVECTOR3(right, top, 0.0f);  // Top right.
	vertices[index++].texture = D3DXVECTOR2(rightTex, topTex);

	vertices[index].position = D3DXVECTOR3(right, bottom, 0.0f);  // Bottom right.
	vertices[index++].texture = D3DXVECTOR2(rightTex, bottomTex);

	// Lock the vertex buffer.
	hr = aQuadData->aVertexBuffer->Map(D3D10_MAP_WRITE_DISCARD, 0, (void**)&mappedVertices);
	if (FAILED(hr))	return hr;

	// Copy the data into the vertex buffer.
	memcpy(mappedVertices, (void*)vertices, (sizeof(A2DVertexData)* 6));

	// Unlock the vertex buffer.
	aQuadData->aVertexBuffer->Unmap();

	return hr;

}

unsigned int A2DQuadFactory::aStride = sizeof(A2DVertexData);
unsigned int A2DQuadFactory::aOffset = 0;

void A2DQuadFactory::RenderQuad(A2DQuadData * aQuadData)
{
	ID3D10Device  *	device = *aDXDevice;

	// Set the vertex buffer to active in the input
	// assembler so it can be rendered.
	device->IASetVertexBuffers(0, 1, &aQuadData->aVertexBuffer, &aStride, &aOffset);

	// Set the index buffer to active in the input
	// assembler so it can be rendered.
	device->IASetIndexBuffer(aIndexBuffer, DXGI_FORMAT_R32_UINT, 0);

	// Set the type of primitive that should be
	// rendered from this vertex buffer, in this case triangles.
	device->IASetPrimitiveTopology(D3D10_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	return;
}

HRESULT A2DQuadFactory::Initialize()
{
	HRESULT hr = S_OK;

	hr = A2DDXShapeUtils::CreateDefaultDynamicVertexBuffer<A2DVertexData>(*aDXDevice, &aVertexBuffer, 6);
	if (FAILED(hr))	return hr;

	hr = A2DDXShapeUtils::CreateDefaultIndexBuffer(*aDXDevice, &aIndexBuffer, 6);
	if (FAILED(hr))	return hr;

	return hr;
}

void A2DQuadFactory::Deinitialize()
{
	if (aVertexBuffer)
	{
		aVertexBuffer->Release();
		delete aVertexBuffer;
		aVertexBuffer = 0;
	}

	if (aIndexBuffer)
	{
		aIndexBuffer->Release();
		delete aIndexBuffer;
		aIndexBuffer = 0;
	}
}

LPCWSTR A2DQuadFactory::GetClass()
{
	return L"A2DQuadFactory";
}

LPCWSTR A2DQuadFactory::ToString()
{
	return L"A2DQuadFactory";
}

bool A2DQuadFactory::operator==(A2DAbstract * A2DAbstract)
{
	return false;
}

<|endoftext|>


<commit_before>
#include <iostream>
#include <sstream>
#include "lexan.hxx"
#include "csynan.hxx"
#include "ast.hxx"
#include "astprint.hxx"

extern int yyparse (void *);

int main (void)
{
    extern int yydebug;
    yydebug = 1;
    try {
        lexan_init(std::cin);
        CCompoundStatement * tree;
        yyparse(&tree);
        std::cerr << "after yyparse()" << std::endl;
	/* prvni vystup tela funkce do docasneho streamu */
	std::ostringstream body;
	astprint(tree, new ASTInfo(NULL, 1, tree), body);

	/* vystup hlavni funkce */
	std::cout << "procedure main;" << std::endl;
	{
	    /* vystup deklaraci */
	    std::cout << "var" << std::endl;
	    declsprint(decls, std::cout);

	    /* vystup tela */
	    std::cout << "begin" << std::endl;
	    std::cout << body.str();
	    std::cout << ";" << std::endl << "end;" << std::endl;
	}
	std::cout << "begin" << std::endl
		  << "main;" << std::endl
		  << "end." << std::endl;

        delete tree;
    }
    catch (std::string & e) {
	std::cerr << e << std::endl;
    }
    catch (...) {
	std::cerr << "exception caught" << std::endl;
	throw;
    }
}
<commit_msg>Turn off yydebug.<commit_after>
#include <iostream>
#include <sstream>
#include "lexan.hxx"
#include "csynan.hxx"
#include "ast.hxx"
#include "astprint.hxx"

extern int yyparse (void *);

int main (void)
{
    extern int yydebug;
    yydebug = 0;
    try {
        lexan_init(std::cin);
        CCompoundStatement * tree;
        yyparse(&tree);
        std::cerr << "after yyparse()" << std::endl;
	/* prvni vystup tela funkce do docasneho streamu */
	std::ostringstream body;
	astprint(tree, new ASTInfo(NULL, 1, tree), body);

	/* vystup hlavni funkce */
	std::cout << "procedure main;" << std::endl;
	{
	    /* vystup deklaraci */
	    std::cout << "var" << std::endl;
	    declsprint(decls, std::cout);

	    /* vystup tela */
	    std::cout << "begin" << std::endl;
	    std::cout << body.str();
	    std::cout << ";" << std::endl << "end;" << std::endl;
	}
	std::cout << "begin" << std::endl
		  << "main;" << std::endl
		  << "end." << std::endl;

        delete tree;
    }
    catch (std::string & e) {
	std::cerr << e << std::endl;
    }
    catch (...) {
	std::cerr << "exception caught" << std::endl;
	throw;
    }
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ResourceLifecycleManager.h"

using namespace activemq::cmsutil;

////////////////////////////////////////////////////////////////////////////////
ResourceLifecycleManager::ResourceLifecycleManager() {
}

////////////////////////////////////////////////////////////////////////////////
ResourceLifecycleManager::~ResourceLifecycleManager() {

    try {

        // Destroy all the resources
        destroy();

    } catch( cms::CMSException& e ) { /* Absorb*/}
}

////////////////////////////////////////////////////////////////////////////////
void ResourceLifecycleManager::releaseAll() {

    connections.clear();
    sessions.clear();
    destinations.clear();
    producers.clear();
    consumers.clear();
}

////////////////////////////////////////////////////////////////////////////////
void ResourceLifecycleManager::destroy() throw (cms::CMSException) {

    // Close all the connections.
    for (std::size_t ix=0; ix<connections.size(); ++ix) {
        connections[ix]->close();
    }

    // Destroy the producers.
    for (std::size_t ix=0; ix<producers.size(); ++ix) {
        delete producers[ix];
    }

    // Destroy the consumers.
    for (std::size_t ix=0; ix<consumers.size(); ++ix) {
        delete consumers[ix];
    }

    // Destroy the destinations.
    for (std::size_t ix=0; ix<destinations.size(); ++ix) {
        delete destinations[ix];
    }

    // Destroy the sessions.
    for (std::size_t ix=0; ix<sessions.size(); ++ix) {
        delete sessions[ix];
    }

    // Destroy the connections,
    for (std::size_t ix=0; ix<connections.size(); ++ix) {
        delete connections[ix];
    }

    // Empty all the vectors.
    releaseAll();
}

<commit_msg>AMQCPP-152 - Adding exception handling to ResourceLifecycleManager.destroy<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ResourceLifecycleManager.h"

using namespace activemq::cmsutil;

////////////////////////////////////////////////////////////////////////////////
ResourceLifecycleManager::ResourceLifecycleManager() {
}

////////////////////////////////////////////////////////////////////////////////
ResourceLifecycleManager::~ResourceLifecycleManager() {

    try {

        // Destroy all the resources
        destroy();

    } catch( cms::CMSException& e ) { /* Absorb*/}
}

////////////////////////////////////////////////////////////////////////////////
void ResourceLifecycleManager::releaseAll() {

    connections.clear();
    sessions.clear();
    destinations.clear();
    producers.clear();
    consumers.clear();
}

////////////////////////////////////////////////////////////////////////////////
void ResourceLifecycleManager::destroy() throw (cms::CMSException) {

    // Close all the connections.
    for (std::size_t ix=0; ix<connections.size(); ++ix) {
        try {
            connections[ix]->close();
        } catch(...){}
    }

    // Destroy the producers.
    for (std::size_t ix=0; ix<producers.size(); ++ix) {
        try {
            delete producers[ix];
        } catch( ... ) {}
    }

    // Destroy the consumers.
    for (std::size_t ix=0; ix<consumers.size(); ++ix) {
        try {
            delete consumers[ix];
        } catch( ... ) {}
    }

    // Destroy the destinations.
    for (std::size_t ix=0; ix<destinations.size(); ++ix) {
        try {
            delete destinations[ix];
        } catch( ... ) {}
    }

    // Destroy the sessions.
    for (std::size_t ix=0; ix<sessions.size(); ++ix) {
        try {
            delete sessions[ix];
        } catch( ... ) {}
    }

    // Destroy the connections,
    for (std::size_t ix=0; ix<connections.size(); ++ix) {
        try {
            delete connections[ix];
        } catch( ... ) {}
    }

    // Empty all the vectors.
    releaseAll();
}

<|endoftext|>


<commit_before>/* Copyright 2014 Open Source Robotics Foundation, Inc.
 *
 * 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.
 */

#ifndef RCLCPP_RCLCPP_EXECUTORS_MULTI_THREADED_EXECUTOR_HPP_
#define RCLCPP_RCLCPP_EXECUTORS_MULTI_THREADED_EXECUTOR_HPP_

#include <cassert>
#include <cstdlib>
#include <memory>
#include <mutex>
#include <vector>

#include <rmw/rmw.h>

#include <rclcpp/executor.hpp>
#include <rclcpp/macros.hpp>
#include <rclcpp/node.hpp>
#include <rclcpp/utilities.hpp>

namespace rclcpp
{
namespace executors
{
namespace multi_threaded_executor
{

class MultiThreadedExecutor : public executor::Executor
{
public:
  RCLCPP_MAKE_SHARED_DEFINITIONS(MultiThreadedExecutor);

  MultiThreadedExecutor()
  {
    number_of_threads_ = std::thread::hardware_concurrency();
    if (number_of_threads_ == 0)
    {
      number_of_threads_ = 1;
    }
  }

  ~MultiThreadedExecutor() {}

  void
  spin()
  {
    std::vector<std::thread> threads;
    {
      std::lock_guard<std::mutex> wait_lock(wait_mutex_);
      size_t thread_id_ = 1;
      for (size_t i = number_of_threads_; i > 0; --i)
      {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        auto func = std::bind(&MultiThreadedExecutor::run, this, thread_id_++);
        threads.emplace_back(func);
      }
    }
    for (auto &thread : threads)
    {
      thread.join();
    }
  }

  size_t
  get_number_of_threads()
  {
    return number_of_threads_;
  }

private:
  void run(size_t this_thread_id)
  {
    rclcpp::thread_id = this_thread_id;
    while (rclcpp::utilities::ok())
    {
      std::shared_ptr<AnyExecutable> any_exec;
      {
        std::lock_guard<std::mutex> wait_lock(wait_mutex_);
        if (!rclcpp::utilities::ok())
        {
          return;
        }
        any_exec = get_next_executable();
      }
      execute_any_executable(any_exec);
    }
  }

  RCLCPP_DISABLE_COPY(MultiThreadedExecutor);

  std::mutex wait_mutex_;
  size_t number_of_threads_;

};

} /* namespace multi_threaded_executor */
} /* namespace executors */
} /* namespace rclcpp */

#endif /* RCLCPP_RCLCPP_EXECUTORS_MULTI_THREADED_EXECUTOR_HPP_ */
<commit_msg>add a clarifying comment<commit_after>/* Copyright 2014 Open Source Robotics Foundation, Inc.
 *
 * 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.
 */

#ifndef RCLCPP_RCLCPP_EXECUTORS_MULTI_THREADED_EXECUTOR_HPP_
#define RCLCPP_RCLCPP_EXECUTORS_MULTI_THREADED_EXECUTOR_HPP_

#include <cassert>
#include <cstdlib>
#include <memory>
#include <mutex>
#include <vector>

#include <rmw/rmw.h>

#include <rclcpp/executor.hpp>
#include <rclcpp/macros.hpp>
#include <rclcpp/node.hpp>
#include <rclcpp/utilities.hpp>

namespace rclcpp
{
namespace executors
{
namespace multi_threaded_executor
{

class MultiThreadedExecutor : public executor::Executor
{
public:
  RCLCPP_MAKE_SHARED_DEFINITIONS(MultiThreadedExecutor);

  MultiThreadedExecutor()
  {
    number_of_threads_ = std::thread::hardware_concurrency();
    if (number_of_threads_ == 0)
    {
      number_of_threads_ = 1;
    }
  }

  ~MultiThreadedExecutor() {}

  void
  spin()
  {
    std::vector<std::thread> threads;
    {
      std::lock_guard<std::mutex> wait_lock(wait_mutex_);
      size_t thread_id_ = 1;  // Use a _ suffix to avoid shadowing `rclcpp::thread_id`
      for (size_t i = number_of_threads_; i > 0; --i)
      {
        std::this_thread::sleep_for(std::chrono::milliseconds(100));
        auto func = std::bind(&MultiThreadedExecutor::run, this, thread_id_++);
        threads.emplace_back(func);
      }
    }
    for (auto &thread : threads)
    {
      thread.join();
    }
  }

  size_t
  get_number_of_threads()
  {
    return number_of_threads_;
  }

private:
  void run(size_t this_thread_id)
  {
    rclcpp::thread_id = this_thread_id;
    while (rclcpp::utilities::ok())
    {
      std::shared_ptr<AnyExecutable> any_exec;
      {
        std::lock_guard<std::mutex> wait_lock(wait_mutex_);
        if (!rclcpp::utilities::ok())
        {
          return;
        }
        any_exec = get_next_executable();
      }
      execute_any_executable(any_exec);
    }
  }

  RCLCPP_DISABLE_COPY(MultiThreadedExecutor);

  std::mutex wait_mutex_;
  size_t number_of_threads_;

};

} /* namespace multi_threaded_executor */
} /* namespace executors */
} /* namespace rclcpp */

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