<commit_before>#include "LuaBinding.h"
#include <iostream>
#include <vector>
#include "MyActor.h"
#include "MyActorBinding.h"

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

void run( lua_State *L, const char *code )
{
    cout << "code> " << code << endl;

    if( luaL_dostring( L, code ) )
    {
        cout << lua_tostring( L, -1 ) << endl;
        lua_pop( L, 1 );
    }
}

typedef std::vector<MyActorPtr> MyActorPtrList;

MyActorPtrList createList()
{
    const char* names[] = {
        "James",
        "Who? Random extra",
        "Harry",
        "Mike",
        nullptr
    };

    MyActorPtrList actors;

    for( int i = 0; names[i] != nullptr; i++ )
    {
        actors.push_back( std::make_shared<MyActor>( names[i] ) );
    }

    return actors;
}

void pushToLua( lua_State* L, MyActorPtrList list )
{
    lua_newtable( L );

    int index = 1;
    for( auto ap = list.begin(); ap != list.end(); ap++ ) {
        MyActorBinding::push( L, *ap );
        lua_rawseti( L, -2, index++ );
    }
}

MyActorPtrList pullFromLua( lua_State* L )
{
    // Note this only stores the values, not the keys/indexes,
    // which are usually just numbers.
    MyActorPtrList list;

    if( lua_istable( L, -1 ) )
    {
        lua_pushnil( L );

        while( lua_next( L, -2 ) )
        {
            if( luaL_testudata( L, -1, "MyActor" ) )
            {
                list.push_back( MyActorBinding::fromStack( L, -1 ) );
            }
            lua_pop( L, 1 );
        }
    }

    return list;
}

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs( L );

    MyActorBinding::register_class( L );

    {
        cout << "Pushing actor list to Lua." << endl;
        MyActorPtrList actors = createList();
        pushToLua( L, actors );
        lua_setglobal( L, "actors" );
    }

    cout << "Editing actor list..." << endl;
    run( L, "actors[2] = nil                    -- Who is this? Pfft, delete." );
    run( L, "collectgarbage()" );
    run( L, "actors['test'] = MyActor('Bob')    -- Hey Bob welcome." );

    run( L, "for k,v in pairs(actors) do print( k, v.name ) end" );

    {
        cout << "Pull list back into C++ vector, and list..." << endl;
        lua_getglobal( L, "actors" );
        MyActorPtrList actors = pullFromLua( L );
        lua_pop( L, 1 );

        for( auto ap = actors.begin(); ap != actors.end(); ap++ )
        {
            cout << (*ap)->_name << endl;
        }
    }

    lua_close(L);
}
<commit_msg>Use Lua ref func rather than index.<commit_after>#include "LuaBinding.h"
#include <iostream>
#include <vector>
#include "MyActor.h"
#include "MyActorBinding.h"

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

void run( lua_State *L, const char *code )
{
    cout << "code> " << code << endl;

    if( luaL_dostring( L, code ) )
    {
        cout << lua_tostring( L, -1 ) << endl;
        lua_pop( L, 1 );
    }
}

typedef std::vector<MyActorPtr> MyActorPtrList;

MyActorPtrList createList()
{
    const char* names[] = {
        "James",
        "Who? Random extra",
        "Harry",
        "Mike",
        nullptr
    };

    MyActorPtrList actors;

    for( int i = 0; names[i] != nullptr; i++ )
    {
        actors.push_back( std::make_shared<MyActor>( names[i] ) );
    }

    return actors;
}

void pushToLua( lua_State* L, MyActorPtrList list )
{
    lua_newtable( L );

    for( auto ap = list.begin(); ap != list.end(); ap++ ) {
        MyActorBinding::push( L, *ap );
        luaL_ref( L, -2 );
    }
}

MyActorPtrList pullFromLua( lua_State* L )
{
    // Note this only stores the values, not the keys/indexes,
    // which are usually just numbers.
    MyActorPtrList list;

    if( lua_istable( L, -1 ) )
    {
        lua_pushnil( L );

        while( lua_next( L, -2 ) )
        {
            if( luaL_testudata( L, -1, "MyActor" ) )
            {
                list.push_back( MyActorBinding::fromStack( L, -1 ) );
            }
            lua_pop( L, 1 );
        }
    }

    return list;
}

int main()
{
    lua_State* L = luaL_newstate();
    luaL_openlibs( L );

    MyActorBinding::register_class( L );

    {
        cout << "Pushing actor list to Lua." << endl;
        MyActorPtrList actors = createList();
        pushToLua( L, actors );
        lua_setglobal( L, "actors" );
    }

    run( L, "for k,v in pairs(actors) do print( k, v.name ) end" );

    cout << "Editing actor list..." << endl;
    run( L, "actors[2] = nil                    -- Who is this? Pfft, delete." );
    run( L, "collectgarbage()" );
    run( L, "actors['test'] = MyActor('Bob')    -- Hey Bob welcome." );

    run( L, "for k,v in pairs(actors) do print( k, v.name ) end" );

    {
        cout << "Pull list back into C++ vector, and list..." << endl;
        lua_getglobal( L, "actors" );
        MyActorPtrList actors = pullFromLua( L );
        lua_pop( L, 1 );

        for( auto ap = actors.begin(); ap != actors.end(); ap++ )
        {
            cout << (*ap)->_name << endl;
        }
    }

    lua_close(L);
}
<|endoftext|>


<commit_before>
// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <MmRequestProxy.h>
#include <MmIndicationWrapper.h>
#include <MmDebugIndicationWrapper.h>
#include <MmDebugRequestProxy.h>
#include <DmaConfigProxy.h>
#include <GeneratedTypes.h>
//#include <DmaIndicationWrapper.h>
#include <StdDmaIndication.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <errno.h>
#include <math.h> // frexp(), fabs()
#include <assert.h>
#include "portalmat.h"
#include "mnist.h"

static int verbose = 0;

class SigmoidIndication;
class MmIndication;
class MmDebugIndication;

#define N 2

RbmRequestProxy *rbmdevice = 0;
MmRequestProxy *mmdevice = 0;
MmDebugRequestProxy *mmdebug = 0;
SigmoidIndication *sigmoidindication = 0;
SigmoidRequestProxy *sigmoiddevice = 0;
TimerRequestProxy *timerdevice = 0;
MmIndication *mmdeviceIndication = 0;
MmDebugIndication *mmDebugIndication = 0;
TimerIndication *timerdeviceIndication = 0;
DmaConfigProxy *dmap = 0;
DmaIndicationWrapper *dmaIndication = 0;

long dotprod = 0;

void dump(const char *prefix, char *buf, size_t len)
{
    fprintf(stderr, "%s ", prefix);
    for (int i = 0; i < (len > 64 ? 64 : len) ; i++) {
	fprintf(stderr, "%02x", (unsigned char)buf[i]);
	if (i % 4 == 3)
	  fprintf(stderr, " ");
    }
    fprintf(stderr, "\n");
}

void *dbgThread(void *)
{
  while (1) {
    sleep(2);
    if (dmap) {
      //dmap->getStateDbg(ChannelType_Read);
    }
    if (mmdebug) {
      fprintf(stderr, "Calling mmdebug->debug()\n");
      mmdebug->debug();
    }
  }
  return 0;
}

int main(int argc, const char **argv)
{
  unsigned int srcGen = 0;

  PortalPoller *poller = new PortalPoller();

  fprintf(stderr, "%s %s\n", __DATE__, __TIME__);
  mmdevice = new MmRequestProxy(IfcNames_MmRequestPortal);
  mmdebug = new MmDebugRequestProxy(IfcNames_MmDebugRequestPortal);
  mmdeviceIndication = new MmIndication(IfcNames_MmIndicationPortal);
  mmDebugIndication = new MmDebugIndication(IfcNames_MmDebugIndicationPortal);
  timerdevice = new TimerRequestProxy(IfcNames_TimerRequestPortal, poller);
  timerdeviceIndication = new TimerIndication(IfcNames_TimerIndicationPortal);

  dmap = new DmaConfigProxy(IfcNames_DmaConfigPortal);
  DmaManager *dma = new DmaManager(dmap);
  dmaIndication = new DmaIndication(dma, IfcNames_DmaIndicationPortal);

  if(sem_init(&mul_sem, 1, 0)){
    fprintf(stderr, "failed to init mul_sem\n");
    return -1;
  }

  pthread_t tid;
  fprintf(stderr, "creating exec thread\n");
  if(pthread_create(&tid, NULL,  portalExec, NULL)){
   fprintf(stderr, "error creating exec thread\n");
   exit(1);
  }

  long req_freq = 100000000;
  long freq = 0;
  poller->setClockFrequency(0, req_freq, &freq);
  fprintf(stderr, "Requested FCLK[0]=%d actually %d\n", req_freq, freq);

  matAllocator = new PortalMatAllocator(dmap, dma);

#define LARGE_MAT
#ifdef LARGE_MAT
#ifdef BSIM
  int A = 32;
  int B = 512;
#else
  int A = 256;
  int B = 2048;
#endif
  if (argc > 1) {
    B = strtoul(argv[1], 0, 0);
    A = 2*B;
  }
  cv::Mat m1(A,B,CV_32F);
  cv::Mat m2(B,A,CV_32F);
  float v = 0;
  for(int a = 0; a < A; a++){
    for(int b = 0; b < B; b++){
      m2.at<float>(b,a) = (A*B)+v;
      m1.at<float>(a,b) = v;
      v++;
    }
  }
#else
  cv::Mat m1 = (cv::Mat_<float>(4,8) <<
		11,12,13,14,15,16,17,18,
		21,22,23,24,25,26,27,28,
		31,32,33,34,35,36,37,38,
		41,42,43,44,45,46,47,48
		);
  cv::Mat m2 = (cv::Mat_<float>(8,4) <<
		51,62,53,54,
		55,56,57,58,
		61,62,63,64,
		65,66,67,68,
		71,72,73,74,
		75,76,77,78,
		81,82,83,84,
		85,86,87,88
		);
#endif

  FILE *octave_file = fopen("foo.m", "w");

  fprintf(stderr, "OpenCV matmul\n");
  start_timer(0);
  cv::Mat  m3 = m1 * m2;
  uint64_t opencv_hw_cycles = lap_timer(0);

  PortalMat tm3;
  fprintf(stderr, "Naive matmul\n");
  start_timer(0);
  tm3.naive_mul(m1,m2, octave_file);
  uint64_t naive_hw_cycles = lap_timer(0);

  bool sane = 1;
  if (1) {
    fprintf(stderr, "DumpMat\n");
    dumpMatOctave<float>("m1",  "%10.5f", m1,  octave_file);
    dumpMatOctave<float>("m2",  "%10.5f", m2,  octave_file);
    dumpMatOctave<float>("m3",  "%10.5f", m3,  octave_file);
    dumpMatOctave<float>("tm3", "%10.5f", tm3, octave_file);
    fclose(octave_file);
    sane = tm3.compare(m3, 0, 0, 0.0001, 0, false);
    fprintf(stderr, "sane=%d\n", sane);
    fflush(stdout);
  }

  fprintf(stderr, "pm1\n");
  PortalMat pm1(m1);
  fprintf(stderr, "pm2t\n");
  PortalMat pm2t(m2.t());
  PortalMat pm3;

  // now reference the matrices so we do not count that in the timer
  pm1.reference();
  pm2t.reference();
  pm3.create(m1.rows, m2.cols, CV_32F);
  pm3.reference();

  pthread_t dbgtid;
  fprintf(stderr, "creating debug thread\n");
  if(pthread_create(&dbgtid, NULL,  dbgThread, NULL)){
   fprintf(stderr, "error creating debug thread\n");
   exit(1);
  }

  fprintf(stderr, "HW matmul\n");
  start_timer(0);
  pm3.multf(pm1, pm2t, mmdeviceIndication);
  uint64_t hw_cycles = lap_timer(0);
  uint64_t read_beats = dma->show_mem_stats(ChannelType_Read);
  uint64_t write_beats = dma->show_mem_stats(ChannelType_Write);
  float read_util = (float)read_beats/(float)mmdeviceIndication->ccnt;
  float write_util = (float)write_beats/(float)mmdeviceIndication->ccnt;
  float read_bw = read_util * N * 4 * freq / 1.0e9;
  float write_bw = write_util * N * 4 * freq / 1.0e9;
  float macs = m1.rows * m2.rows * m2.cols;
  fprintf(stderr, "memory read  beats %lld utilization (beats/cycle): %f, bandwidth (GB/s): %f\n", read_beats, read_util, read_bw);
  fprintf(stderr, "memory write beats %lld utilization (beats/cycle): %f, bandwidth (GB/s): %f\n", write_beats, write_util, write_bw);
  fprintf(stderr, "Throughput %f macs/cycle hw %f macs/cycle %f GFLOP/s hw %f GFLOP/s\n",
	  (float)macs / (float)hw_cycles, (float)macs / (float)mmdeviceIndication->ccnt,
	  2.0 * (float)macs / (float)hw_cycles * freq / 1.0e9, 2.0 * (float)macs / (float)mmdeviceIndication->ccnt * freq / 1.0e9);
  fprintf(stderr, "Time %f cycles hw %f cycles, opencv matmul %f cycles (speedup %f hw %f), naive matmul %f cycles (speedup %f hw %f)\n",
	  (float)hw_cycles, (float)mmdeviceIndication->ccnt,
	  (float)opencv_hw_cycles, (float)opencv_hw_cycles/(float)hw_cycles, (float)opencv_hw_cycles/(float)mmdeviceIndication->ccnt,
	  (float)naive_hw_cycles, (float)naive_hw_cycles/(float)hw_cycles, (float)naive_hw_cycles/(float)mmdeviceIndication->ccnt);

  if (0) {
    dumpMat<float>("pm3", "%5.1f", pm3);
    dumpMat<float>(" m3", "%5.1f", m3);
  }
  //bool eq = std::equal(m3.begin<float>(), m3.end<float>(), pm3.begin<float>());
  bool eq = pm3.compare(pm3);
  fprintf(stderr, "eq=%d\n", eq);
  //device->finish();
  exit(!eq&&!sane);
}
<commit_msg>missed a reference to setClockFrequency<commit_after>
// Copyright (c) 2014 Quanta Research Cambridge, Inc.

// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies
// of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include <MmRequestProxy.h>
#include <MmIndicationWrapper.h>
#include <MmDebugIndicationWrapper.h>
#include <MmDebugRequestProxy.h>
#include <DmaConfigProxy.h>
#include <GeneratedTypes.h>
//#include <DmaIndicationWrapper.h>
#include <StdDmaIndication.h>
#include <stdio.h>
#include <sys/mman.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <semaphore.h>
#include <pthread.h>
#include <errno.h>
#include <math.h> // frexp(), fabs()
#include <assert.h>
#include "portalmat.h"
#include "mnist.h"

static int verbose = 0;

class SigmoidIndication;
class MmIndication;
class MmDebugIndication;

#define N 2

RbmRequestProxy *rbmdevice = 0;
MmRequestProxy *mmdevice = 0;
MmDebugRequestProxy *mmdebug = 0;
SigmoidIndication *sigmoidindication = 0;
SigmoidRequestProxy *sigmoiddevice = 0;
TimerRequestProxy *timerdevice = 0;
MmIndication *mmdeviceIndication = 0;
MmDebugIndication *mmDebugIndication = 0;
TimerIndication *timerdeviceIndication = 0;
DmaConfigProxy *dmap = 0;
DmaIndicationWrapper *dmaIndication = 0;

long dotprod = 0;

void dump(const char *prefix, char *buf, size_t len)
{
    fprintf(stderr, "%s ", prefix);
    for (int i = 0; i < (len > 64 ? 64 : len) ; i++) {
	fprintf(stderr, "%02x", (unsigned char)buf[i]);
	if (i % 4 == 3)
	  fprintf(stderr, " ");
    }
    fprintf(stderr, "\n");
}

void *dbgThread(void *)
{
  while (1) {
    sleep(2);
    if (dmap) {
      //dmap->getStateDbg(ChannelType_Read);
    }
    if (mmdebug) {
      fprintf(stderr, "Calling mmdebug->debug()\n");
      mmdebug->debug();
    }
  }
  return 0;
}

int main(int argc, const char **argv)
{
  unsigned int srcGen = 0;

  PortalPoller *poller = new PortalPoller();

  fprintf(stderr, "%s %s\n", __DATE__, __TIME__);
  mmdevice = new MmRequestProxy(IfcNames_MmRequestPortal);
  mmdebug = new MmDebugRequestProxy(IfcNames_MmDebugRequestPortal);
  mmdeviceIndication = new MmIndication(IfcNames_MmIndicationPortal);
  mmDebugIndication = new MmDebugIndication(IfcNames_MmDebugIndicationPortal);
  timerdevice = new TimerRequestProxy(IfcNames_TimerRequestPortal, poller);
  timerdeviceIndication = new TimerIndication(IfcNames_TimerIndicationPortal);

  dmap = new DmaConfigProxy(IfcNames_DmaConfigPortal);
  DmaManager *dma = new DmaManager(dmap);
  dmaIndication = new DmaIndication(dma, IfcNames_DmaIndicationPortal);

  if(sem_init(&mul_sem, 1, 0)){
    fprintf(stderr, "failed to init mul_sem\n");
    return -1;
  }

  pthread_t tid;
  fprintf(stderr, "creating exec thread\n");
  if(pthread_create(&tid, NULL,  portalExec, NULL)){
   fprintf(stderr, "error creating exec thread\n");
   exit(1);
  }

  long req_freq = 100000000;
  long freq = 0;
  setClockFrequency(0, req_freq, &freq);
  fprintf(stderr, "Requested FCLK[0]=%d actually %d\n", req_freq, freq);

  matAllocator = new PortalMatAllocator(dmap, dma);

#define LARGE_MAT
#ifdef LARGE_MAT
#ifdef BSIM
  int A = 32;
  int B = 512;
#else
  int A = 256;
  int B = 2048;
#endif
  if (argc > 1) {
    B = strtoul(argv[1], 0, 0);
    A = 2*B;
  }
  cv::Mat m1(A,B,CV_32F);
  cv::Mat m2(B,A,CV_32F);
  float v = 0;
  for(int a = 0; a < A; a++){
    for(int b = 0; b < B; b++){
      m2.at<float>(b,a) = (A*B)+v;
      m1.at<float>(a,b) = v;
      v++;
    }
  }
#else
  cv::Mat m1 = (cv::Mat_<float>(4,8) <<
		11,12,13,14,15,16,17,18,
		21,22,23,24,25,26,27,28,
		31,32,33,34,35,36,37,38,
		41,42,43,44,45,46,47,48
		);
  cv::Mat m2 = (cv::Mat_<float>(8,4) <<
		51,62,53,54,
		55,56,57,58,
		61,62,63,64,
		65,66,67,68,
		71,72,73,74,
		75,76,77,78,
		81,82,83,84,
		85,86,87,88
		);
#endif

  FILE *octave_file = fopen("foo.m", "w");

  fprintf(stderr, "OpenCV matmul\n");
  start_timer(0);
  cv::Mat  m3 = m1 * m2;
  uint64_t opencv_hw_cycles = lap_timer(0);

  PortalMat tm3;
  fprintf(stderr, "Naive matmul\n");
  start_timer(0);
  tm3.naive_mul(m1,m2, octave_file);
  uint64_t naive_hw_cycles = lap_timer(0);

  bool sane = 1;
  if (1) {
    fprintf(stderr, "DumpMat\n");
    dumpMatOctave<float>("m1",  "%10.5f", m1,  octave_file);
    dumpMatOctave<float>("m2",  "%10.5f", m2,  octave_file);
    dumpMatOctave<float>("m3",  "%10.5f", m3,  octave_file);
    dumpMatOctave<float>("tm3", "%10.5f", tm3, octave_file);
    fclose(octave_file);
    sane = tm3.compare(m3, 0, 0, 0.0001, 0, false);
    fprintf(stderr, "sane=%d\n", sane);
    fflush(stdout);
  }

  fprintf(stderr, "pm1\n");
  PortalMat pm1(m1);
  fprintf(stderr, "pm2t\n");
  PortalMat pm2t(m2.t());
  PortalMat pm3;

  // now reference the matrices so we do not count that in the timer
  pm1.reference();
  pm2t.reference();
  pm3.create(m1.rows, m2.cols, CV_32F);
  pm3.reference();

  pthread_t dbgtid;
  fprintf(stderr, "creating debug thread\n");
  if(pthread_create(&dbgtid, NULL,  dbgThread, NULL)){
   fprintf(stderr, "error creating debug thread\n");
   exit(1);
  }

  fprintf(stderr, "HW matmul\n");
  start_timer(0);
  pm3.multf(pm1, pm2t, mmdeviceIndication);
  uint64_t hw_cycles = lap_timer(0);
  uint64_t read_beats = dma->show_mem_stats(ChannelType_Read);
  uint64_t write_beats = dma->show_mem_stats(ChannelType_Write);
  float read_util = (float)read_beats/(float)mmdeviceIndication->ccnt;
  float write_util = (float)write_beats/(float)mmdeviceIndication->ccnt;
  float read_bw = read_util * N * 4 * freq / 1.0e9;
  float write_bw = write_util * N * 4 * freq / 1.0e9;
  float macs = m1.rows * m2.rows * m2.cols;
  fprintf(stderr, "memory read  beats %lld utilization (beats/cycle): %f, bandwidth (GB/s): %f\n", read_beats, read_util, read_bw);
  fprintf(stderr, "memory write beats %lld utilization (beats/cycle): %f, bandwidth (GB/s): %f\n", write_beats, write_util, write_bw);
  fprintf(stderr, "Throughput %f macs/cycle hw %f macs/cycle %f GFLOP/s hw %f GFLOP/s\n",
	  (float)macs / (float)hw_cycles, (float)macs / (float)mmdeviceIndication->ccnt,
	  2.0 * (float)macs / (float)hw_cycles * freq / 1.0e9, 2.0 * (float)macs / (float)mmdeviceIndication->ccnt * freq / 1.0e9);
  fprintf(stderr, "Time %f cycles hw %f cycles, opencv matmul %f cycles (speedup %f hw %f), naive matmul %f cycles (speedup %f hw %f)\n",
	  (float)hw_cycles, (float)mmdeviceIndication->ccnt,
	  (float)opencv_hw_cycles, (float)opencv_hw_cycles/(float)hw_cycles, (float)opencv_hw_cycles/(float)mmdeviceIndication->ccnt,
	  (float)naive_hw_cycles, (float)naive_hw_cycles/(float)hw_cycles, (float)naive_hw_cycles/(float)mmdeviceIndication->ccnt);

  if (0) {
    dumpMat<float>("pm3", "%5.1f", pm3);
    dumpMat<float>(" m3", "%5.1f", m3);
  }
  //bool eq = std::equal(m3.begin<float>(), m3.end<float>(), pm3.begin<float>());
  bool eq = pm3.compare(pm3);
  fprintf(stderr, "eq=%d\n", eq);
  //device->finish();
  exit(!eq&&!sane);
}
<|endoftext|>


