<commit_before>// TestDAQ.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "util-nidaqmx.h"

#define CHK(expr) Guarded_DAQmx( (expr), #expr, error )

#define N 4000

void test2(void)
{
	TaskHandle  cur_task=0, ao_task=0, clk_task=0;
	float64     data[N];
	float64     freq = 10000; // Hz	- sample rate
	int32       written;

  { int i=N;
	  while(i--)
		  data[i] = 5.0*(double)i/((double)N);    // linear ramp from 0.0 to 5.0 V
  }

  Reporting_Setup_Log_To_Stdout();
  Reporting_Setup_Log_To_VSDebugger_Console();

  // set up ao task
  cur_task = 0;
	CHK( DAQmxCreateTask            ("galvo",&cur_task));
	CHK( DAQmxCreateAOVoltageChan   (cur_task,"/Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts  ,NULL));
	CHK( DAQmxCfgSampClkTiming      (cur_task,
	                                "Ctr0InternalOutput",
	                                 freq,
	                                 DAQmx_Val_Rising,
	                                 DAQmx_Val_ContSamps,         // use continuous output so that counter stays in control
	                                 N));
	CHK( DAQmxCfgAnlgEdgeStartTrig  (cur_task,"APFI0",DAQmx_Val_Rising, 0.0));
	CHK( DAQmxWriteAnalogF64        (cur_task,
	                                 N,
	                                 0,                           // autostart?
	                                 10.0,                        // timeout (s)
	                                 DAQmx_Val_GroupByChannel,
	                                 data,
	                                 &written,
	                                 NULL));
	ao_task = cur_task;

	// set up counter for sample clock
	cur_task = 0;
	CHK( DAQmxCreateTask                  ( "clock",&cur_task));
	CHK( DAQmxCreateCOPulseChanFreq       ( cur_task, "Dev1/ctr0", "", DAQmx_Val_Hz, DAQmx_Val_Low, 0.0, freq, 0.5 ));
	CHK( DAQmxCfgImplicitTiming           ( cur_task, DAQmx_Val_FiniteSamps, N ));
	CHK( DAQmxCfgDigEdgeStartTrig         ( cur_task, "AnalogComparisonEvent", DAQmx_Val_Rising ));
	CHK( DAQmxSetArmStartTrigType         ( cur_task, DAQmx_Val_DigEdge ));
	CHK( DAQmxSetDigEdgeArmStartTrigSrc   ( cur_task, "PFI0" ));
	CHK( DAQmxSetDigEdgeArmStartTrigEdge  ( cur_task, DAQmx_Val_Rising ));
	clk_task = cur_task;

	{ int i;
	  TicTocTimer clock = tic();
	  CHK( DAQmxStartTask             (ao_task));
	  for(i=0;i<10; i++ )
	  {
	    CHK( DAQmxStartTask             (clk_task));
	         //debug("iter: %d time: %g\r\n",i, toc(&clock) );
	         debug(",%g\r\n",toc(&clock) );
	    CHK( DAQmxWaitUntilTaskDone     (clk_task,100.0));
	         toc(&clock);
	    CHK( DAQmxStopTask              (clk_task));
	  }
	  DAQmxStopTask(ao_task);
	}

Error:

	if( clk_task!=0 ) {
		DAQmxStopTask(clk_task);
		DAQmxClearTask(clk_task);
	}
  if( ao_task!=0 ) {
		DAQmxStopTask(ao_task);
		DAQmxClearTask(ao_task);
	}
	printf("End of program, press Enter key to quit\n");
	getchar();
	return;
}

/* Timings   2010-01-11   Time for Start/Stop of AO task
a = array([8.17151e-005
,0.000236025
,0.000238579
,0.000252806
,0.000249523
,0.000233107
,0.000254995
,0.000231648
,0.000252806
,0.000253901])
*/

/* Timings   2010-01-12   (test2) Time for Start/Stop of doubley triggered ctr task
 *                                delay: 472 +- 6 us max: 483 us min: 459 us
a = array([0.000458918
,0.000482995
,0.000475334
,0.000474969
,0.000468768
,0.00047424
,0.000468768
,0.000476064
,0.000472416])
*/
int _tmain(int argc, _TCHAR* argv[])
{ test2();
}<commit_msg>Integrating w digitizer.<commit_after>// TestDAQ.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include "util-nidaqmx.h"

#define CHK(expr) Guarded_DAQmx( (expr), #expr, error )

#define N 4000

void test2(void)
{
	TaskHandle  cur_task=0, ao_task=0, clk_task=0;//, trg_task=0;
	float64     data[N];
	float64     freq = 10000; // Hz	- sample rate
	int32       written;

  { int i=N;
	  while(i--)
		  data[i] = 5.0*(double)i/((double)N);    // linear ramp from 0.0 to 5.0 V
  }

  Reporting_Setup_Log_To_Stdout();
  Reporting_Setup_Log_To_VSDebugger_Console();

  // set up ao task
  cur_task = 0;
	CHK( DAQmxCreateTask            ("galvo",&cur_task));
	CHK( DAQmxCreateAOVoltageChan   (cur_task,"/Dev1/ao0","",-10.0,10.0,DAQmx_Val_Volts  ,NULL));
	CHK( DAQmxCfgSampClkTiming      (cur_task,
	                                "Ctr1InternalOutput",
	                                 freq,
	                                 DAQmx_Val_Rising,
	                                 DAQmx_Val_ContSamps,         // use continuous output so that counter stays in control
	                                 N));
	CHK( DAQmxCfgAnlgEdgeStartTrig  (cur_task,"APFI0",DAQmx_Val_Rising, 0.0));
	CHK( DAQmxWriteAnalogF64        (cur_task,
	                                 N,
	                                 0,                           // autostart?
	                                 10.0,                        // timeout (s)
	                                 DAQmx_Val_GroupByChannel,
	                                 data,
	                                 &written,
	                                 NULL));
	ao_task = cur_task;

	// set up counter for sample clock
	cur_task = 0;
	CHK( DAQmxCreateTask                  ( "clock",&cur_task));
	CHK( DAQmxCreateCOPulseChanFreq       ( cur_task, "Dev1/ctr1", "", DAQmx_Val_Hz, DAQmx_Val_Low, 0.0, freq, 0.5 ));
	CHK( DAQmxCfgImplicitTiming           ( cur_task, DAQmx_Val_FiniteSamps, N ));
	CHK( DAQmxCfgDigEdgeStartTrig         ( cur_task, "AnalogComparisonEvent", DAQmx_Val_Rising ));
	CHK( DAQmxSetArmStartTrigType         ( cur_task, DAQmx_Val_DigEdge ));
	CHK( DAQmxSetDigEdgeArmStartTrigSrc   ( cur_task, "PFI0" ));
	CHK( DAQmxSetDigEdgeArmStartTrigEdge  ( cur_task, DAQmx_Val_Rising ));
	clk_task = cur_task;

	//// set up retiggerable frame sync pulse
	//cur_task = 0;
	//CHK( DAQmxCreateTask                  ( "FrameSync",&cur_task)); // delay and low time can be used to controllably offset the AO start from digitizier start
	//CHK( DAQmxCreateCOPulseChanTime       ( cur_task, "Dev1/ctr1", "", DAQmx_Val_Seconds, DAQmx_Val_Low, 50e-9, 50e-9, 1e-3 ));
	//CHK( DAQmxCfgDigEdgeStartTrig         ( cur_task, "AnalogComparisonEvent", DAQmx_Val_Rising ));
	//trg_task = cur_task;

	{ int i;
	  TicTocTimer clock = tic();
	  CHK( DAQmxStartTask             ( ao_task));
	  //CHK( DAQmxStartTask             (trg_task));
	  //for(i=0;i<10; i++ )
	  while(1)
	  {
	    CHK( DAQmxStartTask             (clk_task));
	         //debug("iter: %d time: %g\r\n",i, toc(&clock) );
	         debug(",%g\r\n",toc(&clock) );
	    CHK( DAQmxWaitUntilTaskDone     (clk_task,DAQmx_Val_WaitInfinitely));
	         toc(&clock);
	    CHK( DAQmxStopTask              (clk_task));
	  }
	  DAQmxStopTask(ao_task);
	  //DAQmxStopTask(trg_task);
	}

Error:

	if( clk_task!=0 ) {
		DAQmxStopTask(clk_task);
		DAQmxClearTask(clk_task);
	}
  if( ao_task!=0 ) {
		DAQmxStopTask(ao_task);
		DAQmxClearTask(ao_task);
	}
	//if( trg_task!=0 ) {
	//	DAQmxStopTask(trg_task);
	//	DAQmxClearTask(trg_task);
	//}
	printf("End of program, press Enter key to quit\n");
	getchar();
	return;
}

/* Timings   2010-01-11   Time for Start/Stop of AO task
a = array([8.17151e-005
,0.000236025
,0.000238579
,0.000252806
,0.000249523
,0.000233107
,0.000254995
,0.000231648
,0.000252806
,0.000253901])
*/

/* Timings   2010-01-12   (test2) Time for Start/Stop of doubley triggered ctr task
 *                                delay: 472 +- 6 us max: 483 us min: 459 us
 * in git repository (fetch) see commit 43c1803db7fea66082f772afa6f659ebe586da25
 **
a = array([0.000458918
,0.000482995
,0.000475334
,0.000474969
,0.000468768
,0.00047424
,0.000468768
,0.000476064
,0.000472416])
*/
int _tmain(int argc, _TCHAR* argv[])
{ test2();
}<|endoftext|>


<commit_before>#include <windows.h>
#include <OvRender.h>
#include <sloverlay.h>
#include <overlay.h>

SlOverlayMenu* MnuMenu;

MenuVars MenuOsd[20];
MenuVars MnuCache[10];

WCHAR* GroupOpt[] = {L"", L""};
WCHAR* ItemOpt[] = {L"Off", L"On"};

BOOLEAN MnuInitialized;
HANDLE MenuProcessHeap;

//Add menu items to menu

VOID
AddItems()
{
    MnuMenu->AddGroup(L"OSD", GroupOpt, &MenuOsd[0].Var);

    if (MenuOsd[0].Var)
    {
        MnuMenu->AddItem(L"GPU Core utilization",    ItemOpt, &MenuOsd[1].Var);
        MnuMenu->AddItem(L"GPU Core temperature",    ItemOpt, &MenuOsd[2].Var);
        MnuMenu->AddItem(L"GPU Engine Clock",        ItemOpt, &MenuOsd[3].Var);
        MnuMenu->AddItem(L"GPU Memory Clock",        ItemOpt, &MenuOsd[4].Var);
        MnuMenu->AddItem(L"GPU VRAM usage",          ItemOpt, &MenuOsd[5].Var);
        MnuMenu->AddItem(L"CPU utilization",         ItemOpt, &MenuOsd[6].Var);
        MnuMenu->AddItem(L"CPU temperature",         ItemOpt, &MenuOsd[7].Var);
        MnuMenu->AddItem(L"RAM usage",               ItemOpt, &MenuOsd[8].Var);
        MnuMenu->AddItem(L"Max core usage",          ItemOpt, &MenuOsd[9].Var);
        MnuMenu->AddItem(L"Max thread usage",        ItemOpt, &MenuOsd[10].Var);
        MnuMenu->AddItem(L"Disk read-write rate",    ItemOpt, &MenuOsd[11].Var);
        MnuMenu->AddItem(L"Disk response time",      ItemOpt, &MenuOsd[12].Var);
        MnuMenu->AddItem(L"Frame Buffer count",      ItemOpt, &MenuOsd[13].Var);
        MnuMenu->AddItem(L"Show Time",               ItemOpt, &MenuOsd[14].Var);
    }

    MnuMenu->AddGroup(L"CACHE", GroupOpt, &MnuCache[0].Var);

    if (MnuCache[0].Var)
    {
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[1].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[2].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[3].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[4].Var);
    }
}

VOID
ProcessOptions()
{
    if (MenuOsd[1].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_LOAD;
    /*else
        PushSharedMemory->OSDFlags &= ~OSD_GPU_LOAD;*/
    //this needs to be fixed, if it was enable by main gui
    //checkbox then it'll get disabled. too lazy...

    if (MenuOsd[2].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_TEMP;

    if (MenuOsd[3].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_E_CLK;

    if (MenuOsd[4].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_M_CLK;

    if (MenuOsd[7].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_CPU_TEMP;

    if (MenuOsd[9].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MCU;

    if (MenuOsd[10].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MTU;

    if (MenuOsd[11].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_DISK_RWRATE;

    if (MenuOsd[12].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_DISK_RESPONSE;

    if (MenuOsd[14].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_TIME;
}

VOID
MnuRender( OvOverlay* Overlay )
{
    if (!MnuInitialized)
    {
        MnuMenu = new SlOverlayMenu(300);
        MnuInitialized = TRUE;
    }

    if( MnuMenu->mSet.MaxItems == 0 )
        AddItems();

    //Call drawing and navigation functions
    MnuMenu->Render(100, 200, Overlay);
}

#define GROUP 1
#define ITEM  2
#define HEIGHT 16

DWORD LightBlue = 0xFF4DD0EB;
DWORD Green     = 0xFF33FF00;
DWORD White     = 0xFFE6E6E6;
DWORD Blue      = 0xFF00A4C5;

WNDPROC         OldWNDPROC;
SlOverlayMenu*  OvmMenu;

VOID
MenuKeyboardHook( WPARAM Key )
{
    switch( Key )
    {
        case VK_INSERT:
            OvmMenu->mSet.Show = !OvmMenu->mSet.Show;
            break;

        case VK_UP:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                OvmMenu->mSet.SeletedIndex--;

                if (OvmMenu->mSet.SeletedIndex < 0)
                    OvmMenu->mSet.SeletedIndex = OvmMenu->mSet.MaxItems - 1;

            } break;

        case VK_DOWN:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                OvmMenu->mSet.SeletedIndex++;

                if (OvmMenu->mSet.SeletedIndex == OvmMenu->mSet.MaxItems)
                    OvmMenu->mSet.SeletedIndex = 0;

            } break;

        case VK_LEFT:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var && *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var > 0)
                {
                    *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var += -1;

                    if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Type == GROUP)
                        OvmMenu->mSet.MaxItems = 0;
                }

            } break;

        case VK_RIGHT:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var
                    && *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var < (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].MaxValue - 1))
                {
                    *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var += 1;

                    if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Type == GROUP)
                        OvmMenu->mSet.MaxItems = 0;
                }

            } break;
    }

    // Update osd items.
    ProcessOptions();
}

SlOverlayMenu::SlOverlayMenu( int OptionsX )
{
    OpX = OptionsX;

    mSet.Show = FALSE;
    mSet.MaxItems = 0;
    mSet.SeletedIndex = 0;

    OvmMenu = this;
    MenuProcessHeap = GetProcessHeap();
}

void SlOverlayMenu::AddItemToMenu(WCHAR* Title, WCHAR** Options, int* Var, int MaxValue, int Type)
{
    Items[mSet.MaxItems].Title = Title;
    Items[mSet.MaxItems].Options= Options;
    Items[mSet.MaxItems].Var = Var;
    Items[mSet.MaxItems].MaxValue = MaxValue;
    Items[mSet.MaxItems].Type = Type;
    mSet.MaxItems++;
}

VOID
SlOverlayMenu::Render( int X, int Y, OvOverlay* Overlay )
{
    DWORD ColorOne, ColorTwo;
    int ValueOne, ValueTwo;

    if (!mSet.Show)
        return;

    for (int i = 0; i < mSet.MaxItems; i++)
    {
        ValueOne = (Items[i].Var) ? (*Items[i].Var) : 0;
        ValueTwo = (Items[i].Var) ? (*Items[i].Var) : 0;

        if (i == mSet.SeletedIndex)
        {
            ColorOne = LightBlue;
            ColorTwo = (ValueTwo) ? Green : White;
        }
        else if (Items[i].Type == GROUP)
        {
            ColorOne = Blue;
            ColorTwo = Blue;
        }
        else
        {
            ColorOne = (ValueOne) ? White : White;
            ColorTwo = (ValueTwo) ? Green : White;
        }

        if (Items[i].Type == GROUP)
            Overlay->DrawText(Items[i].Title, X, Y, ColorOne);

        if (Items[i].Type == ITEM)
            Overlay->DrawText(Items[i].Title, X + 20, Y, ColorOne);

        if (Items[i].Options)
            Overlay->DrawText(Items[i].Options[ValueTwo], OpX, Y, ColorTwo);

        Y += HEIGHT;
    }
}
<commit_msg>fixed ram usage menu item<commit_after>#include <windows.h>
#include <OvRender.h>
#include <sloverlay.h>
#include <overlay.h>

SlOverlayMenu* MnuMenu;

MenuVars MenuOsd[20];
MenuVars MnuCache[10];

WCHAR* GroupOpt[] = {L"", L""};
WCHAR* ItemOpt[] = {L"Off", L"On"};

BOOLEAN MnuInitialized;
HANDLE MenuProcessHeap;

//Add menu items to menu

VOID
AddItems()
{
    MnuMenu->AddGroup(L"OSD", GroupOpt, &MenuOsd[0].Var);

    if (MenuOsd[0].Var)
    {
        MnuMenu->AddItem(L"GPU Core utilization",    ItemOpt, &MenuOsd[1].Var);
        MnuMenu->AddItem(L"GPU Core temperature",    ItemOpt, &MenuOsd[2].Var);
        MnuMenu->AddItem(L"GPU Engine Clock",        ItemOpt, &MenuOsd[3].Var);
        MnuMenu->AddItem(L"GPU Memory Clock",        ItemOpt, &MenuOsd[4].Var);
        MnuMenu->AddItem(L"GPU VRAM usage",          ItemOpt, &MenuOsd[5].Var);
        MnuMenu->AddItem(L"CPU utilization",         ItemOpt, &MenuOsd[6].Var);
        MnuMenu->AddItem(L"CPU temperature",         ItemOpt, &MenuOsd[7].Var);
        MnuMenu->AddItem(L"RAM usage",               ItemOpt, &MenuOsd[8].Var);
        MnuMenu->AddItem(L"Max core usage",          ItemOpt, &MenuOsd[9].Var);
        MnuMenu->AddItem(L"Max thread usage",        ItemOpt, &MenuOsd[10].Var);
        MnuMenu->AddItem(L"Disk read-write rate",    ItemOpt, &MenuOsd[11].Var);
        MnuMenu->AddItem(L"Disk response time",      ItemOpt, &MenuOsd[12].Var);
        MnuMenu->AddItem(L"Frame Buffer count",      ItemOpt, &MenuOsd[13].Var);
        MnuMenu->AddItem(L"Show Time",               ItemOpt, &MenuOsd[14].Var);
    }

    MnuMenu->AddGroup(L"CACHE", GroupOpt, &MnuCache[0].Var);

    if (MnuCache[0].Var)
    {
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[1].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[2].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[3].Var);
        MnuMenu->AddItem(L"NULL", ItemOpt, &MnuCache[4].Var);
    }
}

VOID
ProcessOptions()
{
    if (MenuOsd[1].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_LOAD;
    /*else
        PushSharedMemory->OSDFlags &= ~OSD_GPU_LOAD;*/
    //this needs to be fixed, if it was enable by main gui
    //checkbox then it'll get disabled. too lazy...

    if (MenuOsd[2].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_TEMP;

    if (MenuOsd[3].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_E_CLK;

    if (MenuOsd[4].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_GPU_M_CLK;

    if (MenuOsd[7].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_CPU_TEMP;

    if (MenuOsd[8].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_RAM;

    if (MenuOsd[9].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MCU;

    if (MenuOsd[10].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_MTU;

    if (MenuOsd[11].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_DISK_RWRATE;

    if (MenuOsd[12].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_DISK_RESPONSE;

    if (MenuOsd[14].Var > 0)
        PushSharedMemory->OSDFlags |= OSD_TIME;
}

VOID
MnuRender( OvOverlay* Overlay )
{
    if (!MnuInitialized)
    {
        MnuMenu = new SlOverlayMenu(300);
        MnuInitialized = TRUE;
    }

    if( MnuMenu->mSet.MaxItems == 0 )
        AddItems();

    //Call drawing and navigation functions
    MnuMenu->Render(100, 200, Overlay);
}

#define GROUP 1
#define ITEM  2
#define HEIGHT 16

DWORD LightBlue = 0xFF4DD0EB;
DWORD Green     = 0xFF33FF00;
DWORD White     = 0xFFE6E6E6;
DWORD Blue      = 0xFF00A4C5;

WNDPROC         OldWNDPROC;
SlOverlayMenu*  OvmMenu;

VOID
MenuKeyboardHook( WPARAM Key )
{
    switch( Key )
    {
        case VK_INSERT:
            OvmMenu->mSet.Show = !OvmMenu->mSet.Show;
            break;

        case VK_UP:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                OvmMenu->mSet.SeletedIndex--;

                if (OvmMenu->mSet.SeletedIndex < 0)
                    OvmMenu->mSet.SeletedIndex = OvmMenu->mSet.MaxItems - 1;

            } break;

        case VK_DOWN:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                OvmMenu->mSet.SeletedIndex++;

                if (OvmMenu->mSet.SeletedIndex == OvmMenu->mSet.MaxItems)
                    OvmMenu->mSet.SeletedIndex = 0;

            } break;

        case VK_LEFT:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var && *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var > 0)
                {
                    *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var += -1;

                    if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Type == GROUP)
                        OvmMenu->mSet.MaxItems = 0;
                }

            } break;

        case VK_RIGHT:
            {
                if (!OvmMenu->mSet.Show)
                    break;

                if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var
                    && *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var < (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].MaxValue - 1))
                {
                    *OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Var += 1;

                    if (OvmMenu->Items[OvmMenu->mSet.SeletedIndex].Type == GROUP)
                        OvmMenu->mSet.MaxItems = 0;
                }

            } break;
    }

    // Update osd items.
    ProcessOptions();
}

SlOverlayMenu::SlOverlayMenu( int OptionsX )
{
    OpX = OptionsX;

    mSet.Show = FALSE;
    mSet.MaxItems = 0;
    mSet.SeletedIndex = 0;

    OvmMenu = this;
    MenuProcessHeap = GetProcessHeap();
}

void SlOverlayMenu::AddItemToMenu(WCHAR* Title, WCHAR** Options, int* Var, int MaxValue, int Type)
{
    Items[mSet.MaxItems].Title = Title;
    Items[mSet.MaxItems].Options= Options;
    Items[mSet.MaxItems].Var = Var;
    Items[mSet.MaxItems].MaxValue = MaxValue;
    Items[mSet.MaxItems].Type = Type;
    mSet.MaxItems++;
}

VOID
SlOverlayMenu::Render( int X, int Y, OvOverlay* Overlay )
{
    DWORD ColorOne, ColorTwo;
    int ValueOne, ValueTwo;

    if (!mSet.Show)
        return;

    for (int i = 0; i < mSet.MaxItems; i++)
    {
        ValueOne = (Items[i].Var) ? (*Items[i].Var) : 0;
        ValueTwo = (Items[i].Var) ? (*Items[i].Var) : 0;

        if (i == mSet.SeletedIndex)
        {
            ColorOne = LightBlue;
            ColorTwo = (ValueTwo) ? Green : White;
        }
        else if (Items[i].Type == GROUP)
        {
            ColorOne = Blue;
            ColorTwo = Blue;
        }
        else
        {
            ColorOne = (ValueOne) ? White : White;
            ColorTwo = (ValueTwo) ? Green : White;
        }

        if (Items[i].Type == GROUP)
            Overlay->DrawText(Items[i].Title, X, Y, ColorOne);

        if (Items[i].Type == ITEM)
            Overlay->DrawText(Items[i].Title, X + 20, Y, ColorOne);

        if (Items[i].Options)
            Overlay->DrawText(Items[i].Options[ValueTwo], OpX, Y, ColorTwo);

        Y += HEIGHT;
    }
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sysplug.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: vg $ $Date: 2007-12-07 11:52:36 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <cstdarg>

#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <osl/thread.h>

#include <plugin/impl.hxx>

int MacPluginComm::nConnCounter = 0;

MacPluginComm::MacPluginComm(
                             const String& mimetype,
                             const String& library,
                             NSView* aParent,
                             int nDescriptor1,
                             int nDescriptor2
                             ) :
PluginComm( ::rtl::OUStringToOString( library, osl_getThreadTextEncoding() ) )/*,
PluginConnector( nDescriptor2 )*/
{
    //char pDesc[32];
//  char pWindow[32];
//  sprintf( pWindow, "%d", aParent );
//    sprintf( pDesc, "%d", nDescriptor1 );
//  ByteString aLib( library, osl_getThreadTextEncoding() );
//
//  char* pArgs[5];
//  pArgs[0] = "pluginapp.bin";
//  pArgs[1] = pDesc;
//  pArgs[2] = const_cast<char*>(aLib.GetBuffer());
//  pArgs[3] = pWindow;
//  pArgs[4] = NULL;
//
//#if OSL_DEBUG_LEVEL > 1
//  m_nCommPID = 10;
//  fprintf( stderr, "Try to launch: %s %s %s %s, descriptors are %d, %d\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3], nDescriptor1, nDescriptor2 );
//#endif
//
//  if( ! ( m_nCommPID = fork() ) )
//      {
//      execvp( pArgs[0], pArgs );
//          fprintf( stderr, "Error: could not exec %s\n", pArgs[0] );
//          _exit(255);
//      }
//
//  if( m_nCommPID != -1 )
//  {
//      // wait for pluginapp.bin to start up
//      if( ! WaitForMessage( 5000 ) )
//      {
//          fprintf( stderr, "Timeout on command: %s %s %s %s\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3] );
//          invalidate();
//      }
//      else
//      {
//          MediatorMessage* pMessage = GetNextMessage( TRUE );
//          Respond( pMessage->m_nID,
//                   "init ack",8,
//                   NULL );
//          delete pMessage;
//          NPP_Initialize();
//      }
//  }
}

MacPluginComm::~MacPluginComm()
{
    NPP_Shutdown();
    if( m_nCommPID != -1 && m_nCommPID != 0 )
    {
        int status = 16777216;
        pid_t nExit = waitpid( m_nCommPID, &status, WUNTRACED );
#if OSL_DEBUG_LEVEL > 1
        fprintf( stderr, "child %d (plugin app child %d) exited with status %d\n", nExit, m_nCommPID, WEXITSTATUS(status) );
#endif
    }
}

NPError MacPluginComm::NPP_Destroy( NPP instance,
                                    NPSavedData** save )
{
    return 0;
}

NPError MacPluginComm::NPP_DestroyStream( NPP instance,
                                          NPStream* stream,
                                          NPError reason )
{
    return 0;
}

void* MacPluginComm::NPP_GetJavaClass()
{
    return 0;
}

NPError MacPluginComm::NPP_Initialize()
{
    return 0;
}

NPError MacPluginComm::NPP_New( NPMIMEType pluginType,
                                NPP instance,
                                uint16 mode,
                                int16 argc,
                                char* argn[],
                                char* argv[],
                                NPSavedData *saved )
{
    return 0;
}

NPError MacPluginComm::NPP_NewStream( NPP instance,
                                      NPMIMEType type,
                                      NPStream* stream,
                                      NPBool seekable,
                                      uint16* stype )
{
    return 0;
}

void MacPluginComm::NPP_Print( NPP instance,
                               NPPrint* platformPrint )
{

}

NPError MacPluginComm::NPP_SetWindow( NPP instance,
                                      NPWindow* window )
{
    return 0;
}

void MacPluginComm::NPP_Shutdown()
{

}

void MacPluginComm::NPP_StreamAsFile( NPP instance,
                                      NPStream* stream,
                                      const char* fname )
{

}

void MacPluginComm::NPP_URLNotify( NPP instance,
                                   const char* url,
                                   NPReason reason,
                                   void* notifyData )
{

}

int32 MacPluginComm::NPP_Write( NPP instance,
                                NPStream* stream,
                                int32 offset,
                                int32 len,
                                void* buffer )
{
    return 0;
}

int32 MacPluginComm::NPP_WriteReady( NPP instance,
                                     NPStream* stream )
{
    return 0;
}

char* MacPluginComm::NPP_GetMIMEDescription()
{
    return "";
}

NPError MacPluginComm::NPP_GetValue( NPP instance, NPPVariable variable, void* value )
{
    return 0;
}

NPError MacPluginComm::NPP_SetValue( NPP instance,
                                     NPNVariable variable,
                                     void *value)
{
    return 0;
}

<commit_msg>INTEGRATION: CWS wae4extensions (1.2.44); FILE MERGED 2008/01/09 21:11:08 ericb 1.2.44.4: RESYNC: (1.3-1.4); FILE MERGED 2007/10/04 21:36:52 ericb 1.2.44.3: #i81612# add a better fix for warning in sysplug.cxx 2007/10/04 15:19:14 ericb 1.2.44.2: #i81612# fix warning on Mac OS X Aqua 2007/10/03 12:45:23 ericb 1.2.44.1: #i81612# fix warning because of bad type in aqua mozilla plugin<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: sysplug.cxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: ihi $ $Date: 2008-01-14 14:49:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#include <cstdarg>

#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include <osl/thread.h>

#include <plugin/impl.hxx>

int MacPluginComm::nConnCounter = 0;

MacPluginComm::MacPluginComm(
                             const String& mimetype,
                             const String& library,
                             NSView* aParent,
                             int nDescriptor1,
                             int nDescriptor2
                             ) :
PluginComm( ::rtl::OUStringToOString( library, osl_getThreadTextEncoding() ) )/*,
PluginConnector( nDescriptor2 )*/
{
    //char pDesc[32];
//  char pWindow[32];
//  sprintf( pWindow, "%d", aParent );
//    sprintf( pDesc, "%d", nDescriptor1 );
//  ByteString aLib( library, osl_getThreadTextEncoding() );
//
//  char* pArgs[5];
//  pArgs[0] = "pluginapp.bin";
//  pArgs[1] = pDesc;
//  pArgs[2] = const_cast<char*>(aLib.GetBuffer());
//  pArgs[3] = pWindow;
//  pArgs[4] = NULL;
//
//#if OSL_DEBUG_LEVEL > 1
//  m_nCommPID = 10;
//  fprintf( stderr, "Try to launch: %s %s %s %s, descriptors are %d, %d\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3], nDescriptor1, nDescriptor2 );
//#endif
//
//  if( ! ( m_nCommPID = fork() ) )
//      {
//      execvp( pArgs[0], pArgs );
//          fprintf( stderr, "Error: could not exec %s\n", pArgs[0] );
//          _exit(255);
//      }
//
//  if( m_nCommPID != -1 )
//  {
//      // wait for pluginapp.bin to start up
//      if( ! WaitForMessage( 5000 ) )
//      {
//          fprintf( stderr, "Timeout on command: %s %s %s %s\n", pArgs[0], pArgs[1], pArgs[2], pArgs[3] );
//          invalidate();
//      }
//      else
//      {
//          MediatorMessage* pMessage = GetNextMessage( TRUE );
//          Respond( pMessage->m_nID,
//                   "init ack",8,
//                   NULL );
//          delete pMessage;
//          NPP_Initialize();
//      }
//  }
}

MacPluginComm::~MacPluginComm()
{
    NPP_Shutdown();
    if( m_nCommPID != -1 && m_nCommPID != 0 )
    {
        int status = 16777216;
#if OSL_DEBUG_LEVEL > 1
    pid_t nExit = waitpid( m_nCommPID, &status, WUNTRACED );
    fprintf( stderr, "child %d (plugin app child %d) exited with status %d\n", nExit, m_nCommPID, WEXITSTATUS(status) );
#else
    waitpid( m_nCommPID, &status, WUNTRACED );
#endif
    }
}

NPError MacPluginComm::NPP_Destroy( NPP instance,
                                    NPSavedData** save )
{
    return 0;
}

NPError MacPluginComm::NPP_DestroyStream( NPP instance,
                                          NPStream* stream,
                                          NPError reason )
{
    return 0;
}

void* MacPluginComm::NPP_GetJavaClass()
{
    return 0;
}

NPError MacPluginComm::NPP_Initialize()
{
    return 0;
}

NPError MacPluginComm::NPP_New( NPMIMEType pluginType,
                                NPP instance,
                                uint16 mode,
                                int16 argc,
                                char* argn[],
                                char* argv[],
                                NPSavedData *saved )
{
    return 0;
}

NPError MacPluginComm::NPP_NewStream( NPP instance,
                                      NPMIMEType type,
                                      NPStream* stream,
                                      NPBool seekable,
                                      uint16* stype )
{
    return 0;
}

void MacPluginComm::NPP_Print( NPP instance,
                               NPPrint* platformPrint )
{

}

NPError MacPluginComm::NPP_SetWindow( NPP instance,
                                      NPWindow* window )
{
    return 0;
}

void MacPluginComm::NPP_Shutdown()
{

}

void MacPluginComm::NPP_StreamAsFile( NPP instance,
                                      NPStream* stream,
                                      const char* fname )
{

}

void MacPluginComm::NPP_URLNotify( NPP instance,
                                   const char* url,
                                   NPReason reason,
                                   void* notifyData )
{

}

int32 MacPluginComm::NPP_Write( NPP instance,
                                NPStream* stream,
                                int32 offset,
                                int32 len,
                                void* buffer )
{
    return 0;
}

int32 MacPluginComm::NPP_WriteReady( NPP instance,
                                     NPStream* stream )
{
    return 0;
}

char* MacPluginComm::NPP_GetMIMEDescription()
{
    return "";
}

NPError MacPluginComm::NPP_GetValue( NPP instance, NPPVariable variable, void* value )
{
    return 0;
}

NPError MacPluginComm::NPP_SetValue( NPP instance,
                                     NPNVariable variable,
                                     void *value)
{
    return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2017 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <Chaos/IO/ColorIO.h>
#include <Chaos/Unittest/TestHarness.h>

CHAOS_TEST(ColorIO, Chaos::FakeTester) {
  namespace cc = ::Chaos::ColorIO;

  cc::fprintf(stdout,
      cc::ColorType::COLORTYPE_GREEN,
      "Chaos::ColorIO unittest - green information with `fprintf`\n");
  cc::printf(cc::ColorType::COLORTYPE_GREEN,
      "Chaos::ColorIO unittest - green information with `printf`\n");
  cc::fprintf(stdout,
      cc::ColorType::COLORTYPE_RED,
      "Chaos::ColorIO unittest - red information with `fprintf`\n");
  cc::printf(cc::ColorType::COLORTYPE_RED,
      "Chaos::ColorIO unittest - red information with `printf`\n");
}
<commit_msg>:construction: test(colorio): updated the unittest for colorio<commit_after>// Copyright (c) 2017 ASMlover. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
//
//  * Redistributions of source code must retain the above copyright
//    notice, this list ofconditions and the following disclaimer.
//
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in
//    the documentation and/or other materialsprovided with the
//    distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
// FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
// COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include <Chaos/IO/ColorIO.h>
#include <Chaos/Unittest/TestHarness.h>

CHAOS_TEST(ColorIO, Chaos::FakeTester) {
  namespace cc = ::Chaos::ColorIO;

  cc::printf(cc::ColorType::COLORTYPE_RED,
      "Chaos::ColorIO unittest - red information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTRED,
      "Chaos::ColorIO unittest - light red information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_GREEN,
      "Chaos::ColorIO unittest - green information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTGREEN,
      "Chaos::ColorIO unittest - light green information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_YELLOW,
      "Chaos::ColorIO unittest - yellow information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTYELLOW,
      "Chaos::ColorIO unittest - light yellow information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_BLUE,
      "Chaos::ColorIO unittest - blue information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTBLUE,
      "Chaos::ColorIO unittest - light blue information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_MAGENTA,
      "Chaos::ColorIO unittest - magenta information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTMAGENTA,
      "Chaos::ColorIO unittest - light magenta information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_CYAN,
      "Chaos::ColorIO unittest - cyan information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTCYAN,
      "Chaos::ColorIO unittest - light cyan information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_WHITE,
      "Chaos::ColorIO unittest - white information with `printf`\n");
  cc::printf(cc::ColorType::COLORTYPE_LIGHTWHITE,
      "Chaos::ColorIO unittest - light white information with `printf`\n");

  cc::fprintf(stdout, cc::ColorType::COLORTYPE_RED,
      "Chaos::ColorIO unittest - red information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTRED,
      "Chaos::ColorIO unittest - light red information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_GREEN,
      "Chaos::ColorIO unittest - green information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTGREEN,
      "Chaos::ColorIO unittest - light green information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_YELLOW,
      "Chaos::ColorIO unittest - yellow information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTYELLOW,
      "Chaos::ColorIO unittest - light yellow information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_BLUE,
      "Chaos::ColorIO unittest - blue information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTBLUE,
      "Chaos::ColorIO unittest - light blue information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_MAGENTA,
      "Chaos::ColorIO unittest - magenta information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTMAGENTA,
      "Chaos::ColorIO unittest - light magenta information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_CYAN,
      "Chaos::ColorIO unittest - cyan information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTCYAN,
      "Chaos::ColorIO unittest - light cyan information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_WHITE,
      "Chaos::ColorIO unittest - white information with `fprintf`\n");
  cc::fprintf(stdout, cc::ColorType::COLORTYPE_LIGHTWHITE,
      "Chaos::ColorIO unittest - light white information with `fprintf`\n");
}
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2015, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Devices/Oculus/OculusScaffold.h"

#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <list>
#include <memory>

#include <OVR_Version.h>
#if 6 == OVR_MAJOR_VERSION
#include <OVR_CAPI_0_6_0.h>
#elif 5 == OVR_MAJOR_VERSION
#include <OVR_CAPI_0_5_0.h>
#endif

#include "SurgSim/DataStructures/DataGroup.h"
#include "SurgSim/DataStructures/DataGroupBuilder.h"
#include "SurgSim/Devices/Oculus/OculusDevice.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Framework/SharedInstance.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/RigidTransform.h"

using SurgSim::DataStructures::DataGroup;
using SurgSim::DataStructures::DataGroupBuilder;
using SurgSim::Framework::Logger;
using SurgSim::Math::makeRigidTransform;
using SurgSim::Math::Quaterniond;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::Vector3d;

namespace SurgSim
{
namespace Devices
{

struct OculusScaffold::DeviceData
{
	/// Constructor
	/// \param device Device to be wrapped
	explicit DeviceData(OculusDevice* device) :
		deviceObject(device),
		handle(nullptr)
	{
#if 6 == OVR_MAJOR_VERSION
		ovrHmd_Create(0, &handle);
#elif 5 == OVR_MAJOR_VERSION
		handle = ovrHmd_Create(0);
#endif
	}

	~DeviceData()
	{
		if (handle != nullptr)
		{
			ovrHmd_Destroy(handle);
		}
	}

	/// The device object wrapped in this class.
	OculusDevice* const deviceObject;

	/// Device handle
	ovrHmd handle;
};

struct OculusScaffold::StateData
{
	/// List of registered devices.
	std::list<std::unique_ptr<OculusScaffold::DeviceData>> registeredDevices;

	/// The mutex that protects the list of registered devices.
	boost::mutex mutex;
};

OculusScaffold::OculusScaffold() :
	Framework::BasicThread("OculusScaffold"),
	m_logger(Logger::getLogger("Devices/Oculus")),
	m_state(new StateData)
{
	SURGSIM_LOG_DEBUG(m_logger) << "Oculus: Shared scaffold created.";

	// Oculus DK2 tracks Gyroscope, Accelerometer, Magnetometer at 1000Hz and
	// positional tracking is done at 60Hz.
	setRate(1000.0);

}

OculusScaffold::~OculusScaffold()
{
	ovr_Shutdown();
}

bool OculusScaffold::registerDevice(OculusDevice* device)
{
	bool success = true;
	if (!isRunning())
	{
		std::shared_ptr<SurgSim::Framework::Barrier> barrier = std::make_shared<SurgSim::Framework::Barrier>(2);
		start(barrier);
		barrier->wait(true); // Wait for initialize
		barrier->wait(true); // Wait for startup
		success = isInitialized();
	}

	if (success)
	{
		boost::lock_guard<boost::mutex> lock(m_state->mutex);
		const std::string deviceName = device->getName();
		auto sameName = [&deviceName](const std::unique_ptr<DeviceData>& info)
		{
			return info->deviceObject->getName() == deviceName;
		};
		auto found = std::find_if(m_state->registeredDevices.cbegin(), m_state->registeredDevices.cend(), sameName);

		if (found == m_state->registeredDevices.end())
		{
			std::unique_ptr<DeviceData> info(new DeviceData(device));
			success = doRegisterDevice(info.get());
			if (success)
			{
				SURGSIM_LOG_INFO(m_logger) << "Device " << device->getName() << ": Registered";
				m_state->registeredDevices.emplace_back(std::move(info));
			}
		}
		else
		{
			SURGSIM_LOG_SEVERE(m_logger) << "Tried to register a device when the same name, '" <<
				device->getName() << "', is already present!";
			success = false;
		}
	}

	return success;
}

bool OculusScaffold::doRegisterDevice(DeviceData* info)
{
	if (ovrHmd_Detect() < 1)
	{
		SURGSIM_LOG_SEVERE(m_logger) << "No available Oculus device detected.";
		return false;
	}

	if (m_state->registeredDevices.size() > 0)
	{
		SURGSIM_LOG_SEVERE(m_logger)
			<< "There is one registered Oculus device already. OculusScaffold only supports one device right now";
		return false;
	}

	if (info->handle == nullptr)
	{
		SURGSIM_LOG_SEVERE(m_logger) << "Failed to obtain a handle to Oculus Device. Is an Oculus device plugged in?";
		return false;
	}

#if 6 == OVR_MAJOR_VERSION
	if (ovrSuccess != ovrHmd_ConfigureTracking(info->handle, ovrTrackingCap_Orientation |
															 ovrTrackingCap_MagYawCorrection |
															 ovrTrackingCap_Position, 0))
#elif 5 == OVR_MAJOR_VERSION
	if (ovrTrue != ovrHmd_ConfigureTracking(info->handle, ovrTrackingCap_Orientation |
														  ovrTrackingCap_MagYawCorrection |
														  ovrTrackingCap_Position, 0))
#endif
	{
		SURGSIM_LOG_SEVERE(m_logger) << "Failed to configure an Oculus Device. Registration failed";
		return false;
	}

	// Query the HMD for the left and right projection matrices.
	ovrFovPort defaultLeftFov = info->handle->DefaultEyeFov[ovrEyeType::ovrEye_Left];
	ovrFovPort defaultRightFov = info->handle->DefaultEyeFov[ovrEyeType::ovrEye_Right];

	float nearPlane = info->deviceObject->getNearPlane();
	float farPlane = info->deviceObject->getFarPlane();

	ovrMatrix4f leftProjection = ovrMatrix4f_Projection(defaultLeftFov, nearPlane, farPlane,
			ovrProjectionModifier::ovrProjection_RightHanded);
	ovrMatrix4f rightProjection = ovrMatrix4f_Projection(defaultRightFov, nearPlane, farPlane,
			ovrProjectionModifier::ovrProjection_RightHanded);

	DataGroup& inputData = info->deviceObject->getInputData();
	inputData.matrices().set(DataStructures::Names::LEFT_PROJECTION_MATRIX,
			Eigen::Map<const Eigen::Matrix<float, 4, 4, Eigen::RowMajor>>
			(&leftProjection.M[0][0]).cast<double>());
	inputData.matrices().set(DataStructures::Names::RIGHT_PROJECTION_MATRIX,
			Eigen::Map<const Eigen::Matrix<float, 4, 4, Eigen::RowMajor>>
			(&rightProjection.M[0][0]).cast<double>());
	info->deviceObject->pushInput();

	return true;
}

bool OculusScaffold::unregisterDevice(const OculusDevice* const device)
{
	bool result = false;
	{
		boost::lock_guard<boost::mutex> lock(m_state->mutex);
		auto match = std::find_if(m_state->registeredDevices.begin(), m_state->registeredDevices.end(),
								  [&device](const std::unique_ptr<DeviceData>& info)
		{
			return info->deviceObject == device;
		});

		if (match != m_state->registeredDevices.end())
		{
			m_state->registeredDevices.erase(match);
			// the iterator is now invalid but that's OK
			SURGSIM_LOG_INFO(m_logger) << "Device " << getName() << ": unregistered.";
			result = true;
		}
	}

	// #threadsafety After unregistering, another thread could be in the process of registering.
	if (isRunning() && m_state->registeredDevices.size() == 0)
	{
		stop();
	}

	SURGSIM_LOG_IF(!result, m_logger, SEVERE) << "Attempted to release a non-registered device.";

	return result;
}

bool OculusScaffold::doInitialize()
{
#if 6 == OVR_MAJOR_VERSION
	if (ovrSuccess != ovr_Initialize(nullptr))
#elif 5 == OVR_MAJOR_VERSION
	if (ovrTrue != ovr_Initialize(nullptr))
#endif
	{
		SURGSIM_LOG_SEVERE(m_logger) << "Oculus SDK initialization failed.";
	}

	return true;
}

bool OculusScaffold::doStartUp()
{
	return true;
}

bool OculusScaffold::doUpdate(double dt)
{
	boost::lock_guard<boost::mutex> lock(m_state->mutex);

	for (auto& device : m_state->registeredDevices)
	{
		DataGroup& inputData = device->deviceObject->getInputData();

		// Query the HMD for the current tracking state.
		// If time in 2nd parameter is now or earlier, no pose prediction is made.
		// Pose is reported in a right handed coordinate system, X->RIGHT, Y->UP, Z->OUT.
		// Positive rotation is counterclockwise.
		// The XZ plane is ALWAYS aligned with the ground regardless of camera orientation.
		// Default tracking origin is one meter away from the camera.
		ovrTrackingState ts = ovrHmd_GetTrackingState(device->handle, ovr_GetTimeInSeconds());
		if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked))
		{
			ovrPosef ovrPose = ts.HeadPose.ThePose;

			Vector3d position(ovrPose.Position.x, ovrPose.Position.y, ovrPose.Position.z);
			Quaterniond orientation(ovrPose.Orientation.w, ovrPose.Orientation.x,
									ovrPose.Orientation.y, ovrPose.Orientation.z);
			RigidTransform3d pose = makeRigidTransform(orientation, position);

			inputData.poses().set(DataStructures::Names::POSE, pose);
		}
		else
		{
			inputData.poses().reset(DataStructures::Names::POSE);
		}

		device->deviceObject->pushInput();
	}

	return true;
}

SurgSim::DataStructures::DataGroup OculusScaffold::buildDeviceInputData()
{
	DataGroupBuilder builder;
	builder.addPose(DataStructures::Names::POSE);
	builder.addMatrix(DataStructures::Names::LEFT_PROJECTION_MATRIX);
	builder.addMatrix(DataStructures::Names::RIGHT_PROJECTION_MATRIX);
	return builder.createData();
}

std::shared_ptr<OculusScaffold> OculusScaffold::getOrCreateSharedInstance()
{
	static auto creator = []()
	{
		return std::shared_ptr<OculusScaffold>(new OculusScaffold);
	};
	static Framework::SharedInstance<OculusScaffold> sharedInstance(creator);
	return sharedInstance.get();
}

};  // namespace Devices
};  // namespace SurgSim
<commit_msg>Fix bug where the occulus desctructs after register<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2015-2016, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "SurgSim/Devices/Oculus/OculusScaffold.h"

#include <boost/thread/locks.hpp>
#include <boost/thread/mutex.hpp>
#include <list>
#include <memory>

#include <OVR_Version.h>
#if 6 == OVR_MAJOR_VERSION
#include <OVR_CAPI_0_6_0.h>
#elif 5 == OVR_MAJOR_VERSION
#include <OVR_CAPI_0_5_0.h>
#endif

#include "SurgSim/DataStructures/DataGroup.h"
#include "SurgSim/DataStructures/DataGroupBuilder.h"
#include "SurgSim/Devices/Oculus/OculusDevice.h"
#include "SurgSim/Framework/Log.h"
#include "SurgSim/Framework/SharedInstance.h"
#include "SurgSim/Math/Quaternion.h"
#include "SurgSim/Math/RigidTransform.h"

using SurgSim::DataStructures::DataGroup;
using SurgSim::DataStructures::DataGroupBuilder;
using SurgSim::Framework::Logger;
using SurgSim::Math::makeRigidTransform;
using SurgSim::Math::Quaterniond;
using SurgSim::Math::RigidTransform3d;
using SurgSim::Math::Vector3d;

namespace SurgSim
{
namespace Devices
{

struct OculusScaffold::DeviceData
{
	/// Constructor
	/// \param device Device to be wrapped
	explicit DeviceData(OculusDevice* device) :
		deviceObject(device),
		handle(nullptr)
	{
#if 6 == OVR_MAJOR_VERSION
		ovrHmd_Create(0, &handle);
#elif 5 == OVR_MAJOR_VERSION
		handle = ovrHmd_Create(0);
#endif
	}

	~DeviceData()
	{
		if (handle != nullptr)
		{
			ovrHmd_Destroy(handle);
		}
	}

	/// The device object wrapped in this class.
	OculusDevice* const deviceObject;

	/// Device handle
	ovrHmd handle;
};

struct OculusScaffold::StateData
{
	/// List of registered devices.
	std::list<std::unique_ptr<OculusScaffold::DeviceData>> registeredDevices;

	/// The mutex that protects the list of registered devices.
	boost::mutex mutex;
};

OculusScaffold::OculusScaffold() :
	Framework::BasicThread("OculusScaffold"),
	m_logger(Logger::getLogger("Devices/Oculus")),
	m_state(new StateData)
{
	SURGSIM_LOG_DEBUG(m_logger) << "Oculus: Shared scaffold created.";

	// Oculus DK2 tracks Gyroscope, Accelerometer, Magnetometer at 1000Hz and
	// positional tracking is done at 60Hz.
	setRate(1000.0);

}

OculusScaffold::~OculusScaffold()
{
	ovr_Shutdown();
}

bool OculusScaffold::registerDevice(OculusDevice* device)
{
	bool success = true;
	if (!isRunning())
	{
		std::shared_ptr<SurgSim::Framework::Barrier> barrier = std::make_shared<SurgSim::Framework::Barrier>(2);
		start(barrier);
		barrier->wait(true); // Wait for initialize
		barrier->wait(true); // Wait for startup
		success = isInitialized();
	}

	if (success)
	{
		boost::lock_guard<boost::mutex> lock(m_state->mutex);
		const std::string deviceName = device->getName();
		auto sameName = [&deviceName](const std::unique_ptr<DeviceData>& info)
		{
			return info->deviceObject->getName() == deviceName;
		};
		auto found = std::find_if(m_state->registeredDevices.cbegin(), m_state->registeredDevices.cend(), sameName);

		if (found == m_state->registeredDevices.end())
		{
			std::unique_ptr<DeviceData> info(new DeviceData(device));
			success = doRegisterDevice(info.get());
			if (success)
			{
				SURGSIM_LOG_INFO(m_logger) << "Device " << device->getName() << ": Registered";
				m_state->registeredDevices.emplace_back(std::move(info));
			}
		}
		else
		{
			SURGSIM_LOG_SEVERE(m_logger) << "Tried to register a device when the same name, '" <<
				device->getName() << "', is already present!";
			success = false;
		}
	}

	if (isRunning() && m_state->registeredDevices.size() == 0)
	{
		stop();
	}

	return success;
}

bool OculusScaffold::doRegisterDevice(DeviceData* info)
{
	if (ovrHmd_Detect() < 1)
	{
		SURGSIM_LOG_SEVERE(m_logger) << "No available Oculus device detected.";
		return false;
	}

	if (m_state->registeredDevices.size() > 0)
	{
		SURGSIM_LOG_SEVERE(m_logger)
			<< "There is one registered Oculus device already. OculusScaffold only supports one device right now";
		return false;
	}

	if (info->handle == nullptr)
	{
		SURGSIM_LOG_SEVERE(m_logger) << "Failed to obtain a handle to Oculus Device. Is an Oculus device plugged in?";
		return false;
	}

#if 6 == OVR_MAJOR_VERSION
	if (ovrSuccess != ovrHmd_ConfigureTracking(info->handle, ovrTrackingCap_Orientation |
															 ovrTrackingCap_MagYawCorrection |
															 ovrTrackingCap_Position, 0))
#elif 5 == OVR_MAJOR_VERSION
	if (ovrTrue != ovrHmd_ConfigureTracking(info->handle, ovrTrackingCap_Orientation |
														  ovrTrackingCap_MagYawCorrection |
														  ovrTrackingCap_Position, 0))
#endif
	{
		SURGSIM_LOG_SEVERE(m_logger) << "Failed to configure an Oculus Device. Registration failed";
		return false;
	}

	// Query the HMD for the left and right projection matrices.
	ovrFovPort defaultLeftFov = info->handle->DefaultEyeFov[ovrEyeType::ovrEye_Left];
	ovrFovPort defaultRightFov = info->handle->DefaultEyeFov[ovrEyeType::ovrEye_Right];

	float nearPlane = info->deviceObject->getNearPlane();
	float farPlane = info->deviceObject->getFarPlane();

	ovrMatrix4f leftProjection = ovrMatrix4f_Projection(defaultLeftFov, nearPlane, farPlane,
			ovrProjectionModifier::ovrProjection_RightHanded);
	ovrMatrix4f rightProjection = ovrMatrix4f_Projection(defaultRightFov, nearPlane, farPlane,
			ovrProjectionModifier::ovrProjection_RightHanded);

	DataGroup& inputData = info->deviceObject->getInputData();
	inputData.matrices().set(DataStructures::Names::LEFT_PROJECTION_MATRIX,
			Eigen::Map<const Eigen::Matrix<float, 4, 4, Eigen::RowMajor>>
			(&leftProjection.M[0][0]).cast<double>());
	inputData.matrices().set(DataStructures::Names::RIGHT_PROJECTION_MATRIX,
			Eigen::Map<const Eigen::Matrix<float, 4, 4, Eigen::RowMajor>>
			(&rightProjection.M[0][0]).cast<double>());
	info->deviceObject->pushInput();

	return true;
}

bool OculusScaffold::unregisterDevice(const OculusDevice* const device)
{
	bool result = false;
	{
		boost::lock_guard<boost::mutex> lock(m_state->mutex);
		auto match = std::find_if(m_state->registeredDevices.begin(), m_state->registeredDevices.end(),
								  [&device](const std::unique_ptr<DeviceData>& info)
		{
			return info->deviceObject == device;
		});

		if (match != m_state->registeredDevices.end())
		{
			m_state->registeredDevices.erase(match);
			// the iterator is now invalid but that's OK
			SURGSIM_LOG_INFO(m_logger) << "Device " << getName() << ": unregistered.";
			result = true;
		}
	}

	// #threadsafety After unregistering, another thread could be in the process of registering.
	if (isRunning() && m_state->registeredDevices.size() == 0)
	{
		stop();
	}

	SURGSIM_LOG_IF(!result, m_logger, SEVERE) << "Attempted to release a non-registered device.";

	return result;
}

bool OculusScaffold::doInitialize()
{
#if 6 == OVR_MAJOR_VERSION
	if (ovrSuccess != ovr_Initialize(nullptr))
#elif 5 == OVR_MAJOR_VERSION
	if (ovrTrue != ovr_Initialize(nullptr))
#endif
	{
		SURGSIM_LOG_SEVERE(m_logger) << "Oculus SDK initialization failed.";
	}

	return true;
}

bool OculusScaffold::doStartUp()
{
	return true;
}

bool OculusScaffold::doUpdate(double dt)
{
	boost::lock_guard<boost::mutex> lock(m_state->mutex);

	for (auto& device : m_state->registeredDevices)
	{
		DataGroup& inputData = device->deviceObject->getInputData();

		// Query the HMD for the current tracking state.
		// If time in 2nd parameter is now or earlier, no pose prediction is made.
		// Pose is reported in a right handed coordinate system, X->RIGHT, Y->UP, Z->OUT.
		// Positive rotation is counterclockwise.
		// The XZ plane is ALWAYS aligned with the ground regardless of camera orientation.
		// Default tracking origin is one meter away from the camera.
		ovrTrackingState ts = ovrHmd_GetTrackingState(device->handle, ovr_GetTimeInSeconds());
		if (ts.StatusFlags & (ovrStatus_OrientationTracked | ovrStatus_PositionTracked))
		{
			ovrPosef ovrPose = ts.HeadPose.ThePose;

			Vector3d position(ovrPose.Position.x, ovrPose.Position.y, ovrPose.Position.z);
			Quaterniond orientation(ovrPose.Orientation.w, ovrPose.Orientation.x,
									ovrPose.Orientation.y, ovrPose.Orientation.z);
			RigidTransform3d pose = makeRigidTransform(orientation, position);

			inputData.poses().set(DataStructures::Names::POSE, pose);
		}
		else
		{
			inputData.poses().reset(DataStructures::Names::POSE);
		}

		device->deviceObject->pushInput();
	}

	return true;
}

SurgSim::DataStructures::DataGroup OculusScaffold::buildDeviceInputData()
{
	DataGroupBuilder builder;
	builder.addPose(DataStructures::Names::POSE);
	builder.addMatrix(DataStructures::Names::LEFT_PROJECTION_MATRIX);
	builder.addMatrix(DataStructures::Names::RIGHT_PROJECTION_MATRIX);
	return builder.createData();
}

std::shared_ptr<OculusScaffold> OculusScaffold::getOrCreateSharedInstance()
{
	static auto creator = []()
	{
		return std::shared_ptr<OculusScaffold>(new OculusScaffold);
	};
	static Framework::SharedInstance<OculusScaffold> sharedInstance(creator);
	return sharedInstance.get();
}

};  // namespace Devices
};  // namespace SurgSim
<|endoftext|>


<commit_before>/**
*  Copyright (C) 2016 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "repo_maker_selection_tree.h"
#include "../../core/model/bson/repo_node_reference.h"
#include "../modeloptimizer/repo_optimizer_ifc.h"

using namespace repo::manipulator::modelutility;

const static std::string REPO_LABEL_VISIBILITY_STATE = "toggleState";
const static std::string REPO_VISIBILITY_STATE_SHOW = "visible";
const static std::string REPO_VISIBILITY_STATE_HIDDEN = "invisible";
const static std::string REPO_VISIBILITY_STATE_HALF_HIDDEN = "parentOfInvisible";

SelectionTreeMaker::SelectionTreeMaker(
	const repo::core::model::RepoScene *scene)
	: scene(scene)
{
}

repo::lib::PropertyTree SelectionTreeMaker::generatePTree(
	const repo::core::model::RepoNode            *currentNode,
	std::unordered_map < std::string,
	std::pair < std::string, std::string >> &idMaps,
	const std::string                            &currentPath,
	bool                                         &hiddenOnDefault,
	std::vector<std::string>                     &hiddenNode) const
{
	repo::lib::PropertyTree tree;
	if (currentNode)
	{
		std::string idString = currentNode->getUniqueID().toString();
		repo::lib::RepoUUID sharedID = currentNode->getSharedID();
		std::string childPath = currentPath.empty() ? idString : currentPath + "__" + idString;

		auto children = scene->getChildrenAsNodes(repo::core::model::RepoScene::GraphType::DEFAULT, sharedID);
		std::vector<repo::lib::PropertyTree> childrenTrees;

		std::vector<repo::core::model::RepoNode*> childrenTypes[2];
		for (const auto &child : children)
		{
			//Ensure IFC Space (if any) are put into the tree first.
			if (child->getName().find(IFC_TYPE_SPACE_LABEL) != std::string::npos)
				childrenTypes[0].push_back(child);
			else
				childrenTypes[1].push_back(child);
		}

		bool hasHiddenChildren = false;
		for (const auto childrenSet : childrenTypes)
		{
			for (const auto &child : childrenSet)
			{
				if (child)
				{
					switch (child->getTypeAsEnum())
					{
					case repo::core::model::NodeType::MESH:
					case repo::core::model::NodeType::TRANSFORMATION:
					case repo::core::model::NodeType::CAMERA:
					case repo::core::model::NodeType::REFERENCE:
					{
						bool hiddenChild = false;
						childrenTrees.push_back(generatePTree(child, idMaps, childPath, hiddenChild, hiddenNode));
						hasHiddenChildren = hasHiddenChildren || hiddenChild;
					}
					}
				}
				else
				{
					repoDebug << "Null pointer for child node at generatePTree, current path : " << currentPath;
					repoError << "Unexpected error at selection tree generation, the tree may not be complete.";
				}
			}
		}
		std::string name = currentNode->getName();
		if (repo::core::model::NodeType::REFERENCE == currentNode->getTypeAsEnum())
		{
			if (auto refNode = dynamic_cast<const repo::core::model::ReferenceNode*>(currentNode))
			{
				auto refDb = refNode->getDatabaseName();
				name = (scene->getDatabaseName() == refDb ? "" : (refDb + "/")) + refNode->getProjectName();
			}
		}

		tree.addToTree("account", scene->getDatabaseName());
		tree.addToTree("project", scene->getProjectName());
		if (!name.empty())
			tree.addToTree("name", name);
		tree.addToTree("path", childPath);
		tree.addToTree("_id", idString);
		tree.addToTree("shared_id", sharedID.toString());
		tree.addToTree("children", childrenTrees);

		if (name.find(IFC_TYPE_SPACE_LABEL) != std::string::npos
			&& currentNode->getTypeAsEnum() == repo::core::model::NodeType::MESH)
		{
			tree.addToTree(REPO_LABEL_VISIBILITY_STATE, REPO_VISIBILITY_STATE_HIDDEN);
			hiddenOnDefault = true;
			hiddenNode.push_back(idString);
		}
		else if (hiddenOnDefault = hiddenOnDefault || hasHiddenChildren)
		{
			tree.addToTree(REPO_LABEL_VISIBILITY_STATE, REPO_VISIBILITY_STATE_HALF_HIDDEN);
		}
		else
		{
			tree.addToTree(REPO_LABEL_VISIBILITY_STATE, REPO_VISIBILITY_STATE_SHOW);
		}

		idMaps[idString] = { name, childPath };
	}
	else
	{
		repoDebug << "Null pointer at generatePTree, current path : " << currentPath;
		repoError << "Unexpected error at selection tree generation, the tree may not be complete.";
	}

	return tree;
}

std::map<std::string, std::vector<uint8_t>> SelectionTreeMaker::getSelectionTreeAsBuffer() const
{
	auto trees = getSelectionTreeAsPropertyTree();
	std::map<std::string, std::vector<uint8_t>> buffer;
	for (const auto &tree : trees)
	{
		std::stringstream ss;
		tree.second.write_json(ss);
		std::string jsonString = ss.str();
		if (!jsonString.empty())
		{
			size_t byteLength = jsonString.size() * sizeof(*jsonString.data());
			buffer[tree.first] = std::vector<uint8_t>();
			buffer[tree.first].resize(byteLength);
			memcpy(buffer[tree.first].data(), jsonString.data(), byteLength);
		}
		else
		{
			repoError << "Failed to write selection tree into the buffer: JSON string is empty.";
		}
	}

	return buffer;
}

std::map<std::string, repo::lib::PropertyTree>  SelectionTreeMaker::getSelectionTreeAsPropertyTree() const
{
	std::map<std::string, repo::lib::PropertyTree> trees;

	repo::core::model::RepoNode *root;
	if (scene && (root = scene->getRoot(repo::core::model::RepoScene::GraphType::DEFAULT)))
	{
		std::unordered_map< std::string, std::pair<std::string, std::string>> map;
		std::vector<std::string> hiddenNodes;
		bool dummy;
		repo::lib::PropertyTree tree, settingsTree;
		tree.mergeSubTree("nodes", generatePTree(root, map, "", dummy, hiddenNodes));
		for (const auto pair : map)
		{
			//if there's an entry in maps it must have an entry in paths
			tree.addToTree("idToName." + pair.first, pair.second.first);
			tree.addToTree("idToPath." + pair.first, pair.second.second);
		}

		trees["fulltree.json"] = tree;

		if (hiddenNodes.size())
		{
			settingsTree.addToTree("hiddenNodes", hiddenNodes);
			trees["modelProperties.json"] = settingsTree;
		}
	}
	else
	{
		repoError << "Failed to generate selection tree: scene is empty or default scene is not loaded";
	}

	return trees;
}

SelectionTreeMaker::~SelectionTreeMaker()
{
}<commit_msg>restore changes that were loss due to merge<commit_after>/**
*  Copyright (C) 2016 3D Repo Ltd
*
*  This program is free software: you can redistribute it and/or modify
*  it under the terms of the GNU Affero General Public License as
*  published by the Free Software Foundation, either version 3 of the
*  License, or (at your option) any later version.
*
*  This program is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*  GNU Affero General Public License for more details.
*
*  You should have received a copy of the GNU Affero General Public License
*  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "repo_maker_selection_tree.h"
#include "../../core/model/bson/repo_node_reference.h"
#include "../modeloptimizer/repo_optimizer_ifc.h"

using namespace repo::manipulator::modelutility;

const static std::string REPO_LABEL_VISIBILITY_STATE = "toggleState";
const static std::string REPO_VISIBILITY_STATE_SHOW = "visible";
const static std::string REPO_VISIBILITY_STATE_HIDDEN = "invisible";
const static std::string REPO_VISIBILITY_STATE_HALF_HIDDEN = "parentOfInvisible";

SelectionTreeMaker::SelectionTreeMaker(
	const repo::core::model::RepoScene *scene)
	: scene(scene)
{
}

repo::lib::PropertyTree SelectionTreeMaker::generatePTree(
	const repo::core::model::RepoNode            *currentNode,
	std::unordered_map < std::string,
	std::pair < std::string, std::string >> &idMaps,
	const std::string                            &currentPath,
	bool                                         &hiddenOnDefault,
	std::vector<std::string>                     &hiddenNode) const
{
	repo::lib::PropertyTree tree;
	if (currentNode)
	{
		std::string idString = currentNode->getUniqueID().toString();
		repo::lib::RepoUUID sharedID = currentNode->getSharedID();
		std::string childPath = currentPath.empty() ? idString : currentPath + "__" + idString;

		auto children = scene->getChildrenAsNodes(repo::core::model::RepoScene::GraphType::DEFAULT, sharedID);
		std::vector<repo::lib::PropertyTree> childrenTrees;

		std::vector<repo::core::model::RepoNode*> childrenTypes[2];
		std::vector<repo::lib::RepoUUID> metaIDs;
		for (const auto &child : children)
		{
			//Ensure IFC Space (if any) are put into the tree first.
			if (child->getName().find(IFC_TYPE_SPACE_LABEL) != std::string::npos)
				childrenTypes[0].push_back(child);
			else if (child->getTypeAsEnum() == repo::core::model::NodeType::METADATA)
			{
				metaIDs.push_back(child->getUniqueID());
			}
			else
				childrenTypes[1].push_back(child);
		}

		bool hasHiddenChildren = false;
		for (const auto childrenSet : childrenTypes)
		{
			for (const auto &child : childrenSet)
			{
				if (child)
				{
					switch (child->getTypeAsEnum())
					{
					case repo::core::model::NodeType::MESH:
					case repo::core::model::NodeType::TRANSFORMATION:
					case repo::core::model::NodeType::CAMERA:
					case repo::core::model::NodeType::REFERENCE:
					{
						bool hiddenChild = false;
						childrenTrees.push_back(generatePTree(child, idMaps, childPath, hiddenChild, hiddenNode));
						hasHiddenChildren = hasHiddenChildren || hiddenChild;
					}
					}
				}
				else
				{
					repoDebug << "Null pointer for child node at generatePTree, current path : " << currentPath;
					repoError << "Unexpected error at selection tree generation, the tree may not be complete.";
				}
			}
		}
		std::string name = currentNode->getName();
		if (repo::core::model::NodeType::REFERENCE == currentNode->getTypeAsEnum())
		{
			if (auto refNode = dynamic_cast<const repo::core::model::ReferenceNode*>(currentNode))
			{
				auto refDb = refNode->getDatabaseName();
				name = (scene->getDatabaseName() == refDb ? "" : (refDb + "/")) + refNode->getProjectName();
			}
		}

		tree.addToTree("account", scene->getDatabaseName());
		tree.addToTree("project", scene->getProjectName());
		if (!name.empty())
			tree.addToTree("name", name);
		tree.addToTree("path", childPath);
		tree.addToTree("_id", idString);
		tree.addToTree("shared_id", sharedID.toString());
		tree.addToTree("children", childrenTrees);
		tree.addToTree("meta", metaIDs);

		if (name.find(IFC_TYPE_SPACE_LABEL) != std::string::npos
			&& currentNode->getTypeAsEnum() == repo::core::model::NodeType::MESH)
		{
			tree.addToTree(REPO_LABEL_VISIBILITY_STATE, REPO_VISIBILITY_STATE_HIDDEN);
			hiddenOnDefault = true;
			hiddenNode.push_back(idString);
		}
		else if (hiddenOnDefault = hiddenOnDefault || hasHiddenChildren)
		{
			tree.addToTree(REPO_LABEL_VISIBILITY_STATE, REPO_VISIBILITY_STATE_HALF_HIDDEN);
		}
		else
		{
			tree.addToTree(REPO_LABEL_VISIBILITY_STATE, REPO_VISIBILITY_STATE_SHOW);
		}

		idMaps[idString] = { name, childPath };
	}
	else
	{
		repoDebug << "Null pointer at generatePTree, current path : " << currentPath;
		repoError << "Unexpected error at selection tree generation, the tree may not be complete.";
	}

	return tree;
}

std::map<std::string, std::vector<uint8_t>> SelectionTreeMaker::getSelectionTreeAsBuffer() const
{
	auto trees = getSelectionTreeAsPropertyTree();
	std::map<std::string, std::vector<uint8_t>> buffer;
	for (const auto &tree : trees)
	{
		std::stringstream ss;
		tree.second.write_json(ss);
		std::string jsonString = ss.str();
		if (!jsonString.empty())
		{
			size_t byteLength = jsonString.size() * sizeof(*jsonString.data());
			buffer[tree.first] = std::vector<uint8_t>();
			buffer[tree.first].resize(byteLength);
			memcpy(buffer[tree.first].data(), jsonString.data(), byteLength);
		}
		else
		{
			repoError << "Failed to write selection tree into the buffer: JSON string is empty.";
		}
	}

	return buffer;
}

std::map<std::string, repo::lib::PropertyTree>  SelectionTreeMaker::getSelectionTreeAsPropertyTree() const
{
	std::map<std::string, repo::lib::PropertyTree> trees;

	repo::core::model::RepoNode *root;
	if (scene && (root = scene->getRoot(repo::core::model::RepoScene::GraphType::DEFAULT)))
	{
		std::unordered_map< std::string, std::pair<std::string, std::string>> map;
		std::vector<std::string> hiddenNodes;
		bool dummy;
		repo::lib::PropertyTree tree, settingsTree;
		tree.mergeSubTree("nodes", generatePTree(root, map, "", dummy, hiddenNodes));
		for (const auto pair : map)
		{
			//if there's an entry in maps it must have an entry in paths
			tree.addToTree("idToName." + pair.first, pair.second.first);
			tree.addToTree("idToPath." + pair.first, pair.second.second);
		}

		trees["fulltree.json"] = tree;

		if (hiddenNodes.size())
		{
			settingsTree.addToTree("hiddenNodes", hiddenNodes);
			trees["modelProperties.json"] = settingsTree;
		}
	}
	else
	{
		repoError << "Failed to generate selection tree: scene is empty or default scene is not loaded";
	}

	return trees;
}

SelectionTreeMaker::~SelectionTreeMaker()
{
}<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_volt.C
/// @brief Calculate and save off rail voltages
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre A. Marin  <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <p9_mss_volt.H>

// std lib
#include <vector>

// fapi2
#include <fapi2.H>

// mss lib
#include <generic/memory/lib/spd/spd_facade.H>
#include <lib/eff_config/attr_setters.H>
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/pos.H>
#include <generic/memory/lib/utils/find.H>
#include <lib/utils/checker.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_MCS;
using fapi2::TARGET_TYPE_MCA;
using fapi2::TARGET_TYPE_DIMM;
using fapi2::FAPI2_RC_SUCCESS;

extern "C"
{

    ///
    /// @brief Calculate and save off rail voltages
    /// @param[in] i_targets vector of controllers (e.g., MCS)
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode p9_mss_volt( const std::vector< fapi2::Target<TARGET_TYPE_MCS> >& i_targets )
    {
        // Loop through MCS
        for (const auto& l_mcs : i_targets)
        {
            FAPI_INF("Populating decoder cache for %s", mss::c_str(l_mcs));

            //Factory cache is per MCS
            std::vector< mss::spd::facade > l_spd_facades;
            FAPI_TRY( get_spd_decoder_list(l_mcs, l_spd_facades) );

            // Get dimms for each MCS
            for ( const auto& l_cache : l_spd_facades )
            {
                const auto l_dimm = l_cache.get_dimm_target();
                uint8_t l_dimm_nominal = 0;
                uint8_t l_dimm_endurant = 0;

                // Read nominal and endurant bits from SPD, 0 = 1.2V is not operable and endurant, 1 = 1.2 is valid
                FAPI_TRY( l_cache.operable_nominal_voltage(l_dimm_nominal) );
                FAPI_TRY( l_cache.endurant_nominal_voltage(l_dimm_endurant) );

                //Check to make sure 1.2 V is both operable and endurant, fail if it is not
                FAPI_ASSERT ( (l_dimm_nominal == mss::spd::OPERABLE) && (l_dimm_endurant == mss::spd::ENDURANT),
                              fapi2::MSS_VOLT_DDR_TYPE_REQUIRED_VOLTAGE().
                              set_ACTUAL_OPERABLE(l_dimm_nominal).
                              set_ACTUAL_ENDURANT(l_dimm_endurant).
                              set_EXPECTED_OPERABLE(mss::spd::OPERABLE).
                              set_EXPECTED_ENDURANT(mss::spd::ENDURANT).
                              set_DIMM_TARGET(l_dimm),
                              "%s: DIMM is not operable (%d) expected (%d)"
                              " and/or endurant (%d) expected (%d) at 1.2V",
                              mss::c_str(l_dimm),
                              l_dimm_nominal,
                              mss::spd::OPERABLE,
                              l_dimm_endurant,
                              mss::spd::ENDURANT);
            } // l_dimm

            // Set the attributes for this MCS, values are in mss_const.H
            FAPI_TRY (mss::set_voltage_attributes (l_mcs,
                                                   mss::DDR4_NOMINAL_VOLTAGE,
                                                   mss::DDR4_VPP_VOLTAGE),
                      "Failed to set volt attributes");
        } // mcs

        FAPI_INF("End mss volt");
        return FAPI2_RC_SUCCESS;

    fapi_try_exit:
        return fapi2::current_err;
    } // p9_mss_volt
} //extern "C"
<commit_msg>Move MSS volt attr setters to generic folder<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_volt.C $     */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

///
/// @file p9_mss_volt.C
/// @brief Calculate and save off rail voltages
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre A. Marin  <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <p9_mss_volt.H>

// std lib
#include <vector>

// fapi2
#include <fapi2.H>

// mss lib
#include <generic/memory/lib/utils/c_str.H>
#include <generic/memory/lib/utils/voltage/gen_mss_volt.H>

using fapi2::TARGET_TYPE_MCS;

extern "C"
{

    ///
    /// @brief Calculate and save off rail voltages
    /// @param[in] i_targets vector of controllers (e.g., MCS)
    /// @return FAPI2_RC_SUCCESS iff ok
    ///
    fapi2::ReturnCode p9_mss_volt( const std::vector< fapi2::Target<TARGET_TYPE_MCS> >& i_targets )
    {
        for (const auto& l_mcs : i_targets)
        {
            FAPI_TRY( (mss::setup_voltage_rail_values<mss::mc_type::NIMBUS, mss::spd::device_type::DDR4>(l_mcs)),
                      "Failed setup_voltage_rail_values for %s", mss::c_str(l_mcs) );
        } // mcs

        FAPI_INF("End mss volt");

    fapi_try_exit:
        return fapi2::current_err;
    } // p9_mss_volt
} //extern "C"
<|endoftext|>


<commit_before>// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#define CAF_SUITE sum_type

#include "caf/sum_type.hpp"

#include "core-test.hpp"

#include <map>
#include <new>
#include <string>

#include "caf/default_sum_type_access.hpp"
#include "caf/detail/overload.hpp"
#include "caf/raise_error.hpp"
#include "caf/sum_type_access.hpp"

namespace {

class union_type {
public:
  friend struct caf::default_sum_type_access<union_type>;

  using T0 = int;
  using T1 = std::string;
  using T2 = std::map<int, int>;

  using types = caf::detail::type_list<T0, T1, T2>;

  union_type() : index_(0), v0(0) {
    // nop
  }

  ~union_type() {
    destroy();
  }

  union_type& operator=(T0 value) {
    destroy();
    index_ = 0;
    v0 = value;
    return *this;
  }

  union_type& operator=(T1 value) {
    destroy();
    index_ = 1;
    new (&v1) T1(std::move(value));
    return *this;
  }

  union_type& operator=(T2 value) {
    destroy();
    index_ = 2;
    new (&v2) T2(std::move(value));
    return *this;
  }

private:
  inline union_type& get_data() {
    return *this;
  }

  inline const union_type& get_data() const {
    return *this;
  }

  inline T0& get(std::integral_constant<int, 0>) {
    CAF_REQUIRE_EQUAL(index_, 0);
    return v0;
  }

  inline const T0& get(std::integral_constant<int, 0>) const {
    CAF_REQUIRE_EQUAL(index_, 0);
    return v0;
  }

  inline T1& get(std::integral_constant<int, 1>) {
    CAF_REQUIRE_EQUAL(index_, 1);
    return v1;
  }

  inline const T1& get(std::integral_constant<int, 1>) const {
    CAF_REQUIRE_EQUAL(index_, 1);
    return v1;
  }

  inline T2& get(std::integral_constant<int, 2>) {
    CAF_REQUIRE_EQUAL(index_, 2);
    return v2;
  }

  inline const T2& get(std::integral_constant<int, 2>) const {
    CAF_REQUIRE_EQUAL(index_, 2);
    return v2;
  }

  template <int Index>
  inline bool is(std::integral_constant<int, Index>) const {
    return index_ == Index;
  }

  template <class Result, class Visitor, class... Ts>
  inline Result apply(Visitor&& f, Ts&&... xs) const {
    switch (index_) {
      case 0:
        return f(std::forward<Ts>(xs)..., v0);
      case 1:
        return f(std::forward<Ts>(xs)..., v1);
      case 2:
        return f(std::forward<Ts>(xs)..., v2);
    }
    CAF_RAISE_ERROR("invalid index in union_type");
  }

  void destroy() {
    if (index_ == 1)
      v1.~T1();
    else if (index_ == 2)
      v2.~T2();
  }

  int index_;
  union {
    T0 v0;
    T1 v1;
    T2 v2;
  };
};

} // namespace

namespace caf {

template <>
struct sum_type_access<union_type> : default_sum_type_access<union_type> {};

} // namespace caf

using namespace caf;

using std::string;
using map_type = std::map<int, int>;

namespace {

struct stringify_t {
  string operator()(int x) const {
    return std::to_string(x);
  }

  string operator()(std::string x) const {
    return x;
  }

  string operator()(const map_type& x) const {
    return deep_to_string(x);
  }

  template <class T0, class T1>
  string operator()(const T0& x0, const T1& x1) const {
    return (*this) (x0) + ", " + (*this) (x1);
  }

  template <class T0, class T1, class T2>
  string operator()(const T0& x0, const T1& x1, const T2& x2) const {
    return (*this) (x0, x1) + ", " + (*this) (x2);
  }
};

constexpr stringify_t stringify = stringify_t{};

} // namespace

CAF_TEST(holds_alternative) {
  union_type x;
  CAF_CHECK_EQUAL(holds_alternative<int>(x), true);
  CAF_CHECK_EQUAL(holds_alternative<string>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<map_type>(x), false);
  x = string{"hello world"};
  CAF_CHECK_EQUAL(holds_alternative<int>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<string>(x), true);
  CAF_CHECK_EQUAL(holds_alternative<map_type>(x), false);
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(holds_alternative<int>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<string>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<map_type>(x), true);
}

CAF_TEST(get) {
  union_type x;
  CAF_CHECK_EQUAL(get<int>(x), 0);
  x = 42;
  CAF_CHECK_EQUAL(get<int>(x), 42);
  x = string{"hello world"};
  CAF_CHECK_EQUAL(get<string>(x), "hello world");
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(get<map_type>(x), map_type({{1, 1}, {2, 2}}));
}

CAF_TEST(get_if) {
  union_type x;
  CAF_CHECK_EQUAL(get_if<int>(&x), &get<int>(x));
  CAF_CHECK_EQUAL(get_if<string>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<map_type>(&x), nullptr);
  x = string{"hello world"};
  CAF_CHECK_EQUAL(get_if<int>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<string>(&x), &get<string>(x));
  CAF_CHECK_EQUAL(get_if<map_type>(&x), nullptr);
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(get_if<int>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<string>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<map_type>(&x), &get<map_type>(x));
}

CAF_TEST(unary visit) {
  union_type x;
  CAF_CHECK_EQUAL(visit(stringify, x), "0");
  x = string{"hello world"};
  CAF_CHECK_EQUAL(visit(stringify, x), "hello world");
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(visit(stringify, x), "{1 = 1, 2 = 2}");
}

CAF_TEST(binary visit) {
  union_type x;
  union_type y;
  CAF_CHECK_EQUAL(visit(stringify, x, y), "0, 0");
  x = 42;
  y = string{"hello world"};
  CAF_CHECK_EQUAL(visit(stringify, x, y), "42, hello world");
}

CAF_TEST(ternary visit) {
  union_type x;
  union_type y;
  union_type z;
  // CAF_CHECK_EQUAL(visit(stringify, x, y, z), "0, 0, 0");
  x = 42;
  y = string{"foo"};
  z = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(visit(stringify, x, y, z), "42, foo, {1 = 1, 2 = 2}");
}
<commit_msg>Fix formatting<commit_after>// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#define CAF_SUITE sum_type

#include "caf/sum_type.hpp"

#include "core-test.hpp"

#include <map>
#include <new>
#include <string>

#include "caf/default_sum_type_access.hpp"
#include "caf/detail/overload.hpp"
#include "caf/raise_error.hpp"
#include "caf/sum_type_access.hpp"

namespace {

class union_type {
public:
  friend struct caf::default_sum_type_access<union_type>;

  using T0 = int;
  using T1 = std::string;
  using T2 = std::map<int, int>;

  using types = caf::detail::type_list<T0, T1, T2>;

  union_type() : index_(0), v0(0) {
    // nop
  }

  ~union_type() {
    destroy();
  }

  union_type& operator=(T0 value) {
    destroy();
    index_ = 0;
    v0 = value;
    return *this;
  }

  union_type& operator=(T1 value) {
    destroy();
    index_ = 1;
    new (&v1) T1(std::move(value));
    return *this;
  }

  union_type& operator=(T2 value) {
    destroy();
    index_ = 2;
    new (&v2) T2(std::move(value));
    return *this;
  }

private:
  inline union_type& get_data() {
    return *this;
  }

  inline const union_type& get_data() const {
    return *this;
  }

  inline T0& get(std::integral_constant<int, 0>) {
    CAF_REQUIRE_EQUAL(index_, 0);
    return v0;
  }

  inline const T0& get(std::integral_constant<int, 0>) const {
    CAF_REQUIRE_EQUAL(index_, 0);
    return v0;
  }

  inline T1& get(std::integral_constant<int, 1>) {
    CAF_REQUIRE_EQUAL(index_, 1);
    return v1;
  }

  inline const T1& get(std::integral_constant<int, 1>) const {
    CAF_REQUIRE_EQUAL(index_, 1);
    return v1;
  }

  inline T2& get(std::integral_constant<int, 2>) {
    CAF_REQUIRE_EQUAL(index_, 2);
    return v2;
  }

  inline const T2& get(std::integral_constant<int, 2>) const {
    CAF_REQUIRE_EQUAL(index_, 2);
    return v2;
  }

  template <int Index>
  inline bool is(std::integral_constant<int, Index>) const {
    return index_ == Index;
  }

  template <class Result, class Visitor, class... Ts>
  inline Result apply(Visitor&& f, Ts&&... xs) const {
    switch (index_) {
      case 0:
        return f(std::forward<Ts>(xs)..., v0);
      case 1:
        return f(std::forward<Ts>(xs)..., v1);
      case 2:
        return f(std::forward<Ts>(xs)..., v2);
    }
    CAF_RAISE_ERROR("invalid index in union_type");
  }

  void destroy() {
    if (index_ == 1)
      v1.~T1();
    else if (index_ == 2)
      v2.~T2();
  }

  int index_;
  union {
    T0 v0;
    T1 v1;
    T2 v2;
  };
};

} // namespace

namespace caf {

template <>
struct sum_type_access<union_type> : default_sum_type_access<union_type> {};

} // namespace caf

using namespace caf;

using std::string;
using map_type = std::map<int, int>;

namespace {

struct stringify_t {
  string operator()(int x) const {
    return std::to_string(x);
  }

  string operator()(std::string x) const {
    return x;
  }

  string operator()(const map_type& x) const {
    return deep_to_string(x);
  }

  template <class T0, class T1>
  string operator()(const T0& x0, const T1& x1) const {
    return (*this)(x0) + ", " + (*this)(x1);
  }

  template <class T0, class T1, class T2>
  string operator()(const T0& x0, const T1& x1, const T2& x2) const {
    return (*this)(x0, x1) + ", " + (*this)(x2);
  }
};

constexpr stringify_t stringify = stringify_t{};

} // namespace

CAF_TEST(holds_alternative) {
  union_type x;
  CAF_CHECK_EQUAL(holds_alternative<int>(x), true);
  CAF_CHECK_EQUAL(holds_alternative<string>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<map_type>(x), false);
  x = string{"hello world"};
  CAF_CHECK_EQUAL(holds_alternative<int>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<string>(x), true);
  CAF_CHECK_EQUAL(holds_alternative<map_type>(x), false);
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(holds_alternative<int>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<string>(x), false);
  CAF_CHECK_EQUAL(holds_alternative<map_type>(x), true);
}

CAF_TEST(get) {
  union_type x;
  CAF_CHECK_EQUAL(get<int>(x), 0);
  x = 42;
  CAF_CHECK_EQUAL(get<int>(x), 42);
  x = string{"hello world"};
  CAF_CHECK_EQUAL(get<string>(x), "hello world");
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(get<map_type>(x), map_type({{1, 1}, {2, 2}}));
}

CAF_TEST(get_if) {
  union_type x;
  CAF_CHECK_EQUAL(get_if<int>(&x), &get<int>(x));
  CAF_CHECK_EQUAL(get_if<string>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<map_type>(&x), nullptr);
  x = string{"hello world"};
  CAF_CHECK_EQUAL(get_if<int>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<string>(&x), &get<string>(x));
  CAF_CHECK_EQUAL(get_if<map_type>(&x), nullptr);
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(get_if<int>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<string>(&x), nullptr);
  CAF_CHECK_EQUAL(get_if<map_type>(&x), &get<map_type>(x));
}

CAF_TEST(unary visit) {
  union_type x;
  CAF_CHECK_EQUAL(visit(stringify, x), "0");
  x = string{"hello world"};
  CAF_CHECK_EQUAL(visit(stringify, x), "hello world");
  x = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(visit(stringify, x), "{1 = 1, 2 = 2}");
}

CAF_TEST(binary visit) {
  union_type x;
  union_type y;
  CAF_CHECK_EQUAL(visit(stringify, x, y), "0, 0");
  x = 42;
  y = string{"hello world"};
  CAF_CHECK_EQUAL(visit(stringify, x, y), "42, hello world");
}

CAF_TEST(ternary visit) {
  union_type x;
  union_type y;
  union_type z;
  // CAF_CHECK_EQUAL(visit(stringify, x, y, z), "0, 0, 0");
  x = 42;
  y = string{"foo"};
  z = map_type{{1, 1}, {2, 2}};
  CAF_CHECK_EQUAL(visit(stringify, x, y, z), "42, foo, {1 = 1, 2 = 2}");
}
<|endoftext|>