<commit_before>#include "HCache.h"

/** MODULE METHODS **/

static PyObject *connectCassandra(PyObject *self, PyObject *args) {
    int nodePort;
    std::string contact_points = "";
    PyObject *py_contact_points;

    if (!PyArg_ParseTuple(args, "Oi", &py_contact_points, &nodePort)) {
        return NULL;
    }

    uint16_t contact_p_len = (uint16_t) PyList_Size(py_contact_points);

    for (uint16_t i = 0; i < contact_p_len; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_contact_points, i);
        char *str_temp;
        if (!PyArg_Parse(obj_to_convert, "s", &str_temp)) {
            throw ModuleException("invalid contact points");
        };
        contact_points += std::string(str_temp) + " ";
    }

    CassFuture *connect_future = NULL;
    cluster = cass_cluster_new();
    session = cass_session_new();
    // add contact points
    cass_cluster_set_contact_points(cluster, contact_points.c_str());
    cass_cluster_set_port(cluster, nodePort);
    cass_cluster_set_token_aware_routing(cluster, cass_true);
    // Provide the cluster object as configuration to connect the session
    connect_future = cass_session_connect(session, cluster);
    CassError rc = cass_future_error_code(connect_future);
    if (rc != CASS_OK) {
        PyErr_SetString(PyExc_RuntimeError, cass_error_desc(rc));
        return NULL;
    }
    cass_future_free(connect_future);
    Py_RETURN_NONE;
}

static PyObject *disconnectCassandra(PyObject *self) {
    if (session != NULL) {
        CassFuture *close_future = cass_session_close(session);
        cass_future_free(close_future);
        cass_session_free(session);
        cass_cluster_free(cluster);
        session = NULL;
    }
    Py_RETURN_TRUE;
}

/*** HCACHE DATA TYPE METHODS AND SETUP ***/

static PyObject *put_row(HCache *self, PyObject *args) {
    PyObject *py_keys, *py_values;
    if (!PyArg_ParseTuple(args, "OO", &py_keys, &py_values)) {
        return NULL;
    }

    self->T->put_row(py_keys, py_values);
    Py_DecRef(py_keys);
    Py_DecRef(py_values);
    Py_RETURN_NONE;
}

static PyObject *get_row(HCache *self, PyObject *args) {
    PyObject *py_keys;
    if (!PyArg_ParseTuple(args, "O", &py_keys)) {
        return NULL;
    }

    return self->T->get_row(py_keys);
}

static void hcache_dealloc(HCache *self) {
    delete (self->T);
    self->ob_type->tp_free((PyObject *) self);
}

static PyObject *hcache_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
    HCache *self;
    self = (HCache *) type->tp_alloc(type, 0);
    return (PyObject *) self;
}

static int hcache_init(HCache *self, PyObject *args, PyObject *kwds) {
    const char *table, *keyspace, *token_range_pred;
    uint32_t cache_size;
    PyObject *py_tokens, *py_keys_names, *py_cols_names;

    if (!PyArg_ParseTuple(args, "IsssOOO", &cache_size, &keyspace, &table, &token_range_pred, &py_tokens,
                          &py_keys_names,
                          &py_cols_names)) {
         return -1;
    };

    uint16_t tokens_size = (uint16_t) PyList_Size(py_tokens);
    uint16_t keys_size = (uint16_t) PyList_Size(py_keys_names);
    uint16_t cols_size = (uint16_t) PyList_Size(py_cols_names);

    std::vector<std::pair<int64_t, int64_t>> token_ranges = std::vector<std::pair<int64_t, int64_t>>(tokens_size);
    for (uint16_t i = 0; i < tokens_size; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_tokens, i);
        int64_t t_a, t_b;
        if (!PyArg_ParseTuple(obj_to_convert, "LL", &t_a, &t_b)) {
            return -1;
        };

        token_ranges[i] = std::make_pair(t_a, t_b);
    }

    std::vector<std::string> keys_names = std::vector<std::string>(keys_size);

    for (uint16_t i = 0; i < keys_size; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_keys_names, i);
        char *str_temp;
        if (!PyArg_Parse(obj_to_convert, "s", &str_temp)) {
            return -1;
        }

        keys_names[i] = std::string(str_temp);

    }

    std::vector<std::string> columns_names = std::vector<std::string>(cols_size);
    for (uint16_t i = 0; i < cols_size; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_cols_names, i);
        char *str_temp;
        if (!PyArg_Parse(obj_to_convert, "s", &str_temp)) {
            return -1;
        };
        columns_names[i] = std::string(str_temp);
    }

    try {
        self->T = new CacheTable((uint32_t) cache_size, std::string(table), std::string(keyspace), keys_names,
                                 columns_names, std::string(token_range_pred), token_ranges, session);

      }catch (ModuleException e) {
        PyErr_SetString(PyExc_RuntimeError,e.what());
        return -1;
    }
    return 0;
}

static PyMethodDef hcache_type_methods[] = {
        {"get_row",    (PyCFunction) get_row,            METH_VARARGS, NULL},
        {"put_row",    (PyCFunction) put_row,            METH_VARARGS, NULL},
        {"iterkeys",   (PyCFunction) create_iter_keys,   METH_VARARGS, NULL},
        {"iteritems",  (PyCFunction) create_iter_items,  METH_VARARGS, NULL},
        {"itervalues", (PyCFunction) create_iter_values, METH_VARARGS, NULL},
        {NULL, NULL, 0,                                                NULL}
};

static PyTypeObject hfetch_HCacheType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "hfetch.Hcache",             /* tp_name */
        sizeof(HCache), /* tp_basicsize */
        0,                         /*tp_itemsize*/
        (destructor) hcache_dealloc, /*tp_dealloc*/
        0,                         /*tp_print*/
        0,                         /*tp_getattr*/
        0,                         /*tp_setattr*/
        0,                         /*tp_compare*/
        0,                         /*tp_repr*/
        0,                         /*tp_as_number*/
        0,                         /*tp_as_sequence*/
        0,                         /*tp_as_mapping*/
        0,                         /*tp_hash */
        0,                         /*tp_call*/
        0,                         /*tp_str*/
        0,                         /*tp_getattro*/
        0,                         /*tp_setattro*/
        0,                         /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
        "Cassandra rows",           /* tp_doc */
        0,                       /* tp_traverse */
        0,                       /* tp_clear */
        0,                       /* tp_richcompare */
        0,                       /* tp_weaklistoffset */
        0,                       /* tp_iter */
        0,                       /* tp_iternext */
        hcache_type_methods,             /* tp_methods */
        0,             /* tp_members */
        0,                         /* tp_getset */
        0,                         /* tp_base */
        0,                         /* tp_dict */
        0,                         /* tp_descr_get */
        0,                         /* tp_descr_set */
        0,                         /* tp_dictoffset */
        (initproc) hcache_init,      /* tp_init */
        0,                         /* tp_alloc */
        hcache_new,                 /* tp_new */
};

/*** ITERATOR METHODS AND SETUP ***/

static PyObject *hiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
    HIterator *self;
    self = (HIterator *) type->tp_alloc(type, 0);
    return (PyObject *) self;
}

static int hiter_init(HIterator *self, PyObject *args, PyObject *kwds) {
    //self->P = 0;// new prefetch
    return 0;
}

static PyObject *get_next(HIterator *self) {
    return self->P->get_next();
}

static void hiter_dealloc(HIterator *self) {
    delete (self->P);
    self->ob_type->tp_free((PyObject *) self);
}

static PyMethodDef hiter_type_methods[] = {
        {"get_next", (PyCFunction) get_next, METH_NOARGS, NULL},
        {NULL, NULL, 0,                                   NULL}
};

static PyTypeObject hfetch_HIterType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "hfetch.HIter",             /* tp_name */
        sizeof(HIterator), /* tp_basicsize */
        0,                         /*tp_itemsize*/
        (destructor) hiter_dealloc, /*tp_dealloc*/
        0,                         /*tp_print*/
        0,                         /*tp_getattr*/
        0,                         /*tp_setattr*/
        0,                         /*tp_compare*/
        0,                         /*tp_repr*/
        0,                         /*tp_as_number*/
        0,                         /*tp_as_sequence*/
        0,                         /*tp_as_mapping*/
        0,                         /*tp_hash */
        0,                         /*tp_call*/
        0,                         /*tp_str*/
        0,                         /*tp_getattro*/
        0,                         /*tp_setattro*/
        0,                         /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
        "Cassandra iter",           /* tp_doc */
        0,                       /* tp_traverse */
        0,                       /* tp_clear */
        0,                       /* tp_richcompare */
        0,                       /* tp_weaklistoffset */
        0,                       /* tp_iter */
        0,                       /* tp_iternext */
        hiter_type_methods,             /* tp_methods */
        0,             /* tp_members */
        0,                         /* tp_getset */
        0,                         /* tp_base */
        0,                         /* tp_dict */
        0,                         /* tp_descr_get */
        0,                         /* tp_descr_set */
        0,                         /* tp_dictoffset */
        (initproc) hiter_init,      /* tp_init */
        0,                         /* tp_alloc */
        hiter_new,                 /* tp_new */
};

/*** MODULE SETUP ****/

static PyMethodDef module_methods[] = {
        {"connectCassandra", (PyCFunction) connectCassandra, METH_VARARGS, NULL},
        {NULL, NULL, 0,                                                    NULL}
};

static PyObject *create_iter_keys(HCache *self, PyObject *args) {
    int prefetch_size;
    if (!PyArg_ParseTuple(args, "i", &prefetch_size)) {
        return NULL;
    }

    HIterator *iter = (HIterator *) hiter_new(&hfetch_HIterType, args, args);
    hiter_init(iter, args, args);
    iter->P = self->T->get_keys_iter(prefetch_size);
    return (PyObject *) iter;
}

static PyObject *create_iter_items(HCache *self, PyObject *args) {
    int prefetch_size;
    if (!PyArg_ParseTuple(args, "i", &prefetch_size)){
        return NULL;
    }
    HIterator *iter = (HIterator *) hiter_new(&hfetch_HIterType, args, args);
    hiter_init(iter, args, args);
    iter->P = self->T->get_items_iter(prefetch_size);
    return (PyObject *) iter;
}

static PyObject *create_iter_values(HCache *self, PyObject *args) {
    int prefetch_size;
    if (!PyArg_ParseTuple(args, "i", &prefetch_size)){
        return NULL;
    }
    HIterator *iter = (HIterator *) hiter_new(&hfetch_HIterType, args, args);
    hiter_init(iter, args, args);
    iter->P = self->T->get_values_iter(prefetch_size);
    return (PyObject *) iter;
}

void (*f)(PyObject *) = NULL;

static void module_dealloc(PyObject *self) {
    disconnectCassandra(self);
    if (f) f(self);
}