<commit_before>#include "Particle.h"

#include "ADXL362DMA/ADXL362DMA.h"

// Library for the ADXL362 that uses SPI DMI for efficient data transfers
// https://github.com/rickkas7/ADXL362DMA

// Data Sheet:
// http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL362.pdf

static Mutex syncCallbackMutex;

static ADXL362Data *readFifoData;
static ADXL362DMA *readFifoObject;

// These methods are described in greater detail in the .h file

ADXL362DMA::ADXL362DMA(SPIClass &spi, int ss) : spi(spi), ss(ss) {
	spi.begin(ss);

	// This initialization possibly should go in beginTransaction() for compatibility with SPI
	// bus sharing in different modes, but it seems to require an indeterminate delay to take
	// effect, otherwise the operations fail. Since SPI bus sharing across modes tends not to
	// work with other devices, anyway, I put the code here.
	spi.setBitOrder(MSBFIRST);
	spi.setClockSpeed(8, MHZ);
	spi.setDataMode(SPI_MODE0); // CPHA = 0, CPOL = 0 : MODE = 0
}

ADXL362DMA::~ADXL362DMA() {
}

void ADXL362DMA::softReset() {

	// Serial.println("softReset");
	writeRegister8(REG_SOFT_RESET, 'R');
}

void ADXL362DMA::setMeasureMode(bool enabled) {

	uint8_t value = readRegister8(REG_POWER_CTL);

	value &= 0xfc; // remove low 2 bits
	if (enabled) {
		value |= 0x02;
	}

	writeRegister8(REG_POWER_CTL, value);

	//value = readRegister8(REG_POWER_CTL);
	//Serial.printlnf("setMeasureMode check=%02d", value);

}

void ADXL362DMA::readXYZT(int &x, int &y, int &z, int &t) {
	uint8_t req[10], resp[10];

	req[0] = CMD_READ_REGISTER;
	req[1] = REG_XDATA_L;
	for(size_t ii = 2; ii < sizeof(req); ii++) {
		req[ii] = 0;
	}

	syncTransaction(req, resp, sizeof(req));

	x = resp[2] | (((int)resp[3]) << 8);
	y = resp[4] | (((int)resp[5]) << 8);
	z = resp[6] | (((int)resp[7]) << 8);
	t = resp[8] | (((int)resp[9]) << 8);
}

uint8_t ADXL362DMA::readStatus() {
	return readRegister8(REG_STATUS);
}

uint16_t ADXL362DMA::readNumFifoEntries() {
	return readRegister16(REG_FIFO_ENTRIES_L);
}

void ADXL362DMA::readFifoAsync(ADXL362Data *data) {
	if (busy) {
		return;
	}

	readFifoData = data;
	readFifoObject = this;

	size_t entrySetSize = getEntrySetSize();

	size_t maxFullEntries = ADXL362Data::BUF_SIZE / entrySetSize;

	size_t numEntries = ((size_t) readNumFifoEntries() * 2) / entrySetSize;
	if (numEntries > maxFullEntries) {
		numEntries = maxFullEntries;
	}
	data->bytesRead = numEntries * entrySetSize;
	data->state = ADXL362Data::STATE_READING_FIFO;
	data->storeTemp = storeTemp;

	beginTransaction();

	spi.transfer(CMD_READ_FIFO);

	spi.transfer(NULL, data->buf, data->bytesRead, readFifoCallbackInternal);
}

// [static]
void ADXL362DMA::readFifoCallbackInternal(void) {
	readFifoObject->endTransaction();
	readFifoData->state = ADXL362Data::STATE_READ_COMPLETE;
}

void ADXL362DMA::writeActivityThreshold(uint16_t value) { // value is an 11-bit integer
	writeRegister16(REG_THRESH_ACT_L, value);
}

void ADXL362DMA::writeActivityTime(uint8_t value) {
	writeRegister8(REG_TIME_ACT, value);
}
void ADXL362DMA::writeInactivityThreshold(uint16_t value) { // value is an 11-bit integer
	writeRegister16(REG_THRESH_INACT_L, value);
}
void ADXL362DMA::writeInactivityTime(uint16_t value) {
	writeRegister16(REG_TIME_INACT_L, value);
}

uint8_t ADXL362DMA::readActivityControl(uint8_t value) {
	return readRegister8(REG_ACT_INACT_CTL);
}

void ADXL362DMA::writeActivityControl(uint8_t value) {
	writeRegister8(REG_ACT_INACT_CTL, value);
}

void ADXL362DMA::writeActivityControl(uint8_t linkLoop, bool inactRef, bool inactEn, bool actRef, bool actEn) {
	uint8_t value = 0;

	value |= (linkLoop & 0x3) << 4;
	if (inactRef) {
		value |= ACTIVITY_INACT_REF;
	}
	if (inactEn) {
		value |= ACTIVITY_INACT_EN;
	}
	if (actRef) {
		value |= ACTIVITY_ACT_REF;
	}
	if (actEn) {
		value |= ACTIVITY_ACT_EN;
	}

	writeActivityControl(value);
}

uint8_t ADXL362DMA::readFifoControl() {
	return readRegister8(REG_FIFO_CONTROL);
}

void ADXL362DMA::writeFifoControl(uint8_t value) {
	writeRegister8(REG_FIFO_CONTROL, value);
}

void ADXL362DMA::writeFifoSamples(uint8_t value) {
	writeRegister8(REG_FIFO_SAMPLES, value);
}

void ADXL362DMA::writeFifoControlAndSamples(uint16_t samples, bool storeTemp, uint8_t fifoMode) {
	uint8_t value = 0;

	this->storeTemp = storeTemp;

	if (samples >= 0x100) {
		value |= 0x08; // AH bit
	}
	if (storeTemp) {
		value |= 0x04; // FIFO_TEMP bit
	}

	value |= (fifoMode & 0x3);

	writeRegister8(REG_FIFO_SAMPLES, samples & 0xff);
	writeRegister8(REG_FIFO_CONTROL, value);
}

uint8_t ADXL362DMA::readIntmap1() {
	return readRegister8(REG_FIFO_INTMAP1);
}

void ADXL362DMA::writeIntmap1(uint8_t value) {
	writeRegister8(REG_FIFO_INTMAP1, value);
}

uint8_t ADXL362DMA::readIntmap2() {
	return readRegister8(REG_FIFO_INTMAP2);
}

void ADXL362DMA::writeIntmap2(uint8_t value) {
	writeRegister8(REG_FIFO_INTMAP2, value);
}

uint8_t ADXL362DMA::readPowerCtl() {
	return readRegister8(REG_POWER_CTL);
}

void ADXL362DMA::writePowerCtl(uint8_t value) {
	writeRegister8(REG_POWER_CTL, value);
}

void ADXL362DMA::writePowerCtl(bool extClock, uint8_t lowNoise, bool wakeup, bool autosleep, uint8_t measureMode) {
	uint8_t temp = 0;

	if (extClock) {
		temp |= POWERCTL_EXT_CLK;
	}
	temp |= (lowNoise & 0x3) << 4;
	if (wakeup) {
		temp |= POWERCTL_WAKEUP;
	}
	if (autosleep) {
		temp |= POWERCTL_AUTOSLEEP;
	}
	temp |= measureMode & 0x3;

	writePowerCtl(temp);
}

void ADXL362DMA::writeLowNoise(uint8_t value) {
	uint8_t temp = readPowerCtl();

	temp &= 0xc0;
	temp |= (value & 0x3) << 4;

	writePowerCtl(temp);
}

void ADXL362DMA::writeMeasureMode(uint8_t value) {
	uint8_t temp = readPowerCtl();

	temp &= 0x3;
	temp |= value & 0x3;

	writePowerCtl(temp);
}

uint8_t ADXL362DMA::readFilterControl() {
	return readRegister8(REG_FILTER_CTL);
}

void ADXL362DMA::writeFilterControl(uint8_t value) {
	writeRegister8(REG_FILTER_CTL, value);
}

void ADXL362DMA::writeFilterControl(uint8_t range, bool halfBW, bool extSample, uint8_t odr) {
	uint8_t value = 0;

	value |= (range & 0x3) << 6;

	if (halfBW) {
		value |= 0x10;
	}
	if (extSample) {
		value |= 0x08;
	}
	value |= (odr & 0x7);

	writeRegister8(REG_FILTER_CTL, value);
}

uint8_t ADXL362DMA::readRegister8(uint8_t addr) {
	uint8_t req[3], resp[3];

	req[0] = CMD_READ_REGISTER;
	req[1] = addr;
	req[2] = 0;

	syncTransaction(req, resp, sizeof(req));

	return resp[2];
}

uint16_t ADXL362DMA::readRegister16(uint8_t addr) {
	uint8_t req[4], resp[4];

	req[0] = CMD_READ_REGISTER;
	req[1] = addr;
	req[2] = req[3] = 0;

	syncTransaction(req, resp, sizeof(req));

	return resp[2] | (((uint16_t)resp[3]) << 8);
}

void ADXL362DMA::writeRegister8(uint8_t addr, uint8_t value) {
	// Serial.printlnf("writeRegister addr=%02x value=%02x", addr, value);

	uint8_t req[3], resp[3];

	req[0] = CMD_WRITE_REGISTER;
	req[1] = addr;
	req[2] = value;

	syncTransaction(req, resp, sizeof(req));
}

void ADXL362DMA::writeRegister16(uint8_t addr, uint16_t value) {
	// Serial.printlnf("writeRegister addr=%02x value=%04x", addr, value);

	uint8_t req[4], resp[4];

	req[0] = CMD_WRITE_REGISTER;
	req[1] = addr;
	req[2] = value & 0xff;
	req[3] = value >> 8;

	syncTransaction(req, resp, sizeof(req));
}

void ADXL362DMA::beginTransaction() {
	// See note in the constructor for ADXL362DMA
	busy = true;
	digitalWrite(ss, LOW);
}

void ADXL362DMA::endTransaction() {
	digitalWrite(ss, HIGH);
	busy = false;
}

void ADXL362DMA::syncTransaction(void *req, void *resp, size_t len) {
	syncCallbackMutex.lock();

	beginTransaction();

	spi.transfer(req, resp, len, syncCallback);
	syncCallbackMutex.lock();

	endTransaction();

	syncCallbackMutex.unlock();
}

// [static]
void ADXL362DMA::syncCallback(void) {
	syncCallbackMutex.unlock();
}

ADXL362Data::ADXL362Data() {
}

ADXL362Data::~ADXL362Data() {
}

<commit_msg>fix spark core support<commit_after>#include "Particle.h"

#include "ADXL362DMA/ADXL362DMA.h"

// Library for the ADXL362 that uses SPI DMI for efficient data transfers
// https://github.com/rickkas7/ADXL362DMA

// Data Sheet:
// http://www.analog.com/media/en/technical-documentation/data-sheets/ADXL362.pdf

#if PLATFORM_ID != 0
static Mutex syncCallbackMutex;
#else
#define NO_MUTEX 1
static bool syncCallbackDone;
#endif

static ADXL362Data *readFifoData;
static ADXL362DMA *readFifoObject;

// These methods are described in greater detail in the .h file

