<commit_before>#include "gm.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "SkXfermode.h"

namespace skiagm {

static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
    src->setConfig(SkBitmap::kARGB_8888_Config, w, h);
    src->allocPixels();
    src->eraseColor(0);

    SkCanvas c(*src);
    SkPaint p;
    SkRect r;
    SkScalar ww = SkIntToScalar(w);
    SkScalar hh = SkIntToScalar(h);

    p.setAntiAlias(true);
    p.setColor(0xFFFFCC44);
    r.set(0, 0, ww*3/4, hh*3/4);
    c.drawOval(r, p);

    dst->setConfig(SkBitmap::kARGB_8888_Config, w, h);
    dst->allocPixels();
    dst->eraseColor(0);
    c.setBitmapDevice(*dst);

    p.setColor(0xFF66AAFF);
    r.set(ww/3, hh/3, ww*19/20, hh*19/20);
    c.drawRect(r, p);
}

static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };

class XfermodesGM : public GM {
    SkBitmap    fBitmap;
    SkBitmap    fBG;
    SkBitmap    fSrcB, fDstB;

    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha) {
        SkPaint p;

        canvas->drawBitmap(fSrcB, 0, 0, &p);
        p.setAlpha(alpha);
        p.setXfermode(mode);
        canvas->drawBitmap(fDstB, 0, 0, &p);
    }

public:
	XfermodesGM() {
        const int W = 64;
        const int H = 64;

        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, W, H);
        fBitmap.allocPixels();

        fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
        fBG.setPixels(gBG);
        fBG.setIsOpaque(true);

        make_bitmaps(W, H, &fSrcB, &fDstB);
    }

protected:
    SkString onShortName() {
        return SkString("xfermodes");
    }

	SkISize onISize() { return make_isize(640, 380); }

    void drawBG(SkCanvas* canvas) {
        canvas->drawColor(SK_ColorWHITE);
        return;
        SkShader* s = SkShader::CreateBitmapShader(fBG,
                                                   SkShader::kRepeat_TileMode,
                                                   SkShader::kRepeat_TileMode);
        SkPaint p;
        SkMatrix m;

        p.setShader(s)->unref();
        m.setScale(SkIntToScalar(8), SkIntToScalar(8));
        s->setLocalMatrix(m);
        canvas->drawPaint(p);
    }

    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);

        const struct {
            SkPorterDuff::Mode  fMode;
            const char*         fLabel;
        } gModes[] = {
            { SkPorterDuff::kClear_Mode,    "Clear"     },
            { SkPorterDuff::kSrc_Mode,      "Src"       },
            { SkPorterDuff::kDst_Mode,      "Dst"       },
            { SkPorterDuff::kSrcOver_Mode,  "SrcOver"   },
            { SkPorterDuff::kDstOver_Mode,  "DstOver"   },
            { SkPorterDuff::kSrcIn_Mode,    "SrcIn"     },
            { SkPorterDuff::kDstIn_Mode,    "DstIn"     },
            { SkPorterDuff::kSrcOut_Mode,   "SrcOut"    },
            { SkPorterDuff::kDstOut_Mode,   "DstOut"    },
            { SkPorterDuff::kSrcATop_Mode,  "SrcATop"   },
            { SkPorterDuff::kDstATop_Mode,  "DstATop"   },
            { SkPorterDuff::kXor_Mode,      "Xor"       },
            { SkPorterDuff::kDarken_Mode,   "Darken"    },
            { SkPorterDuff::kLighten_Mode,  "Lighten"   },
            { SkPorterDuff::kMultiply_Mode, "Multiply"  },
            { SkPorterDuff::kScreen_Mode,   "Screen"    }
        };

        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));

        SkCanvas c(fBitmap);
        const SkScalar w = SkIntToScalar(fBitmap.width());
        const SkScalar h = SkIntToScalar(fBitmap.height());
        SkShader* s = SkShader::CreateBitmapShader(fBG,
                                                   SkShader::kRepeat_TileMode,
                                                   SkShader::kRepeat_TileMode);
        SkMatrix m;
        m.setScale(SkIntToScalar(6), SkIntToScalar(6));
        s->setLocalMatrix(m);

        SkPaint labelP;
        labelP.setAntiAlias(true);
        labelP.setTextAlign(SkPaint::kCenter_Align);

        SkScalar x0 = 0;
        for (int twice = 0; twice < 2; twice++) {
            SkScalar x = x0, y = 0;
            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
                SkXfermode* mode = SkPorterDuff::CreateXfermode(gModes[i].fMode);

                fBitmap.eraseColor(0);
                draw_mode(&c, mode, twice ? 0x88 : 0xFF);
                mode->safeUnref();

                SkPaint p;
                SkRect r;
                r.set(x, y, x+w, y+h);
                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
                p.setStyle(SkPaint::kStroke_Style);
                canvas->drawRect(r, p);
                p.setStyle(SkPaint::kFill_Style);
                p.setShader(s);
                r.inset(SK_ScalarHalf, SK_ScalarHalf);
                canvas->drawRect(r, p);

                canvas->drawBitmap(fBitmap, x, y, NULL);

#if 1
                canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
                                 x + w/2, y - labelP.getTextSize()/2, labelP);
#endif
                x += w + SkIntToScalar(10);
                if ((i & 3) == 3) {
                    x = x0;
                    y += h + SkIntToScalar(30);
                }
            }
            x0 += SkIntToScalar(330);
        }
        s->unref();
    }

private:
    typedef GM INHERITED;
};

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

static GM* MyFactory(void*) { return new XfermodesGM; }
static GMRegistry reg(MyFactory);

}

<commit_msg>update to use new xfermodes<commit_after>#include "gm.h"
#include "SkBitmap.h"
#include "SkShader.h"
#include "SkXfermode.h"

namespace skiagm {

static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
    src->setConfig(SkBitmap::kARGB_8888_Config, w, h);
    src->allocPixels();
    src->eraseColor(0);

    SkCanvas c(*src);
    SkPaint p;
    SkRect r;
    SkScalar ww = SkIntToScalar(w);
    SkScalar hh = SkIntToScalar(h);

    p.setAntiAlias(true);
    p.setColor(0xFFFFCC44);
    r.set(0, 0, ww*3/4, hh*3/4);
    c.drawOval(r, p);

    dst->setConfig(SkBitmap::kARGB_8888_Config, w, h);
    dst->allocPixels();
    dst->eraseColor(0);
    c.setBitmapDevice(*dst);

    p.setColor(0xFF66AAFF);
    r.set(ww/3, hh/3, ww*19/20, hh*19/20);
    c.drawRect(r, p);
}

static uint16_t gBG[] = { 0xFFFF, 0xCCCF, 0xCCCF, 0xFFFF };

class XfermodesGM : public GM {
    SkBitmap    fBitmap;
    SkBitmap    fBG;
    SkBitmap    fSrcB, fDstB;

    void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha) {
        SkPaint p;

        canvas->drawBitmap(fSrcB, 0, 0, &p);
        p.setAlpha(alpha);
        p.setXfermode(mode);
        canvas->drawBitmap(fDstB, 0, 0, &p);
    }

public:
	XfermodesGM() {
        const int W = 64;
        const int H = 64;

        fBitmap.setConfig(SkBitmap::kARGB_8888_Config, W, H);
        fBitmap.allocPixels();

        fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
        fBG.setPixels(gBG);
        fBG.setIsOpaque(true);

        make_bitmaps(W, H, &fSrcB, &fDstB);
    }

protected:
    SkString onShortName() {
        return SkString("xfermodes");
    }

	SkISize onISize() { return make_isize(790, 480); }

    void drawBG(SkCanvas* canvas) {
        canvas->drawColor(SK_ColorWHITE);
        return;
        SkShader* s = SkShader::CreateBitmapShader(fBG,
                                                   SkShader::kRepeat_TileMode,
                                                   SkShader::kRepeat_TileMode);
        SkPaint p;
        SkMatrix m;

        p.setShader(s)->unref();
        m.setScale(SkIntToScalar(8), SkIntToScalar(8));
        s->setLocalMatrix(m);
        canvas->drawPaint(p);
    }

    virtual void onDraw(SkCanvas* canvas) {
        this->drawBG(canvas);

        const struct {
            SkXfermode::Mode    fMode;
            const char*         fLabel;
        } gModes[] = {
            { SkXfermode::kClear_Mode,    "Clear"     },
            { SkXfermode::kSrc_Mode,      "Src"       },
            { SkXfermode::kDst_Mode,      "Dst"       },
            { SkXfermode::kSrcOver_Mode,  "SrcOver"   },
            { SkXfermode::kDstOver_Mode,  "DstOver"   },
            { SkXfermode::kSrcIn_Mode,    "SrcIn"     },
            { SkXfermode::kDstIn_Mode,    "DstIn"     },
            { SkXfermode::kSrcOut_Mode,   "SrcOut"    },
            { SkXfermode::kDstOut_Mode,   "DstOut"    },
            { SkXfermode::kSrcATop_Mode,  "SrcATop"   },
            { SkXfermode::kDstATop_Mode,  "DstATop"   },
            { SkXfermode::kXor_Mode,      "Xor"       },

            { SkXfermode::kPlus_Mode,         "Plus"          },
            { SkXfermode::kMultiply_Mode,     "Multiply"      },
            { SkXfermode::kScreen_Mode,       "Screen"        },
            { SkXfermode::kOverlay_Mode,      "Overlay"       },
            { SkXfermode::kDarken_Mode,       "Darken"        },
            { SkXfermode::kLighten_Mode,      "Lighten"       },
            { SkXfermode::kColorDodge_Mode,   "ColorDodge"    },
            { SkXfermode::kColorBurn_Mode,    "ColorBurn"     },
            { SkXfermode::kHardLight_Mode,    "HardLight"     },
            { SkXfermode::kSoftLight_Mode,    "SoftLight"     },
            { SkXfermode::kDifference_Mode,   "Difference"    },
            { SkXfermode::kExclusion_Mode,    "Exclusion"     },
        };

        canvas->translate(SkIntToScalar(10), SkIntToScalar(20));

        SkCanvas c(fBitmap);
        const SkScalar w = SkIntToScalar(fBitmap.width());
        const SkScalar h = SkIntToScalar(fBitmap.height());
        SkShader* s = SkShader::CreateBitmapShader(fBG,
                                                   SkShader::kRepeat_TileMode,
                                                   SkShader::kRepeat_TileMode);
        SkMatrix m;
        m.setScale(SkIntToScalar(6), SkIntToScalar(6));
        s->setLocalMatrix(m);

        SkPaint labelP;
        labelP.setAntiAlias(true);
        labelP.setTextAlign(SkPaint::kCenter_Align);

        const int W = 5;

        SkScalar x0 = 0;
        for (int twice = 0; twice < 2; twice++) {
            SkScalar x = x0, y = 0;
            for (size_t i = 0; i < SK_ARRAY_COUNT(gModes); i++) {
                SkXfermode* mode = SkXfermode::Create(gModes[i].fMode);

                fBitmap.eraseColor(0);
                draw_mode(&c, mode, twice ? 0x88 : 0xFF);
                SkSafeUnref(mode);

                SkPaint p;
                SkRect r;
                r.set(x, y, x+w, y+h);
                r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
                p.setStyle(SkPaint::kStroke_Style);
                canvas->drawRect(r, p);
                p.setStyle(SkPaint::kFill_Style);
                p.setShader(s);
                r.inset(SK_ScalarHalf, SK_ScalarHalf);
                canvas->drawRect(r, p);

                canvas->drawBitmap(fBitmap, x, y, NULL);

                canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
                                 x + w/2, y - labelP.getTextSize()/2, labelP);

                x += w + SkIntToScalar(10);
                if ((i % W) == W - 1) {
                    x = x0;
                    y += h + SkIntToScalar(30);
                }
            }
            x0 += SkIntToScalar(400);
        }
        s->unref();
    }