PyMODINIT_FUNC
inithfetch(void) {
    PyObject *m;
    hfetch_HIterType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&hfetch_HIterType) < 0)
        return;

    Py_INCREF(&hfetch_HIterType);
    hfetch_HCacheType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&hfetch_HCacheType) < 0)
        return;

    Py_INCREF(&hfetch_HCacheType);

    m = Py_InitModule3("hfetch", module_methods, "c++ bindings for hecuba cache & prefetch");
    f = m->ob_type->tp_dealloc;
    m->ob_type->tp_dealloc = module_dealloc;

    PyModule_AddObject(m, "Hcache", (PyObject *) &hfetch_HCacheType);
    PyModule_AddObject(m, "HIterator", (PyObject *) &hfetch_HIterType);

}<commit_msg>Solved bug when taking a list of contact points<commit_after>#include "HCache.h"

/** MODULE METHODS **/

static PyObject *connectCassandra(PyObject *self, PyObject *args) {
    int nodePort;
    std::string contact_points = "";
    PyObject *py_contact_points;

    if (!PyArg_ParseTuple(args, "Oi", &py_contact_points, &nodePort)) {
        return NULL;
    }

    uint16_t contact_p_len = (uint16_t) PyList_Size(py_contact_points);

    for (uint16_t i = 0; i < contact_p_len; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_contact_points, i);
        char *str_temp;
        if (!PyArg_Parse(obj_to_convert, "s", &str_temp)) {
            throw ModuleException("invalid contact points");
        };
        contact_points += std::string(str_temp) + ",";
    }

    CassFuture *connect_future = NULL;
    cluster = cass_cluster_new();
    session = cass_session_new();
    // add contact points
    cass_cluster_set_contact_points(cluster, contact_points.c_str());
    cass_cluster_set_port(cluster, nodePort);
    cass_cluster_set_token_aware_routing(cluster, cass_true);
    // Provide the cluster object as configuration to connect the session
    connect_future = cass_session_connect(session, cluster);
    CassError rc = cass_future_error_code(connect_future);
    if (rc != CASS_OK) {
        PyErr_SetString(PyExc_RuntimeError, cass_error_desc(rc));
        return NULL;
    }
    cass_future_free(connect_future);
    Py_RETURN_NONE;
}

static PyObject *disconnectCassandra(PyObject *self) {
    if (session != NULL) {
        CassFuture *close_future = cass_session_close(session);
        cass_future_free(close_future);
        cass_session_free(session);
        cass_cluster_free(cluster);
        session = NULL;
    }
    Py_RETURN_TRUE;
}

/*** HCACHE DATA TYPE METHODS AND SETUP ***/

static PyObject *put_row(HCache *self, PyObject *args) {
    PyObject *py_keys, *py_values;
    if (!PyArg_ParseTuple(args, "OO", &py_keys, &py_values)) {
        return NULL;
    }

    self->T->put_row(py_keys, py_values);
    Py_DecRef(py_keys);
    Py_DecRef(py_values);
    Py_RETURN_NONE;
}

static PyObject *get_row(HCache *self, PyObject *args) {
    PyObject *py_keys;
    if (!PyArg_ParseTuple(args, "O", &py_keys)) {
        return NULL;
    }

    return self->T->get_row(py_keys);
}

static void hcache_dealloc(HCache *self) {
    delete (self->T);
    self->ob_type->tp_free((PyObject *) self);
}

static PyObject *hcache_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
    HCache *self;
    self = (HCache *) type->tp_alloc(type, 0);
    return (PyObject *) self;
}

static int hcache_init(HCache *self, PyObject *args, PyObject *kwds) {
    const char *table, *keyspace, *token_range_pred;
    uint32_t cache_size;
    PyObject *py_tokens, *py_keys_names, *py_cols_names;

    if (!PyArg_ParseTuple(args, "IsssOOO", &cache_size, &keyspace, &table, &token_range_pred, &py_tokens,
                          &py_keys_names,
                          &py_cols_names)) {
         return -1;
    };

    uint16_t tokens_size = (uint16_t) PyList_Size(py_tokens);
    uint16_t keys_size = (uint16_t) PyList_Size(py_keys_names);
    uint16_t cols_size = (uint16_t) PyList_Size(py_cols_names);

    std::vector<std::pair<int64_t, int64_t>> token_ranges = std::vector<std::pair<int64_t, int64_t>>(tokens_size);
    for (uint16_t i = 0; i < tokens_size; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_tokens, i);
        int64_t t_a, t_b;
        if (!PyArg_ParseTuple(obj_to_convert, "LL", &t_a, &t_b)) {
            return -1;
        };

        token_ranges[i] = std::make_pair(t_a, t_b);
    }

    std::vector<std::string> keys_names = std::vector<std::string>(keys_size);

    for (uint16_t i = 0; i < keys_size; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_keys_names, i);
        char *str_temp;
        if (!PyArg_Parse(obj_to_convert, "s", &str_temp)) {
            return -1;
        }

        keys_names[i] = std::string(str_temp);

    }

    std::vector<std::string> columns_names = std::vector<std::string>(cols_size);
    for (uint16_t i = 0; i < cols_size; ++i) {
        PyObject *obj_to_convert = PyList_GetItem(py_cols_names, i);
        char *str_temp;
        if (!PyArg_Parse(obj_to_convert, "s", &str_temp)) {
            return -1;
        };
        columns_names[i] = std::string(str_temp);
    }

    try {
        self->T = new CacheTable((uint32_t) cache_size, std::string(table), std::string(keyspace), keys_names,
                                 columns_names, std::string(token_range_pred), token_ranges, session);

      }catch (ModuleException e) {
        PyErr_SetString(PyExc_RuntimeError,e.what());
        return -1;
    }
    return 0;
}

static PyMethodDef hcache_type_methods[] = {
        {"get_row",    (PyCFunction) get_row,            METH_VARARGS, NULL},
        {"put_row",    (PyCFunction) put_row,            METH_VARARGS, NULL},
        {"iterkeys",   (PyCFunction) create_iter_keys,   METH_VARARGS, NULL},
        {"iteritems",  (PyCFunction) create_iter_items,  METH_VARARGS, NULL},
        {"itervalues", (PyCFunction) create_iter_values, METH_VARARGS, NULL},
        {NULL, NULL, 0,                                                NULL}
};

static PyTypeObject hfetch_HCacheType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "hfetch.Hcache",             /* tp_name */
        sizeof(HCache), /* tp_basicsize */
        0,                         /*tp_itemsize*/
        (destructor) hcache_dealloc, /*tp_dealloc*/
        0,                         /*tp_print*/
        0,                         /*tp_getattr*/
        0,                         /*tp_setattr*/
        0,                         /*tp_compare*/
        0,                         /*tp_repr*/
        0,                         /*tp_as_number*/
        0,                         /*tp_as_sequence*/
        0,                         /*tp_as_mapping*/
        0,                         /*tp_hash */
        0,                         /*tp_call*/
        0,                         /*tp_str*/
        0,                         /*tp_getattro*/
        0,                         /*tp_setattro*/
        0,                         /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
        "Cassandra rows",           /* tp_doc */
        0,                       /* tp_traverse */
        0,                       /* tp_clear */
        0,                       /* tp_richcompare */
        0,                       /* tp_weaklistoffset */
        0,                       /* tp_iter */
        0,                       /* tp_iternext */
        hcache_type_methods,             /* tp_methods */
        0,             /* tp_members */
        0,                         /* tp_getset */
        0,                         /* tp_base */
        0,                         /* tp_dict */
        0,                         /* tp_descr_get */
        0,                         /* tp_descr_set */
        0,                         /* tp_dictoffset */
        (initproc) hcache_init,      /* tp_init */
        0,                         /* tp_alloc */
        hcache_new,                 /* tp_new */
};

/*** ITERATOR METHODS AND SETUP ***/

static PyObject *hiter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) {
    HIterator *self;
    self = (HIterator *) type->tp_alloc(type, 0);
    return (PyObject *) self;
}

static int hiter_init(HIterator *self, PyObject *args, PyObject *kwds) {
    //self->P = 0;// new prefetch
    return 0;
}

static PyObject *get_next(HIterator *self) {
    return self->P->get_next();
}

static void hiter_dealloc(HIterator *self) {
    delete (self->P);
    self->ob_type->tp_free((PyObject *) self);
}

static PyMethodDef hiter_type_methods[] = {
        {"get_next", (PyCFunction) get_next, METH_NOARGS, NULL},
        {NULL, NULL, 0,                                   NULL}
};

static PyTypeObject hfetch_HIterType = {
        PyVarObject_HEAD_INIT(NULL, 0)
        "hfetch.HIter",             /* tp_name */
        sizeof(HIterator), /* tp_basicsize */
        0,                         /*tp_itemsize*/
        (destructor) hiter_dealloc, /*tp_dealloc*/
        0,                         /*tp_print*/
        0,                         /*tp_getattr*/
        0,                         /*tp_setattr*/
        0,                         /*tp_compare*/
        0,                         /*tp_repr*/
        0,                         /*tp_as_number*/
        0,                         /*tp_as_sequence*/
        0,                         /*tp_as_mapping*/
        0,                         /*tp_hash */
        0,                         /*tp_call*/
        0,                         /*tp_str*/
        0,                         /*tp_getattro*/
        0,                         /*tp_setattro*/
        0,                         /*tp_as_buffer*/
        Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
        "Cassandra iter",           /* tp_doc */
        0,                       /* tp_traverse */
        0,                       /* tp_clear */
        0,                       /* tp_richcompare */
        0,                       /* tp_weaklistoffset */
        0,                       /* tp_iter */
        0,                       /* tp_iternext */
        hiter_type_methods,             /* tp_methods */
        0,             /* tp_members */
        0,                         /* tp_getset */
        0,                         /* tp_base */
        0,                         /* tp_dict */
        0,                         /* tp_descr_get */
        0,                         /* tp_descr_set */
        0,                         /* tp_dictoffset */
        (initproc) hiter_init,      /* tp_init */
        0,                         /* tp_alloc */
        hiter_new,                 /* tp_new */
};

/*** MODULE SETUP ****/

static PyMethodDef module_methods[] = {
        {"connectCassandra", (PyCFunction) connectCassandra, METH_VARARGS, NULL},
        {NULL, NULL, 0,                                                    NULL}
};

static PyObject *create_iter_keys(HCache *self, PyObject *args) {
    int prefetch_size;
    if (!PyArg_ParseTuple(args, "i", &prefetch_size)) {
        return NULL;
    }

    HIterator *iter = (HIterator *) hiter_new(&hfetch_HIterType, args, args);
    hiter_init(iter, args, args);
    iter->P = self->T->get_keys_iter(prefetch_size);
    return (PyObject *) iter;
}

static PyObject *create_iter_items(HCache *self, PyObject *args) {
    int prefetch_size;
    if (!PyArg_ParseTuple(args, "i", &prefetch_size)){
        return NULL;
    }
    HIterator *iter = (HIterator *) hiter_new(&hfetch_HIterType, args, args);
    hiter_init(iter, args, args);
    iter->P = self->T->get_items_iter(prefetch_size);
    return (PyObject *) iter;
}

static PyObject *create_iter_values(HCache *self, PyObject *args) {
    int prefetch_size;
    if (!PyArg_ParseTuple(args, "i", &prefetch_size)){
        return NULL;
    }
    HIterator *iter = (HIterator *) hiter_new(&hfetch_HIterType, args, args);
    hiter_init(iter, args, args);
    iter->P = self->T->get_values_iter(prefetch_size);
    return (PyObject *) iter;
}