ADXL362DMA::ADXL362DMA(SPIClass &spi, int ss) : spi(spi), ss(ss) {
	spi.begin(ss);

	// This initialization possibly should go in beginTransaction() for compatibility with SPI
	// bus sharing in different modes, but it seems to require an indeterminate delay to take
	// effect, otherwise the operations fail. Since SPI bus sharing across modes tends not to
	// work with other devices, anyway, I put the code here.
	spi.setBitOrder(MSBFIRST);
	spi.setClockSpeed(8, MHZ);
	spi.setDataMode(SPI_MODE0); // CPHA = 0, CPOL = 0 : MODE = 0
}

ADXL362DMA::~ADXL362DMA() {
}

void ADXL362DMA::softReset() {

	// Serial.println("softReset");
	writeRegister8(REG_SOFT_RESET, 'R');
}

void ADXL362DMA::setMeasureMode(bool enabled) {

	uint8_t value = readRegister8(REG_POWER_CTL);

	value &= 0xfc; // remove low 2 bits
	if (enabled) {
		value |= 0x02;
	}

	writeRegister8(REG_POWER_CTL, value);

	//value = readRegister8(REG_POWER_CTL);
	//Serial.printlnf("setMeasureMode check=%02d", value);

}

void ADXL362DMA::readXYZT(int &x, int &y, int &z, int &t) {
	uint8_t req[10], resp[10];

	req[0] = CMD_READ_REGISTER;
	req[1] = REG_XDATA_L;
	for(size_t ii = 2; ii < sizeof(req); ii++) {
		req[ii] = 0;
	}

	syncTransaction(req, resp, sizeof(req));

	x = resp[2] | (((int)resp[3]) << 8);
	y = resp[4] | (((int)resp[5]) << 8);
	z = resp[6] | (((int)resp[7]) << 8);
	t = resp[8] | (((int)resp[9]) << 8);
}

uint8_t ADXL362DMA::readStatus() {
	return readRegister8(REG_STATUS);
}

uint16_t ADXL362DMA::readNumFifoEntries() {
	return readRegister16(REG_FIFO_ENTRIES_L);
}

void ADXL362DMA::readFifoAsync(ADXL362Data *data) {
	if (busy) {
		return;
	}

	readFifoData = data;
	readFifoObject = this;

	size_t entrySetSize = getEntrySetSize();

	size_t maxFullEntries = ADXL362Data::BUF_SIZE / entrySetSize;

	size_t numEntries = ((size_t) readNumFifoEntries() * 2) / entrySetSize;
	if (numEntries > maxFullEntries) {
		numEntries = maxFullEntries;
	}
	data->bytesRead = numEntries * entrySetSize;
	data->state = ADXL362Data::STATE_READING_FIFO;
	data->storeTemp = storeTemp;

	beginTransaction();

	spi.transfer(CMD_READ_FIFO);

	spi.transfer(NULL, data->buf, data->bytesRead, readFifoCallbackInternal);
}

// [static]
void ADXL362DMA::readFifoCallbackInternal(void) {
	readFifoObject->endTransaction();
	readFifoData->state = ADXL362Data::STATE_READ_COMPLETE;
}

void ADXL362DMA::writeActivityThreshold(uint16_t value) { // value is an 11-bit integer
	writeRegister16(REG_THRESH_ACT_L, value);
}

void ADXL362DMA::writeActivityTime(uint8_t value) {
	writeRegister8(REG_TIME_ACT, value);
}
void ADXL362DMA::writeInactivityThreshold(uint16_t value) { // value is an 11-bit integer
	writeRegister16(REG_THRESH_INACT_L, value);
}
void ADXL362DMA::writeInactivityTime(uint16_t value) {
	writeRegister16(REG_TIME_INACT_L, value);
}

uint8_t ADXL362DMA::readActivityControl(uint8_t value) {
	return readRegister8(REG_ACT_INACT_CTL);
}

void ADXL362DMA::writeActivityControl(uint8_t value) {
	writeRegister8(REG_ACT_INACT_CTL, value);
}

void ADXL362DMA::writeActivityControl(uint8_t linkLoop, bool inactRef, bool inactEn, bool actRef, bool actEn) {
	uint8_t value = 0;

	value |= (linkLoop & 0x3) << 4;
	if (inactRef) {
		value |= ACTIVITY_INACT_REF;
	}
	if (inactEn) {
		value |= ACTIVITY_INACT_EN;
	}
	if (actRef) {
		value |= ACTIVITY_ACT_REF;
	}
	if (actEn) {
		value |= ACTIVITY_ACT_EN;
	}

	writeActivityControl(value);
}

uint8_t ADXL362DMA::readFifoControl() {
	return readRegister8(REG_FIFO_CONTROL);
}

void ADXL362DMA::writeFifoControl(uint8_t value) {
	writeRegister8(REG_FIFO_CONTROL, value);
}

void ADXL362DMA::writeFifoSamples(uint8_t value) {
	writeRegister8(REG_FIFO_SAMPLES, value);
}

void ADXL362DMA::writeFifoControlAndSamples(uint16_t samples, bool storeTemp, uint8_t fifoMode) {
	uint8_t value = 0;

	this->storeTemp = storeTemp;

	if (samples >= 0x100) {
		value |= 0x08; // AH bit
	}
	if (storeTemp) {
		value |= 0x04; // FIFO_TEMP bit
	}

	value |= (fifoMode & 0x3);

	writeRegister8(REG_FIFO_SAMPLES, samples & 0xff);
	writeRegister8(REG_FIFO_CONTROL, value);
}

uint8_t ADXL362DMA::readIntmap1() {
	return readRegister8(REG_FIFO_INTMAP1);
}

void ADXL362DMA::writeIntmap1(uint8_t value) {
	writeRegister8(REG_FIFO_INTMAP1, value);
}

uint8_t ADXL362DMA::readIntmap2() {
	return readRegister8(REG_FIFO_INTMAP2);
}

void ADXL362DMA::writeIntmap2(uint8_t value) {
	writeRegister8(REG_FIFO_INTMAP2, value);
}

uint8_t ADXL362DMA::readPowerCtl() {
	return readRegister8(REG_POWER_CTL);
}

void ADXL362DMA::writePowerCtl(uint8_t value) {
	writeRegister8(REG_POWER_CTL, value);
}

void ADXL362DMA::writePowerCtl(bool extClock, uint8_t lowNoise, bool wakeup, bool autosleep, uint8_t measureMode) {
	uint8_t temp = 0;

	if (extClock) {
		temp |= POWERCTL_EXT_CLK;
	}
	temp |= (lowNoise & 0x3) << 4;
	if (wakeup) {
		temp |= POWERCTL_WAKEUP;
	}
	if (autosleep) {
		temp |= POWERCTL_AUTOSLEEP;
	}
	temp |= measureMode & 0x3;

	writePowerCtl(temp);
}

void ADXL362DMA::writeLowNoise(uint8_t value) {
	uint8_t temp = readPowerCtl();

	temp &= 0xc0;
	temp |= (value & 0x3) << 4;

	writePowerCtl(temp);
}

void ADXL362DMA::writeMeasureMode(uint8_t value) {
	uint8_t temp = readPowerCtl();

	temp &= 0x3;
	temp |= value & 0x3;

	writePowerCtl(temp);
}

uint8_t ADXL362DMA::readFilterControl() {
	return readRegister8(REG_FILTER_CTL);
}

void ADXL362DMA::writeFilterControl(uint8_t value) {
	writeRegister8(REG_FILTER_CTL, value);
}

void ADXL362DMA::writeFilterControl(uint8_t range, bool halfBW, bool extSample, uint8_t odr) {
	uint8_t value = 0;

	value |= (range & 0x3) << 6;

	if (halfBW) {
		value |= 0x10;
	}
	if (extSample) {
		value |= 0x08;
	}
	value |= (odr & 0x7);

	writeRegister8(REG_FILTER_CTL, value);
}

uint8_t ADXL362DMA::readRegister8(uint8_t addr) {
	uint8_t req[3], resp[3];

	req[0] = CMD_READ_REGISTER;
	req[1] = addr;
	req[2] = 0;

	syncTransaction(req, resp, sizeof(req));

	return resp[2];
}

uint16_t ADXL362DMA::readRegister16(uint8_t addr) {
	uint8_t req[4], resp[4];

	req[0] = CMD_READ_REGISTER;
	req[1] = addr;
	req[2] = req[3] = 0;

	syncTransaction(req, resp, sizeof(req));

	return resp[2] | (((uint16_t)resp[3]) << 8);
}

void ADXL362DMA::writeRegister8(uint8_t addr, uint8_t value) {
	// Serial.printlnf("writeRegister addr=%02x value=%02x", addr, value);

	uint8_t req[3], resp[3];

	req[0] = CMD_WRITE_REGISTER;
	req[1] = addr;
	req[2] = value;

	syncTransaction(req, resp, sizeof(req));
}

void ADXL362DMA::writeRegister16(uint8_t addr, uint16_t value) {
	// Serial.printlnf("writeRegister addr=%02x value=%04x", addr, value);

	uint8_t req[4], resp[4];

	req[0] = CMD_WRITE_REGISTER;
	req[1] = addr;
	req[2] = value & 0xff;
	req[3] = value >> 8;

	syncTransaction(req, resp, sizeof(req));
}

void ADXL362DMA::beginTransaction() {
	// See note in the constructor for ADXL362DMA
	busy = true;
	digitalWrite(ss, LOW);
}

void ADXL362DMA::endTransaction() {
	digitalWrite(ss, HIGH);
	busy = false;
}

void ADXL362DMA::syncTransaction(void *req, void *resp, size_t len) {
#ifndef NO_MUTEX
	syncCallbackMutex.lock();

	beginTransaction();

	spi.transfer(req, resp, len, syncCallback);
	syncCallbackMutex.lock();

	endTransaction();

	syncCallbackMutex.unlock();
#else
	syncCallbackDone = false;
	beginTransaction();

	spi.transfer(req, resp, len, syncCallback);

	while(!syncCallbackDone) {
	}

	endTransaction();
#endif
}

// [static]
void ADXL362DMA::syncCallback(void) {
#ifndef NO_MUTEX
	syncCallbackMutex.unlock();
#else
	syncCallbackDone = true;
#endif
}

ADXL362Data::ADXL362Data() {
}

ADXL362Data::~ADXL362Data() {
}

<|endoftext|>


<commit_before>#include "ace.h"
#ifdef _DEBUG
#pragma comment(lib, "Debug/ace_engine.lib")
#else
#pragma comment(lib, "Release/ace_engine.lib")
#endif
/*
e: EBhEIɃG[

錴:
O[oϐɃeNX`ȂǂāAEngine::Terminate()Ă΂ꂽƂ
\[XNƃG[ɂȂB

*/

using namespace ace;

namespace ImgManager {
	void setTexture2D(std::shared_ptr<Texture2D>& tex, char const* file) {
		tex = Engine::GetGraphics()->CreateTexture2D(ToAString(file).c_str());
	}
	std::shared_ptr<Texture2D> img; // O[oϐɃ\[Xu
	void init() {
		setTexture2D(img, "img.png");
	}
}

class EngineProvider {
public:
	EngineProvider() {
		auto opt = ace::EngineOption();
		opt.GraphicsType = ace::eGraphicsType::GRAPHICS_TYPE_GL;
		opt.IsFullScreen = false;
		opt.IsMultithreadingMode = true;
		if(!ace::Engine::Initialize(ace::ToAString("Test").c_str(), 800, 600, opt)){ assert(!"Err in init"); };
		Engine::SetTargetFPS(60);
	}