private:
    typedef GM INHERITED;
};

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

static GM* MyFactory(void*) { return new XfermodesGM; }
static GMRegistry reg(MyFactory);

}

<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

int main()
{
    std::vector<int> ivec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    for (auto &i : ivec)
        i = (i % 2) ? (i * 2) : i;

    //Check
    for (auto i : ivec)
        std::cout << i << " ";
    std::cout << std::endl;

    return 0;
}
<commit_msg>Update ex4_21.cpp<commit_after>#include <iostream>
#include <vector>

using std::cout;
using std::endl;
using std::vector;

int main()
{
    vector<int> ivec{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };

    for (auto i : ivec) {
        cout << ((i & 0x1) ? i * 2 : i) << " ";
    }
    cout << endl;

    return 0;
}
<|endoftext|>


<commit_before>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include "ns3/object.h"
#include "ns3/global-value.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include <ns3/gnuplot.h>
#include <sstream>

#include "Observador.h"

#define STARTTIME 2.0
#define STOPTIME  100.0
#define T_STUDENT_VALUE 2.2622

typedef struct datos {
    double mediaNumIntentosTotales;
    double mediaTiempoEcoTotal;
    double mediaPorcentajeErrorClientes;
} DATOS;

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("practica05");

DATOS simulacion (uint32_t nCsma, Time retardoProp, DataRate capacidad,
        uint32_t tamPaquete, Time intervalo, uint32_t maxReintentos) {

    NodeContainer csmaNodes;
    csmaNodes.Create (nCsma);

    CsmaHelper csma;
    csma.SetChannelAttribute ("DataRate", DataRateValue (capacidad));
    csma.SetChannelAttribute ("Delay", TimeValue (retardoProp));

    NetDeviceContainer csmaDevices;
    csmaDevices = csma.Install (csmaNodes);
    // Instalamos la pila TCP/IP en todos los nodos
    InternetStackHelper stack;
    stack.Install (csmaNodes);
    // Y les asignamos direcciones
    Ipv4AddressHelper address;
    address.SetBase ("10.1.2.0", "255.255.255.0");
    Ipv4InterfaceContainer csmaInterfaces = address.Assign (csmaDevices);

    /////////// Instalación de las aplicaciones
    // Servidor
    UdpEchoServerHelper echoServer (9);
    ApplicationContainer serverApp = echoServer.Install (csmaNodes.Get (nCsma - 1));
    serverApp.Start (Seconds (STARTTIME));
    serverApp.Stop (Seconds (STOPTIME));
    // Clientes
    UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma - 1), 9);
    echoClient.SetAttribute ("MaxPackets", UintegerValue (10000));
    echoClient.SetAttribute ("Interval", TimeValue (intervalo));
    echoClient.SetAttribute ("PacketSize", UintegerValue (tamPaquete));
    NodeContainer clientes;

    for (uint32_t i = 0; i < nCsma - 1; i++)
    {
        clientes.Add (csmaNodes.Get (i));
    }
    NS_LOG_FUNCTION ("Fin bucle de creacion de observadores");

    ApplicationContainer clientApps = echoClient.Install (clientes);
    NS_LOG_FUNCTION ("Instalacion de clientes de echo realizada");
    clientApps.Start (Seconds (STARTTIME));
    clientApps.Stop (Seconds (STOPTIME));

    // Cálculo de rutas
    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

    csma.EnablePcap ("practica05", csmaDevices.Get (nCsma - 1), true);

    Observador observadores[nCsma];
    for (uint32_t i = 0; i < nCsma; i++) {
        csmaDevices.Get(i)->TraceConnectWithoutContext ("PhyTxEnd",     MakeCallback(&Observador::PaqueteEnviado,              &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("PhyTxDrop",    MakeCallback(&Observador::PaquetePerdido,              &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("MacTxBackoff", MakeCallback(&Observador::PaqueteEnBackoff,            &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("MacTx",        MakeCallback(&Observador::PaqueteParaEnviar,           &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("MacRx",        MakeCallback(&Observador::PaqueteRecibidoParaEntregar, &observadores[i]));

        Ptr<CsmaNetDevice> csma_device = csmaDevices.Get(i)->GetObject<CsmaNetDevice>();
        csma_device->SetBackoffParams (Time ("1us"), 10, 1000, 10, maxReintentos);
    }

    NS_LOG_FUNCTION ("Va a comenzar la simulacion");
    Simulator::Run ();
    Simulator::Destroy ();
    NS_LOG_FUNCTION ("Finalizada simulacion");

    Average<uint32_t> numIntentosTotales;
    Average<double>   tiempoEcoTotal;
    Average<double>   porcentajeErrorClientes;
    Average<double>   porcentajeErrorEscenario;

    for (uint32_t i = 0; i < nCsma; i++) {

        double mediaNumIntentos = observadores[i].GetMediaNumIntentos();
        double mediaTiempoEco = observadores[i].GetMediaTiempoEco();
        double porcentajeError = observadores[i].GetPorcentajePaquetesPerdidos();

        if (std::isnan(mediaNumIntentos)) {
            mediaNumIntentos = 0;
        }
        if (std::isnan(mediaTiempoEco)) {
            mediaTiempoEco = 0;
        }

        NS_LOG_INFO ("Media de intentos en nodo " << i << ": " << mediaNumIntentos);
        porcentajeErrorEscenario.Update(porcentajeError);
        if (i < nCsma - 1) {
           NS_LOG_INFO ("Tiempo medio de eco en nodo " << i << ": " << Time(mediaTiempoEco));
           if (i > 1) {
               porcentajeErrorClientes.Update(porcentajeError);
               tiempoEcoTotal.Update(mediaTiempoEco);
               numIntentosTotales.Update(mediaNumIntentos);
           }
        }
        NS_LOG_INFO ("Porcentaje de paquetes perdidos en nodo " << i << ": " << porcentajeError << " %");
        NS_LOG_INFO ("");
    }

    double mediaNumIntentosTotales = numIntentosTotales.Mean();
    double mediaTiempoEcoTotal = tiempoEcoTotal.Mean();
    double mediaPorcentajeErrorClientes = porcentajeErrorClientes.Mean();
    double mediaPorcentajeErrorEscenario = porcentajeErrorEscenario.Mean();

    if (std::isnan(mediaNumIntentosTotales)) {
        mediaNumIntentosTotales = 0;
    }
    if (std::isnan(mediaTiempoEcoTotal)) {
        mediaTiempoEcoTotal = 0;
    }
    if (std::isnan(mediaPorcentajeErrorClientes)) {
        mediaPorcentajeErrorClientes = 0;
    }
    if (std::isnan(mediaPorcentajeErrorEscenario)) {
        mediaPorcentajeErrorEscenario = 0;
    }

    NS_LOG_INFO ("--------------------------------------------------------");
    NS_LOG_INFO ("Media de intentos de transmision en el escenario: " << mediaNumIntentosTotales);
    NS_LOG_INFO ("Tiempo de eco medio en el escenario: " << Time(mediaTiempoEcoTotal));
    NS_LOG_INFO ("Porcentaje de paquetes perdidos por los clientes: " << mediaPorcentajeErrorClientes << " %");
    NS_LOG_INFO ("Porcentaje de paquetes perdidos en el escenario: " << mediaPorcentajeErrorEscenario << " %");
    NS_LOG_INFO ("--------------------------------------------------------");

    return { mediaNumIntentosTotales, mediaTiempoEcoTotal, mediaPorcentajeErrorClientes };
}

int
main (int argc, char *argv[])
{
    GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
    Time::SetResolution (Time::US);

    uint32_t seed = 1;

    int dni[8] = {3,0,2,2,8,4,1,3};
    NS_LOG_INFO ("DNI: " << dni[0]<<dni[1]<<dni[2]<<dni[3]<<dni[4]<<dni[5]<<dni[6]<<dni[7]);

    //Parametros de simulacion
    uint32_t nCsma             = 10;
    Time     retardoProp       = Time ("6560ns");
    DataRate capacidad         = DataRate ("100Mbps");
    uint32_t tamPaquete        = 1024;
    Time     intervalo         = Time ("1s");
    uint32_t reintentosInicial = 8;
    uint32_t reintentosFinal   = 20;

    CommandLine cmd;
    cmd.AddValue ("nCsma", "Número de nodos de la red local", nCsma);
    cmd.AddValue ("retardoProp", "retardo de propagación en el bus", retardoProp);
    cmd.AddValue ("capacidad", "capacidad del bus", capacidad);
    cmd.AddValue ("tamPaquete", "tamaño de las SDU de aplicación", tamPaquete);
    cmd.AddValue ("intervalo", "tiempo entre dos paquetes consecutivos enviados por el mismo cliente", intervalo);
    cmd.AddValue ("reintentosInicial", "valor inicial de reintentos", reintentosInicial);
    cmd.AddValue ("reintentosFinal", "valor final de reintentos", reintentosFinal);
    cmd.Parse (argc,argv);

    Gnuplot plot[3];
    plot[0].SetTitle ("Evolución del número medio de intentos");
    plot[0].SetLegend ("maxReint", "numIntentos");
    plot[1].SetTitle ("Evolución del tiempo medio de eco");
    plot[1].SetLegend ("maxReint", "tEco (us)");
    plot[2].SetTitle ("Evolución del porcentaje de error");
    plot[2].SetLengend ("maxReint", "perror (%)");

    Gnuplot2dDataset dataset[3];
    for (int i = 0; i < 3 ; i++) {
        dataset[i].SetStyle (Gnuplot2dDataset::LINES_POINTS);
        dataset[i].SetErrorBars(Gnuplot2dDataset::Y);
    }

    for (uint32_t maxReintentos = reintentosInicial; maxReintentos <= reintentosFinal; maxReintentos++) {
        Average<double> numIntentosTotales;
        Average<double> tiempoEcoTotal;
        Average<double> porcentajeErrorClientes;
        for (int i = 0; i < 10; i++) {
            DATOS datos;
            //Modificamos la semilla de la simulacion
            SeedManager::SetRun (seed++);
            datos = simulacion(nCsma, retardoProp, capacidad, tamPaquete, intervalo, maxReintentos);
            numIntentosTotales.Update (datos.mediaNumIntentosTotales);
            tiempoEcoTotal.Update (datos.mediaTiempoEcoTotal);
            porcentajeErrorClientes.Update (datos.mediaPorcentajeErrorClientes);
        }
        double z[3];
        z[0] = T_STUDENT_VALUE * std::sqrt (numIntentosTotales.Var() / 10);
        dataset[0].Add(maxReintentos, numIntentosTotales.Mean(), 2 * z[0]);
        z[1] = T_STUDENT_VALUE * std::sqrt (tiempoEcoTotal.Var() / 10);
        dataset[1].Add(maxReintentos, tiempoEcoTotal.Mean(), 2 * z[1]);
        z[2] = T_STUDENT_VALUE * std::sqrt (porcentajeErrorClientes.Var() / 10);
        dataset[2].Add(maxReintentos, porcentajeErrorClientes.Mean(), 2 * z[2]);
        NS_LOG_DEBUG (numIntentosTotales.Mean() - z[0] << " < numIntentosTotales < " << numIntentosTotales.Mean() + z[0]);
        NS_LOG_DEBUG (tiempoEcoTotal.Mean() - z[1] << " < tiempoEcoTotal < " << tiempoEcoTotal.Mean() + z[1]);
        NS_LOG_DEBUG (porcentajeErrorClientes.Mean() - z[2] << " < porcentajeErrorClientes < " << porcentajeErrorClientes.Mean() + z[2]);
        NS_LOG_DEBUG ("");
    }

    for (int i = 0; i < 3; i++) {
        plot[i].AddDataset (dataset[i]);
        std::ostringstream nombreFichero;
        nombreFichero << "practica05-0" << i << ".plt";
        std::ofstream plotFile (nombreFichero.str());
        plot.GenerateOutput (plotFile);
        plotFile << "pause -1" << std::endl;
        plotFile.close ();
    }

    return 0;
}
<commit_msg>P05 parece que ya funciona, falta añadir valores de DNI<commit_after>/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */

#include "ns3/object.h"
#include "ns3/global-value.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/applications-module.h"
#include <ns3/gnuplot.h>
#include <sstream>

#include "Observador.h"

#define STARTTIME 2.0
#define STOPTIME  100.0
#define T_STUDENT_VALUE 2.2622

typedef struct datos {
    double mediaNumIntentosTotales;
    double mediaTiempoEcoTotal;
    double mediaPorcentajeErrorClientes;
} DATOS;

using namespace ns3;

NS_LOG_COMPONENT_DEFINE ("practica05");

DATOS simulacion (uint32_t nCsma, Time retardoProp, DataRate capacidad,
        uint32_t tamPaquete, Time intervalo, uint32_t maxReintentos) {

    NodeContainer csmaNodes;
    csmaNodes.Create (nCsma);

    CsmaHelper csma;
    csma.SetChannelAttribute ("DataRate", DataRateValue (capacidad));
    csma.SetChannelAttribute ("Delay", TimeValue (retardoProp));

    NetDeviceContainer csmaDevices;
    csmaDevices = csma.Install (csmaNodes);
    // Instalamos la pila TCP/IP en todos los nodos
    InternetStackHelper stack;
    stack.Install (csmaNodes);
    // Y les asignamos direcciones
    Ipv4AddressHelper address;
    address.SetBase ("10.1.2.0", "255.255.255.0");
    Ipv4InterfaceContainer csmaInterfaces = address.Assign (csmaDevices);

    /////////// Instalación de las aplicaciones
    // Servidor
    UdpEchoServerHelper echoServer (9);
    ApplicationContainer serverApp = echoServer.Install (csmaNodes.Get (nCsma - 1));
    serverApp.Start (Seconds (STARTTIME));
    serverApp.Stop (Seconds (STOPTIME));
    // Clientes
    UdpEchoClientHelper echoClient (csmaInterfaces.GetAddress (nCsma - 1), 9);
    echoClient.SetAttribute ("MaxPackets", UintegerValue (10000));
    echoClient.SetAttribute ("Interval", TimeValue (intervalo));
    echoClient.SetAttribute ("PacketSize", UintegerValue (tamPaquete));
    NodeContainer clientes;

    for (uint32_t i = 0; i < nCsma - 1; i++)
    {
        clientes.Add (csmaNodes.Get (i));
    }
    NS_LOG_FUNCTION ("Fin bucle de creacion de observadores");

    ApplicationContainer clientApps = echoClient.Install (clientes);
    NS_LOG_FUNCTION ("Instalacion de clientes de echo realizada");
    clientApps.Start (Seconds (STARTTIME));
    clientApps.Stop (Seconds (STOPTIME));

    // Cálculo de rutas
    Ipv4GlobalRoutingHelper::PopulateRoutingTables ();

    csma.EnablePcap ("practica05", csmaDevices.Get (nCsma - 1), true);

    Observador observadores[nCsma];
    for (uint32_t i = 0; i < nCsma; i++) {
        csmaDevices.Get(i)->TraceConnectWithoutContext ("PhyTxEnd",     MakeCallback(&Observador::PaqueteEnviado,              &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("PhyTxDrop",    MakeCallback(&Observador::PaquetePerdido,              &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("MacTxBackoff", MakeCallback(&Observador::PaqueteEnBackoff,            &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("MacTx",        MakeCallback(&Observador::PaqueteParaEnviar,           &observadores[i]));
        csmaDevices.Get(i)->TraceConnectWithoutContext ("MacRx",        MakeCallback(&Observador::PaqueteRecibidoParaEntregar, &observadores[i]));

        Ptr<CsmaNetDevice> csma_device = csmaDevices.Get(i)->GetObject<CsmaNetDevice>();
        csma_device->SetBackoffParams (Time ("1us"), 10, 1000, 10, maxReintentos);
    }

    NS_LOG_FUNCTION ("Va a comenzar la simulacion");
    Simulator::Run ();
    Simulator::Destroy ();
    NS_LOG_FUNCTION ("Finalizada simulacion");

    Average<uint32_t> numIntentosTotales;
    Average<double>   tiempoEcoTotal;
    Average<double>   porcentajeErrorClientes;
    Average<double>   porcentajeErrorEscenario;

    for (uint32_t i = 0; i < nCsma; i++) {

        double mediaNumIntentos = observadores[i].GetMediaNumIntentos();
        double mediaTiempoEco = observadores[i].GetMediaTiempoEco();
        double porcentajeError = observadores[i].GetPorcentajePaquetesPerdidos();

        if (std::isnan(mediaNumIntentos)) {
            mediaNumIntentos = 0;
        }
        if (std::isnan(mediaTiempoEco)) {
            mediaTiempoEco = 0;
        }

        NS_LOG_INFO ("Media de intentos en nodo " << i << ": " << mediaNumIntentos);
        porcentajeErrorEscenario.Update(porcentajeError);
        if (i < nCsma - 1) {
           NS_LOG_INFO ("Tiempo medio de eco en nodo " << i << ": " << Time(mediaTiempoEco));
           if (i > 1) {
               porcentajeErrorClientes.Update(porcentajeError);
               tiempoEcoTotal.Update(mediaTiempoEco);
               numIntentosTotales.Update(mediaNumIntentos);
           }
        }
        NS_LOG_INFO ("Porcentaje de paquetes perdidos en nodo " << i << ": " << porcentajeError << " %");
        NS_LOG_INFO ("");
    }

    double mediaNumIntentosTotales = numIntentosTotales.Mean();
    double mediaTiempoEcoTotal = tiempoEcoTotal.Mean();
    double mediaPorcentajeErrorClientes = porcentajeErrorClientes.Mean();
    double mediaPorcentajeErrorEscenario = porcentajeErrorEscenario.Mean();

    if (std::isnan(mediaNumIntentosTotales)) {
        mediaNumIntentosTotales = 0;
    }
    if (std::isnan(mediaTiempoEcoTotal)) {
        mediaTiempoEcoTotal = 0;
    }
    if (std::isnan(mediaPorcentajeErrorClientes)) {
        mediaPorcentajeErrorClientes = 0;
    }
    if (std::isnan(mediaPorcentajeErrorEscenario)) {
        mediaPorcentajeErrorEscenario = 0;
    }

    NS_LOG_INFO ("--------------------------------------------------------");
    NS_LOG_INFO ("Media de intentos de transmision en el escenario: " << mediaNumIntentosTotales);
    NS_LOG_INFO ("Tiempo de eco medio en el escenario: " << Time(mediaTiempoEcoTotal));
    NS_LOG_INFO ("Porcentaje de paquetes perdidos por los clientes: " << mediaPorcentajeErrorClientes << " %");
    NS_LOG_INFO ("Porcentaje de paquetes perdidos en el escenario: " << mediaPorcentajeErrorEscenario << " %");
    NS_LOG_INFO ("--------------------------------------------------------");

    DATOS datos = { mediaNumIntentosTotales, mediaTiempoEcoTotal, mediaPorcentajeErrorClientes };
    return datos;
}

int
main (int argc, char *argv[])
{
    GlobalValue::Bind("ChecksumEnabled", BooleanValue(true));
    Time::SetResolution (Time::US);

    uint32_t seed = 1;

    int dni[8] = {3,0,2,2,8,4,1,3};
    NS_LOG_INFO ("DNI: " << dni[0]<<dni[1]<<dni[2]<<dni[3]<<dni[4]<<dni[5]<<dni[6]<<dni[7]);

    //Parametros de simulacion
    uint32_t nCsma             = 10;
    Time     retardoProp       = Time ("6560ns");
    DataRate capacidad         = DataRate ("100Mbps");
    uint32_t tamPaquete        = 1024;
    Time     intervalo         = Time ("1s");
    uint32_t reintentosInicial = 8;
    uint32_t reintentosFinal   = 20;

    CommandLine cmd;
    cmd.AddValue ("nCsma", "Número de nodos de la red local", nCsma);
    cmd.AddValue ("retardoProp", "retardo de propagación en el bus", retardoProp);
    cmd.AddValue ("capacidad", "capacidad del bus", capacidad);
    cmd.AddValue ("tamPaquete", "tamaño de las SDU de aplicación", tamPaquete);
    cmd.AddValue ("intervalo", "tiempo entre dos paquetes consecutivos enviados por el mismo cliente", intervalo);
    cmd.AddValue ("reintentosInicial", "valor inicial de reintentos", reintentosInicial);
    cmd.AddValue ("reintentosFinal", "valor final de reintentos", reintentosFinal);
    cmd.Parse (argc,argv);

    Gnuplot plot[3];
    plot[0].SetTitle ("Evolución del número medio de intentos");
    plot[0].SetLegend ("maxReint", "numIntentos");
    plot[1].SetTitle ("Evolución del tiempo medio de eco");
    plot[1].SetLegend ("maxReint", "tEco (us)");
    plot[2].SetTitle ("Evolución del porcentaje de error");
    plot[2].SetLegend ("maxReint", "perror (%)");

    Gnuplot2dDataset dataset[3];
    for (int i = 0; i < 3 ; i++) {
        dataset[i].SetStyle (Gnuplot2dDataset::LINES_POINTS);
        dataset[i].SetErrorBars(Gnuplot2dDataset::Y);
    }

    for (uint32_t maxReintentos = reintentosInicial; maxReintentos <= reintentosFinal; maxReintentos++) {
        Average<double> numIntentosTotales;
        Average<double> tiempoEcoTotal;
        Average<double> porcentajeErrorClientes;
        for (int i = 0; i < 10; i++) {
            DATOS datos;
            //Modificamos la semilla de la simulacion
            SeedManager::SetRun (seed++);
            datos = simulacion(nCsma, retardoProp, capacidad, tamPaquete, intervalo, maxReintentos);
            numIntentosTotales.Update (datos.mediaNumIntentosTotales);
            tiempoEcoTotal.Update (datos.mediaTiempoEcoTotal);
            porcentajeErrorClientes.Update (datos.mediaPorcentajeErrorClientes);
        }
        double z[3];
        z[0] = T_STUDENT_VALUE * std::sqrt (numIntentosTotales.Var() / 10);
        dataset[0].Add(maxReintentos, numIntentosTotales.Mean(), 2 * z[0]);
        z[1] = T_STUDENT_VALUE * std::sqrt (tiempoEcoTotal.Var() / 10);
        dataset[1].Add(maxReintentos, tiempoEcoTotal.Mean(), 2 * z[1]);
        z[2] = T_STUDENT_VALUE * std::sqrt (porcentajeErrorClientes.Var() / 10);
        dataset[2].Add(maxReintentos, porcentajeErrorClientes.Mean(), 2 * z[2]);
        NS_LOG_DEBUG (numIntentosTotales.Mean() - z[0] << " < numIntentosTotales < " << numIntentosTotales.Mean() + z[0]);
        NS_LOG_DEBUG (tiempoEcoTotal.Mean() - z[1] << " < tiempoEcoTotal < " << tiempoEcoTotal.Mean() + z[1]);
        NS_LOG_DEBUG (porcentajeErrorClientes.Mean() - z[2] << " < porcentajeErrorClientes < " << porcentajeErrorClientes.Mean() + z[2]);
        NS_LOG_DEBUG ("");
    }

        plot[0].AddDataset (dataset[0]);
        std::ofstream plotFile1 ("practica05-01.plt");
        plot[0].GenerateOutput (plotFile1);
        plotFile1 << "pause -1" << std::endl;
        plotFile1.close ();

        plot[1].AddDataset (dataset[1]);
        std::ofstream plotFile2 ("practica05-02.plt");
        plot[1].GenerateOutput (plotFile2);
        plotFile2 << "pause -1" << std::endl;
        plotFile2.close ();

        plot[2].AddDataset (dataset[2]);
        std::ofstream plotFile3 ("practica05-03.plt");
        plot[2].GenerateOutput (plotFile3);
        plotFile3 << "pause -1" << std::endl;
        plotFile3.close ();

    return 0;
}
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	ST7565(R) LCD ドライバー
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ST7565 テンプレートクラス
		@param[in]	CSI_IO	CSI(SPI) 制御クラス
		@param[in]	CS	デバイス選択、レジスター選択、制御クラス
		@param[in]	A0	制御切り替え、レジスター選択、制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class CSI_IO, class CS, class A0>
	class ST7565 {

		CSI_IO&	csi_;

		enum class CMD : uint8_t {
			DISPLAY_OFF = 0xAE,
			DISPLAY_ON  = 0xAF,
			SET_DISP_START_LINE = 0x40,
			SET_PAGE = 0xB0,

			SET_COLUMN_UPPER = 0x10,
			SET_COLUMN_LOWER = 0x00,

			SET_ADC_NORMAL  = 0xA0,
			SET_ADC_REVERSE = 0xA1,

			SET_DISP_NORMAL = 0xA6,
			SET_DISP_REVERSE = 0xA7,

			SET_ALLPTS_NORMAL = 0xA4,
			SET_ALLPTS_ON = 0xA5,
			SET_BIAS_9 = 0xA2,
			SET_BIAS_7 = 0xA3,

			RMW = 0xE0,
			RMW_CLEAR = 0xEE,
			INTERNAL_RESET = 0xE2,
			SET_COM_NORMAL = 0xC0,
			SET_COM_REVERSE = 0xC8,
			SET_POWER_CONTROL = 0x28,
			SET_RESISTOR_RATIO = 0x20,
			SET_VOLUME_FIRST = 0x81,
			SET_VOLUME_SECOND = 0x00,
			SET_STATIC_OFF = 0xAC,
			SET_STATIC_ON = 0xAD,
			SET_STATIC_REG = 0x00,
			SET_BOOSTER_FIRST = 0xF8,
			SET_BOOSTER_234 = 0,
			SET_BOOSTER_5 = 1,
			SET_BOOSTER_6 = 3,
			NOP = 0xE3,
			TEST = 0xF0,
		};

		inline void write_(CMD cmd) {
			csi_.xchg(static_cast<uint8_t>(cmd));
		}

		inline void write_(CMD cmd, uint8_t ord) {
			csi_.xchg(static_cast<uint8_t>(cmd) | ord);
		}

		inline void chip_enable_(bool f = true) const {
			CS::P = !f;
		}

		inline void reg_select_(bool f) const {
			A0::P = f;
		}

		void init_(bool comrvs) {

			reg_select_(0);
			chip_enable_();

			// toggle RST low to reset; CS low so it'll listen to us
			// if (cs > 0)
    		//     digitalWrite(cs, LOW);

			// digitalWrite(rst, LOW);
			// _delay_ms(500);
			// digitalWrite(rst, HIGH);

			write_(CMD::DISPLAY_OFF);

			// LCD bias select
			write_(CMD::SET_BIAS_7);
			// ADC select
			write_(CMD::SET_ADC_NORMAL);
			// SHL select
			if(comrvs) {
				write_(CMD::SET_COM_REVERSE);
			} else {
				write_(CMD::SET_COM_NORMAL);
			}

			// Initial display line
			write_(CMD::SET_DISP_START_LINE);

			// turn on voltage converter (VC=1, VR=0, VF=0)
			write_(CMD::SET_POWER_CONTROL, 0x4);
			// wait for 50% rising
			utils::delay::milli_second(50);

			// turn on voltage regulator (VC=1, VR=1, VF=0)
			write_(CMD::SET_POWER_CONTROL, 0x6);

			// wait >=50ms
			utils::delay::milli_second(50);

			// turn on voltage follower (VC=1, VR=1, VF=1)
			write_(CMD::SET_POWER_CONTROL, 0x7);

			// wait 10ms
			utils::delay::milli_second(10);

			// set lcd operating voltage (regulator resistor, ref voltage resistor)
			write_(CMD::SET_RESISTOR_RATIO, 0x6);
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		ST7565(CSI_IO& csi) : csi_(csi) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  ブライトネス設定
			@param[in]	val	ブライトネス値
		*/
		//-----------------------------------------------------------------//
		void set_brightness(uint8_t val)
		{
    		write_(CMD::SET_VOLUME_FIRST);
    		write_(CMD::SET_VOLUME_SECOND, (val & 0x3f));
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  開始
			@param[in]	contrast コントラスト
			@param[in]	comrvs	コモンライン・リバースの場合：true
		*/
		//-----------------------------------------------------------------//
		void start(uint8_t contrast, bool comrvs = false)
		{
			CS::DIR = 1;  // (/CS) output
			A0::DIR = 1;  // (A0) output

			reg_select_(0);
			chip_enable_(false);

			utils::delay::milli_second(100);

			init_(comrvs);
			write_(CMD::DISPLAY_ON);
	  		write_(CMD::SET_ALLPTS_NORMAL);
			set_brightness(contrast);
			chip_enable_(false);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  コピー
			@param[in]	src	フレームバッファソース
			@param[in]	num	転送ページ数
			@param[in]	ofs	転送オフセット
		*/
		//-----------------------------------------------------------------//
		void copy(const uint8_t* src, uint8_t num, uint8_t ofs = 0) {
			chip_enable_();
			uint8_t o = 0x00;
			for(uint8_t page = ofs; page < (ofs + num); ++page) {
				reg_select_(0);
				write_(CMD::SET_PAGE, page);
				write_(CMD::SET_COLUMN_LOWER, o & 0x0f);
				write_(CMD::SET_COLUMN_UPPER, o >> 4);
///    			write_(CMD::RMW);
				reg_select_(1);
				csi_.send(src, 128);
				src += 128;
			}
			reg_select_(0);
			chip_enable_(false);
		}

	};
}
<commit_msg>update comment<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	ST7565(R) LCD ドライバー @n
			Copyright 2016 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include "common/delay.hpp"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  ST7565 テンプレートクラス
		@param[in]	CSI_IO	CSI(SPI) 制御クラス
		@param[in]	CS	デバイス選択、レジスター選択、制御クラス
		@param[in]	A0	制御切り替え、レジスター選択、制御クラス
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class CSI_IO, class CS, class A0>
	class ST7565 {

		CSI_IO&	csi_;

		enum class CMD : uint8_t {
			DISPLAY_OFF = 0xAE,
			DISPLAY_ON  = 0xAF,
			SET_DISP_START_LINE = 0x40,
			SET_PAGE = 0xB0,

			SET_COLUMN_UPPER = 0x10,
			SET_COLUMN_LOWER = 0x00,

			SET_ADC_NORMAL  = 0xA0,
			SET_ADC_REVERSE = 0xA1,

			SET_DISP_NORMAL = 0xA6,
			SET_DISP_REVERSE = 0xA7,

			SET_ALLPTS_NORMAL = 0xA4,
			SET_ALLPTS_ON = 0xA5,
			SET_BIAS_9 = 0xA2,
			SET_BIAS_7 = 0xA3,

			RMW = 0xE0,
			RMW_CLEAR = 0xEE,
			INTERNAL_RESET = 0xE2,
			SET_COM_NORMAL = 0xC0,
			SET_COM_REVERSE = 0xC8,
			SET_POWER_CONTROL = 0x28,
			SET_RESISTOR_RATIO = 0x20,
			SET_VOLUME_FIRST = 0x81,
			SET_VOLUME_SECOND = 0x00,
			SET_STATIC_OFF = 0xAC,
			SET_STATIC_ON = 0xAD,
			SET_STATIC_REG = 0x00,
			SET_BOOSTER_FIRST = 0xF8,
			SET_BOOSTER_234 = 0,
			SET_BOOSTER_5 = 1,
			SET_BOOSTER_6 = 3,
			NOP = 0xE3,
			TEST = 0xF0,
		};

		inline void write_(CMD cmd) {
			csi_.xchg(static_cast<uint8_t>(cmd));
		}

		inline void write_(CMD cmd, uint8_t ord) {
			csi_.xchg(static_cast<uint8_t>(cmd) | ord);
		}

		inline void chip_enable_(bool f = true) const {
			CS::P = !f;
		}

		inline void reg_select_(bool f) const {
			A0::P = f;
		}

		void init_(bool comrvs) {

			reg_select_(0);
			chip_enable_();

			// toggle RST low to reset; CS low so it'll listen to us
			// if (cs > 0)
    		//     digitalWrite(cs, LOW);

			// digitalWrite(rst, LOW);
			// _delay_ms(500);
			// digitalWrite(rst, HIGH);

			write_(CMD::DISPLAY_OFF);

			// LCD bias select
			write_(CMD::SET_BIAS_7);
			// ADC select
			write_(CMD::SET_ADC_NORMAL);
			// SHL select
			if(comrvs) {
				write_(CMD::SET_COM_REVERSE);
			} else {
				write_(CMD::SET_COM_NORMAL);
			}

			// Initial display line
			write_(CMD::SET_DISP_START_LINE);

			// turn on voltage converter (VC=1, VR=0, VF=0)
			write_(CMD::SET_POWER_CONTROL, 0x4);
			// wait for 50% rising
			utils::delay::milli_second(50);

			// turn on voltage regulator (VC=1, VR=1, VF=0)
			write_(CMD::SET_POWER_CONTROL, 0x6);

			// wait >=50ms
			utils::delay::milli_second(50);

			// turn on voltage follower (VC=1, VR=1, VF=1)
			write_(CMD::SET_POWER_CONTROL, 0x7);

			// wait 10ms
			utils::delay::milli_second(10);

			// set lcd operating voltage (regulator resistor, ref voltage resistor)
			write_(CMD::SET_RESISTOR_RATIO, 0x6);
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief  コンストラクター
		*/
		//-----------------------------------------------------------------//
		ST7565(CSI_IO& csi) : csi_(csi) { }

		//-----------------------------------------------------------------//
		/*!
			@brief  ブライトネス設定
			@param[in]	val	ブライトネス値
		*/
		//-----------------------------------------------------------------//
		void set_brightness(uint8_t val)
		{
    		write_(CMD::SET_VOLUME_FIRST);
    		write_(CMD::SET_VOLUME_SECOND, (val & 0x3f));
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  開始
			@param[in]	contrast コントラスト
			@param[in]	comrvs	コモンライン・リバースの場合：true
		*/
		//-----------------------------------------------------------------//
		void start(uint8_t contrast, bool comrvs = false)
		{
			CS::DIR = 1;  // (/CS) output
			A0::DIR = 1;  // (A0) output

			reg_select_(0);
			chip_enable_(false);

			utils::delay::milli_second(100);

			init_(comrvs);
			write_(CMD::DISPLAY_ON);
	  		write_(CMD::SET_ALLPTS_NORMAL);
			set_brightness(contrast);
			chip_enable_(false);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief  コピー
			@param[in]	src	フレームバッファソース
			@param[in]	num	転送ページ数
			@param[in]	ofs	転送オフセット
		*/
		//-----------------------------------------------------------------//
		void copy(const uint8_t* src, uint8_t num, uint8_t ofs = 0) {
			chip_enable_();
			uint8_t o = 0x00;
			for(uint8_t page = ofs; page < (ofs + num); ++page) {
				reg_select_(0);
				write_(CMD::SET_PAGE, page);
				write_(CMD::SET_COLUMN_LOWER, o & 0x0f);
				write_(CMD::SET_COLUMN_UPPER, o >> 4);
///    			write_(CMD::RMW);
				reg_select_(1);
				csi_.send(src, 128);
				src += 128;
			}
			reg_select_(0);
			chip_enable_(false);
		}

	};
}
<|endoftext|>


<commit_before>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include "transportsocketcache.hpp"

namespace qi {

  TransportSocketCache::~TransportSocketCache() {
    close();
  }

  void TransportSocketCache::init() {
    boost::mutex::scoped_lock sl(_socketsMutex);
    _dying = false;
  }

  void TransportSocketCache::close() {
    {
      _dying = true;
      MachineConnectionMap socketsCopy;
      {
        // Do not hold _socketsMutex while iterating or deadlock may occurr
        // between disconnect() that waits for callback handler
        // and callback handler that tries to acquire _socketsMutex
        boost::mutex::scoped_lock sl(_socketsMutex);
        socketsCopy = _sockets;
      }
      MachineConnectionMap::iterator mcmIt;
      for (mcmIt = socketsCopy.begin(); mcmIt != socketsCopy.end(); ++mcmIt) {
        TransportSocketConnectionMap& tscm = mcmIt->second;
        TransportSocketConnectionMap::iterator tscmIt;
        for (tscmIt = tscm.begin(); tscmIt != tscm.end(); ++tscmIt) {
          TransportSocketConnection& tsc = tscmIt->second;
          tsc.socket->disconnected.disconnect(tscmIt->second.disconnectLink);
          tsc.socket->connected.disconnect(tscmIt->second.connectLink);
          //remove callback before calling disconnect. (we dont need them)
          if (tscmIt->second.socket->isConnected())
            tscmIt->second.socket->disconnect();
          tscmIt->second.promise.setError("session closed");
        }
      }
    }
  }

  qi::Future<qi::TransportSocketPtr> TransportSocketCache::socket(const ServiceInfo& servInfo) {
    qi::UrlVector endpoints;
    qi::UrlVector::const_iterator urlIt;

    bool local = servInfo.machineId() == qi::os::getMachineId();

    // RFC 3330 - http://tools.ietf.org/html/rfc3330
    //   -> 127.0.0.0/8 is assigned to loopback address.
    //
    // This filters endpoints. If we are on the same machine, we just try to
    // connect on the loopback address, else we will try on all endpoints we
    // have that are not loopback.
    for (urlIt = servInfo.endpoints().begin(); urlIt != servInfo.endpoints().end(); ++urlIt) {
      qi::Url url = *urlIt;
      if (!url.isValid())
        continue;
      if (url.host().substr(0, 4) == "127.") {
        if (local) {
          endpoints.push_back(url);
          break;
        }
      } else if (!local) {
        endpoints.push_back(url);
      }
    }

    {
      boost::mutex::scoped_lock sl(_socketsMutex);
      if (_dying)
        return qi::makeFutureError<qi::TransportSocketPtr>("TransportSocketCache is closed.");

      // From here, we will see if we have a pending/established connection to
      // machineId on one of the endpoints (they all share the same promise
      // anyway). If it is the case, we return its future.
      MachineConnectionMap::iterator mcmIt;
      if ((mcmIt = _sockets.find(servInfo.machineId())) != _sockets.end()) {
        TransportSocketConnectionMap& tscm = mcmIt->second;
        TransportSocketConnectionMap::iterator tscmIt;
        for (urlIt = endpoints.begin(); urlIt != endpoints.end(); ++urlIt) {
          if ((tscmIt = tscm.find((*urlIt).str())) != tscm.end()) {
            TransportSocketConnection& tsc = tscmIt->second;
            if (tsc.promise.future().hasError()) {
              // When we have a socket with an error, we will try to connect to
              // all endpoints in case the old one is completely down.
              continue;
            }
            qiLogVerbose("tsc.socket") << "A connection is pending or already"
                                       << " established.";
            return tsc.promise.future();
          }
        }
      }

      // Launching connections to all endpoints at the same time. They all share
      // the same promise.
      qi::Promise<qi::TransportSocketPtr> prom;

      // We will need this to report error (to know if all sockets didn't
      // connect).
      TransportSocketConnectionAttempt& tsca = _attempts[servInfo.machineId()];
      tsca.promise = prom;
      tsca.socket_count = 0;
      tsca.successful = false;

      // This part launches all the socket connections on the same promise. The
      // first socket to connect is the winner.
      TransportSocketConnectionMap& tscm = _sockets[servInfo.machineId()];
      for (urlIt = endpoints.begin(); urlIt != endpoints.end(); ++urlIt) {
        qi::Url url = *urlIt;
        qi::TransportSocketPtr socket = makeTransportSocket(url.protocol());
        TransportSocketConnection& tsc = tscm[url.str()];
        qiLogVerbose("tsc.socket") << "Attempting connection to " << url.str()
                                   << " of machine id " << servInfo.machineId();
        tsc.socket = socket;
        tsc.promise = prom;
        tsc.url = url;
        tsc.connectLink = socket->connected.connect(boost::bind(&TransportSocketCache::onSocketConnected, this, socket, servInfo, url));
        tsc.disconnectLink = socket->disconnected.connect(boost::bind(&TransportSocketCache::onSocketDisconnected, this, _1, socket, servInfo, url));
        socket->connect(url).async();
        tsca.socket_count++;
      }
      return prom.future();
    } // ! boost::mutex::scoped_lock
  }

  void TransportSocketCache::onSocketDisconnected(int error, TransportSocketPtr socket, const qi::ServiceInfo& servInfo, const qi::Url& url) {
    {
      boost::mutex::scoped_lock sl(_socketsMutex);

      // First, we get the attempts of the machineId. It is used to know if we
      // have pending connections to other endpoints.
      MachineAttemptsMap::iterator mamIt;
      if ((mamIt = _attempts.find(servInfo.machineId())) == _attempts.end()) {
        // Unknown error. This shouldn't happen...
        return;
      }
      TransportSocketConnectionAttempt& tsca = mamIt->second;

      if (_dying) {
        tsca.promise.setError("TransportSocketCache is closed.");
        return;
      }

      tsca.socket_count--;
      if (tsca.socket_count != 0) {
        // We still have some sockets attempting to connect to the service, so
        // we just ignore this disconnection.
        return;
      }

      // No socket can be created, we just return an error.
      std::stringstream ss;
      ss << "Failed to connect to service " << servInfo.name() << " on "
         << "machine " << servInfo.machineId() << ". All endpoints are "
         << "unavailable.";
      tsca.promise.setError(ss.str());
    } // ! boost::mutex::scoped_lock
  }

  /*
   * Corner case to manage (TODO):
   *
   * You are connecting to machineId foo, you are machineId bar. foo and bar are
   * on different sub-networks with the same netmask. They sadly got the same IP
   * on their subnet: 192.168.1.42. When trying to connect to foo from bar, we
   * will try to connect its endpoints, basically:
   *   - tcp://1.2.3.4:1333 (public IP)
   *   - tcp://192.168.1.42:1333 (subnet public IP)
   * If bar is listening on port 1333, we may connect to it instead of foo (our
   * real target).
   */
  void TransportSocketCache::onSocketConnected(TransportSocketPtr socket, const qi::ServiceInfo& servInfo, const qi::Url& url) {
    {
      boost::mutex::scoped_lock sl(_socketsMutex);

      MachineAttemptsMap::iterator mamIt;
      if ((mamIt = _attempts.find(servInfo.machineId())) == _attempts.end()) {
        // Unknown error. This shouldn't happen...
        return;
      }
      TransportSocketConnectionAttempt& tsca = mamIt->second;

      if (_dying) {
        tsca.promise.setError("TransportSocketCache is closed.");
        return;
      }

      if (tsca.successful) {
        // If we are already connected to this service, disconnect this socket.
        tsca.socket_count--;
        socket->disconnect();
        return;
      }

      // Else, we set promise to this socket. We have a winner.
      MachineConnectionMap::iterator mcmIt;
      if ((mcmIt = _sockets.find(servInfo.machineId())) != _sockets.end()) {
        TransportSocketConnectionMap& tscm = mcmIt->second;
        TransportSocketConnectionMap::iterator tscmIt;
        if ((tscmIt = tscm.find(url.str())) != tscm.end()) {
          tscmIt->second.promise.setValue(socket);
          tsca.successful = true;
        }
      }
    } // ! boost::mutex::scoped_lock
  }
}
<commit_msg>fix connection problems when more than one endpoint is available.<commit_after>/*
**  Copyright (C) 2012 Aldebaran Robotics
**  See COPYING for the license
*/
#include "transportsocketcache.hpp"

namespace qi {

  TransportSocketCache::~TransportSocketCache() {
    close();
  }

  void TransportSocketCache::init() {
    boost::mutex::scoped_lock sl(_socketsMutex);
    _dying = false;
  }

  void TransportSocketCache::close() {
    {
      _dying = true;
      MachineConnectionMap socketsCopy;
      {
        // Do not hold _socketsMutex while iterating or deadlock may occurr
        // between disconnect() that waits for callback handler
        // and callback handler that tries to acquire _socketsMutex
        boost::mutex::scoped_lock sl(_socketsMutex);
        socketsCopy = _sockets;
      }
      MachineConnectionMap::iterator mcmIt;
      for (mcmIt = socketsCopy.begin(); mcmIt != socketsCopy.end(); ++mcmIt) {
        TransportSocketConnectionMap& tscm = mcmIt->second;
        TransportSocketConnectionMap::iterator tscmIt;
        for (tscmIt = tscm.begin(); tscmIt != tscm.end(); ++tscmIt) {
          TransportSocketConnection& tsc = tscmIt->second;
          tsc.socket->disconnected.disconnect(tscmIt->second.disconnectLink);
          tsc.socket->connected.disconnect(tscmIt->second.connectLink);
          //remove callback before calling disconnect. (we dont need them)
          if (tscmIt->second.socket->isConnected())
            tscmIt->second.socket->disconnect();
          tscmIt->second.promise.setError("session closed");
        }
      }
    }
  }

  qi::Future<qi::TransportSocketPtr> TransportSocketCache::socket(const ServiceInfo& servInfo) {
    qi::UrlVector endpoints;
    qi::UrlVector::const_iterator urlIt;

    bool local = servInfo.machineId() == qi::os::getMachineId();

    // RFC 3330 - http://tools.ietf.org/html/rfc3330
    //   -> 127.0.0.0/8 is assigned to loopback address.
    //
    // This filters endpoints. If we are on the same machine, we just try to
    // connect on the loopback address, else we will try on all endpoints we
    // have that are not loopback.
    for (urlIt = servInfo.endpoints().begin(); urlIt != servInfo.endpoints().end(); ++urlIt) {
      qi::Url url = *urlIt;
      if (!url.isValid())
        continue;
      if (url.host().substr(0, 4) == "127.") {
        if (local) {
          endpoints.push_back(url);
          break;
        }
      } else if (!local) {
        endpoints.push_back(url);
      }
    }

    {
      boost::mutex::scoped_lock sl(_socketsMutex);
      if (_dying)
        return qi::makeFutureError<qi::TransportSocketPtr>("TransportSocketCache is closed.");

      // From here, we will see if we have a pending/established connection to
      // machineId on one of the endpoints (they all share the same promise
      // anyway). If it is the case, we return its future.
      MachineConnectionMap::iterator mcmIt;
      if ((mcmIt = _sockets.find(servInfo.machineId())) != _sockets.end()) {
        TransportSocketConnectionMap& tscm = mcmIt->second;
        TransportSocketConnectionMap::iterator tscmIt;
        for (urlIt = endpoints.begin(); urlIt != endpoints.end(); ++urlIt) {
          if ((tscmIt = tscm.find((*urlIt).str())) != tscm.end()) {
            TransportSocketConnection& tsc = tscmIt->second;
            if (tsc.promise.future().hasError()) {
              // When we have a socket with an error, we will try to connect to
              // all endpoints in case the old one is completely down.
              continue;
            }
            qiLogVerbose("tsc.socket") << "A connection is pending or already"
                                       << " established.";
            return tsc.promise.future();
          }
        }
      }

      // Launching connections to all endpoints at the same time. They all share
      // the same promise.
      qi::Promise<qi::TransportSocketPtr> prom;

      // We will need this to report error (to know if all sockets didn't
      // connect).
      TransportSocketConnectionAttempt& tsca = _attempts[servInfo.machineId()];
      tsca.promise = prom;
      tsca.socket_count = 0;
      tsca.successful = false;

      // This part launches all the socket connections on the same promise. The
      // first socket to connect is the winner.
      TransportSocketConnectionMap& tscm = _sockets[servInfo.machineId()];
      for (urlIt = endpoints.begin(); urlIt != endpoints.end(); ++urlIt) {
        qi::Url url = *urlIt;
        qi::TransportSocketPtr socket = makeTransportSocket(url.protocol());
        TransportSocketConnection& tsc = tscm[url.str()];
        qiLogVerbose("tsc.socket") << "Attempting connection to " << url.str()
                                   << " of machine id " << servInfo.machineId();
        tsc.socket = socket;
        tsc.promise = prom;
        tsc.url = url;
        tsc.connectLink = socket->connected.connect(boost::bind(&TransportSocketCache::onSocketConnected, this, socket, servInfo, url));
        tsc.disconnectLink = socket->disconnected.connect(boost::bind(&TransportSocketCache::onSocketDisconnected, this, _1, socket, servInfo, url));
        socket->connect(url).async();
        tsca.socket_count++;
      }
      return prom.future();
    } // ! boost::mutex::scoped_lock
  }

  void TransportSocketCache::onSocketDisconnected(int error, TransportSocketPtr socket, const qi::ServiceInfo& servInfo, const qi::Url& url) {
    {
      boost::mutex::scoped_lock sl(_socketsMutex);

      // First, we get the attempts of the machineId. It is used to know if we
      // have pending connections to other endpoints.
      MachineAttemptsMap::iterator mamIt;
      if ((mamIt = _attempts.find(servInfo.machineId())) == _attempts.end()) {
        // Unknown error. This shouldn't happen...
        return;
      }
      TransportSocketConnectionAttempt& tsca = mamIt->second;

      if (_dying) {
        tsca.promise.setError("TransportSocketCache is closed.");
        return;
      }

      tsca.socket_count--;
      if (tsca.socket_count != 0) {
        // We still have some sockets attempting to connect to the service, so
        // we just ignore this disconnection.
        return;
      }

      // No socket can be created, we just return an error.
      std::stringstream ss;
      ss << "Failed to connect to service " << servInfo.name() << " on "
         << "machine " << servInfo.machineId() << ". All endpoints are "
         << "unavailable.";
      tsca.promise.setError(ss.str());
    } // ! boost::mutex::scoped_lock
  }

  /*
   * Corner case to manage (TODO):
   *
   * You are connecting to machineId foo, you are machineId bar. foo and bar are
   * on different sub-networks with the same netmask. They sadly got the same IP
   * on their subnet: 192.168.1.42. When trying to connect to foo from bar, we
   * will try to connect its endpoints, basically:
   *   - tcp://1.2.3.4:1333 (public IP)
   *   - tcp://192.168.1.42:1333 (subnet public IP)
   * If bar is listening on port 1333, we may connect to it instead of foo (our
   * real target).
   */
  void TransportSocketCache::onSocketConnected(TransportSocketPtr socket, const qi::ServiceInfo& servInfo, const qi::Url& url) {
    {
      boost::mutex::scoped_lock sl(_socketsMutex);

      MachineAttemptsMap::iterator mamIt;
      if ((mamIt = _attempts.find(servInfo.machineId())) == _attempts.end()) {
        // Unknown error. This shouldn't happen...
        return;
      }
      TransportSocketConnectionAttempt& tsca = mamIt->second;

      if (_dying) {
        tsca.promise.setError("TransportSocketCache is closed.");
        return;
      }

      if (tsca.successful) {
        // If we are already connected to this service, disconnect this socket.
        socket->disconnect();
        return;
      }

      // Else, we set promise to this socket. We have a winner.
      MachineConnectionMap::iterator mcmIt;
      if ((mcmIt = _sockets.find(servInfo.machineId())) != _sockets.end()) {
        TransportSocketConnectionMap& tscm = mcmIt->second;
        TransportSocketConnectionMap::iterator tscmIt;
        if ((tscmIt = tscm.find(url.str())) != tscm.end()) {
          tscmIt->second.promise.setValue(socket);
          tsca.successful = true;
        }
      }
    } // ! boost::mutex::scoped_lock
  }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <type_traits>

using std::cout;
using std::endl;

class JustBeforeReturnEvent {
    // ...
};

class CoutShouter {
public:
    static void handle(const JustBeforeReturnEvent& evt) {
        cout << "Goodbye!\n";
    }
};

class QuietGuy {};

template <typename... Args>
struct type_list;

template <typename Type>
struct type_list<Type> {
    using head = Type;
};

template <typename Head, typename... Tail>
struct type_list<Head, Tail...> : type_list<Head> {
    using tail = type_list<Tail...>;
};

template <typename List>
class has_tail_1 {
    template <typename X>
    static std::true_type test(typename X::tail* x = 0);

    template <typename X>
    static std::false_type test(...);

public:
    static constexpr bool value = decltype(test<List>(0))();
};

template <typename...>
using void_t = void;

template <typename, typename = void>
struct has_tail_2 : std::false_type {};

template <typename T>
struct has_tail_2<T, void_t<typename T::tail>> : std::true_type {};

template <typename T, typename = void>
struct count : std::integral_constant<int, 1> {};

template <typename T>
struct count<T, void_t<typename T::tail>> :
    std::integral_constant<int, 1 + count<typename T::tail>()>
{};

template <typename Listeners>
class Dispatcher {
    template <typename Handler, typename Evt, typename = void>
    struct has_handler : std::false_type {};

    template <typename Handler, typename Evt>
    struct has_handler<Handler, Evt, decltype( Handler::handle( std::declval<const Evt&>() ) )> :
        std::true_type {};

    template <typename Evt, typename List, bool HasTail, typename = void>
    struct post_impl;

    // Case 1: no tail, has a handler
    template <typename Evt, typename List>
    struct post_impl<Evt, List, true,
                     typename std::enable_if<
                        has_handler<typename List::head, Evt>::value
                     >::type>
    {
        static void call(const Evt& evt) {
            cout << "I've got a tail";
            List::head::handle(evt);
            using Tail = typename List::tail;
            post_impl<Evt, Tail, has_tail_2<Tail>::value>::call(evt);
        }
    };

    // Case 2: has no tail, has a handler
    template <typename Evt, typename List>
    struct post_impl<Evt, List, false,
                     typename std::enable_if<
                        has_handler<typename List::head, Evt>::value
                     >::type>
    {
        static void call(const Evt& evt) {
            cout << "I don't";
            List::head::handle(evt);
        }
    };

    // Case 3: has a tail, has no handler

public:
    template <typename Evt>
    static void post(const Evt& t) {
        post_impl<Evt, Listeners, has_tail_2<Listeners>::value>::call(t);
    }
};

int main() {
    using listeners = type_list<CoutShouter>;
    using listeners_2 = type_list<CoutShouter, CoutShouter>;

    cout << has_tail_1<listeners>::value << endl;
    cout << has_tail_2<listeners_2>() << endl;

    cout << count<listeners>() << endl;
    cout << count<listeners_2>() << endl;

    cout << "listeners 1: ";
    Dispatcher<listeners>::post(JustBeforeReturnEvent{});

    cout << "listeners_2: ";
    Dispatcher<listeners_2>::post(JustBeforeReturnEvent{});
    return 0;
}<commit_msg>Now we're cooking with fire!<commit_after>#include <iostream>
#include <type_traits>

using std::cout;
using std::endl;

class JustBeforeReturnEvent {
    // ...
};

class CoutShouter {
public:
    static void handle(const JustBeforeReturnEvent& evt) {
        cout << "Goodbye!\n";
    }
};

class QuietGuy {};

template <typename... Args>
struct type_list;

template <typename Type>
struct type_list<Type> {
    using head = Type;
};

template <typename Head, typename... Tail>
struct type_list<Head, Tail...> : type_list<Head> {
    using tail = type_list<Tail...>;
};

template <typename List>
class has_tail_1 {
    template <typename X>
    static std::true_type test(typename X::tail* x = 0);

    template <typename X>
    static std::false_type test(...);

public:
    static constexpr bool value = decltype(test<List>(0))();
};

template <typename...>
using void_t = void;

template <typename, typename = void>
struct has_tail_2 : std::false_type {};

template <typename T>
struct has_tail_2<T, void_t<typename T::tail>> : std::true_type {};

template <typename T, typename = void>
struct count : std::integral_constant<int, 1> {};

template <typename T>
struct count<T, void_t<typename T::tail>> :
    std::integral_constant<int, 1 + count<typename T::tail>()>
{};

template <typename Listeners>
class Dispatcher {
    template <typename Handler, typename Evt, typename = void>
    struct has_handler : std::false_type {};

    template <typename Handler, typename Evt>
    struct has_handler<Handler, Evt, decltype( Handler::handle( std::declval<const Evt&>() ) )> :
        std::true_type {};

    template <typename Evt, typename List, bool HasTail, bool HasHandler>
    struct post_impl;

    // Case 1: Has tail, has a handler
    template <typename Evt, typename List>
    struct post_impl<Evt, List, true, true>
    {
        static void call(const Evt& evt) {
            List::head::handle(evt);
            using Tail = typename List::tail;
            constexpr bool has_handler_v = has_handler<typename Tail::head, Evt>::value;
            post_impl<Evt, Tail, has_tail_2<Tail>::value, has_handler_v>::call(evt);
        }
    };

    // Case 2: Has no tail, has a handler
    template <typename Evt, typename List>
    struct post_impl<Evt, List, false, true>
    {
        static void call(const Evt& evt) {
            List::head::handle(evt);
        }
    };

    // Case 3: Has tail, has no handler
    template <typename Evt, typename List>
    struct post_impl<Evt, List, true, false>
    {
        static void call(const Evt& evt) {
            using Tail = typename List::tail;
            constexpr bool has_handler_v = has_handler<typename Tail::head, Evt>::value;
            post_impl<Evt, Tail, has_tail_2<Tail>::value, has_handler_v>::call(evt);
        }
    };

    // Case 4: Has no tail, has no handler
    template <typename Evt, typename List>
    struct post_impl<Evt, List, false, false>
    {
        static void call(const Evt& evt) {
            // do nothing.
        }
    };

public:
    template <typename Evt>
    static void post(const Evt& t) {
        constexpr bool has_handler_v = has_handler<typename Listeners::head, Evt>::value;
        post_impl<Evt, Listeners, has_tail_2<Listeners>::value, has_handler_v>::call(t);
    }
};

int main() {
    using listeners = type_list<CoutShouter, QuietGuy>;
    using listeners_2 = type_list<CoutShouter, CoutShouter>;
    using listeners_3 = type_list<QuietGuy, QuietGuy, QuietGuy, QuietGuy>;

    cout << has_tail_1<listeners>::value << endl;
    cout << has_tail_2<listeners_2>() << endl;

    cout << count<listeners>() << endl;
    cout << count<listeners_2>() << endl;

    cout << "listeners 1: ";
    Dispatcher<listeners>::post(JustBeforeReturnEvent{});

    cout << "listeners_2: ";
    Dispatcher<listeners_2>::post(JustBeforeReturnEvent{});

    cout << "listeners_3: ";
    Dispatcher<listeners_3>::post(JustBeforeReturnEvent{});
    return 0;
}<|endoftext|>


<commit_before>#pragma once

#include <cmath>
#include <limits>

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

namespace _acmacs_base_internal
{
    template <char Tag> class SizeScale
    {
     public:
        inline SizeScale() : mValue(0) {}
        inline explicit SizeScale(double aValue) : mValue(aValue) {}
          // inline SizeScale(const SizeScale& a) = default;
        inline SizeScale& operator = (double aValue) { mValue = aValue; return *this; }
        inline double value() const { return mValue; }
        inline SizeScale operator / (double a) const { return SizeScale{mValue / a}; }
        inline SizeScale operator * (double a) const { return SizeScale{mValue * a}; }
        inline SizeScale& operator *= (double a) { mValue *= a; return *this; }
        inline SizeScale operator - () const { return SizeScale{- mValue}; }
        inline bool empty() const { return std::isnan(mValue); }
        static SizeScale make_empty() { return SizeScale(std::numeric_limits<double>::quiet_NaN()); }

     private:
        double mValue;
    };
}

using Pixels = _acmacs_base_internal::SizeScale<'P'>; // size in pixels, indepenent from the surface internal coordinate system
using Scaled = _acmacs_base_internal::SizeScale<'S'>; // size in the surface internal coordinate system

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

using Aspect = _acmacs_base_internal::SizeScale<'A'>;
using Rotation = _acmacs_base_internal::SizeScale<'R'>;

#include "acmacs-base/global-constructors-push.hh"

const Rotation NoRotation{0.0};
const Aspect AspectNormal{1.0};

#include "acmacs-base/diagnostics-pop.hh"

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<commit_msg>minor improvement<commit_after>#pragma once

#include <cmath>
#include <limits>

#include "float.hh"

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

namespace _acmacs_base_internal
{
    template <char Tag> class SizeScale
    {
     public:
        inline SizeScale() : mValue(0) {}
        inline explicit SizeScale(double aValue) : mValue(aValue) {}
          // inline SizeScale(const SizeScale& a) = default;
        inline bool operator==(SizeScale a) const { return float_equal(mValue, a.mValue); }
        inline SizeScale& operator = (double aValue) { mValue = aValue; return *this; }
        inline double value() const { return mValue; }
        inline SizeScale operator / (double a) const { return SizeScale{mValue / a}; }
        inline SizeScale operator * (double a) const { return SizeScale{mValue * a}; }
        inline SizeScale& operator *= (double a) { mValue *= a; return *this; }
        inline SizeScale operator - () const { return SizeScale{- mValue}; }
        inline bool empty() const { return std::isnan(mValue); }
        static SizeScale make_empty() { return SizeScale(std::numeric_limits<double>::quiet_NaN()); }

     private:
        double mValue;
    };
}

using Pixels = _acmacs_base_internal::SizeScale<'P'>; // size in pixels, indepenent from the surface internal coordinate system
using Scaled = _acmacs_base_internal::SizeScale<'S'>; // size in the surface internal coordinate system

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

using Aspect = _acmacs_base_internal::SizeScale<'A'>;
using Rotation = _acmacs_base_internal::SizeScale<'R'>;

#include "acmacs-base/global-constructors-push.hh"

const Rotation NoRotation{0.0};
const Aspect AspectNormal{1.0};

#include "acmacs-base/diagnostics-pop.hh"

// ----------------------------------------------------------------------
/// Local Variables:
/// eval: (if (fboundp 'eu-rename-buffer) (eu-rename-buffer))
/// End:
<|endoftext|>


<commit_before>//===--- RIFF.cpp - Binary container file format --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "RIFF.h"
#include "llvm/Support/Endian.h"

using namespace llvm;
namespace clang {
namespace clangd {
namespace riff {

static Error makeError(const char *Msg) {
  return createStringError(inconvertibleErrorCode(), Msg);
}

Expected<Chunk> readChunk(StringRef &Stream) {
  if (Stream.size() < 8)
    return makeError("incomplete chunk header");
  Chunk C;
  std::copy(Stream.begin(), Stream.begin() + 4, C.ID.begin());
  Stream = Stream.drop_front(4);
  uint32_t Len = support::endian::read32le(Stream.take_front(4).begin());
  Stream = Stream.drop_front(4);
  if (Stream.size() < Len)
    return makeError("truncated chunk");
  C.Data = Stream.take_front(Len);
  Stream = Stream.drop_front(Len);
  if (Len % 2 & !Stream.empty()) { // Skip padding byte.
    if (Stream.front())
      return makeError("nonzero padding byte");
    Stream = Stream.drop_front();
  }
  return std::move(C);
};

raw_ostream &operator<<(raw_ostream &OS, const Chunk &C) {
  OS.write(C.ID.data(), C.ID.size());
  char Size[4];
  llvm::support::endian::write32le(Size, C.Data.size());
  OS.write(Size, sizeof(Size));
  OS << C.Data;
  if (C.Data.size() % 2)
    OS.write(0);
  return OS;
}

llvm::Expected<File> readFile(llvm::StringRef Stream) {
  auto RIFF = readChunk(Stream);
  if (!RIFF)
    return RIFF.takeError();
  if (RIFF->ID != fourCC("RIFF"))
    return makeError("not a RIFF container");
  if (RIFF->Data.size() < 4)
    return makeError("RIFF chunk too short");
  File F;
  std::copy(RIFF->Data.begin(), RIFF->Data.begin() + 4, F.Type.begin());
  for (llvm::StringRef Body = RIFF->Data.drop_front(4); !Body.empty();)
    if (auto Chunk = readChunk(Body)) {
      F.Chunks.push_back(*Chunk);
    } else
      return Chunk.takeError();
  return std::move(F);
}

raw_ostream &operator<<(raw_ostream &OS, const File &F) {
  // To avoid copies, we serialize the outer RIFF chunk "by hand".
  size_t DataLen = 4; // Predict length of RIFF chunk data.
  for (const auto &C : F.Chunks)
    DataLen += 4 + 4 + C.Data.size() + (C.Data.size() % 2);
  OS << "RIFF";
  char Size[4];
  llvm::support::endian::write32le(Size, DataLen);
  OS.write(Size, sizeof(Size));
  OS.write(F.Type.data(), F.Type.size());
  for (const auto &C : F.Chunks)
    OS << C;
  return OS;
}

} // namespace riff
} // namespace clangd
} // namespace clang
<commit_msg>Remove unnecessary semicolon to silence -Wpedantic warning. NFCI.<commit_after>//===--- RIFF.cpp - Binary container file format --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "RIFF.h"
#include "llvm/Support/Endian.h"

using namespace llvm;
namespace clang {
namespace clangd {
namespace riff {

static Error makeError(const char *Msg) {
  return createStringError(inconvertibleErrorCode(), Msg);
}

Expected<Chunk> readChunk(StringRef &Stream) {
  if (Stream.size() < 8)
    return makeError("incomplete chunk header");
  Chunk C;
  std::copy(Stream.begin(), Stream.begin() + 4, C.ID.begin());
  Stream = Stream.drop_front(4);
  uint32_t Len = support::endian::read32le(Stream.take_front(4).begin());
  Stream = Stream.drop_front(4);
  if (Stream.size() < Len)
    return makeError("truncated chunk");
  C.Data = Stream.take_front(Len);
  Stream = Stream.drop_front(Len);
  if (Len % 2 & !Stream.empty()) { // Skip padding byte.
    if (Stream.front())
      return makeError("nonzero padding byte");
    Stream = Stream.drop_front();
  }
  return std::move(C);
}

raw_ostream &operator<<(raw_ostream &OS, const Chunk &C) {
  OS.write(C.ID.data(), C.ID.size());
  char Size[4];
  llvm::support::endian::write32le(Size, C.Data.size());
  OS.write(Size, sizeof(Size));
  OS << C.Data;
  if (C.Data.size() % 2)
    OS.write(0);
  return OS;
}

llvm::Expected<File> readFile(llvm::StringRef Stream) {
  auto RIFF = readChunk(Stream);
  if (!RIFF)
    return RIFF.takeError();
  if (RIFF->ID != fourCC("RIFF"))
    return makeError("not a RIFF container");
  if (RIFF->Data.size() < 4)
    return makeError("RIFF chunk too short");
  File F;
  std::copy(RIFF->Data.begin(), RIFF->Data.begin() + 4, F.Type.begin());
  for (llvm::StringRef Body = RIFF->Data.drop_front(4); !Body.empty();)
    if (auto Chunk = readChunk(Body)) {
      F.Chunks.push_back(*Chunk);
    } else
      return Chunk.takeError();
  return std::move(F);
}

raw_ostream &operator<<(raw_ostream &OS, const File &F) {
  // To avoid copies, we serialize the outer RIFF chunk "by hand".
  size_t DataLen = 4; // Predict length of RIFF chunk data.
  for (const auto &C : F.Chunks)
    DataLen += 4 + 4 + C.Data.size() + (C.Data.size() % 2);
  OS << "RIFF";
  char Size[4];
  llvm::support::endian::write32le(Size, DataLen);
  OS.write(Size, sizeof(Size));
  OS.write(F.Type.data(), F.Type.size());
  for (const auto &C : F.Chunks)
    OS << C;
  return OS;
}

} // namespace riff
} // namespace clangd
} // namespace clang
<|endoftext|>


<commit_before>/*
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "qtscriptcomponent.h"

#include <QtScript/QScriptEngine>

#include <gameobject.h>
#include <core/debughelper.h>

REGISTER_OBJECTTYPE(GluonEngine, QtScriptComponent)

using namespace GluonEngine;

class QtScriptComponent::QtScriptComponentPrivate
{
    public:
        QtScriptComponentPrivate() { }

        QString code;
        QScriptEngine engine;

        QScriptValue script;
};

QtScriptComponent::QtScriptComponent ( QObject* parent ) : Component ( parent )
{
    d = new QtScriptComponentPrivate;
}

QtScriptComponent::QtScriptComponent ( const QtScriptComponent& other )
    : Component ( other ),
    d(other.d)
{
}

QtScriptComponent::~QtScriptComponent()
{

}

GluonCore::GluonObject* QtScriptComponent::instantiate()
{
    return new QtScriptComponent(this);
}

void QtScriptComponent::start()
{
    d->script = d->engine.evaluate(code());
    QScriptValue object = d->engine.newQObject(gameObject());
    d->engine.globalObject().setProperty("gameObject", object);

    QScriptValue startFunc = d->engine.globalObject().property("start");
    if(startFunc.isFunction())
        startFunc.call();
}

void QtScriptComponent::draw ( int timeLapse )
{
    QScriptValue drawFunc = d->engine.globalObject().property("draw");
    if(drawFunc.isFunction())
        drawFunc.call(QScriptValue(), QScriptValueList() << timeLapse);
}

void QtScriptComponent::update ( int elapsedMilliseconds )
{
    QScriptValue updateFunc = d->engine.globalObject().property("update");
    if(updateFunc.isFunction())
        updateFunc.call(QScriptValue(), QScriptValueList() << elapsedMilliseconds);
}

QString QtScriptComponent::code()
{
    return d->code;
}

void QtScriptComponent::setCode(const QString& code)
{
    d->code = code;
}

Q_EXPORT_PLUGIN2(gluon_component_qtscript, GluonEngine::QtScriptComponent);

#include "qtscriptcomponent.moc"
<commit_msg>Add some debug output and more global objects to the scritable component<commit_after>/*
   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License version 2 as published by the Free Software Foundation.

   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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
*/

#include "qtscriptcomponent.h"

#include <QtScript/QScriptEngine>
#include <QtCore/QDebug>

#include <gameobject.h>
#include <core/debughelper.h>
#include <game.h>

REGISTER_OBJECTTYPE(GluonEngine, QtScriptComponent)

using namespace GluonEngine;

class QtScriptComponent::QtScriptComponentPrivate
{
    public:
        QtScriptComponentPrivate() { }

        QString code;
        QScriptEngine engine;
        QScriptValue thisObject;
};

QtScriptComponent::QtScriptComponent ( QObject* parent ) : Component ( parent )
{
    d = new QtScriptComponentPrivate;
}

QtScriptComponent::QtScriptComponent ( const QtScriptComponent& other )
    : Component ( other ),
    d(other.d)
{
}

QtScriptComponent::~QtScriptComponent()
{

}

GluonCore::GluonObject* QtScriptComponent::instantiate()
{
    return new QtScriptComponent(this);
}

void QtScriptComponent::start()
{
    d->engine.evaluate(code(), gameObject()->name());
    if(!d->engine.uncaughtException().isNull()) {
        qDebug() << d->engine.uncaughtException().toString();
        qDebug() << d->engine.uncaughtExceptionBacktrace().join(" ");
        return;
    }

    d->thisObject = d->engine.newQObject(this);
    d->engine.globalObject().setProperty("Component", d->thisObject);

    QScriptValue object = d->engine.newQObject(gameObject());
    d->engine.globalObject().setProperty("GameObject", object);

    object = d->engine.newQObject(Game::instance());
    d->engine.globalObject().setProperty("Game", object);

    QScriptValue startFunc = d->engine.globalObject().property("start");
    if(startFunc.isFunction()) {
        startFunc.call(d->thisObject);
        if(!d->engine.uncaughtException().isNull()) {
            qDebug() << d->engine.uncaughtException().toString();
            qDebug() << d->engine.uncaughtExceptionBacktrace().join(" ");
        }
    }
}

void QtScriptComponent::draw ( int timeLapse )
{
    QScriptValue drawFunc = d->engine.globalObject().property("draw");
    if(drawFunc.isFunction()) {
        drawFunc.call(d->thisObject, QScriptValueList() << timeLapse);
        if(!d->engine.uncaughtException().isNull()) {
            qDebug() << d->engine.uncaughtException().toString();
            qDebug() << d->engine.uncaughtExceptionBacktrace().join(" ");
        }
    }
}

void QtScriptComponent::update ( int elapsedMilliseconds )
{
    QScriptValue updateFunc = d->engine.globalObject().property("update");
    if(updateFunc.isFunction()) {
        updateFunc.call(d->thisObject, QScriptValueList() << elapsedMilliseconds);
        if(!d->engine.uncaughtException().isNull()) {
            qDebug() << d->engine.uncaughtException().toString();
            qDebug() << d->engine.uncaughtExceptionBacktrace().join(" ");
        }
    }
}

QString QtScriptComponent::code()
{
    return d->code;
}

void QtScriptComponent::setCode(const QString& code)
{
    d->code = code;
}

Q_EXPORT_PLUGIN2(gluon_component_qtscript, GluonEngine::QtScriptComponent);

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