void (*f)(PyObject *) = NULL;

static void module_dealloc(PyObject *self) {
    disconnectCassandra(self);
    if (f) f(self);
}

PyMODINIT_FUNC
inithfetch(void) {
    PyObject *m;
    hfetch_HIterType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&hfetch_HIterType) < 0)
        return;

    Py_INCREF(&hfetch_HIterType);
    hfetch_HCacheType.tp_new = PyType_GenericNew;
    if (PyType_Ready(&hfetch_HCacheType) < 0)
        return;

    Py_INCREF(&hfetch_HCacheType);

    m = Py_InitModule3("hfetch", module_methods, "c++ bindings for hecuba cache & prefetch");
    f = m->ob_type->tp_dealloc;
    m->ob_type->tp_dealloc = module_dealloc;

    PyModule_AddObject(m, "Hcache", (PyObject *) &hfetch_HCacheType);
    PyModule_AddObject(m, "HIterator", (PyObject *) &hfetch_HIterType);

}<|endoftext|>


<commit_before>#ifndef __GLYPH_HPP_INCLUDED
#define __GLYPH_HPP_INCLUDED

#include "font.hpp"
#include "model_common_functions.hpp"
#include "model_templates.hpp"
#include "species_or_glyph.hpp"

namespace model
{
    class Glyph
    {
        public:
            // constructor.
            Glyph(GlyphStruct glyph_struct);

            // destructor.
            ~Glyph();

            // this method sets a object pointer.
            void set_object_pointer(GLuint childID, void* parent_pointer);

            // this method gets a object ID and removes it from the `free_objectID_queue` if it was popped from the queue.
            GLuint get_objectID();

            glm::vec3 lightPos;                    // light position.

            // The rest fields are created in the constructor.
            GLuint image_width;
            GLuint image_height;

            GLuint vertexPosition_modelspaceID;
            GLuint vertexUVID;
            GLuint vertexNormal_modelspaceID;

            std::vector<glm::vec3> vertices;       // vertices of the object.
            std::vector<glm::vec2> UVs;            // UVs of the object.
            std::vector<glm::vec3> normals;        // normals of the object.

            std::vector<GLuint> indices;           // the deleted vertices will be reused (though it is not required, if there's enough memory).
            std::vector<glm::vec3> indexed_vertices;
            std::vector<glm::vec2> indexed_UVs;
            std::vector<glm::vec3> indexed_normals;

            GLuint vertexbuffer;
            GLuint uvbuffer;
            GLuint normalbuffer;
            GLuint elementbuffer;

            model::Font *parent_pointer;             // pointer to the font.

            // friend class Object;
            template<class T1>
                friend void render_children(std::vector<void*> &child_pointer_vector);
            template<class T1>
                friend void bind_child_to_parent(T1 child_pointer, std::vector<void*> &child_pointer_vector, std::queue<GLuint> &free_childID_queue);
            template<class T1>
                friend void render_species_or_glyph(T1 species_or_glyph_pointer);

        // private:
            void bind_to_parent();

            // this method renders all objects of this species.
            void render();

            GLuint glyphID;                        // glyph ID, returned by `model::Font->get_glyphID()`.
            GLuint lightID;                        // light ID, returned by `glGetUniformLocation(programID, "LightPosition_worldspace");`.

            std::vector<void*> object_pointer_vector;
            std::queue<GLuint> free_objectID_queue;
    };
}

#endif
<commit_msg>`class Glyph`: Palautettu `private:` & `friend`-määritykset ennalleen.<commit_after>#ifndef __GLYPH_HPP_INCLUDED
#define __GLYPH_HPP_INCLUDED

#include "font.hpp"
#include "model_common_functions.hpp"
#include "model_templates.hpp"
#include "species_or_glyph.hpp"

namespace model
{
    class Object;

    class Glyph
    {
        public:
            // constructor.
            Glyph(GlyphStruct glyph_struct);

            // destructor.
            ~Glyph();

            // this method sets a object pointer.
            void set_object_pointer(GLuint childID, void* parent_pointer);

            // this method gets a object ID and removes it from the `free_objectID_queue` if it was popped from the queue.
            GLuint get_objectID();

            glm::vec3 lightPos;                    // light position.

            // The rest fields are created in the constructor.
            GLuint image_width;
            GLuint image_height;

            GLuint vertexPosition_modelspaceID;
            GLuint vertexUVID;
            GLuint vertexNormal_modelspaceID;

            std::vector<glm::vec3> vertices;       // vertices of the object.
            std::vector<glm::vec2> UVs;            // UVs of the object.
            std::vector<glm::vec3> normals;        // normals of the object.

            std::vector<GLuint> indices;           // the deleted vertices will be reused (though it is not required, if there's enough memory).
            std::vector<glm::vec3> indexed_vertices;
            std::vector<glm::vec2> indexed_UVs;
            std::vector<glm::vec3> indexed_normals;

            GLuint vertexbuffer;
            GLuint uvbuffer;
            GLuint normalbuffer;
            GLuint elementbuffer;

            model::Font *parent_pointer;             // pointer to the font.

            friend class Object;
            template<class T1>
                friend void render_children(std::vector<void*> &child_pointer_vector);
            template<class T1>
                friend void bind_child_to_parent(T1 child_pointer, std::vector<void*> &child_pointer_vector, std::queue<GLuint> &free_childID_queue);
            template<class T1>
                friend void render_species_or_glyph(T1 species_or_glyph_pointer);

        private:
            void bind_to_parent();

            // this method renders all objects of this species.
            void render();

            GLuint glyphID;                        // glyph ID, returned by `model::Font->get_glyphID()`.
            GLuint lightID;                        // light ID, returned by `glGetUniformLocation(programID, "LightPosition_worldspace");`.

            std::vector<void*> object_pointer_vector;
            std::queue<GLuint> free_objectID_queue;
    };
}

#endif
<|endoftext|>