	virtual ~EngineProvider() {
		ace::Engine::Terminate();
	}

};

int main() {
	EngineProvider engineProvider;
	ImgManager::init();
	while(Engine::DoEvents()) {

	}

}<commit_msg>update description about the issue.<commit_after>#include "ace.h"
#ifdef _DEBUG
#pragma comment(lib, "Debug/ace_engine.lib")
#else
#pragma comment(lib, "Release/ace_engine.lib")
#endif
/*
e:
O[öɃeNX`ƁAvOIɃG[ɂȂ
*/

using namespace ace;

namespace ImgManager {
	void setTexture2D(std::shared_ptr<Texture2D>& tex, char const* file) {
		tex = Engine::GetGraphics()->CreateTexture2D(ToAString(file).c_str());
	}
	std::shared_ptr<Texture2D> img; // O[oϐɃ\[Xu
	void init() {
		setTexture2D(img, "img.png");
	}
}

class EngineProvider {
public:
	EngineProvider() {
		auto opt = ace::EngineOption();
		opt.GraphicsType = ace::eGraphicsType::GRAPHICS_TYPE_GL;
		opt.IsFullScreen = false;
		opt.IsMultithreadingMode = true;
		if(!ace::Engine::Initialize(ace::ToAString("Test").c_str(), 800, 600, opt)){ assert(!"Err in init"); };
		Engine::SetTargetFPS(60);
	}

	virtual ~EngineProvider() {
		ace::Engine::Terminate();
	}

};

int main() {
	EngineProvider engineProvider;
	auto tex = Engine::GetGraphics()->CreateTexture2D(ToAString("img.png").c_str());;
	ImgManager::init();
	while(Engine::DoEvents()) {

	}
}<|endoftext|>


<commit_before>#ifndef RUNNER_INTERPRETER_VISIT_HXX
# define RUNNER_INTERPRETER_VISIT_HXX

# include <boost/bind.hpp>

# include <libport/compiler.hh>
# include <libport/finally.hh>
# include <libport/foreach.hh>

# include <ast/all.hh>
# include <ast/print.hh>

# include <kernel/exception.hh>
# include <kernel/uconnection.hh>

# include <object/code-class.hh>
# include <object/global-class.hh>
# include <object/list-class.hh>
# include <object/tag-class.hh>
# include <object/symbols.hh>

# include <runner/interpreter.hh>

# include <libport/compilation.hh>

/// Job echo.
#define JECHO(Title, Content)                           \
  ECHO ("job " << ME << ", " Title ": " << Content)

/// Job & astecho.
#define JAECHO(Title, Ast)                      \
  JECHO (Title, AST(Ast))

/* Yield and trace. */
#define YIELD()                                 \
  do                                            \
  {                                             \
    ECHO ("job " << ME << " yielding on AST: "  \
	  << &e << ' ' << AST(e));              \
    yield ();                                   \
  } while (0)