<commit_before>/*
 * Copyright 2013  Daniel Vrátil <dvratil@redhat.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License or (at your option) version 3 or any later version
 * accepted by the membership of KDE e.V. (or its successor approved
 * by the membership of KDE e.V.), which shall act as a proxy
 * defined in Section 14 of version 3 of the license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "resolutionslider.h"
#include "utils.h"

#include <QtGui/QGridLayout>
#include <QtGui/QLabel>
#include <QtGui/QSlider>

#include <KLocalizedString>

#include <kscreen/output.h>

static bool sizeLessThan(const QSize &sizeA, const QSize &sizeB)
{
    return sizeA.width() * sizeA.height() < sizeB.width() * sizeB.height();
}

ResolutionSlider::ResolutionSlider(KScreen::Output *output, QWidget *parent)
    : QWidget(parent)
    , mOutput(output)
{
    connect(output, SIGNAL(currentModeIdChanged()),
            this, SLOT(slotOutputModeChanged()));

    QGridLayout *layout = new QGridLayout(this);

    mSmallestLabel = new QLabel(this);
    layout->addWidget(mSmallestLabel, 0, 0);

    mSlider = new QSlider(Qt::Horizontal, this);
    mSlider->setTickInterval(1);
    mSlider->setTickPosition(QSlider::TicksBelow);
    mSlider->setSingleStep(1);
    mSlider->setPageStep(1);
    layout->addWidget(mSlider, 0, 1);
    connect(mSlider, SIGNAL(valueChanged(int)),
            this, SLOT(slotSlideValueChanged(int)));

    mBiggestLabel = new QLabel(this);
    layout->addWidget(mBiggestLabel, 0, 2);

    mCurrentLabel = new QLabel(this);
    mCurrentLabel->setAlignment(Qt::AlignCenter);
    layout->addWidget(mCurrentLabel, 1, 0, 1, 3);

    Q_FOREACH (KScreen::Mode* mode, output->modes()) {
        if (mModes.contains(mode->size())) {
            continue;
        }

        mModes << mode->size();
    }

    qSort(mModes.begin(), mModes.end(), sizeLessThan);

    if (mModes.size() < 2) {
        mSmallestLabel->hide();
        mBiggestLabel->hide();
        mSlider->hide();
        mCurrentLabel->setAlignment(Qt::AlignLeft);
        if (mModes.size() == 0) {
            mCurrentLabel->setText(i18n("No available resolutions"));
        } else {
            mCurrentLabel->setText(Utils::sizeToString(mModes.first()));
        }

        return;
    }

    mSmallestLabel->setText(Utils::sizeToString(mModes.first()));
    mBiggestLabel->setText(Utils::sizeToString(mModes.last()));
    mSlider->setMinimum(0);
    mSlider->setMaximum(mModes.size() - 1);
    mSlider->setSingleStep(1);
    mSlider->setValue(mModes.indexOf(output->currentMode()->size()));
    slotOutputModeChanged();
}

ResolutionSlider::~ResolutionSlider()
{
}

QSize ResolutionSlider::currentResolution() const
{
    if (mModes.isEmpty()) {
        return QSize();
    }

    if (mModes.size() < 2) {
        return mModes.first();
    }

    return mModes.at(mSlider->value());
}

void ResolutionSlider::slotOutputModeChanged()
{
    if (!mOutput->currentMode()) {
        return;
    }

    mSlider->setValue(mModes.indexOf(mOutput->currentMode()->size()));
}

void ResolutionSlider::slotSlideValueChanged(int value)
{
    const QSize &size = mModes.at(value);
    mCurrentLabel->setText(Utils::sizeToString(size));

    Q_EMIT resolutionChanged(size);
}

#include "resolutionslider.moc"
<commit_msg>Fix crash when output does not have currentMode() set (disabled outputs)<commit_after>/*
 * Copyright 2013  Daniel Vrátil <dvratil@redhat.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License or (at your option) version 3 or any later version
 * accepted by the membership of KDE e.V. (or its successor approved
 * by the membership of KDE e.V.), which shall act as a proxy
 * defined in Section 14 of version 3 of the license.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "resolutionslider.h"
#include "utils.h"

#include <QtGui/QGridLayout>
#include <QtGui/QLabel>
#include <QtGui/QSlider>

#include <KLocalizedString>

#include <kscreen/output.h>

static bool sizeLessThan(const QSize &sizeA, const QSize &sizeB)
{
    return sizeA.width() * sizeA.height() < sizeB.width() * sizeB.height();
}

ResolutionSlider::ResolutionSlider(KScreen::Output *output, QWidget *parent)
    : QWidget(parent)
    , mOutput(output)
{
    connect(output, SIGNAL(currentModeIdChanged()),
            this, SLOT(slotOutputModeChanged()));

    QGridLayout *layout = new QGridLayout(this);

    mSmallestLabel = new QLabel(this);
    layout->addWidget(mSmallestLabel, 0, 0);

    mSlider = new QSlider(Qt::Horizontal, this);
    mSlider->setTickInterval(1);
    mSlider->setTickPosition(QSlider::TicksBelow);
    mSlider->setSingleStep(1);
    mSlider->setPageStep(1);
    layout->addWidget(mSlider, 0, 1);
    connect(mSlider, SIGNAL(valueChanged(int)),
            this, SLOT(slotSlideValueChanged(int)));

    mBiggestLabel = new QLabel(this);
    layout->addWidget(mBiggestLabel, 0, 2);

    mCurrentLabel = new QLabel(this);
    mCurrentLabel->setAlignment(Qt::AlignCenter);
    layout->addWidget(mCurrentLabel, 1, 0, 1, 3);

    Q_FOREACH (KScreen::Mode* mode, output->modes()) {
        if (mModes.contains(mode->size())) {
            continue;
        }

        mModes << mode->size();
    }

    qSort(mModes.begin(), mModes.end(), sizeLessThan);

    if (mModes.size() < 2) {
        mSmallestLabel->hide();
        mBiggestLabel->hide();
        mSlider->hide();
        mCurrentLabel->setAlignment(Qt::AlignLeft);
        if (mModes.size() == 0) {
            mCurrentLabel->setText(i18n("No available resolutions"));
        } else {
            mCurrentLabel->setText(Utils::sizeToString(mModes.first()));
        }

        return;
    }

    mSmallestLabel->setText(Utils::sizeToString(mModes.first()));
    mBiggestLabel->setText(Utils::sizeToString(mModes.last()));
    mSlider->setMinimum(0);
    mSlider->setMaximum(mModes.size() - 1);
    mSlider->setSingleStep(1);
    if (output->currentMode()) {
      mSlider->setValue(mModes.indexOf(output->currentMode()->size()));
    } else if (output->preferredMode()) {
      mSlider->setValue(mModes.indexOf(output->preferredMode()->size()));
    } else {
      mSlider->setValue(mSlider->maximum());
    }
    slotOutputModeChanged();
}

ResolutionSlider::~ResolutionSlider()
{
}

QSize ResolutionSlider::currentResolution() const
{
    if (mModes.isEmpty()) {
        return QSize();
    }

    if (mModes.size() < 2) {
        return mModes.first();
    }

    return mModes.at(mSlider->value());
}

void ResolutionSlider::slotOutputModeChanged()
{
    if (!mOutput->currentMode()) {
        return;
    }

    mSlider->setValue(mModes.indexOf(mOutput->currentMode()->size()));
}

void ResolutionSlider::slotSlideValueChanged(int value)
{
    const QSize &size = mModes.at(value);
    mCurrentLabel->setText(Utils::sizeToString(size));

    Q_EMIT resolutionChanged(size);
}

#include "resolutionslider.moc"
<|endoftext|>


<commit_before>#include <cmath>
#include <thread>

#include "../../chan.hh"

void term(chan::chan<double>& ch, int k) {
	double x = 4.0 * std::pow(-1, k);
	x /= 2 * k + 1;
	ch << x;
}

double pi(int n) {
	chan::unbuffered_chan<double> ch;

	for (int k = 0 ; k <= n ; k++) {
		std::thread(term, std::ref(ch), k).detach();
	}

	double f = 0;
	for (int k = 0 ; k <= n ; k++) {
		double x = 0;
		ch >> x;
		f += x;
	}

	return f;
}

int main () {
	printf("%lf\n", pi(5000));
}
<commit_msg>examples/go/pi: make term oneline<commit_after>#include <cmath>
#include <thread>

#include "../../chan.hh"

void term(chan::chan<double>& ch, int k) {
	ch << (4.0 * std::pow(-1, k)) / (2 * k + 1);
}

double pi(int n) {
	chan::unbuffered_chan<double> ch;

	for (int k = 0 ; k <= n ; k++) {
		std::thread(term, std::ref(ch), k).detach();
	}

	double f = 0;
	for (int k = 0 ; k <= n ; k++) {
		double x = 0;
		ch >> x;
		f += x;
	}

	return f;
}

int main () {
	printf("%lf\n", pi(5000));
}
<|endoftext|>


<commit_before>/*
 *  Copyright 2017 Oluwatobi Adeyinka
 *
 *  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 <sstream>
#include "databasemanager.h"

DatabaseManager::DatabaseManager() {
    createPodcastsTable();
    createEpisodesTable();
}

DatabaseManager::~DatabaseManager() = default;

void DatabaseManager::openDatabase() {
    int responseCode = sqlite3_open_v2(DATABASE_FILE.c_str(), &database, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
    if (responseCode != SQLITE_OK) {
        std::stringstream ss;
        ss << "Error opening database: " << sqlite3_errmsg(database) << " (error code " << responseCode << ")";
        throw ss.str();
    }
}

void DatabaseManager::closeDatabase() {
    sqlite3_close(database);
}

void DatabaseManager::createPodcastsTable() {
    openDatabase();
    closeDatabase();
}

void DatabaseManager::createEpisodesTable() {
    openDatabase();
    closeDatabase();
}
<commit_msg>implement podcasts & episodes tbale creation<commit_after>/*
 *  Copyright 2017 Oluwatobi Adeyinka
 *
 *  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 <sstream>
#include "databasemanager.h"

DatabaseManager::DatabaseManager() {
    createPodcastsTable();
    createEpisodesTable();
}

DatabaseManager::~DatabaseManager() = default;

void DatabaseManager::openDatabase() {
    int resultCode = sqlite3_open_v2(DATABASE_FILE.c_str(), &database, SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE, NULL);
    if (resultCode != SQLITE_OK) {
        std::stringstream ss;
        ss << "Error opening database: " << sqlite3_errmsg(database) << " (error code " << resultCode << ")";
        throw ss.str();
    }
}

void DatabaseManager::closeDatabase() {
    sqlite3_close(database);
}

void DatabaseManager::createPodcastsTable() {
    int resultCode;
    char * errorMessage = 0;

    std::string sql =
            "CREATE TABLE IF NOT EXISTS podcasts("
            "id TEXT PRIMARY KEY NOT NULL,"
            "name TEXT NOT NULL);";

    openDatabase();
    resultCode = sqlite3_exec(database, sql.c_str(), nullptr, nullptr, &errorMessage);
    if (resultCode != SQLITE_OK){
        std::stringstream ss;
        ss << "Error creating podcasts table: " << errorMessage << " (error code " << resultCode << ")";
        throw ss.str();
    }
    closeDatabase();
}

void DatabaseManager::createEpisodesTable() {
    int resultCode;
    char * errorMessage = 0;

    std::string sql =
            "CREATE TABLE IF NOT EXISTS episodes("
            "id TEXT PRIMARY KEY NOT NULL,"
            "name TEXT NOT NULL);";

    openDatabase();
    resultCode = sqlite3_exec(database, sql.c_str(), nullptr, nullptr, &errorMessage);
    if (resultCode != SQLITE_OK){
        std::stringstream ss;
        ss << "Error creating episodes table: " << errorMessage << " (error code " << resultCode << ")";
        throw ss.str();
    }
    closeDatabase();
}
<|endoftext|>


<commit_before>/***************************************************************************
*   Copyright (C) 2006 by                                                 *
*   Jason Kivlighn (jkivlighn@gmail.com)                                  *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "conversiondialog.h"

#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <klineedit.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <q3whatsthis.h>

#include <KVBox>

#include <kcombobox.h>
#include <klineedit.h>
#include <klocale.h>
#include <kvbox.h>

#include "backends/recipedb.h"
#include "widgets/unitcombobox.h"
#include "widgets/ingredientcombobox.h"
#include "widgets/prepmethodcombobox.h"
#include "widgets/fractioninput.h"

ConversionDialog::ConversionDialog( QWidget* parent, RecipeDB *db, const char* name )
		: KDialog( parent ),
		m_database(db)
{
	 setObjectName( name );
	 setCaption(i18n( "Measurement Converter" ));
	 setButtons(KDialog::Close | KDialog::User1 | KDialog::Help);
	 setDefaultButton(KDialog::Close);
	 setHelp("measure-converter");
	 setButtonText( KDialog::User1, i18n("Convert") );

	 setModal( false );

	 KVBox *page = new KVBox( this );
	 setMainWidget( page );

	KHBox *vbox = new KVBox(page);

	KHBox *fromTopBox = new KHBox(vbox);
	convertLabel = new QLabel( fromTopBox );

	amountEdit = new FractionInput( fromTopBox );

	fromUnitBox = new UnitComboBox( fromTopBox, db );
	fromUnitBox->reload();
	fromTopBox->setStretchFactor( fromUnitBox, 2 );
	fromTopBox->setSpacing(3);

	KHBox *fromBottomBox = new KHBox(vbox);

	ingredientBox = new IngredientComboBox( false, fromBottomBox, db, i18n( "--Ingredient (optional)--" ) );
	ingredientBox->reload();

	prepMethodBox = new PrepMethodComboBox( false, fromBottomBox, db, i18n( "-No Preparation-" ) );
	prepMethodBox->reload();
	fromBottomBox->setSpacing(3);

	KHBox *toBox = new KHBox(vbox);

	toLabel = new QLabel( toBox );

	toUnitBox = new UnitComboBox( toBox, db );
	toUnitBox->reload();
	toBox->setStretchFactor( toUnitBox, 2 );
	toBox->setSpacing(8);

	KHBox *resultBox = new KHBox(vbox);
	resultLabel = new QLabel( resultBox );
	resultLabel->setObjectName( "resultLabel" );
	resultText = new QLabel( resultBox );
	resultText->setObjectName( "resultText" );
	resultBox->setStretchFactor( resultText, 2 );

	languageChange();

	setInitialSize( QSize(300, 200).expandedTo(minimumSizeHint()) );

	// signals and slots connections
	connect ( this, SIGNAL( closeClicked() ), this, SLOT( accept() ) );
	connect( this, SIGNAL( user1Clicked() ), this, SLOT( convert() ) );
}

ConversionDialog::~ConversionDialog()
{
}

void ConversionDialog::languageChange()
{
	convertLabel->setText( i18n( "Convert" ) );
	toLabel->setText( i18n( "To" ) );
	resultLabel->setText( i18n( "Result:" ) );
	resultText->setText( QString::null );
}

void ConversionDialog::show()
{
	reset();
	KDialog::show();
}

void ConversionDialog::reset()
{
	resultText->setText( QString::null );
	ingredientBox->setCurrentItem( 0 );
	prepMethodBox->setCurrentItem( 0 );
	toUnitBox->setCurrentItem( 0 );
	fromUnitBox->setCurrentItem( 0 );
	amountEdit->clear();
}

void ConversionDialog::convert()
{
	Ingredient result, ing;
	Unit unit = m_database->unitName(toUnitBox->id(toUnitBox->currentIndex()));

	ing.amount = amountEdit->value().toDouble();
	ing.ingredientID = ingredientBox->id(ingredientBox->currentIndex());
	ing.units = m_database->unitName(fromUnitBox->id(fromUnitBox->currentIndex()));

	int prepID = prepMethodBox->id(prepMethodBox->currentIndex());
	if ( prepID != -1 )
		ing.prepMethodList.append(Element(QString::null,prepID));

	switch ( m_database->convertIngredientUnits( ing, unit, result ) ) {
	case RecipeDB::Success:
		resultLabel->setText( i18n( "Result:" ) );
		resultText->setText(QString::number(result.amount)+" "+((result.amount>1)?result.units.plural:result.units.name));
		break;
	case RecipeDB::MismatchedPrepMethodUsingApprox:
		resultLabel->setText( i18n( "Approximated result:" ) );
		resultText->setText(QString::number(result.amount)+" "+((result.amount>1)?result.units.plural:result.units.name));
		break;
	case RecipeDB::MissingUnitConversion:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("Missing unit conversion") );
		break;
	case RecipeDB::MissingIngredientWeight:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("No ingredient weight available") );
		break;
	case RecipeDB::MismatchedPrepMethod:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("No ingredient weight available for this method of preparation") );
		break;
	case RecipeDB::MissingIngredient:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("Ingredient required for conversion") );
		break;
	case RecipeDB::InvalidTypes:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("Impossible unit conversion based on unit types") );
		break;
	}
}

#include "conversiondialog.moc"
<commit_msg>Removed duplicated include, it fixes a krazy issue.<commit_after>/***************************************************************************
*   Copyright (C) 2006 by                                                 *
*   Jason Kivlighn (jkivlighn@gmail.com)                                  *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
***************************************************************************/

#include "conversiondialog.h"

#include <qvariant.h>
#include <qpushbutton.h>
#include <qlabel.h>
#include <qlayout.h>
#include <qtooltip.h>
#include <q3whatsthis.h>

#include <KVBox>

#include <kcombobox.h>
#include <klineedit.h>
#include <klocale.h>
#include <kvbox.h>

#include "backends/recipedb.h"
#include "widgets/unitcombobox.h"
#include "widgets/ingredientcombobox.h"
#include "widgets/prepmethodcombobox.h"
#include "widgets/fractioninput.h"

ConversionDialog::ConversionDialog( QWidget* parent, RecipeDB *db, const char* name )
		: KDialog( parent ),
		m_database(db)
{
	 setObjectName( name );
	 setCaption(i18n( "Measurement Converter" ));
	 setButtons(KDialog::Close | KDialog::User1 | KDialog::Help);
	 setDefaultButton(KDialog::Close);
	 setHelp("measure-converter");
	 setButtonText( KDialog::User1, i18n("Convert") );

	 setModal( false );

	 KVBox *page = new KVBox( this );
	 setMainWidget( page );

	KHBox *vbox = new KVBox(page);

	KHBox *fromTopBox = new KHBox(vbox);
	convertLabel = new QLabel( fromTopBox );

	amountEdit = new FractionInput( fromTopBox );

	fromUnitBox = new UnitComboBox( fromTopBox, db );
	fromUnitBox->reload();
	fromTopBox->setStretchFactor( fromUnitBox, 2 );
	fromTopBox->setSpacing(3);

	KHBox *fromBottomBox = new KHBox(vbox);

	ingredientBox = new IngredientComboBox( false, fromBottomBox, db, i18n( "--Ingredient (optional)--" ) );
	ingredientBox->reload();

	prepMethodBox = new PrepMethodComboBox( false, fromBottomBox, db, i18n( "-No Preparation-" ) );
	prepMethodBox->reload();
	fromBottomBox->setSpacing(3);

	KHBox *toBox = new KHBox(vbox);

	toLabel = new QLabel( toBox );

	toUnitBox = new UnitComboBox( toBox, db );
	toUnitBox->reload();
	toBox->setStretchFactor( toUnitBox, 2 );
	toBox->setSpacing(8);

	KHBox *resultBox = new KHBox(vbox);
	resultLabel = new QLabel( resultBox );
	resultLabel->setObjectName( "resultLabel" );
	resultText = new QLabel( resultBox );
	resultText->setObjectName( "resultText" );
	resultBox->setStretchFactor( resultText, 2 );

	languageChange();

	setInitialSize( QSize(300, 200).expandedTo(minimumSizeHint()) );

	// signals and slots connections
	connect ( this, SIGNAL( closeClicked() ), this, SLOT( accept() ) );
	connect( this, SIGNAL( user1Clicked() ), this, SLOT( convert() ) );
}

ConversionDialog::~ConversionDialog()
{
}

void ConversionDialog::languageChange()
{
	convertLabel->setText( i18n( "Convert" ) );
	toLabel->setText( i18n( "To" ) );
	resultLabel->setText( i18n( "Result:" ) );
	resultText->setText( QString::null );
}

void ConversionDialog::show()
{
	reset();
	KDialog::show();
}

void ConversionDialog::reset()
{
	resultText->setText( QString::null );
	ingredientBox->setCurrentItem( 0 );
	prepMethodBox->setCurrentItem( 0 );
	toUnitBox->setCurrentItem( 0 );
	fromUnitBox->setCurrentItem( 0 );
	amountEdit->clear();
}

void ConversionDialog::convert()
{
	Ingredient result, ing;
	Unit unit = m_database->unitName(toUnitBox->id(toUnitBox->currentIndex()));

	ing.amount = amountEdit->value().toDouble();
	ing.ingredientID = ingredientBox->id(ingredientBox->currentIndex());
	ing.units = m_database->unitName(fromUnitBox->id(fromUnitBox->currentIndex()));

	int prepID = prepMethodBox->id(prepMethodBox->currentIndex());
	if ( prepID != -1 )
		ing.prepMethodList.append(Element(QString::null,prepID));

	switch ( m_database->convertIngredientUnits( ing, unit, result ) ) {
	case RecipeDB::Success:
		resultLabel->setText( i18n( "Result:" ) );
		resultText->setText(QString::number(result.amount)+" "+((result.amount>1)?result.units.plural:result.units.name));
		break;
	case RecipeDB::MismatchedPrepMethodUsingApprox:
		resultLabel->setText( i18n( "Approximated result:" ) );
		resultText->setText(QString::number(result.amount)+" "+((result.amount>1)?result.units.plural:result.units.name));
		break;
	case RecipeDB::MissingUnitConversion:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("Missing unit conversion") );
		break;
	case RecipeDB::MissingIngredientWeight:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("No ingredient weight available") );
		break;
	case RecipeDB::MismatchedPrepMethod:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("No ingredient weight available for this method of preparation") );
		break;
	case RecipeDB::MissingIngredient:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("Ingredient required for conversion") );
		break;
	case RecipeDB::InvalidTypes:
		resultLabel->setText( i18n( "Error:" ) );
		resultText->setText( i18n("Impossible unit conversion based on unit types") );
		break;
	}
}

#include "conversiondialog.moc"
<|endoftext|>


<commit_before>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2012 Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "edit-display-name-button.h"

#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLabel>

#include <KDE/KDialog>
#include <KDE/KLineEdit>
#include <KDE/KLocalizedString>
#include <KDE/KDebug>

#include <TelepathyQt/Account>
#include <TelepathyQt/PendingOperation>

class EditDisplayNameDialog : public KDialog
{
    Q_OBJECT
    Q_DISABLE_COPY(EditDisplayNameDialog)

public:
    EditDisplayNameDialog(const Tp::AccountPtr &account,
                          QWidget* parent = 0,
                          Qt::WFlags flags = 0);
    virtual ~EditDisplayNameDialog();

    QString displayName() const;

private:
    Tp::AccountPtr m_account;
    KLineEdit *m_displayNameLineEdit;
};

EditDisplayNameDialog::EditDisplayNameDialog(const Tp::AccountPtr &account,
                                             QWidget* parent,
                                             Qt::WFlags flags)
    : KDialog(parent, flags),
      m_account(account)
{
    setCaption(i18n("Edit Display Name"));
    setButtons( KDialog::Ok | KDialog::Cancel );
    setWindowIcon(KIcon(QLatin1String("telepathy-kde")));
    setFixedSize(400, 150);

    QWidget * mainWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout();
    QHBoxLayout *topLayout = new QHBoxLayout();

    QLabel *topLabel = new QLabel(i18n("Choose a new display name for your account"), this);
    topLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
    topLabel->setWordWrap(true);
    QFont font = topLabel->font();
    font.setBold(true);
    topLabel->setFont(font);

    QLabel *bottomLabel = new QLabel(i18n("A display name is your local alias for the account, only you will see it."), this);
    bottomLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
    bottomLabel->setWordWrap(true);

    QLabel *icon = new QLabel;
    icon->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    icon->setPixmap(KIcon(account->iconName()).pixmap(KIconLoader::SizeMedium));

    m_displayNameLineEdit = new KLineEdit(account->displayName(), this);
    m_displayNameLineEdit->setToolTip(i18n("New display name"));
    m_displayNameLineEdit->setWhatsThis(i18n("A display name is your local alias for the account, only you will see it."));

    topLayout->addWidget(topLabel);
    topLayout->addWidget(icon);

    mainLayout->addLayout(topLayout);
    mainLayout->addStretch();

    mainLayout->addWidget(m_displayNameLineEdit);
    mainLayout->addWidget(bottomLabel);
    mainLayout->addStretch();

    mainWidget->setLayout(mainLayout);
    setMainWidget(mainWidget);
}

EditDisplayNameDialog::~EditDisplayNameDialog()
{
}

QString EditDisplayNameDialog::displayName() const
{
    return m_displayNameLineEdit->text();
}

EditDisplayNameButton::EditDisplayNameButton(QWidget* parent) :
    KPushButton(parent)
{
    connect(this,
            SIGNAL(clicked(bool)),
            SLOT(onClicked()));
}

EditDisplayNameButton::~EditDisplayNameButton()
{
}

void EditDisplayNameButton::setAccount(const Tp::AccountPtr &account)
{
    m_account = account;
}

Tp::AccountPtr EditDisplayNameButton::account() const
{
    return m_account;
}

void EditDisplayNameButton::onClicked()
{
    if (!m_account.isNull() && m_account->isValid()) {
        EditDisplayNameDialog *dialog = new EditDisplayNameDialog(m_account, this);
        dialog->exec();
        if (dialog->result() == KDialog::Accepted && dialog->displayName() != m_account->displayName()) {
            kDebug() << "Setting display name" << dialog->displayName() << "for account" << account()->uniqueIdentifier();
            Tp::PendingOperation *op = m_account->setDisplayName(dialog->displayName());
            connect(op, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onFinished(Tp::PendingOperation*)));
        }
    }
}

void EditDisplayNameButton::onFinished(Tp::PendingOperation* op)
{
    if (op->isError()) {
        kWarning() << "Cannot set display name" << op->errorName() << op->errorMessage();
    }
}