namespace runner
{
  using boost::bind;
  using libport::Finally;

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::And* e)
  {
    // Collect all subrunners
    scheduler::jobs_type jobs;

    // Create separate runners for every child but the first
    foreach (const ast::rConstExp& child,
             boost::make_iterator_range(e->children_get(), 1, 0))
    {
      Interpreter* job = new Interpreter(*this, eval(child));
      // Propagate errors from subrunners.
      link(job);
      jobs.push_back(job);
      job->start_job();
    }

    // Evaluate the first child in this runner
    rRoutine code = eval(e->children_get().front()).unsafe_cast<object::Code>();
    assert(code);
    // This is a closure, it won't use its 'this'
    object::objects_type args;
    args.push_back(rObject());
    apply_urbi(code, SYMBOL(), args, 0);

    // Wait for all other jobs to terminate
    yield_until_terminated(jobs);

    return object::void_class;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Assignment* e)
  {
    rObject val = eval(e->value_get());
    stacks_.set(e, val);
    return val;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Call* e)
  {
    // The invoked slot (probably a function).
    const ast::rConstExp& ast_tgt = e->target_get();
    rObject tgt = ast_tgt->implicit() ? stacks_.self() : eval(ast_tgt);
    return apply(tgt, e->name_get(), e->arguments_get(), e->location_get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::CallMsg*)
  {
    return stacks_.call();
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Declaration* d)
  {
    rObject val = eval(d->value_get());
    stacks_.def(d, val);
    return val;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Float* e)
  {
    return new object::Float(e->value_get());
  }

  LIBPORT_SPEED_INLINE object::rObject Interpreter::visit(const ast::Routine* e, bool closure)
  {
    rRoutine res = make_routine(e);

    // Capture variables
    foreach (const ast::rDeclaration& dec, *e->captured_variables_get())
    {
      ast::rLocal local = dec->value_get().unsafe_cast<ast::Local>();
      assert(local);
      res->captures_get().push_back(stacks_.rget(local));
    }

    // Capture 'this' and 'call' in closures
    if (closure)
    {
      res->self_get() = stacks_.self();
      res->call_get() = stacks_.call();
    }

    return res;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Function* e)
  {
    return visit(e, false);
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Closure* e)
  {
    return visit(e, true);
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::If* e)
  {
    // Evaluate the test.
    JAECHO ("test", e->test_get ());
    rObject cond = operator()(e->test_get().get());

    if (object::is_true(cond, SYMBOL(if)))
    {
      JAECHO ("then", e->thenclause_get());
      return operator()(e->thenclause_get().get());
    }
    else
    {
      JAECHO ("else", e->elseclause_get());
      return operator()(e->elseclause_get().get());
    }
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::List* e)
  {
    object::List::value_type res;
    // Evaluate every expression in the list
    foreach (const ast::rConstExp& c, e->value_get())
    {
      rObject v = eval(c);
      // Refuse void in literal lists
      if (v == object::void_class)
      {
        object::WrongArgumentType e(SYMBOL(new));
        e.location_set(c->location_get());
        throw e;
      }
      res.push_back(v);
    }
    return new object::List(res);
    //ECHO ("result: " << *result_);
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Lazy* e)
  {
    return operator()(e->strict_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Local* e)
  {
    const rObject& value = stacks_.get(e);

    passert("Local variable read before being set", value);

    if (e->arguments_get())
      // FIXME: Register in the call stack
      return apply(stacks_.self(), value,
                   e->name_get(), e->arguments_get(),
                   e->location_get());
    else
      return value;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Message* e)
  {
    send_message(e->tag_get(), e->text_get());
    return object::void_class;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Nary* e)
  {
    // List of runners for Stmt flavored by a comma.
    scheduler::jobs_type runners;

    // In case we're empty, {} evaluates to void.
    rObject res = object::void_class;

    bool tail = false;
    foreach (const ast::rConstExp& c, e->children_get())
    {
      // Allow some time to pass before we execute what follows.  If
      // we don't do this, the ;-operator would act almost like the
      // |-operator because it would always start to execute its RHS
      // immediately. However, we don't want to do it before the first
      // statement or if we only have one statement in the scope.
      if (tail++)
	YIELD();

      JAECHO("child", c);

      if (c.unsafe_cast<const ast::Stmt>() &&
	  c.unsafe_cast<const ast::Stmt>()->flavor_get() == ast::flavor_comma)
      {
	// The new runners are attached to the same tags as we are.
	Interpreter* subrunner = new Interpreter(*this, eval(c));
	// If the subrunner throws an exception, propagate it here ASAP, unless
	// we are at the top level.
	if (!e->toplevel_get())
	  link(subrunner);
	runners.push_back(subrunner);
	subrunner->start_job ();
      }
      else
      {
	// If at toplevel, print errors and continue, else rethrow them
	try
	{
          // We do not use operator() to avoid duplicating the catch
          // of UrbiExceptions
          res = c->eval(*this);
	  // We need to keep checking for void here because it can not be passed
	  // to the << function
	  if (e->toplevel_get()
              && res.get() // FIXME: What's that for?
              && res != object::void_class)
	  {
	    try
	    {
	      assertion(res);
	      ECHO("toplevel: returning a result to the connection.");

	      // Display the value using the topLevel channel.
	      // If it is not (yet) defined, do nothing, unless the environment
	      // variable TOPLEVEL_DEBUG is set.

	      static bool toplevel_debug = getenv("TOPLEVEL_DEBUG");
	      if (rObject topLevel =
	        object::global_class->slot_locate(SYMBOL(topLevel), false,
		  true))
	      {
		rObject e = topLevel->slot_get(SYMBOL(LT_LT));
                objects_type args;
                args.push_back(topLevel);
                args.push_back(res);
		apply(e, SYMBOL(topLevel), args);
	      }
	      else if (toplevel_debug)
		lobby_->value_get().connection.new_result(res);
	    }
	    catch (std::exception &ke)
	    {
	      std::cerr << "Exception when printing result: "
                        << ke.what() << std::endl;
	    }
	    catch (object::UrbiException& e)
	    {
	      throw;
	    }
	    catch (...)
	    {
	      std::cerr << "Unknown exception when printing result"
                        << std::endl;
	    }
	  }
	}
	catch (object::UrbiException& ue)
	{
          propagate_error_(ue, c->location_get());
	  if (e->toplevel_get())
	    show_error_(ue);
	  else
	    throw;
	}
      }
    }

    // If the Nary is not the toplevel one, all subrunners must be finished when
    // the runner exits the Nary node. However, it we have a scopeTag, we must
    // issue a "stop" which may interrupt subrunners.
    if (!e->toplevel_get() && !runners.empty())
    {
      const scheduler::rTag& tag = scope_tag_get();
      if (tag)
	tag->stop(scheduler_get(), object::void_class);
      yield_until_terminated(runners);
    }

    return res;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Noop*)
  {
    return object::void_class;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Pipe* e)
  {
    // lhs
    JAECHO ("lhs", e->lhs_get ());
    operator() (e->lhs_get().get());

    // rhs:  start the execution immediately.
    JAECHO ("rhs", e->rhs_get ());
    return operator() (e->rhs_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Scope* e)
  {
    libport::Finally finally;
    create_scope_tag();
    finally << boost::bind(&Interpreter::cleanup_scope_tag, this);
    finally << libport::restore(non_interruptible_);
    return operator()(e->body_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Do* e)
  {
    Finally finally;

    rObject tgt = eval(e->target_get());

    finally << stacks_.switch_self(tgt);

    const ast::Scope* scope = reinterpret_cast<const ast::Scope*>(e);
    visit(scope);
    // This is arguable. Do, just like Scope, should maybe return
    // their last inner value.
    return tgt;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Stmt* e)
  {
    JAECHO ("expression", e->expression_get());
    return operator()(e->expression_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::String* e)
  {
    return new object::String(libport::Symbol(e->value_get()));
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Tag* t)
  {
    return eval_tag(t->exp_get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::TaggedStmt* t)
  {
    int result_depth = tags_get().size();
    try
    {
      // FIXME: might be simplified after type checking code is moved
      // to Object
      object::rObject unchecked_tag = eval(t->tag_get());
      object::type_check<object::Tag>(unchecked_tag, SYMBOL(tagged_stmt));
      const object::rTag& urbi_tag = unchecked_tag->as<object::Tag>();
      const scheduler::rTag& tag = urbi_tag->value_get();

      // If tag is blocked, do not start and ignore the
      // statement completely but use the provided payload.
      if (tag->blocked())
	return boost::any_cast<rObject>(tag->payload_get());

      push_tag (tag);
      Finally finally(bind(&Interpreter::pop_tag, this));
      // If the latest tag causes us to be frozen, let the
      // scheduler handle this properly to avoid duplicating the
      // logic.
      if (tag->frozen())
	yield();
      urbi_tag->triggerEnter(*this);
      rObject res = eval (t->exp_get());
      urbi_tag->triggerLeave(*this);
      return res;
    }
    catch (scheduler::StopException& e)
    {
      // Rewind up to the appropriate depth.
      if (e.depth_get() < result_depth)
	throw;
      // Extract the value from the exception.
      return boost::any_cast<rObject>(e.payload_get());
      // If we are frozen, reenter the scheduler for a while.
      if (frozen())
	yield();
    }
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::This*)
  {
    return stacks_.self();
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::While* e)
  {
    const bool must_yield = e->flavor_get() == ast::flavor_semicolon;
    bool tail = false;
    // Evaluate the test.
    while (true)
    {
      if (must_yield && tail++)
	YIELD();
      JAECHO ("while test", e->test_get());
      rObject cond = operator()(e->test_get().get());
      if (!object::is_true(cond, SYMBOL(while)))
	break;

      JAECHO ("while body", e->body_get());

      operator()(e->body_get().get());
    }
    return object::void_class;
  }

  // Invalid nodes
#define INVALID(Node)                                      \
  LIBPORT_SPEED_INLINE object::rObject                                   \
  Interpreter::visit(const ast::Node* n)                   \
  {                                                        \
    static_cast<void>(n);                                  \
    pabort("Invalid node in the Interpreter: " << *n);     \
  }                                                        \

  INVALID(Binding);
  INVALID(Break);
  INVALID(Continue);
  INVALID(Foreach);
  INVALID(Implicit);
  INVALID(MetaExp);
  INVALID(Return);

#undef INVALID

}

#endif
<commit_msg>Uniformize spacing between functions.<commit_after>#ifndef RUNNER_INTERPRETER_VISIT_HXX
# define RUNNER_INTERPRETER_VISIT_HXX

# include <boost/bind.hpp>

# include <libport/compiler.hh>
# include <libport/finally.hh>
# include <libport/foreach.hh>

# include <ast/all.hh>
# include <ast/print.hh>

# include <kernel/exception.hh>
# include <kernel/uconnection.hh>

# include <object/code-class.hh>
# include <object/global-class.hh>
# include <object/list-class.hh>
# include <object/tag-class.hh>
# include <object/symbols.hh>

# include <runner/interpreter.hh>

# include <libport/compilation.hh>

/// Job echo.
#define JECHO(Title, Content)                           \
  ECHO ("job " << ME << ", " Title ": " << Content)

/// Job & astecho.
#define JAECHO(Title, Ast)                      \
  JECHO (Title, AST(Ast))

/* Yield and trace. */
#define YIELD()                                 \
  do                                            \
  {                                             \
    ECHO ("job " << ME << " yielding on AST: "  \
	  << &e << ' ' << AST(e));              \
    yield ();                                   \
  } while (0)

namespace runner
{
  using boost::bind;
  using libport::Finally;

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::And* e)
  {
    // Collect all subrunners
    scheduler::jobs_type jobs;

    // Create separate runners for every child but the first
    foreach (const ast::rConstExp& child,
             boost::make_iterator_range(e->children_get(), 1, 0))
    {
      Interpreter* job = new Interpreter(*this, eval(child));
      // Propagate errors from subrunners.
      link(job);
      jobs.push_back(job);
      job->start_job();
    }

    // Evaluate the first child in this runner
    rRoutine code = eval(e->children_get().front()).unsafe_cast<object::Code>();
    assert(code);
    // This is a closure, it won't use its 'this'
    object::objects_type args;
    args.push_back(rObject());
    apply_urbi(code, SYMBOL(), args, 0);

    // Wait for all other jobs to terminate
    yield_until_terminated(jobs);

    return object::void_class;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Assignment* e)
  {
    rObject val = eval(e->value_get());
    stacks_.set(e, val);
    return val;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Call* e)
  {
    // The invoked slot (probably a function).
    const ast::rConstExp& ast_tgt = e->target_get();
    rObject tgt = ast_tgt->implicit() ? stacks_.self() : eval(ast_tgt);
    return apply(tgt, e->name_get(), e->arguments_get(), e->location_get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::CallMsg*)
  {
    return stacks_.call();
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Declaration* d)
  {
    rObject val = eval(d->value_get());
    stacks_.def(d, val);
    return val;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Float* e)
  {
    return new object::Float(e->value_get());
  }

  LIBPORT_SPEED_INLINE object::rObject Interpreter::visit(const ast::Routine* e, bool closure)
  {
    rRoutine res = make_routine(e);

    // Capture variables
    foreach (const ast::rDeclaration& dec, *e->captured_variables_get())
    {
      ast::rLocal local = dec->value_get().unsafe_cast<ast::Local>();
      assert(local);
      res->captures_get().push_back(stacks_.rget(local));
    }

    // Capture 'this' and 'call' in closures
    if (closure)
    {
      res->self_get() = stacks_.self();
      res->call_get() = stacks_.call();
    }

    return res;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Function* e)
  {
    return visit(e, false);
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Closure* e)
  {
    return visit(e, true);
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::If* e)
  {
    // Evaluate the test.
    JAECHO ("test", e->test_get ());
    rObject cond = operator()(e->test_get().get());

    if (object::is_true(cond, SYMBOL(if)))
    {
      JAECHO ("then", e->thenclause_get());
      return operator()(e->thenclause_get().get());
    }
    else
    {
      JAECHO ("else", e->elseclause_get());
      return operator()(e->elseclause_get().get());
    }
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::List* e)
  {
    object::List::value_type res;
    // Evaluate every expression in the list
    foreach (const ast::rConstExp& c, e->value_get())
    {
      rObject v = eval(c);
      // Refuse void in literal lists
      if (v == object::void_class)
      {
        object::WrongArgumentType e(SYMBOL(new));
        e.location_set(c->location_get());
        throw e;
      }
      res.push_back(v);
    }
    return new object::List(res);
    //ECHO ("result: " << *result_);
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Lazy* e)
  {
    return operator()(e->strict_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Local* e)
  {
    const rObject& value = stacks_.get(e);

    passert("Local variable read before being set", value);

    if (e->arguments_get())
      // FIXME: Register in the call stack
      return apply(stacks_.self(), value,
                   e->name_get(), e->arguments_get(),
                   e->location_get());
    else
      return value;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Message* e)
  {
    send_message(e->tag_get(), e->text_get());
    return object::void_class;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Nary* e)
  {
    // List of runners for Stmt flavored by a comma.
    scheduler::jobs_type runners;

    // In case we're empty, {} evaluates to void.
    rObject res = object::void_class;

    bool tail = false;
    foreach (const ast::rConstExp& c, e->children_get())
    {
      // Allow some time to pass before we execute what follows.  If
      // we don't do this, the ;-operator would act almost like the
      // |-operator because it would always start to execute its RHS
      // immediately. However, we don't want to do it before the first
      // statement or if we only have one statement in the scope.
      if (tail++)
	YIELD();

      JAECHO("child", c);

      if (c.unsafe_cast<const ast::Stmt>() &&
	  c.unsafe_cast<const ast::Stmt>()->flavor_get() == ast::flavor_comma)
      {
	// The new runners are attached to the same tags as we are.
	Interpreter* subrunner = new Interpreter(*this, eval(c));
	// If the subrunner throws an exception, propagate it here ASAP, unless
	// we are at the top level.
	if (!e->toplevel_get())
	  link(subrunner);
	runners.push_back(subrunner);
	subrunner->start_job ();
      }
      else
      {
	// If at toplevel, print errors and continue, else rethrow them
	try
	{
          // We do not use operator() to avoid duplicating the catch
          // of UrbiExceptions
          res = c->eval(*this);
	  // We need to keep checking for void here because it can not be passed
	  // to the << function
	  if (e->toplevel_get()
              && res.get() // FIXME: What's that for?
              && res != object::void_class)
	  {
	    try
	    {
	      assertion(res);
	      ECHO("toplevel: returning a result to the connection.");

	      // Display the value using the topLevel channel.
	      // If it is not (yet) defined, do nothing, unless the environment
	      // variable TOPLEVEL_DEBUG is set.

	      static bool toplevel_debug = getenv("TOPLEVEL_DEBUG");
	      if (rObject topLevel =
	        object::global_class->slot_locate(SYMBOL(topLevel), false,
		  true))
	      {
		rObject e = topLevel->slot_get(SYMBOL(LT_LT));
                objects_type args;
                args.push_back(topLevel);
                args.push_back(res);
		apply(e, SYMBOL(topLevel), args);
	      }
	      else if (toplevel_debug)
		lobby_->value_get().connection.new_result(res);
	    }
	    catch (std::exception &ke)
	    {
	      std::cerr << "Exception when printing result: "
                        << ke.what() << std::endl;
	    }
	    catch (object::UrbiException& e)
	    {
	      throw;
	    }
	    catch (...)
	    {
	      std::cerr << "Unknown exception when printing result"
                        << std::endl;
	    }
	  }
	}
	catch (object::UrbiException& ue)
	{
          propagate_error_(ue, c->location_get());
	  if (e->toplevel_get())
	    show_error_(ue);
	  else
	    throw;
	}
      }
    }

    // If the Nary is not the toplevel one, all subrunners must be finished when
    // the runner exits the Nary node. However, it we have a scopeTag, we must
    // issue a "stop" which may interrupt subrunners.
    if (!e->toplevel_get() && !runners.empty())
    {
      const scheduler::rTag& tag = scope_tag_get();
      if (tag)
	tag->stop(scheduler_get(), object::void_class);
      yield_until_terminated(runners);
    }

    return res;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Noop*)
  {
    return object::void_class;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Pipe* e)
  {
    // lhs
    JAECHO ("lhs", e->lhs_get ());
    operator() (e->lhs_get().get());

    // rhs:  start the execution immediately.
    JAECHO ("rhs", e->rhs_get ());
    return operator() (e->rhs_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Scope* e)
  {
    libport::Finally finally;
    create_scope_tag();
    finally << boost::bind(&Interpreter::cleanup_scope_tag, this);
    finally << libport::restore(non_interruptible_);
    return operator()(e->body_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Do* e)
  {
    Finally finally;

    rObject tgt = eval(e->target_get());

    finally << stacks_.switch_self(tgt);

    const ast::Scope* scope = reinterpret_cast<const ast::Scope*>(e);
    visit(scope);
    // This is arguable. Do, just like Scope, should maybe return
    // their last inner value.
    return tgt;
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Stmt* e)
  {
    JAECHO ("expression", e->expression_get());
    return operator()(e->expression_get().get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::String* e)
  {
    return new object::String(libport::Symbol(e->value_get()));
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::Tag* t)
  {
    return eval_tag(t->exp_get());
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::TaggedStmt* t)
  {
    int result_depth = tags_get().size();
    try
    {
      // FIXME: might be simplified after type checking code is moved
      // to Object
      object::rObject unchecked_tag = eval(t->tag_get());
      object::type_check<object::Tag>(unchecked_tag, SYMBOL(tagged_stmt));
      const object::rTag& urbi_tag = unchecked_tag->as<object::Tag>();
      const scheduler::rTag& tag = urbi_tag->value_get();

      // If tag is blocked, do not start and ignore the
      // statement completely but use the provided payload.
      if (tag->blocked())
	return boost::any_cast<rObject>(tag->payload_get());

      push_tag (tag);
      Finally finally(bind(&Interpreter::pop_tag, this));
      // If the latest tag causes us to be frozen, let the
      // scheduler handle this properly to avoid duplicating the
      // logic.
      if (tag->frozen())
	yield();
      urbi_tag->triggerEnter(*this);
      rObject res = eval (t->exp_get());
      urbi_tag->triggerLeave(*this);
      return res;
    }
    catch (scheduler::StopException& e)
    {
      // Rewind up to the appropriate depth.
      if (e.depth_get() < result_depth)
	throw;
      // Extract the value from the exception.
      return boost::any_cast<rObject>(e.payload_get());
      // If we are frozen, reenter the scheduler for a while.
      if (frozen())
	yield();
    }
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::This*)
  {
    return stacks_.self();
  }

  LIBPORT_SPEED_INLINE object::rObject
  Interpreter::visit(const ast::While* e)
  {
    const bool must_yield = e->flavor_get() == ast::flavor_semicolon;
    bool tail = false;
    // Evaluate the test.
    while (true)
    {
      if (must_yield && tail++)
	YIELD();
      JAECHO ("while test", e->test_get());
      rObject cond = operator()(e->test_get().get());
      if (!object::is_true(cond, SYMBOL(while)))
	break;

      JAECHO ("while body", e->body_get());

      operator()(e->body_get().get());
    }
    return object::void_class;
  }

  // Invalid nodes
#define INVALID(Node)                                      \
  LIBPORT_SPEED_INLINE object::rObject                                   \
  Interpreter::visit(const ast::Node* n)                   \
  {                                                        \
    static_cast<void>(n);                                  \
    pabort("Invalid node in the Interpreter: " << *n);     \
  }                                                        \

  INVALID(Binding);
  INVALID(Break);
  INVALID(Continue);
  INVALID(Foreach);
  INVALID(Implicit);
  INVALID(MetaExp);
  INVALID(Return);

#undef INVALID

}

#endif
<|endoftext|>


<commit_before>/**
 * Application Context of Session Manager
 *
 * Copyright 2013 Thincast Technologies GmbH
 * Copyright 2013 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/library.h>
#include <winpr/environment.h>

#include <list>
#include <utils/StringHelpers.h>

#include "ApplicationContext.h"

#include <session/TaskSessionTimeout.h>

namespace freerds
{
	namespace sessionmanager
	{
		ApplicationContext::ApplicationContext()
		{
			wLogLayout* layout;
			wLogAppender* appender;

			initPaths();
			configureExecutableSearchPath();

			WLog_Init();

			mWLogRoot = WLog_GetRoot();

			WLog_SetLogAppenderType(mWLogRoot, WLOG_APPENDER_CONSOLE);

			appender = WLog_GetLogAppender(mWLogRoot);
			WLog_ConsoleAppender_SetOutputStream(mWLogRoot, (wLogConsoleAppender*) appender, WLOG_CONSOLE_STDERR);

			layout = WLog_GetLogLayout(mWLogRoot);
			WLog_Layout_SetPrefixFormat(mWLogRoot, layout, "[%lv:%mn] [%fl|%fn|%ln] - ");

			WLog_OpenAppender(mWLogRoot);
			WLog_SetLogLevel(mWLogRoot, WLOG_TRACE);

			setupTestingPropValues();
		}

		ApplicationContext::~ApplicationContext()
		{
			WLog_CloseAppender(mWLogRoot);
			WLog_Uninit();
		}

		std::string ApplicationContext::getHomePath()
		{

			if (mHomePath.size() == 0)
			{
				char* p;
				int length;
				char separator;
				char moduleFileName[4096];

				separator = PathGetSeparatorA(PATH_STYLE_NATIVE);
				GetModuleFileNameA(NULL, moduleFileName, sizeof(moduleFileName));

				p = strrchr(moduleFileName, separator);
				*p = '\0';
				p = strrchr(moduleFileName, separator);
				*p = '\0';

				mHomePath.assign(moduleFileName);
			}
			return mHomePath;
		}

		std::string ApplicationContext::getLibraryPath()
		{
			if (mLibraryPath.size() == 0)
			{
				mLibraryPath = getHomePath();
				mLibraryPath += "/";
				mLibraryPath += FREERDS_INSTALL_LIBDIR;
			}
			return mLibraryPath;
		}

		std::string ApplicationContext::getExecutablePath()
		{
			if (mExecutablePath.size() == 0)
			{
				mExecutablePath = getHomePath();
				mExecutablePath += "/";
				mExecutablePath += FREERDS_INSTALL_BINDIR;
			}
			return mExecutablePath;
		}

		std::string ApplicationContext::getShareDataPath()
		{
			if (mShareDataPath.size() == 0)
			{
				mShareDataPath = getHomePath();
				mShareDataPath += "/";
				mShareDataPath += FREERDS_INSTALL_DATAROOTDIR;
				mShareDataPath += "/";
				mShareDataPath += "freerds";
			}
			return mShareDataPath;
		}

		std::string ApplicationContext::getSystemConfigPath()
		{
			if (mSystemConfigPath.size() == 0)
			{

				mSystemConfigPath = getHomePath();
				mSystemConfigPath += "/";
				mSystemConfigPath += FREERDS_INSTALL_SYSCONFDIR;
				mSystemConfigPath += "/";
				mSystemConfigPath += "freerds";
			}
			return mSystemConfigPath;
		}

		void ApplicationContext::exportContext()
		{
			int size;
			FILE* fp;
			char iniStr[2048];

			const char iniFmt[] =
				"[FreeRDS]\n"
				"prefix=\"%s\"\n"
				"bindir=\"%s\"\n"
				"sbindir=\"%s\"\n"
				"libdir=\"\"%s\n"
				"datarootdir=\"%s\"\n"
				"localstatedir=\"%s\"\n"
				"sysconfdir=\"%s\"\n"
				"\n";

			sprintf_s(iniStr, sizeof(iniStr), iniFmt,
				mHomePath.c_str(), /* prefix */
				FREERDS_INSTALL_BINDIR, /* bindir */
				FREERDS_INSTALL_SBINDIR, /* sbindir */
				FREERDS_INSTALL_LIBDIR, /* libdir */
				FREERDS_INSTALL_DATAROOTDIR, /* datarootdir */
				FREERDS_INSTALL_LOCALSTATEDIR, /* localstatedir */
				FREERDS_INSTALL_SYSCONFDIR /* sysconfdir */
				);

			size = strlen(iniStr) + 1;

			fp = fopen("/var/run/freerds.instance", "w");

			if (fp)
			{
				fwrite(iniStr, 1, size, fp);
				fclose(fp);
			}
		}

		void ApplicationContext::initPaths()
		{
			getHomePath();
			getLibraryPath();
			getExecutablePath();
			getShareDataPath();
			getSystemConfigPath();

			exportContext();
		}

		void ApplicationContext::configureExecutableSearchPath()
		{
			int index;
			DWORD nSize;

			nSize = GetEnvironmentVariableA("PATH", NULL, 0);

			if (nSize)
			{
				std::string pathExtra = "";
				bool executablePathPresent = false;
				bool systemConfigPathPresent = false;

				char* lpBuffer = (LPSTR) malloc(nSize);
				nSize = GetEnvironmentVariableA("PATH", lpBuffer, nSize);

				std::string pathEnv(lpBuffer);
				std::vector<std::string> pathList = split<std::string>(pathEnv, ":");

				for (index = 0; index < pathList.size(); index++)
				{
					if (strcmp(mExecutablePath.c_str(), pathList[index].c_str()) == 0)
						executablePathPresent = true;
					else if (strcmp(mSystemConfigPath.c_str(), pathList[index].c_str()) == 0)
						systemConfigPathPresent = true;
				}

				if (!executablePathPresent)
				{
					pathExtra += mExecutablePath;
					pathExtra += ":";
				}

				if (!systemConfigPathPresent)
				{
					pathExtra += mSystemConfigPath;
					pathExtra += ":";
				}

				if (pathExtra.length() > 0)
				{
					pathEnv = pathExtra + pathEnv;
					SetEnvironmentVariableA("PATH", pathEnv.c_str());
				}
			}
		}

		sessionNS::SessionStore* ApplicationContext::getSessionStore()
		{
			return &mSessionStore;
		}

		sessionNS::ConnectionStore* ApplicationContext::getConnectionStore()
		{
			return &mConnectionStore;
		}

		configNS::PropertyManager* ApplicationContext::getPropertyManager()
		{
			return &mPropertyManager;
		}

		int ApplicationContext::startRPCEngine()
		{
#ifdef WITH_FDSAPI
			mFDSApiServer.startFDSApi();
#endif
			return mRpcEngine.startEngine();
		}

		int ApplicationContext::stopRPCEngine()
		{
#ifdef WITH_FDSAPI
			mFDSApiServer.stopFDSApi();
#endif
			return mRpcEngine.stopEngine();
		}

		SignalingQueue<callNS::Call *> * ApplicationContext::getRpcOutgoingQueue()
		{
			return &mRpcOutgoingCalls;
		}

		int ApplicationContext::loadModulesFromPath(std::string path)
		{
			LPCSTR pszExt;
			char pattern[256];

			pszExt = PathGetSharedLibraryExtensionA(0);
			sprintf_s(pattern, 256, "*freerds-module-*.%s", pszExt);

			return mModuleManager.loadModulesFromPathAndEnv(path, pattern);
		}

		moduleNS::ModuleManager* ApplicationContext::getModuleManager()
		{
			return &mModuleManager;
		}

		void ApplicationContext::setupTestingPropValues()
		{

			mPropertyManager.setPropertyString(Global, 0, "module","xsession");
			mPropertyManager.setPropertyString(Global, 0, "auth.module","PAM");
			mPropertyManager.setPropertyString(Global, 0, "auth.greeter","greeter");
			mPropertyManager.setPropertyBool(Global, 0, "session.reconnect",true);
			mPropertyManager.setPropertyNumber(Global, 0, "session.timeout",1);

			mPropertyManager.setPropertyString(Global, 0, "module.xsession.modulename","X11");
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.maxXRes",1920);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.maxYRes",1200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.minXRes",320);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.minYRes",200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.xres",1024);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.yres",768);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.colordepth",24);
			mPropertyManager.setPropertyString(Global, 0, "module.xsession.startwm","startwm.sh");

			mPropertyManager.setPropertyString(Global, 0, "module.greeter.modulename","Qt");
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.maxXRes",1920);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.maxYRes",1200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.minXRes",320);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.minYRes",200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.xres",1024);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.yres",768);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.colordepth",24);
			mPropertyManager.setPropertyString(Global, 0, "module.greeter.cmd","nice_greeter");

			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.xres",800,"demo1");
			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.yres",600,"demo1");
			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.xres",800,"demo2");
			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.yres",600,"demo2");
			mPropertyManager.setPropertyBool(User, 0, "session.reconnect",false,"demo1");
			mPropertyManager.setPropertyString(User, 0, "module","xsession","demo2");

		}

		void ApplicationContext::startTaskExecutor() {
			mTaskExecutor.start();
		}

		void ApplicationContext::stopTaskExecutor() {
			mTaskExecutor.stop();
		}

		void ApplicationContext::startSessionTimoutMonitor(){
			sessionNS::TaskSessionTimeoutPtr task(new sessionNS::TaskSessionTimeout());
			addTask(task);
		}

		bool ApplicationContext::addTask(taskNS::TaskPtr task) {
			return mTaskExecutor.addTask(task);
		}

		void ApplicationContext::rpcDisconnected() {
			// remove all connections
			getConnectionStore()->reset();
			// iterate over the session and disconnect them if they are auth sessions.
			std::list<sessionNS::SessionPtr> allSessions = getSessionStore()->getAllSessions();

			std::list<sessionNS::SessionPtr>::iterator iterator;
			for (iterator = allSessions.begin(); iterator != allSessions.end(); ++iterator) {
				sessionNS::SessionPtr currentSession = (*iterator);
				if (currentSession->isAuthSession()) {
					currentSession->stopModule();
					getSessionStore()->removeSession(currentSession->getSessionID());
				} else {
					// disconnect the session
					currentSession->setConnectState(WTSDisconnected);
				}
			}
		}

	}
}

<commit_msg>freerds: fix freerds.instance generation<commit_after>/**
 * Application Context of Session Manager
 *
 * Copyright 2013 Thincast Technologies GmbH
 * Copyright 2013 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
 *
 * 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.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <winpr/crt.h>
#include <winpr/path.h>
#include <winpr/library.h>
#include <winpr/environment.h>

#include <list>
#include <utils/StringHelpers.h>

#include "ApplicationContext.h"

#include <session/TaskSessionTimeout.h>

namespace freerds
{
	namespace sessionmanager
	{
		ApplicationContext::ApplicationContext()
		{
			wLogLayout* layout;
			wLogAppender* appender;

			initPaths();
			configureExecutableSearchPath();

			WLog_Init();

			mWLogRoot = WLog_GetRoot();

			WLog_SetLogAppenderType(mWLogRoot, WLOG_APPENDER_CONSOLE);

			appender = WLog_GetLogAppender(mWLogRoot);
			WLog_ConsoleAppender_SetOutputStream(mWLogRoot, (wLogConsoleAppender*) appender, WLOG_CONSOLE_STDERR);

			layout = WLog_GetLogLayout(mWLogRoot);
			WLog_Layout_SetPrefixFormat(mWLogRoot, layout, "[%lv:%mn] [%fl|%fn|%ln] - ");

			WLog_OpenAppender(mWLogRoot);
			WLog_SetLogLevel(mWLogRoot, WLOG_TRACE);

			setupTestingPropValues();
		}

		ApplicationContext::~ApplicationContext()
		{
			WLog_CloseAppender(mWLogRoot);
			WLog_Uninit();
		}

		std::string ApplicationContext::getHomePath()
		{

			if (mHomePath.size() == 0)
			{
				char* p;
				int length;
				char separator;
				char moduleFileName[4096];

				separator = PathGetSeparatorA(PATH_STYLE_NATIVE);
				GetModuleFileNameA(NULL, moduleFileName, sizeof(moduleFileName));

				p = strrchr(moduleFileName, separator);
				*p = '\0';
				p = strrchr(moduleFileName, separator);
				*p = '\0';

				mHomePath.assign(moduleFileName);
			}
			return mHomePath;
		}

		std::string ApplicationContext::getLibraryPath()
		{
			if (mLibraryPath.size() == 0)
			{
				mLibraryPath = getHomePath();
				mLibraryPath += "/";
				mLibraryPath += FREERDS_INSTALL_LIBDIR;
			}
			return mLibraryPath;
		}

		std::string ApplicationContext::getExecutablePath()
		{
			if (mExecutablePath.size() == 0)
			{
				mExecutablePath = getHomePath();
				mExecutablePath += "/";
				mExecutablePath += FREERDS_INSTALL_BINDIR;
			}
			return mExecutablePath;
		}

		std::string ApplicationContext::getShareDataPath()
		{
			if (mShareDataPath.size() == 0)
			{
				mShareDataPath = getHomePath();
				mShareDataPath += "/";
				mShareDataPath += FREERDS_INSTALL_DATAROOTDIR;
				mShareDataPath += "/";
				mShareDataPath += "freerds";
			}
			return mShareDataPath;
		}

		std::string ApplicationContext::getSystemConfigPath()
		{
			if (mSystemConfigPath.size() == 0)
			{

				mSystemConfigPath = getHomePath();
				mSystemConfigPath += "/";
				mSystemConfigPath += FREERDS_INSTALL_SYSCONFDIR;
				mSystemConfigPath += "/";
				mSystemConfigPath += "freerds";
			}
			return mSystemConfigPath;
		}

		void ApplicationContext::exportContext()
		{
			int size;
			FILE* fp;
			char iniStr[2048];

			const char iniFmt[] =
				"[FreeRDS]\n"
				"prefix=\"%s\"\n"
				"bindir=\"%s\"\n"
				"sbindir=\"%s\"\n"
				"libdir=\"%s\"\n"
				"datarootdir=\"%s\"\n"
				"localstatedir=\"%s\"\n"
				"sysconfdir=\"%s\"\n"
				"\n";

			sprintf_s(iniStr, sizeof(iniStr), iniFmt,
				mHomePath.c_str(), /* prefix */
				FREERDS_INSTALL_BINDIR, /* bindir */
				FREERDS_INSTALL_SBINDIR, /* sbindir */
				FREERDS_INSTALL_LIBDIR, /* libdir */
				FREERDS_INSTALL_DATAROOTDIR, /* datarootdir */
				FREERDS_INSTALL_LOCALSTATEDIR, /* localstatedir */
				FREERDS_INSTALL_SYSCONFDIR /* sysconfdir */
				);

			size = strlen(iniStr) + 1;

			fp = fopen("/var/run/freerds.instance", "w");

			if (fp)
			{
				fwrite(iniStr, 1, size, fp);
				fclose(fp);
			}
		}

		void ApplicationContext::initPaths()
		{
			getHomePath();
			getLibraryPath();
			getExecutablePath();
			getShareDataPath();
			getSystemConfigPath();

			exportContext();
		}

		void ApplicationContext::configureExecutableSearchPath()
		{
			int index;
			DWORD nSize;

			nSize = GetEnvironmentVariableA("PATH", NULL, 0);

			if (nSize)
			{
				std::string pathExtra = "";
				bool executablePathPresent = false;
				bool systemConfigPathPresent = false;

				char* lpBuffer = (LPSTR) malloc(nSize);
				nSize = GetEnvironmentVariableA("PATH", lpBuffer, nSize);

				std::string pathEnv(lpBuffer);
				std::vector<std::string> pathList = split<std::string>(pathEnv, ":");

				for (index = 0; index < pathList.size(); index++)
				{
					if (strcmp(mExecutablePath.c_str(), pathList[index].c_str()) == 0)
						executablePathPresent = true;
					else if (strcmp(mSystemConfigPath.c_str(), pathList[index].c_str()) == 0)
						systemConfigPathPresent = true;
				}

				if (!executablePathPresent)
				{
					pathExtra += mExecutablePath;
					pathExtra += ":";
				}

				if (!systemConfigPathPresent)
				{
					pathExtra += mSystemConfigPath;
					pathExtra += ":";
				}

				if (pathExtra.length() > 0)
				{
					pathEnv = pathExtra + pathEnv;
					SetEnvironmentVariableA("PATH", pathEnv.c_str());
				}
			}
		}

		sessionNS::SessionStore* ApplicationContext::getSessionStore()
		{
			return &mSessionStore;
		}

		sessionNS::ConnectionStore* ApplicationContext::getConnectionStore()
		{
			return &mConnectionStore;
		}

		configNS::PropertyManager* ApplicationContext::getPropertyManager()
		{
			return &mPropertyManager;
		}

		int ApplicationContext::startRPCEngine()
		{
#ifdef WITH_FDSAPI
			mFDSApiServer.startFDSApi();
#endif
			return mRpcEngine.startEngine();
		}

		int ApplicationContext::stopRPCEngine()
		{
#ifdef WITH_FDSAPI
			mFDSApiServer.stopFDSApi();
#endif
			return mRpcEngine.stopEngine();
		}

		SignalingQueue<callNS::Call *> * ApplicationContext::getRpcOutgoingQueue()
		{
			return &mRpcOutgoingCalls;
		}

		int ApplicationContext::loadModulesFromPath(std::string path)
		{
			LPCSTR pszExt;
			char pattern[256];

			pszExt = PathGetSharedLibraryExtensionA(0);
			sprintf_s(pattern, 256, "*freerds-module-*.%s", pszExt);

			return mModuleManager.loadModulesFromPathAndEnv(path, pattern);
		}

		moduleNS::ModuleManager* ApplicationContext::getModuleManager()
		{
			return &mModuleManager;
		}

		void ApplicationContext::setupTestingPropValues()
		{

			mPropertyManager.setPropertyString(Global, 0, "module","xsession");
			mPropertyManager.setPropertyString(Global, 0, "auth.module","PAM");
			mPropertyManager.setPropertyString(Global, 0, "auth.greeter","greeter");
			mPropertyManager.setPropertyBool(Global, 0, "session.reconnect",true);
			mPropertyManager.setPropertyNumber(Global, 0, "session.timeout",1);

			mPropertyManager.setPropertyString(Global, 0, "module.xsession.modulename","X11");
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.maxXRes",1920);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.maxYRes",1200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.minXRes",320);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.minYRes",200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.xres",1024);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.yres",768);
			mPropertyManager.setPropertyNumber(Global, 0, "module.xsession.colordepth",24);
			mPropertyManager.setPropertyString(Global, 0, "module.xsession.startwm","startwm.sh");

			mPropertyManager.setPropertyString(Global, 0, "module.greeter.modulename","Qt");
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.maxXRes",1920);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.maxYRes",1200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.minXRes",320);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.minYRes",200);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.xres",1024);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.yres",768);
			mPropertyManager.setPropertyNumber(Global, 0, "module.greeter.colordepth",24);
			mPropertyManager.setPropertyString(Global, 0, "module.greeter.cmd","nice_greeter");

			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.xres",800,"demo1");
			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.yres",600,"demo1");
			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.xres",800,"demo2");
			mPropertyManager.setPropertyNumber(User, 0, "module.xsession.yres",600,"demo2");
			mPropertyManager.setPropertyBool(User, 0, "session.reconnect",false,"demo1");
			mPropertyManager.setPropertyString(User, 0, "module","xsession","demo2");

		}

		void ApplicationContext::startTaskExecutor() {
			mTaskExecutor.start();
		}

		void ApplicationContext::stopTaskExecutor() {
			mTaskExecutor.stop();
		}

		void ApplicationContext::startSessionTimoutMonitor(){
			sessionNS::TaskSessionTimeoutPtr task(new sessionNS::TaskSessionTimeout());
			addTask(task);
		}

		bool ApplicationContext::addTask(taskNS::TaskPtr task) {
			return mTaskExecutor.addTask(task);
		}

		void ApplicationContext::rpcDisconnected() {
			// remove all connections
			getConnectionStore()->reset();
			// iterate over the session and disconnect them if they are auth sessions.
			std::list<sessionNS::SessionPtr> allSessions = getSessionStore()->getAllSessions();

			std::list<sessionNS::SessionPtr>::iterator iterator;
			for (iterator = allSessions.begin(); iterator != allSessions.end(); ++iterator) {
				sessionNS::SessionPtr currentSession = (*iterator);
				if (currentSession->isAuthSession()) {
					currentSession->stopModule();
					getSessionStore()->removeSession(currentSession->getSessionID());
				} else {
					// disconnect the session
					currentSession->setConnectState(WTSDisconnected);
				}
			}
		}

	}
}

<|endoftext|>