#include "edit-display-name-button.moc"
#include "moc_edit-display-name-button.cpp"
<commit_msg>Fix potentially crashy code<commit_after>/*
 * This file is part of telepathy-accounts-kcm
 *
 * Copyright (C) 2012 Daniele E. Domenichelli <daniele.domenichelli@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "edit-display-name-button.h"

#include <QtGui/QHBoxLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLabel>

#include <KDE/KDialog>
#include <KDE/KLineEdit>
#include <KDE/KLocalizedString>
#include <KDE/KDebug>

#include <TelepathyQt/Account>
#include <TelepathyQt/PendingOperation>

class EditDisplayNameDialog : public KDialog
{
    Q_OBJECT
    Q_DISABLE_COPY(EditDisplayNameDialog)

public:
    EditDisplayNameDialog(const Tp::AccountPtr &account,
                          QWidget* parent = 0,
                          Qt::WFlags flags = 0);
    virtual ~EditDisplayNameDialog();

    QString displayName() const;

private:
    Tp::AccountPtr m_account;
    KLineEdit *m_displayNameLineEdit;
};

EditDisplayNameDialog::EditDisplayNameDialog(const Tp::AccountPtr &account,
                                             QWidget* parent,
                                             Qt::WFlags flags)
    : KDialog(parent, flags),
      m_account(account)
{
    setCaption(i18n("Edit Display Name"));
    setButtons( KDialog::Ok | KDialog::Cancel );
    setWindowIcon(KIcon(QLatin1String("telepathy-kde")));
    setFixedSize(400, 150);

    QWidget * mainWidget = new QWidget(this);
    QVBoxLayout *mainLayout = new QVBoxLayout();
    QHBoxLayout *topLayout = new QHBoxLayout();

    QLabel *topLabel = new QLabel(i18n("Choose a new display name for your account"), this);
    topLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
    topLabel->setWordWrap(true);
    QFont font = topLabel->font();
    font.setBold(true);
    topLabel->setFont(font);

    QLabel *bottomLabel = new QLabel(i18n("A display name is your local alias for the account, only you will see it."), this);
    bottomLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
    bottomLabel->setWordWrap(true);

    QLabel *icon = new QLabel;
    icon->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    icon->setPixmap(KIcon(account->iconName()).pixmap(KIconLoader::SizeMedium));

    m_displayNameLineEdit = new KLineEdit(account->displayName(), this);
    m_displayNameLineEdit->setToolTip(i18n("New display name"));
    m_displayNameLineEdit->setWhatsThis(i18n("A display name is your local alias for the account, only you will see it."));

    topLayout->addWidget(topLabel);
    topLayout->addWidget(icon);

    mainLayout->addLayout(topLayout);
    mainLayout->addStretch();

    mainLayout->addWidget(m_displayNameLineEdit);
    mainLayout->addWidget(bottomLabel);
    mainLayout->addStretch();

    mainWidget->setLayout(mainLayout);
    setMainWidget(mainWidget);
}

EditDisplayNameDialog::~EditDisplayNameDialog()
{
}

QString EditDisplayNameDialog::displayName() const
{
    return m_displayNameLineEdit->text();
}

EditDisplayNameButton::EditDisplayNameButton(QWidget* parent) :
    KPushButton(parent)
{
    connect(this,
            SIGNAL(clicked(bool)),
            SLOT(onClicked()));
}

EditDisplayNameButton::~EditDisplayNameButton()
{
}

void EditDisplayNameButton::setAccount(const Tp::AccountPtr &account)
{
    m_account = account;
}

Tp::AccountPtr EditDisplayNameButton::account() const
{
    return m_account;
}

void EditDisplayNameButton::onClicked()
{
    if (!m_account.isNull() && m_account->isValid()) {
        QWeakPointer<EditDisplayNameDialog> dialog = new EditDisplayNameDialog(m_account, this);
        dialog.data()->exec();
        if (!dialog.isNull()) {
            if (dialog.data()->result() == KDialog::Accepted && dialog.data()->displayName() != m_account->displayName()) {
                kDebug() << "Setting display name" << dialog.data()->displayName() << "for account" << account()->uniqueIdentifier();
                Tp::PendingOperation *op = m_account->setDisplayName(dialog.data()->displayName());
                connect(op, SIGNAL(finished(Tp::PendingOperation*)), SLOT(onFinished(Tp::PendingOperation*)));
            }
            dialog.data()->deleteLater();
        }
    }
}

void EditDisplayNameButton::onFinished(Tp::PendingOperation* op)
{
    if (op->isError()) {
        kWarning() << "Cannot set display name" << op->errorName() << op->errorMessage();
    }
}

#include "edit-display-name-button.moc"
#include "moc_edit-display-name-button.cpp"
<|endoftext|>


<commit_before>// addon.cc
#include <list>
#include <string>
#include <chrono>
#include <thread>
#include <iostream>
#include <functional>

#include <node.h>

#include "DHT22.h"
#include "PIR.h"
#include "TSL2561.h"
#include "BMP180.h"
#include "sensor_result.h"
#include "scheduler.h"

using namespace v8;

/**
 * Init a sensor based of the V8 object given. If no sensor could be created, nullptr is returned. Will throw
 * exception if any error occured during the creation of the sensor
 * @param  sensorName   The name of the sensor
 * @param  sensorConfig The sensor configuration. Must contains the type of sensor
 * @return              The created sensor, or nullptr
 */
sensor::sensor* InitSensor(const Local<String>& sensorName, const Local<Object>& sensorConfig) {
    Isolate* isolate = Isolate::GetCurrent();

    // String used in the method
    const Local<String> pin = String::NewFromUtf8(isolate, "pin");
    const Local<String> addr = String::NewFromUtf8(isolate, "address");
    const Local<String> t = String::NewFromUtf8(isolate, "type");
    const Local<String> freq = String::NewFromUtf8(isolate, "frequence");

    if(!sensorConfig->Has(freq) || !sensorConfig->Get(freq)->IsNumber())
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : all sensors require a valid 'frequence' property (number >= 0)"));

    if(!sensorConfig->Has(t) || !sensorConfig->Get(t)->IsString())
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : no type specified. All sensors require a valid 'type' property"));

    // Get the sensor name
    String::Utf8Value nameValue(sensorName->ToString());
    const std::string name = std::string(*nameValue);

    // Get the type of sensor
    const Local<Value> jsvalue = sensorConfig->Get(t);
    String::Utf8Value value(jsvalue->ToString());
    const std::string type = std::string(*value);

    // Get the frequence
    const Local<Value> jsFrequence = sensorConfig->Get(freq);
    int frequence = (int) jsFrequence->NumberValue();

    // Only type is required
    if (type == "DHT22") {
        // Get the pin
        if(!sensorConfig->Has(pin) || !sensorConfig->Get(pin)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : DHT22 require a valid 'pin' property (number > 0)"));
        }

        Local<Number> pinValue = Local<Number>::Cast(sensorConfig->Get(pin));

        std::cout << "Sensor of type DHT22 created" << std::endl;
        return (sensor::sensor*) new sensor::DHT22_sensor((unsigned) pinValue->NumberValue(), frequence, name);
    } else if (type == "PIR") {
        // Get the pin
        if(!sensorConfig->Has(pin) || !sensorConfig->Get(pin)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : PIR require a valid 'pin' property (number > 0)"));
        }

        Local<Number> pinValue = Local<Number>::Cast(sensorConfig->Get(pin));

        std::cout << "Sensor of type PIR created" << std::endl;
        return (sensor::sensor*) new sensor::PIR_sensor((unsigned) pinValue->NumberValue(), frequence, name);
    }
    else if (type == "TSL2561") {
        // Get the address
        if(!sensorConfig->Has(addr) || !sensorConfig->Get(addr)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : TSL2561 require a valid 'address' property (number > 0)"));
        }

        Local<Number> addrValue = Local<Number>::Cast(sensorConfig->Get(addr));

        std::cout << "Sensor of type TSL2561 created" << std::endl;
        return (sensor::sensor*) new sensor::TSL2561_sensor((uint16_t) addrValue->NumberValue(), frequence, name);
    }
    else if (type == "BMP180") {
        // Get the address
        if(!sensorConfig->Has(addr) || !sensorConfig->Get(addr)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : BMP180 require a valid 'address' property (number > 0)"));
        }

        Local<Number> addrValue = Local<Number>::Cast(sensorConfig->Get(addr));

        std::cout << "Sensor of type BMP180 created" << std::endl;
        return (sensor::sensor*) new sensor::BMP180_sensor((uint16_t) addrValue->NumberValue(), frequence, name);
    }
    else {
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : invalid sensor type"));
    }

    return nullptr;
}

/**
 * For now, main method of the NodeJS plugin
 * @param args The arguments used to call the method. Must contains a callbacks and a V8 object
 */
void RunCallback(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    std::list<sensor::sensor*> sensors;

    try {
        // Check that all the parameters are good
        if (args.Length() < 2)
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : Wrong number of arguments : two are required"));

        if (!args[0]->IsFunction() || !args[1]->IsObject())
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : Wrong argument(s) : first must be a callback, and the second must be the configuration"));

        // Get elements
        Local<Function> cb = Local<Function>::Cast(args[0]);
        Local<Object> options = Local<Object>::Cast(args[1]);

        Persistent<Function, CopyablePersistentTraits<Function>> callback(isolate, cb);

        // Iter on each property
        const Local<Array> props = options->GetPropertyNames();
        const uint32_t length = props->Length();

        for (uint32_t i = 0 ; i < length ; i++) {
            const Local<Value> key = props->Get(i);
            const Local<Value> value = options->Get(key);

            // Init the sensor
            sensor::sensor* s = InitSensor(key->ToString(), value->ToObject());

            if(s != nullptr) {
                s->initialize();
                sensors.push_back(s);
            }
        }

        // Create & launch the main scheduler
        sensor::scheduler* handler = new sensor::scheduler(sensors, [callback, isolate](sensor::sensor* s, sensor::result* r) {
            // Get the type of value & the value
            Local<Object> result = Object::New(isolate);

            Local<String> type;
            Local<String> unit;
            Local<String> unit_display;
            Local<Number> value;

            // Local reference of the callback
            Local<Function> cb = Local<Function>::New(isolate, callback);

            if(r->getType() == sensor::resultType::TEMPERATURE) {
                type = String::NewFromUtf8(isolate, "Temperature");
                unit = String::NewFromUtf8(isolate, "Degree Celsius");
                unit_display = String::NewFromUtf8(isolate, "°C");
                value = Number::New(isolate, r->getValue().f);
            }
            else if(r->getType() == sensor::resultType::HUMIDITY) {
                type = String::NewFromUtf8(isolate, "Humidity");
                unit = String::NewFromUtf8(isolate, "Percent");
                unit_display = String::NewFromUtf8(isolate, "%");
                value = Number::New(isolate, r->getValue().f);
            }
            else if(r->getType() == sensor::resultType::LIGHT) {
                type = String::NewFromUtf8(isolate, "Light");
                unit = String::NewFromUtf8(isolate, "Lux");
                unit_display = String::NewFromUtf8(isolate, "Lux");
                value = Number::New(isolate, r->getValue().i);
            }
            else if(r->getType() == sensor::resultType::PRESSURE) {
                type = String::NewFromUtf8(isolate, "Pressure");
                unit = String::NewFromUtf8(isolate, "Pascal");
                unit_display = String::NewFromUtf8(isolate, "Pa");
                value = Number::New(isolate, r->getValue().f);
            }
            else if(r->getType() == sensor::resultType::DETECTION) {
                type = String::NewFromUtf8(isolate, "Detection");
                unit = String::NewFromUtf8(isolate, "Boolean");
                unit_display = String::NewFromUtf8(isolate, "Boolean");
                value = Number::New(isolate, r->getValue().i);
            }
            else {
                type = String::NewFromUtf8(isolate, "Other");
                unit = String::NewFromUtf8(isolate, "-");
                unit_display = String::NewFromUtf8(isolate, "");
                value = Number::New(isolate, 0);
            }

            result->Set(String::NewFromUtf8(isolate, "type"), type);
            result->Set(String::NewFromUtf8(isolate, "unit"), unit);
            result->Set(String::NewFromUtf8(isolate, "unit_display"), unit_display);
            result->Set(String::NewFromUtf8(isolate, "value"), value);
            result->Set(String::NewFromUtf8(isolate, "date"), Date::New(isolate, r->getTimestamp()));
            result->Set(String::NewFromUtf8(isolate, "timestamp"), Number::New(isolate, r->getTimestamp()));
            result->Set(String::NewFromUtf8(isolate, "sensor_name"), String::NewFromUtf8(isolate, s->getName().c_str()));
            result->Set(String::NewFromUtf8(isolate, "sensor_type"), String::NewFromUtf8(isolate, s->getType().c_str()));

            // Call the callback with the values
            Local<Value> argv[1] = { result };
            cb->Call(isolate->GetCurrentContext()->Global(), 1, argv);
        });

        handler->launch();

    } catch(Local<Value> &e) {
        // If we catch any error error here, then no thread are launched : everything can be free'd
        // TODO free every sensor

        // Transfer the exception to node
        isolate->ThrowException(e);
    }
}

void Init(Handle<Object> exports, Handle<Object> module) {
    NODE_SET_METHOD(module, "exports", RunCallback);
}

// TODO handle destructor ?

NODE_MODULE(meteonetwork, Init)
<commit_msg>Tests for cleaner initialization<commit_after>// addon.cc
#include <list>
#include <string>
#include <chrono>
#include <thread>
#include <iostream>
#include <functional>

#include <node.h>

#include "DHT22.h"
#include "PIR.h"
#include "TSL2561.h"
#include "BMP180.h"
#include "sensor_result.h"
#include "scheduler.h"

using namespace v8;

enum SensorType { GPIO, I2C };

struct SensorConf {
    std::string model;
    SensorType type;
    //std::function<int (std::string&, int)> factory;
};

const struct SensorConf conf[] = {
    {
        type   : "DHT22",
        bus    : GPIO
        //factory : test
    },
    {
        type   : "PIR",
        bus    : GPIO
        //factory : test
    },
    {
        type   : "TSL2561",
        bus    : I2C
        //factory : test
    }
};

sensor::sensor* InitSensor2(const Local<String>& sensorName, const Local<Object>& sensorConfig) {
    Isolate* isolate = Isolate::GetCurrent();

    // String used in the method
    const Local<String> pin = String::NewFromUtf8(isolate, "pin");
    const Local<String> addr = String::NewFromUtf8(isolate, "address");
    const Local<String> t = String::NewFromUtf8(isolate, "type");

    // Check for type
    if(!sensorConfig->Has(t) || !sensorConfig->Get(t)->IsString())
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : no type specified. All sensors require a valid 'type' property"));

    // Get the type of sensor
    const Local<Value> jsvalue = sensorConfig->Get(t);
    String::Utf8Value value(jsvalue->ToString());
    const std::string type = std::string(*value);

    const size_t size = std::extent<decltype(conf)>::value;

    for(size_t i = 0; i < size; i++) {
        if(conf[i].type == type) {
            std::cout << "Found " << conf[i].type << std::endl;
            break;
        }
    }
}

/**
 * Init a sensor based of the V8 object given. If no sensor could be created, nullptr is returned. Will throw
 * exception if any error occured during the creation of the sensor
 * @param  sensorName   The name of the sensor
 * @param  sensorConfig The sensor configuration. Must contains the type of sensor
 * @return              The created sensor, or nullptr
 */
sensor::sensor* InitSensor(const Local<String>& sensorName, const Local<Object>& sensorConfig) {
    Isolate* isolate = Isolate::GetCurrent();

    // String used in the method
    const Local<String> pin = String::NewFromUtf8(isolate, "pin");
    const Local<String> addr = String::NewFromUtf8(isolate, "address");
    const Local<String> t = String::NewFromUtf8(isolate, "type");
    const Local<String> freq = String::NewFromUtf8(isolate, "frequence");

    if(!sensorConfig->Has(freq) || !sensorConfig->Get(freq)->IsNumber())
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : all sensors require a valid 'frequence' property (number >= 0)"));

    if(!sensorConfig->Has(t) || !sensorConfig->Get(t)->IsString())
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : no type specified. All sensors require a valid 'type' property"));

    // Get the sensor name
    String::Utf8Value nameValue(sensorName->ToString());
    const std::string name = std::string(*nameValue);

    // Get the type of sensor
    const Local<Value> jsvalue = sensorConfig->Get(t);
    String::Utf8Value value(jsvalue->ToString());
    const std::string type = std::string(*value);

    // Get the frequence
    const Local<Value> jsFrequence = sensorConfig->Get(freq);
    int frequence = (int) jsFrequence->NumberValue();

    // Only type is required
    if (type == "DHT22") {
        // Get the pin
        if(!sensorConfig->Has(pin) || !sensorConfig->Get(pin)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : DHT22 require a valid 'pin' property (number > 0)"));
        }

        Local<Number> pinValue = Local<Number>::Cast(sensorConfig->Get(pin));

        std::cout << "Sensor of type DHT22 created" << std::endl;
        return (sensor::sensor*) new sensor::DHT22_sensor((unsigned) pinValue->NumberValue(), frequence, name);
    } else if (type == "PIR") {
        // Get the pin
        if(!sensorConfig->Has(pin) || !sensorConfig->Get(pin)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : PIR require a valid 'pin' property (number > 0)"));
        }

        Local<Number> pinValue = Local<Number>::Cast(sensorConfig->Get(pin));

        std::cout << "Sensor of type PIR created" << std::endl;
        return (sensor::sensor*) new sensor::PIR_sensor((unsigned) pinValue->NumberValue(), frequence, name);
    }
    else if (type == "TSL2561") {
        // Get the address
        if(!sensorConfig->Has(addr) || !sensorConfig->Get(addr)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : TSL2561 require a valid 'address' property (number > 0)"));
        }

        Local<Number> addrValue = Local<Number>::Cast(sensorConfig->Get(addr));

        std::cout << "Sensor of type TSL2561 created" << std::endl;
        return (sensor::sensor*) new sensor::TSL2561_sensor((uint16_t) addrValue->NumberValue(), frequence, name);
    }
    else if (type == "BMP180") {
        // Get the address
        if(!sensorConfig->Has(addr) || !sensorConfig->Get(addr)->IsNumber()) {
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : BMP180 require a valid 'address' property (number > 0)"));
        }

        Local<Number> addrValue = Local<Number>::Cast(sensorConfig->Get(addr));

        std::cout << "Sensor of type BMP180 created" << std::endl;
        return (sensor::sensor*) new sensor::BMP180_sensor((uint16_t) addrValue->NumberValue(), frequence, name);
    }
    else {
        throw Exception::TypeError(
            String::NewFromUtf8(isolate, "Error : invalid sensor type"));
    }

    return nullptr;
}

/**
 * For now, main method of the NodeJS plugin
 * @param args The arguments used to call the method. Must contains a callbacks and a V8 object
 */
void RunCallback(const FunctionCallbackInfo<Value>& args) {
    Isolate* isolate = Isolate::GetCurrent();
    HandleScope scope(isolate);

    std::list<sensor::sensor*> sensors;

    try {
        // Check that all the parameters are good
        if (args.Length() < 2)
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : Wrong number of arguments : two are required"));

        if (!args[0]->IsFunction() || !args[1]->IsObject())
            throw Exception::TypeError(
                String::NewFromUtf8(isolate, "Error : Wrong argument(s) : first must be a callback, and the second must be the configuration"));

        // Get elements
        Local<Function> cb = Local<Function>::Cast(args[0]);
        Local<Object> options = Local<Object>::Cast(args[1]);

        Persistent<Function, CopyablePersistentTraits<Function>> callback(isolate, cb);

        // Iter on each property
        const Local<Array> props = options->GetPropertyNames();
        const uint32_t length = props->Length();

        for (uint32_t i = 0 ; i < length ; i++) {
            const Local<Value> key = props->Get(i);
            const Local<Value> value = options->Get(key);

            // Init the sensor
            InitSensor2(key->ToString(), value->ToObject());
            sensor::sensor* s = InitSensor(key->ToString(), value->ToObject());

            if(s != nullptr) {
                s->initialize();
                sensors.push_back(s);
            }
        }

        // Create & launch the main scheduler
        sensor::scheduler* handler = new sensor::scheduler(sensors, [callback, isolate](sensor::sensor* s, sensor::result* r) {
            // Get the type of value & the value
            Local<Object> result = Object::New(isolate);

            Local<String> type;
            Local<String> unit;
            Local<String> unit_display;
            Local<Number> value;

            // Local reference of the callback
            Local<Function> cb = Local<Function>::New(isolate, callback);

            if(r->getType() == sensor::resultType::TEMPERATURE) {
                type = String::NewFromUtf8(isolate, "Temperature");
                unit = String::NewFromUtf8(isolate, "Degree Celsius");
                unit_display = String::NewFromUtf8(isolate, "°C");
                value = Number::New(isolate, r->getValue().f);
            }
            else if(r->getType() == sensor::resultType::HUMIDITY) {
                type = String::NewFromUtf8(isolate, "Humidity");
                unit = String::NewFromUtf8(isolate, "Percent");
                unit_display = String::NewFromUtf8(isolate, "%");
                value = Number::New(isolate, r->getValue().f);
            }
            else if(r->getType() == sensor::resultType::LIGHT) {
                type = String::NewFromUtf8(isolate, "Light");
                unit = String::NewFromUtf8(isolate, "Lux");
                unit_display = String::NewFromUtf8(isolate, "Lux");
                value = Number::New(isolate, r->getValue().i);
            }
            else if(r->getType() == sensor::resultType::PRESSURE) {
                type = String::NewFromUtf8(isolate, "Pressure");
                unit = String::NewFromUtf8(isolate, "Pascal");
                unit_display = String::NewFromUtf8(isolate, "Pa");
                value = Number::New(isolate, r->getValue().f);
            }
            else if(r->getType() == sensor::resultType::DETECTION) {
                type = String::NewFromUtf8(isolate, "Detection");
                unit = String::NewFromUtf8(isolate, "Boolean");
                unit_display = String::NewFromUtf8(isolate, "Boolean");
                value = Number::New(isolate, r->getValue().i);
            }
            else {
                type = String::NewFromUtf8(isolate, "Other");
                unit = String::NewFromUtf8(isolate, "-");
                unit_display = String::NewFromUtf8(isolate, "");
                value = Number::New(isolate, 0);
            }

            result->Set(String::NewFromUtf8(isolate, "type"), type);
            result->Set(String::NewFromUtf8(isolate, "unit"), unit);
            result->Set(String::NewFromUtf8(isolate, "unit_display"), unit_display);
            result->Set(String::NewFromUtf8(isolate, "value"), value);
            result->Set(String::NewFromUtf8(isolate, "date"), Date::New(isolate, r->getTimestamp()));
            result->Set(String::NewFromUtf8(isolate, "timestamp"), Number::New(isolate, r->getTimestamp()));
            result->Set(String::NewFromUtf8(isolate, "sensor_name"), String::NewFromUtf8(isolate, s->getName().c_str()));
            result->Set(String::NewFromUtf8(isolate, "sensor_type"), String::NewFromUtf8(isolate, s->getType().c_str()));

            // Call the callback with the values
            Local<Value> argv[1] = { result };
            cb->Call(isolate->GetCurrentContext()->Global(), 1, argv);
        });

        handler->launch();

    } catch(Local<Value> &e) {
        // If we catch any error error here, then no thread are launched : everything can be free'd
        // TODO free every sensor

        // Transfer the exception to node
        isolate->ThrowException(e);
    }
}

void Init(Handle<Object> exports, Handle<Object> module) {
    NODE_SET_METHOD(module, "exports", RunCallback);
}

// TODO handle destructor ?

NODE_MODULE(meteonetwork, Init)
<|endoftext|>


<commit_before>#include "SkArithmeticMode.h"
#include "SkColorPriv.h"
#include "SkUnPreMultiply.h"

class SkArithmeticMode_scalar : public SkXfermode {
public:
    SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) {
        fK[0] = k1;
        fK[1] = k2;
        fK[2] = k3;
        fK[3] = k4;
    }

    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                        const SkAlpha aa[]) SK_OVERRIDE;

    SK_DECLARE_UNFLATTENABLE_OBJECT()

private:
    SkScalar fK[4];
};

static int pinToByte(int value) {
    if (value < 0) {
        value = 0;
    } else if (value > 255) {
        value = 255;
    }
    return value;
}

static int arith(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
                 int src, int dst) {
    SkScalar result = SkScalarMul(k1, src * dst) +
                      SkScalarMul(k2, src) +
                      SkScalarMul(k3, dst) +
                      k4;
    int res = SkScalarRoundToInt(result);
    return pinToByte(res);
}

static int blend(int src, int dst, int scale) {
    return dst + ((src - dst) * scale >> 8);
}

static bool needsUnpremul(int alpha) {
    return 0 != alpha && 0xFF != alpha;
}

void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[],
                                     int count, const SkAlpha aaCoverage[]) {
    SkScalar k1 = fK[0] / 255;
    SkScalar k2 = fK[1];
    SkScalar k3 = fK[2];
    SkScalar k4 = fK[3] * 255;

    for (int i = 0; i < count; ++i) {
        if ((NULL == aaCoverage) || aaCoverage[i]) {
            SkPMColor sc = src[i];
            SkPMColor dc = dst[i];
            int sa = SkGetPackedA32(sc);
            int da = SkGetPackedA32(dc);

            int srcNeedsUnpremul = needsUnpremul(sa);
            int dstNeedsUnpremul = needsUnpremul(sa);

            int a, r, g, b;

            if (!srcNeedsUnpremul && !dstNeedsUnpremul) {
                a = arith(k1, k2, k3, k4, sa, sa);
                r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc));
                g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc));
                b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc));
            } else {
                int sr = SkGetPackedR32(sc);
                int sg = SkGetPackedG32(sc);
                int sb = SkGetPackedB32(sc);
                if (srcNeedsUnpremul) {
                    SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(sa);
                    sr = SkUnPreMultiply::ApplyScale(scale, sr);
                    sg = SkUnPreMultiply::ApplyScale(scale, sg);
                    sb = SkUnPreMultiply::ApplyScale(scale, sb);
                }

                int dr = SkGetPackedR32(dc);
                int dg = SkGetPackedG32(dc);
                int db = SkGetPackedB32(dc);
                if (dstNeedsUnpremul) {
                    SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(da);
                    dr = SkUnPreMultiply::ApplyScale(scale, dr);
                    dg = SkUnPreMultiply::ApplyScale(scale, dg);
                    db = SkUnPreMultiply::ApplyScale(scale, db);
                }

                a = arith(k1, k2, k3, k4, sa, sa);
                r = arith(k1, k2, k3, k4, sr, dr);
                g = arith(k1, k2, k3, k4, sg, dg);
                b = arith(k1, k2, k3, k4, sb, db);
            }

            // apply antialias coverage if necessary
            if (aaCoverage && 0xFF != aaCoverage[i]) {
                int scale = aaCoverage[i] + (aaCoverage[i] >> 7);
                a = blend(a, SkGetPackedA32(sc), scale);
                r = blend(r, SkGetPackedR32(sc), scale);
                g = blend(g, SkGetPackedG32(sc), scale);
                b = blend(b, SkGetPackedB32(sc), scale);
            }

            // turn the result back into premul
            if (0xFF != a) {
                int scale = a + (a >> 7);
                r = SkAlphaMul(r, scale);
                g = SkAlphaMul(g, scale);
                b = SkAlphaMul(b, scale);
            }
            dst[i] = SkPackARGB32(a, r, g, b);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

static bool fitsInBits(SkScalar x, int bits) {
#ifdef SK_SCALAR_IS_FIXED
    x = SkAbs32(x);
    x += 1 << 7;
    x >>= 8;
    return x < (1 << (bits - 1));
#else
    return SkScalarAbs(x) < (1 << (bits - 1));
#endif
}

#if 0 // UNUSED
static int32_t toDot8(SkScalar x) {
#ifdef SK_SCALAR_IS_FIXED
    x += 1 << 7;
    x >>= 8;
    return x;
#else
    return (int32_t)(x * 256);
#endif
}
#endif

SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2,
                                     SkScalar k3, SkScalar k4) {
    if (fitsInBits(k1, 8) && fitsInBits(k2, 16) &&
        fitsInBits(k2, 16) && fitsInBits(k2, 24)) {

#if 0 // UNUSED
        int32_t i1 = toDot8(k1);
        int32_t i2 = toDot8(k2);
        int32_t i3 = toDot8(k3);
        int32_t i4 = toDot8(k4);
        if (i1) {
            return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4));
        }
        if (0 == i2) {
            return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4));
        }
        if (0 == i3) {
            return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4));
        }
        return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4));
#endif
    }
    return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4));
}

<commit_msg>use premul macro to pack components<commit_after>#include "SkArithmeticMode.h"
#include "SkColorPriv.h"
#include "SkUnPreMultiply.h"

class SkArithmeticMode_scalar : public SkXfermode {
public:
    SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) {
        fK[0] = k1;
        fK[1] = k2;
        fK[2] = k3;
        fK[3] = k4;
    }

    virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
                        const SkAlpha aa[]) SK_OVERRIDE;

    SK_DECLARE_UNFLATTENABLE_OBJECT()

private:
    SkScalar fK[4];
};

static int pinToByte(int value) {
    if (value < 0) {
        value = 0;
    } else if (value > 255) {
        value = 255;
    }
    return value;
}

static int arith(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
                 int src, int dst) {
    SkScalar result = SkScalarMul(k1, src * dst) +
                      SkScalarMul(k2, src) +
                      SkScalarMul(k3, dst) +
                      k4;
    int res = SkScalarRoundToInt(result);
    return pinToByte(res);
}

static int blend(int src, int dst, int scale) {
    return dst + ((src - dst) * scale >> 8);
}

static bool needsUnpremul(int alpha) {
    return 0 != alpha && 0xFF != alpha;
}

void SkArithmeticMode_scalar::xfer32(SkPMColor dst[], const SkPMColor src[],
                                     int count, const SkAlpha aaCoverage[]) {
    SkScalar k1 = fK[0] / 255;
    SkScalar k2 = fK[1];
    SkScalar k3 = fK[2];
    SkScalar k4 = fK[3] * 255;

    for (int i = 0; i < count; ++i) {
        if ((NULL == aaCoverage) || aaCoverage[i]) {
            SkPMColor sc = src[i];
            SkPMColor dc = dst[i];
            int sa = SkGetPackedA32(sc);
            int da = SkGetPackedA32(dc);

            int srcNeedsUnpremul = needsUnpremul(sa);
            int dstNeedsUnpremul = needsUnpremul(sa);

            int a, r, g, b;

            if (!srcNeedsUnpremul && !dstNeedsUnpremul) {
                a = arith(k1, k2, k3, k4, sa, sa);
                r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc));
                g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc));
                b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc));
            } else {
                int sr = SkGetPackedR32(sc);
                int sg = SkGetPackedG32(sc);
                int sb = SkGetPackedB32(sc);
                if (srcNeedsUnpremul) {
                    SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(sa);
                    sr = SkUnPreMultiply::ApplyScale(scale, sr);
                    sg = SkUnPreMultiply::ApplyScale(scale, sg);
                    sb = SkUnPreMultiply::ApplyScale(scale, sb);
                }

                int dr = SkGetPackedR32(dc);
                int dg = SkGetPackedG32(dc);
                int db = SkGetPackedB32(dc);
                if (dstNeedsUnpremul) {
                    SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(da);
                    dr = SkUnPreMultiply::ApplyScale(scale, dr);
                    dg = SkUnPreMultiply::ApplyScale(scale, dg);
                    db = SkUnPreMultiply::ApplyScale(scale, db);
                }

                a = arith(k1, k2, k3, k4, sa, sa);
                r = arith(k1, k2, k3, k4, sr, dr);
                g = arith(k1, k2, k3, k4, sg, dg);
                b = arith(k1, k2, k3, k4, sb, db);
            }

            // apply antialias coverage if necessary
            if (aaCoverage && 0xFF != aaCoverage[i]) {
                int scale = aaCoverage[i] + (aaCoverage[i] >> 7);
                a = blend(a, SkGetPackedA32(sc), scale);
                r = blend(r, SkGetPackedR32(sc), scale);
                g = blend(g, SkGetPackedG32(sc), scale);
                b = blend(b, SkGetPackedB32(sc), scale);
            }

            dst[i] = SkPremultiplyARGBInline(a, r, g, b);
        }
    }
}

///////////////////////////////////////////////////////////////////////////////

static bool fitsInBits(SkScalar x, int bits) {
#ifdef SK_SCALAR_IS_FIXED
    x = SkAbs32(x);
    x += 1 << 7;
    x >>= 8;
    return x < (1 << (bits - 1));
#else
    return SkScalarAbs(x) < (1 << (bits - 1));
#endif
}

#if 0 // UNUSED
static int32_t toDot8(SkScalar x) {
#ifdef SK_SCALAR_IS_FIXED
    x += 1 << 7;
    x >>= 8;
    return x;
#else
    return (int32_t)(x * 256);
#endif
}
#endif

SkXfermode* SkArithmeticMode::Create(SkScalar k1, SkScalar k2,
                                     SkScalar k3, SkScalar k4) {
    if (fitsInBits(k1, 8) && fitsInBits(k2, 16) &&
        fitsInBits(k2, 16) && fitsInBits(k2, 24)) {

#if 0 // UNUSED
        int32_t i1 = toDot8(k1);
        int32_t i2 = toDot8(k2);
        int32_t i3 = toDot8(k3);
        int32_t i4 = toDot8(k4);
        if (i1) {
            return SkNEW_ARGS(SkArithmeticMode_quad, (i1, i2, i3, i4));
        }
        if (0 == i2) {
            return SkNEW_ARGS(SkArithmeticMode_dst, (i3, i4));
        }
        if (0 == i3) {
            return SkNEW_ARGS(SkArithmeticMode_src, (i2, i4));
        }
        return SkNEW_ARGS(SkArithmeticMode_linear, (i2, i3, i4));
#endif
    }
    return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4));
}

<|endoftext|>