Ejemplo n.º 1
0
void ARController::Draw(Mat * rgbaImage)
{
    if (drawingLevel == 2 || drawingLevel == 3)
    {
        struct timespec start,end;
        SET_TIME(&start);
        //Draw objects onto camera texture
        for (int i=0; i<drawObjects.size(); i++)
        {
            if (drawObjects.at(i)->IsVisible())
            {
                LOGV(LOGTAG_ARCONTROLLER,"Drawing object %d",i);
                drawObjects.at(i)->Draw(rgbaImage);
            }
        }
        SET_TIME(&end);
        LOG_TIME_PRECISE("ARController Drawing",start,end);
    }

    //resetButton->Draw(rgbaImage);
    certaintyIndicator->Draw(rgbaImage);
    //Draw FPS label on top of everything else
    fpsLabel->Draw(rgbaImage);
    //Update textured quad
    quadBackground->SetImage(rgbaImage);
}
Ejemplo n.º 2
0
static void event_init(ACL_EVENT *eventp, int fdsize,
	int delay_sec, int delay_usec)
{
	eventp->fdsize = fdsize;
	/* eventp->fdtab_free_cnt = 0; */
	eventp->fdcnt  = 0;
	eventp->fdcnt_ready  = 0;
	eventp->fdtabs = (ACL_EVENT_FDTABLE **)
		acl_mycalloc(fdsize,sizeof(ACL_EVENT_FDTABLE *));
	eventp->fdtabs_ready = (ACL_EVENT_FDTABLE **)
		acl_mycalloc(fdsize, sizeof(ACL_EVENT_FDTABLE *));

	eventp->maxfd  = 0;
	eventp->nested = 0;

	eventp->delay_sec  = delay_sec + delay_usec / 1000000;
	eventp->delay_usec = delay_usec % 1000000;

	acl_ring_init(&eventp->timer_head);
	eventp->timer_keep = 0;
	SET_TIME(eventp->present);
	SET_TIME(eventp->last_debug);

	eventp->check_inter = 100000;  /* default: 100 ms */

	if (eventp->init_fn)
		eventp->init_fn(eventp);
}
Ejemplo n.º 3
0
void ARController::getImages(Engine * engine)
{
    struct timespec start, end;

    //Retrieve image from the camera
    if (debugUI->currentDrawMode == DrawModes::ColorImage)
    {
        SET_TIME(&start);
        engine->imageCollector->newFrame();
        engine->imageCollector->getColorCameraImage(*rgbImage);
        SET_TIME(&end);
        LOG_TIME_PRECISE("Color Image Capture", start, end);

        cvtColor(*rgbImage, *grayImage, CV_RGBA2GRAY, 1);
    }
    else
    {
        SET_TIME(&start);
        engine->imageCollector->newFrame();
        engine->imageCollector->getGrayCameraImage(*grayImage);
        SET_TIME(&end);
        LOG_TIME_PRECISE("Gray Image Capture", start, end);

        cvtColor(*grayImage, *rgbImage, CV_GRAY2RGBA, 4);
    }


}
Ejemplo n.º 4
0
void   get_cpu_time   (Time* usrT,  Time* sysT)   {
    //
    // Get the user and/or system cpu times in a system independent way.

    time_struct_t   ts;

    GET_TIME(ts);

    if (usrT != NULL) {
	SET_TIME(usrT, USR_TIME(ts));
	if (usrT->seconds < lastU.seconds)
	    usrT->seconds = lastU.seconds;
	if ((usrT->seconds == lastU.seconds) && (usrT->uSeconds < lastU.uSeconds))
	    usrT->uSeconds = lastU.uSeconds;
	lastU = *usrT;
    }

    if (sysT != NULL) {
	SET_TIME(sysT, SYS_TIME(ts));
	if (sysT->seconds < lastS.seconds)
	    sysT->seconds = lastS.seconds;
	if ((sysT->seconds == lastS.seconds) && (sysT->uSeconds < lastS.uSeconds))
	    sysT->uSeconds = lastS.uSeconds;
	lastS = *sysT;
    }
}
//Finds vertical edges and stores in edgeArray
static void FindEdgesVertical(const Mat & inputImg, Mat & edgeArray, int xPosition, short threshold, bool nonMaxSuppress, int detectorSize)
{
	//const short detectorSize = 3;
	const short maxColumn = inputImg.rows - detectorSize;
	
	struct timespec start,end;
	SET_TIME(&start);

	//Copy the column into a row for faster access
	Mat rowBasedImg(1,inputImg.rows,CV_8U);
	for (int i=0;i<inputImg.rows;i++)
	{
		rowBasedImg.at<unsigned char>(0,i) = inputImg.at<unsigned char>(i,xPosition);
	}
	const unsigned char * imgRowPtr = rowBasedImg.ptr<unsigned char>(0);
	
	Mat tmpEdgeArray = Mat::zeros(1,inputImg.rows,CV_16S); //Located and scored edges
	short * edgeRowPtr = tmpEdgeArray.ptr<short>(0);
	edgeArray = Mat::zeros(1,inputImg.rows,CV_16S);
	short * outputEdgeRowPtr = edgeArray.ptr<short>(0);	
		
	for (int j=detectorSize;j < maxColumn;j++)
	{
		if (detectorSize == 3)
			edgeRowPtr[j] = -((short)(imgRowPtr[j+1] + (short)imgRowPtr[j+2] + (short)imgRowPtr[j+3])) + (short)imgRowPtr[j-1] + (short)imgRowPtr[j-2] + (short)imgRowPtr[j-3];
		else if (detectorSize == 4)
			edgeRowPtr[j] = -((short)imgRowPtr[j+1] + (short)imgRowPtr[j+2] + (short)imgRowPtr[j+3] + (short)imgRowPtr[j+4]) + (short)imgRowPtr[j-1] + (short)imgRowPtr[j-2] + (short)imgRowPtr[j-3] + (short)imgRowPtr[j-4];
		else			
			edgeRowPtr[j] = -((short)imgRowPtr[j+1] + (short)imgRowPtr[j+2]) + (short)imgRowPtr[j-1] + (short)imgRowPtr[j-2];

		if (j > (detectorSize + 1) && edgeRowPtr[j-1] != 0 && abs(edgeRowPtr[j-1]) > threshold && 
				(	
					!nonMaxSuppress || 
					(
						abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j-2]) && // || (abs(edgeRowPtr[j-1]) == abs(edgeRowPtr[j-2])  && abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j-3]))) &&
						abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j])
					)
				)
			)
		{
			outputEdgeRowPtr[j-1] = (edgeRowPtr[j-1] < 0) ? 1 : -1; 
		}
		/*else
		{
			outputEdgeRowPtr[j-1] = 0;
		}*/
	}

	SET_TIME(&end);
	LOG_TIME_PRECISE("VerticalEdgeTest",start,end);	
}
Ejemplo n.º 6
0
AugmentedView::AugmentedView(UIElementCollection * window, Engine * engine, cv::Mat _cameraMatrix)
{
	cameraMatrix = new Mat();
	_cameraMatrix.copyTo(*cameraMatrix);
	rotation = new Mat();
	position = new Mat();
	objectVector = std::vector<ARObject*>();
	LOGI(LOGTAG_POSITION, "Created AugmentedView");
	canDraw = false;

	Scalar selectColor = Colors::DodgerBlue;
	selectColor[3] = 80;
	selectionIndicator = new ARObject(OpenGLHelper::CreateSolidColorCube(1,selectColor));
	selectedObject = NULL;
	SET_TIME(&lastSelectionTime);
	testObject = new ARObject(OpenGLHelper::CreateSolidColorCube(10,Colors::OrangeRed));

	tabs = new TabDisplay(true);
	window->AddChild(tabs);

	createNext =false;

	GridLayout * myGrid = new GridLayout(cv::Size2i(5,4));

	cancelSelection = new Button("Cancel");
	cancelSelection->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this));
	myGrid->AddChild(cancelSelection,Point2i(4,3));		
	cancelSelection->SetVisible(false);
	cancelSelection->Name = "Cancel";
	
	releaseSelection = new Button("Release");
	releaseSelection->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this));
	myGrid->AddChild(releaseSelection,Point2i(4,2));	
	releaseSelection->SetVisible(false);
	releaseSelection->Name = "Release";

	Button * createCube = new Button("Create");
	createCube->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this));
	myGrid->AddChild(createCube,Point2i(4,1));	
	createCube->Name = "Create";
	createCube->FillColor = Colors::LightGreen;

	Button * deleteObject = new Button("Delete");
	deleteObject->AddClickDelegate(ClickEventDelegate::from_method<AugmentedView,&AugmentedView::ButtonPressed>(this));
	myGrid->AddChild(deleteObject,Point2i(4,0));	
	deleteObject->Name = "Delete";
	deleteObject->FillColor = Colors::Orange;

	tabs->AddTab("AR",myGrid);
	LOGD(LOGTAG_ARINPUT,"Laying out tabs %d,%d",engine->imageWidth,engine->imageHeight);
	tabs->DoLayout(Rect(0,0,engine->imageWidth,engine->imageHeight));
	
	tabs->SetTab(0);
}
Ejemplo n.º 7
0
void QuadBackground::Render(OpenGL * openGL)
{
	struct timespec start,end;
	SET_TIME(&start);
	OpenGLSettings();
	
	//Draw object
	SetMatrices(openGL);

	//glEnable(GL_TEXTURE_2D);	
	glActiveTexture(GL_TEXTURE0);	
	glBindTexture(GL_TEXTURE_2D, textureID);
	glUniform1i(openGL->renderData.textureLocation,0);
	
	
	//Debugging - Draw a solid color to texture
	if (ENABLE_TEXTURE_COLOR)
	{
		u_int32_t * pxData = new u_int32_t[textureWidth*textureHeight];
		for (int i=0;i<(textureWidth*textureHeight);i++)
		{
			pxData[i] = 123912048;
		}
		glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, textureWidth, textureHeight, GL_RGBA, GL_UNSIGNED_BYTE, pxData);
		delete[] pxData;
	}
	
	//Update the texture 
	glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,imageWidth,imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, imagePixels);
		
	openGL->DrawGLObject(testCube);
	openGL->DrawGLObject(texturedQuad);
	
	ResetGLSettings();
	SET_TIME(&end);
	LOG_TIME("QuadBG Render", start, end);	
}
Ejemplo n.º 8
0
/******************************************************************************
* The interrupt service routine
*/
__irq void EXTI15_10_IRQHandler(void){
    uint8_t lwmode = wmode;                                             //let this variables in registers
    uint8_t lmode = mode;

    if((lwmode == OWW_WRITE_0)) {SET_LOW;lwmode = OWW_NO_WRITE;}        //if necessary set 0-Bit
    DIS_OWINT;                                                          //disable interrupt, only in OWM_SLEEP mode it is active
    switch(lmode){
        case OWM_SLEEP:
            SET_TIME(OWT_MIN_RESET);
            EN_OWINT;                                                   //other edges ?
        break;

        //Start of reading with falling edge from master, reading closed in timer isr
        case OWM_MATCH_ROM:                                             //falling edge wait for receive
        case OWM_WRITE_SCRATCHPAD:
        case OWM_READ_COMMAND:
            SET_TIME(OWT_READLINE);                                     //wait a time for reading
            break;

        case OWM_SEARCH_ROM:                                            //Search algorithm waiting for receive or send
            if (srcount<2) {                                            //this means bit or complement is writing,
                SET_TIME(OWT_LOWTIME);
            } else
                SET_TIME(OWT_READLINE);                                 //init for read answer of master
            break;

        case OWM_READ_SCRATCHPAD:                                       //a bit is sending
        case OWM_READ_ROM:                                              //a bit is sending
            SET_TIME(OWT_LOWTIME);
            break;

        case OWM_CHK_RESET:                                             //rising edge of reset pulse
            SET_FALLING;
            SET_TIME(OWT_RESET_PRESENCE);                               //waiting for sending presence pulse
            lmode = OWM_RESET;
            break;
    }
    EN_TIMER;
    mode        =  lmode;
    wmode       =  lwmode;
    EXTI->PR    |= EXTI_PR_PR12;
}
Ejemplo n.º 9
0
/******************************************************************************
* The timer interrupt service routine
*/
__irq void TIM1_BRK_TIM15_IRQHandler(void)
{
    uint8_t lwmode  =  wmode;                                           //let this variables in registers
    uint8_t lmode = mode;
    uint8_t lbytep = bytep;
    uint8_t lbitp = bitp;
    uint8_t lsrcount = srcount;
    uint8_t lactbit = actbit;
    uint8_t lscrc = scrc;
    //Ask input line sate
    uint8_t p;
    
    p = OW_PIN;
    //Interrupt still active ?
    if(CHK_INT_EN){
        //maybe reset pulse
        if(p == 0){
            lmode = OWM_CHK_RESET;                                      //wait for rising edge
            SET_RISING;
        }
        DIS_TIMER;
    }else
    switch(lmode){
        case OWM_RESET:                                                 //Reset pulse and time after is finished, now go in presence state
            lmode = OWM_PRESENCE;
            SET_LOW;
            SET_TIME(OWT_PRESENCE);
            DIS_OWINT;                                                  //No Pin interrupt necessary only wait for presence is done
        break;
        
        case OWM_PRESENCE:
            RESET_LOW;                                                  //Presence is done now wait for a command
            lmode = OWM_READ_COMMAND;
            cbuf = 0;lbitp = 1;                                         //Command buffer have to set zero, only set bits will write in
        break;
        
        case OWM_READ_COMMAND:
            if(p){                                                      //Set bit if line high
                cbuf|= lbitp;
            }
            lbitp = (lbitp<<1);
            if(!lbitp){                                                 //8-Bits read
                lbitp = 1;
                switch(cbuf){
                    //case OWCOM_SKIP_ROM:
                    case OWCOM_READ_ROM:                                //READ_ROM
                        lmode = OWM_READ_ROM;
                        lbytep = 0;                                     //From first position
                        lactbit = (lbitp & sps_owid[0]) == lbitp;
                        lwmode = lactbit;                               //Prepare for send firs bit
                    break;

                    case OWCOM_MATCH_ROM:
                        lbytep = 0;
                        lmode = OWM_MATCH_ROM;
                    break;

                    case OWCOM_SEARCH_ROM:                              //Initialize search rom
                        lmode = OWM_SEARCH_ROM;
                        lsrcount = 0;
                        lbytep = 0;
                        lactbit = (sps_owid[lbytep] & lbitp) == lbitp;  //Sset actual bit
                        lwmode = lactbit;                               //Prepare for writing when next falling edge
                    break;

                    case OWCOM_WRITE_SCRATCHPAD:
                        lmode = OWM_WRITE_SCRATCHPAD;
                        lbytep  = 0;
                        lscrc   = 0;
                        bffForWriteScr[0] = 0;
                    break;

                    case OWCOM_READ_SCRATCHPAD:                             //READ_SCRATCHPAD
                        lmode   = OWM_READ_SCRATCHPAD;
                        lbytep  = 0;
                        lscrc   = 0;                                        //From first position
                        lactbit = (lbitp & scratchpad[0]) == lbitp;
                        lwmode  = lactbit;                                  //Prepare for send firs bit
                    break;

                    default: lmode = OWM_SLEEP;                             //all other commands do nothing
                }
            }
        break;

        case OWCOM_SKIP_ROM:
            lmode = OWM_READ_COMMAND;
        break;

        case OWM_READ_ROM:
            RESET_LOW;
            lbitp = (lbitp << 1);
            if(lbitp == 0){
                lbytep++;
                lbitp = 1;
                if(lbytep >= OWID_BUF_SIZE){
                    lmode = OWM_SLEEP;
                    break;
                }
            }
            lactbit = (lbitp & sps_owid[lbytep]) == lbitp;
            lwmode = lactbit;
        break;

        case OWM_SEARCH_ROM:
            RESET_LOW;                                                  //Set low also if nothing send (branch takes time and memory)
            lsrcount++;                                                 //next search rom mode
            switch(lsrcount){
                case 1:lwmode = !lactbit;                               //preparation sending complement
                    break;
                case 3:
                    if(p != (lactbit == 1)){                            //check master bit
                        lmode = OWM_SLEEP;                              //not the same go sleep
                    }else{
                        lbitp = (lbitp << 1);                           //prepare next bit
                        if(lbitp == 0){
                            lbitp = 1;
                            lbytep++;
                            if(lbytep >= 8){
                                lmode = OWM_SLEEP;                      //all bits processed
                                break;
                            }
                        }
                        lsrcount = 0;
                        lactbit = (sps_owid[lbytep]&lbitp) == lbitp;
                        lwmode = lactbit;
                    }
                    break;
            }
        break;
        case OWM_MATCH_ROM:
            if(p == ((sps_owid[lbytep] & lbitp) == lbitp)){             //Compare with ID Buffer
                lbitp = (lbitp<<1);
                if (lbitp == 0){
                    lbytep++;
                    lbitp = 1;
                    if(lbytep >= 8){
                        lmode = OWM_READ_COMMAND;                       //same? get next command

                        cbuf = 0;
                        break;
                    }
                }
            }else{
                lmode = OWM_SLEEP;
            }
        break;

        case OWM_WRITE_SCRATCHPAD:
            if(p != 0){
                bffForWriteScr[lbytep] |= lbitp;
            }
            if(lbytep < (wrSz - 1)){
                if((lscrc&1) != p)          lscrc = (lscrc>>1) ^ 0x8c;
                else                        lscrc >>= 1;
            }
            lbitp = (lbitp << 1);
            if(lbitp == 0){
                lbytep++;
                lbitp = 1;
                if(lbytep == wrSz){
                    if(bffForWriteScr[wrSz - 1] == lscrc){
                        memcpy((uint8_t*)&spStr.bitTask, (uint8_t*)bffForWriteScr, wrSz);
                        spStr.rxCnt++;
                    }else{
                        spStr.errCnt++;
                    }
                    lmode = OWM_SLEEP;
                    break;
                }else{
                    bffForWriteScr[lbytep] = 0;
                }
            }
        break;
        
        case OWM_READ_SCRATCHPAD:
            RESET_LOW;
            if((lscrc&1) != lactbit)    lscrc = (lscrc>>1) ^ 0x8c;
            else                        lscrc >>= 1;
Ejemplo n.º 10
0
static void event_loop(ACL_EVENT *eventp)
{
	const char *myname = "event_loop";
	EVENT_POLL *ev = (EVENT_POLL *) eventp;
	ACL_EVENT_TIMER *timer;
	int   nready, i, revents;
	acl_int64 delay;
	ACL_EVENT_FDTABLE *fdp;

	delay = eventp->delay_sec * 1000000 + eventp->delay_usec;
	if (delay < DELAY_MIN)
		delay = DELAY_MIN;

	/* 调整事件引擎的时间截 */

	SET_TIME(eventp->present);

	/* 根据定时器任务的最近任务计算 poll 的检测超时上限 */

	if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		acl_int64 n = timer->when - eventp->present;
		if (n <= 0)
			delay = 0;
		else if (n < delay)
			delay = n;
	}

	/* 调用 event_prepare 检查有多少个描述字需要通过 poll 进行检测 */

	if (event_prepare(eventp) == 0) {
		/* 说明无须 poll 检测 */

		if (eventp->ready_cnt == 0)
			/* 为避免循环过快,休眠一下 */
			acl_doze(delay > DELAY_MIN ? (int) delay / 1000 : 1);

		goto TAG_DONE;
	}

	/* 如果已经有描述字准备好则 poll 检测超时时间置 0 */

	if (eventp->ready_cnt > 0)
		delay = 0;

	/* 调用 poll 系统调用检测可用描述字 */

	nready = poll(ev->fds, eventp->fdcnt, (int) (delay / 1000));

	if (eventp->nested++ > 0) {
		acl_msg_error("%s(%d): recursive call", myname, __LINE__);
		exit (1);
	}
	if (nready < 0) {
		if (acl_last_error() != ACL_EINTR) {
			acl_msg_error("%s(%d), %s: select: %s", __FILE__,
				__LINE__, myname, acl_last_serror());
			exit (1);
		}
		goto TAG_DONE;
	} else if (nready == 0)
		goto TAG_DONE;

	/* 检查 poll 的检测结果集合 */

	for (i = 0; i < eventp->fdcnt; i++) {
		fdp = acl_fdmap_ctx(ev->fdmap, ev->fds[i].fd);
		if (fdp == NULL || fdp->stream == NULL)
			continue;

		/* 如果该描述字对象已经在被设置为异常或超时状态则继续 */

		if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT)))
			continue;

		revents = ev->fds[i].revents;

		/* 检查描述字是否出现异常 */

		if ((revents & (POLLHUP | POLLERR)) != 0) {
			fdp->event_type |= ACL_EVENT_XCPT;
			fdp->fdidx_ready = eventp->ready_cnt;
			eventp->ready[eventp->ready_cnt++] = fdp;
			continue;
		}

		/* 检查描述字是否可读 */

		if ((fdp->flag & EVENT_FDTABLE_FLAG_READ)
			&& (revents & POLLIN) )
		{
			/* 给该描述字对象附加可读属性 */
			if ((fdp->event_type & (ACL_EVENT_READ
				| ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_READ;
				fdp->fdidx_ready = eventp->ready_cnt;
				eventp->ready[eventp->ready_cnt++] = fdp;
			}

			if (fdp->listener)
				fdp->event_type |= ACL_EVENT_ACCEPT;

			/* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而
			 * 触发 ACL_VSTREAM 流在读时调用系统的 read 函数
			 */
			else
				fdp->stream->read_ready = 1;
		}

		/* 检查描述字是否可写 */

		if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE)
			&& (revents & POLLOUT))
		{

			/* 给该描述字对象附加可写属性 */

			if ((fdp->event_type & (ACL_EVENT_READ
				| ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_WRITE;
				fdp->fdidx_ready = eventp->ready_cnt;
				eventp->ready[eventp->ready_cnt++] = fdp;
			}
		}
	}

TAG_DONE:

	event_timer_trigger(eventp);

	/* 处理准备好的描述字事件 */
	if (eventp->ready_cnt > 0)
		event_fire(eventp);

	eventp->nested--;
}
//Finds vertical edges and stores in edgeArray
//Vertical edge array is the size of the image, transposed, and contains vertical edge transition features
void QRFinder::FindEdgesVerticalClosed(const Mat & inputImg, int xPosition)
{
	const short maxRow = inputImg.rows - detectorSize;
	if (xPosition < 1 || xPosition >= inputImg.cols - 1)
		return;
	if (calculatedEdges.count(xPosition) != 0 && calculatedEdges.at(xPosition)) //This column has already been completely calculated
		return;
		
	struct timespec start,end;
	SET_TIME(&start);


	Mat tmpEdgeArray = Mat::zeros(1,inputImg.rows,CV_16S); //Located and scored edges
	short * edgeRowPtr = tmpEdgeArray.ptr<short>(0);
	short * outputEdgeRowPtr;
	
	for (int i=xPosition-1;i <= xPosition+1;i++)
	{
		if (calculatedEdges.count(i) != 0)
			continue;

		outputEdgeRowPtr = verticalEdgeArray.ptr<short>(i);	
		for (int j=detectorSize;j < maxRow;j++)
		{
			edgeRowPtr[j] = -((short)inputImg.at<unsigned char>((j-1),i) + (short)inputImg.at<unsigned char>((j-2),i)) + (short)inputImg.at<unsigned char>((j+1),i) + (short)inputImg.at<unsigned char>((j+2),i);

			if (j > (detectorSize + 1) && edgeRowPtr[j-1] != 0 && abs(edgeRowPtr[j-1]) > edgeThreshold 
				&& 
					(	
						!nonMaxEnabled || 
						(
							abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j-2]) && 
							abs(edgeRowPtr[j-1]) > abs(edgeRowPtr[j])
						)
					)
				)
			{
				outputEdgeRowPtr[j-1] = (edgeRowPtr[j-1] < 0) ? -1 : 1; 
			}
			else
			{
				outputEdgeRowPtr[j-1] = 0;
			}
		}
		calculatedEdges[i] = false;
	}
		
	outputEdgeRowPtr = verticalEdgeArray.ptr<short>(xPosition+1);	
	short * lastOutputRow = verticalEdgeArray.ptr<short>(xPosition);
	short * beforeLastOutputRow = verticalEdgeArray.ptr<short>(xPosition-1);
	for (int j=detectorSize;j < maxRow;j++)
	{
		if (lastOutputRow[j-1] == 0 && 
			(outputEdgeRowPtr[j-2] != 0 || outputEdgeRowPtr[j-1] != 0 || outputEdgeRowPtr[j] != 0) &&
			(beforeLastOutputRow[j-2] != 0 || beforeLastOutputRow[j-1] != 0 || beforeLastOutputRow[j] != 0))

			lastOutputRow[j-1] = outputEdgeRowPtr[j-1] * 2;
	}

	calculatedEdges[xPosition] = true;

	SET_TIME(&end);
	//LOG_TIME_PRECISE("VerticalEdgeTest",start,end);	
}
Ejemplo n.º 12
0
static void event_loop(ACL_EVENT *eventp)
{
	const char *myname = "event_loop";
	EVENT_KERNEL *ev = (EVENT_KERNEL *) eventp;
	ACL_EVENT_NOTIFY_TIME timer_fn;
	void    *timer_arg;
	ACL_EVENT_TIMER *timer;
	int   delay;
	ACL_EVENT_FDTABLE *fdp;

	delay = (int) (eventp->delay_sec * 1000 + eventp->delay_usec / 1000);
	if (delay < 0)
		delay = 0; /* 0 milliseconds at least */

	SET_TIME(eventp->present);

	/*
	 * Find out when the next timer would go off. Timer requests are sorted.
	 * If any timer is scheduled, adjust the delay appropriately.
	 */
	if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		acl_int64 n = (timer->when - eventp->present) / 1000;

		if (n <= 0)
			delay = 0;
		else if ((int) n < delay)
			delay = (int) n;
	}

	eventp->nested++;

	event_set_all(eventp);

	if (eventp->fdcnt == 0) {
		if (eventp->fdcnt_ready == 0)
			sleep(1);
		goto TAG_DONE;
	}

	if (eventp->fdcnt_ready > 0)
		delay = 0;

TAG_DONE:

	/*
	* Deliver timer events. Requests are sorted: we can stop when we reach
	* the future or the list end. Allow the application to update the timer
	* queue while it is being called back. To this end, we repeatedly pop
	* the first request off the timer queue before delivering the event to
	* the application.
	*/
	SET_TIME(eventp->present);
	while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		if (timer->when > eventp->present)
			break;
		timer_fn  = timer->callback;
		timer_arg = timer->context;

		/* 如果定时器的时间间隔 > 0 且允许定时器被循环调用,则再重设定时器 */
		if (timer->delay > 0 && timer->keep) {
			timer->ncount++;
			eventp->timer_request(eventp, timer->callback,
				timer->context, timer->delay, timer->keep);
		} else {
			acl_ring_detach(&timer->ring);		/* first this */
			timer->nrefer--;
			if (timer->nrefer != 0)
				acl_msg_fatal("%s(%d): nrefer(%d) != 0",
					myname, __LINE__, timer->nrefer);
			acl_myfree(timer);
		}
		timer_fn(ACL_EVENT_TIME, eventp, timer_arg);
	}

	for (;;) {
		BOOL isSuccess = FALSE;
		DWORD bytesTransferred = 0;
		DWORD iocpKey = 0;
		DWORD lastError = 0;
		IOCP_EVENT *iocp_event = NULL;

		isSuccess = GetQueuedCompletionStatus(ev->h_iocp,
			&bytesTransferred, (DWORD*) &fdp,
			(OVERLAPPED**) &iocp_event, delay);

		if (!isSuccess) {

			if (iocp_event == NULL)
				break;
			if (iocp_event->type == IOCP_EVENT_DEAD)
				acl_myfree(iocp_event);
			else if (iocp_event->fdp == NULL) {
				acl_msg_warn("%s(%d): fdp null",
					myname, __LINE__);
				acl_myfree(iocp_event);
			} else if (iocp_event->fdp != fdp)
				acl_msg_fatal("%s(%d): invalid fdp",
					myname, __LINE__);
			else if (!(fdp->event_type & (ACL_EVENT_XCPT
				| ACL_EVENT_RW_TIMEOUT)))
			{
				fdp->event_type |= ACL_EVENT_XCPT;
				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready] = fdp;
				eventp->fdcnt_ready++;
			}
			continue;
		}

		acl_assert(fdp == iocp_event->fdp);

		if ((fdp->event_type & (ACL_EVENT_XCPT
			| ACL_EVENT_RW_TIMEOUT)))
		{
			continue;
		}

		if (iocp_event->type == IOCP_EVENT_READ) {
			acl_assert(fdp->event_read == iocp_event);
			iocp_event->type &= ~IOCP_EVENT_READ;
			fdp->stream->sys_read_ready = 1;
			if ((fdp->event_type & (ACL_EVENT_READ
				| ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_READ;
				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready] = fdp;
				eventp->fdcnt_ready++;
			}
		}
		if (iocp_event->type == IOCP_EVENT_WRITE) {
			acl_assert(fdp->event_write == iocp_event);
			iocp_event->type &= ~IOCP_EVENT_WRITE;
			if ((fdp->event_type & (ACL_EVENT_READ
				| ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_WRITE;
				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready] = fdp;
				eventp->fdcnt_ready++;
			}
		}
		delay = 0;
	}

	if (eventp->fdcnt_ready > 0)
		event_fire(eventp);
	eventp->nested--;
}
void QRFinder::FindFinderPatterns(cv::Mat& inputImg, Rect regionOfInterest, vector<FinderPattern*> & finderPatterns, vector<Drawable*> & debugVector)
{
	struct timespec start,end;
	SET_TIME(&start);	

	//Get parameters from config
	edgeThreshold = config->GetIntegerParameter("EdgeThreshold");
	debugLevel = config->GetIntegerParameter("QR Debug Level");
	int verticalResolution = config->GetIntegerParameter("YResolution");
	nonMaxEnabled = config->GetBooleanParameter("EdgeNonMax");
	minimumFinderPatternScore = config->GetIntegerParameter("MinimumFPScore");
	detectorSize = config->GetIntegerParameter("DetectorSize");

	int yBorder = detectorSize;
	vector<Point3i> exclusionZones;
	
	//Calculate limits
	int maxColumn = regionOfInterest.x + regionOfInterest.width;
	maxColumn -= detectorSize;	
	int maxRow = regionOfInterest.y + regionOfInterest.height;
	int xStart = regionOfInterest.x;
	int yStart = regionOfInterest.y;
	xStart += detectorSize;
	yStart += detectorSize;
	maxColumn -= detectorSize;
	maxRow -= detectorSize;

	
	if (debugLevel > 0)
		debugVector.push_back(new DebugRectangle(Rect(Point2i(xStart,yStart),Point2i(maxColumn,maxRow)),Colors::Aqua,1));

	
	//Find horizontal edges
	SET_TIME(&start);
	FindEdgesClosed(inputImg,regionOfInterest,edgeArray,edgeThreshold,nonMaxEnabled,detectorSize);
	SET_TIME(&end);
	double edgeTime_local = calc_time_double(start,end);
	edgeTime = (edgeTime + edgeTime_local)/2.0;
	config->SetLabelValue("EdgeTime",(float)edgeTime/1000.0f);
	
	//If debug level set, find all vertical edges and draw them
	if (debugLevel <= -2)
	{
		for (int x = 1; x < verticalEdgeArray.rows-1; x ++)
		{
			FindEdgesVerticalClosed(inputImg,x);		
			const short * verticalEdgePtr = verticalEdgeArray.ptr<short>(x);
			for (int y = 0; y < (verticalEdgeArray.cols);y++)
			{
				short transition = verticalEdgePtr[y];
				if (transition < 0)
				{
					debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Fuchsia,true));
				}
				else if (transition > 0)
				{
					debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Cyan,true));
				}
			}
		}	
	}
	//END
	
	
	int bw[6] = { 0 };
	int k = 0;
	//LOGV(LOGTAG_QR,"ImgSize=[%d,%d] EdgeSize=[%d,%d]",inputImg.rows,inputImg.cols,edgeArray.rows,edgeArray.cols);

	int yDirection = 1;
	int yCenter = yStart + (maxRow - yStart)/2;
	int y = yStart, absOffset = 0;

	LOGV(LOGTAG_QR,"Beginning search. y[%d->%d], Center=%d, x[%d->%d]",yStart,maxRow,yCenter,xStart,maxColumn);
	
	while (y < maxRow && y >= yStart)
	{	
		y = yCenter + absOffset * yDirection;

		if (yDirection == 1) absOffset += verticalResolution;	//Increment every other frame		
		yDirection = -yDirection;								//Change direction every frame

		k = 0;
		bw[0] = bw[1] = bw[2] = bw[3] = bw[4] = bw[5] = 0;

		const short * edgeRowPtr = edgeArray.ptr<short>(y);
		for (int x = xStart; x < maxColumn; x++)
		{
			if (isInRadius(exclusionZones,Point2i(x,y)))
				continue;

			int transition =  edgeRowPtr[x]; //getTransition(Mi,x,threshold);

			
			if (k == 0) //Haven't found edge yet
			{
				if (transition < 0) /* Light->dark transistion */
				{					
					k++;
				}
			}
			else //Found at least one edge
			{
				if ((k & 1) == 1) //Counting dark
				{
					if (transition > 0) //dark to light
					{					
						++k;
					}
				}
				else //Counting light
				{
					if (transition < 0) //light to dark
					{					
						++k;
					}
				}
			}

			if (k > 0) ++bw[k-1];

			if (FP_DEBUG_ENABLED && (debugLevel == -1 || debugLevel == -2))
			{				
				if (transition < 0)
					debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Lime,true));
				else if (transition > 0)
					debugVector.push_back(new DebugCircle(Point2i(x,y),0,Colors::Yellow,true));

				
			}	


			if (k == 6)
			{		
				int result = 0;
				result = CheckRatios(bw,NULL);

				if (result == 1)
				{	
					//LOGV(LOGTAG_QR,"Ratio check pass");
					//Center based on initial ratio					
					float patternCenterWidth = (float)bw[2];
					int tempXCenter = (x - bw[4] - bw[3]) - (int)round(patternCenterWidth/2.0f); 
					float xOffset = (patternCenterWidth/6.0f);
					
					//y coordinate of center. If check fails, returns 0.
					int tempYCenterArray[] = {0,0,0};

					int * verticalPatternSizes[3];

					for (int i = 0;i < 3;i++)
						verticalPatternSizes[i] = new int[5];

					tempYCenterArray[0] = FindCenterVertical(inputImg, tempXCenter, y, bw, debugVector,verticalPatternSizes[0]);
					tempYCenterArray[1] = FindCenterVertical(inputImg, tempXCenter - xOffset, y, bw, debugVector,verticalPatternSizes[1]);
					tempYCenterArray[2] = FindCenterVertical(inputImg, tempXCenter + xOffset, y, bw, debugVector,verticalPatternSizes[2]);
										
					int tempYCenter = 0;
					int passCount = 0;
					float avgYSize = 0;

					int averageVerticalSize[5] = {0,0,0,0,0};

					for (int yTest = 0; yTest < 3; yTest++)
					{
						if (tempYCenterArray[yTest] > 0)
						{
							passCount++;
							tempYCenter += tempYCenterArray[yTest];
							for (int i=0;i<5;i++)
							{
								averageVerticalSize[i] += (verticalPatternSizes[yTest])[i];
								avgYSize += (verticalPatternSizes[yTest])[i]; 
							}
						}						
					}

					if (passCount >= 2)
					{
						//LOGV(LOGTAG_QR,"Vertical test pass-1");
						
						tempYCenter = (int)round((float)tempYCenter / (float)passCount);
						avgYSize = (float)avgYSize / (float)passCount;

						int allowedVariance = (int)avgYSize >> 2;
						bool yVarianceTest = true;
						for (int yTest = 0; yTest < 3; yTest++)
						{
							if (tempYCenterArray[yTest] > 0)
							{
								if (abs(tempYCenterArray[yTest] - tempYCenter) > allowedVariance)
								{
									yVarianceTest = false;
									break;
								}
							}						
						}

						if (yVarianceTest)
						{
							//LOGV(LOGTAG_QR,"Vertical test pass-2. Passcount=%d",passCount);
							//Average the vertical pattern sizes
							for (int i=0;i<5;i++)
							{
								averageVerticalSize[i] = idiv(averageVerticalSize[i],passCount);
							}
							//LOGV(LOGTAG_QR,"Averaged sizes. Center=%d",averageVerticalSize[2]);

							int tempXCenterArray[] = {0,0,0};
							int xSizeArray[] = {0,0,0};
							int yOffset = idiv(averageVerticalSize[2],6.0f);

							//LOGV(LOGTAG_QR,"Yoffset=%d,yCenter=%d",yOffset,tempYCenter);
							tempXCenterArray[0] = FindCenterHorizontal(tempXCenter, tempYCenter-yOffset, bw, xSizeArray[0], debugVector); 
							tempXCenterArray[1] = FindCenterHorizontal(tempXCenter, tempYCenter, bw, xSizeArray[1], debugVector); 
							tempXCenterArray[2] = FindCenterHorizontal(tempXCenter, tempYCenter+yOffset, bw, xSizeArray[2], debugVector); 

							tempXCenter = 0;
							passCount = 0;
							float avgXSize = 0;

							for (int xTest = 0; xTest < 3; xTest++)
							{
								if (tempXCenterArray[xTest] > 0)
								{
									passCount++;
									tempXCenter += tempXCenterArray[xTest];
									avgXSize += xSizeArray[xTest];
								}						
							}

							if (passCount >= 2)
							{
								
								//LOGV(LOGTAG_QR,"Horizontal test pass");
								tempXCenter = (int)round((float)tempXCenter / (float)passCount);
								avgXSize = (float)avgXSize/(float)passCount;
								//allowedVariance = (int)round((float)avgYSize/1.5f);
								float aspectRatio = avgXSize/avgYSize;
								
								if (aspectRatio > 0.33f && aspectRatio < 3.0f)
								{
									
									//LOGV(LOGTAG_QR,"Size test pass");
									Point2i finderPatternCenter = Point2i(tempXCenter,tempYCenter); //Center of finder pattern

									int finderPatternSize =  MAX(avgXSize,avgYSize);
									int fpRadius = (int)round((float)finderPatternSize/2.0f);
									int fpRadiusExclude = ipow(finderPatternSize,2);

									//LOGD(LOGTAG_QR,"Creating new pattern[%d,%d]",avgXSize,avgYSize);
									//Create a new pattern
									FinderPattern * newPattern = new FinderPattern(finderPatternCenter,Size2i(avgXSize,avgYSize));
									Size2f patternSearchSize = Size2f(avgXSize,avgYSize);

									vector<Point2i> corners;
									struct timespec fastStart,fastEnd;
									SET_TIME(&fastStart);
									fastQRFinder->LocateFPCorners(inputImg,newPattern,corners,debugVector);
//									fastQRFinder->CheckAlignmentPattern(inputImg,finderPatternCenter,patternSearchSize,corners,debugVector);
									SET_TIME(&fastEnd);
									double fastFPTime_Local = calc_time_double(fastStart,fastEnd);
									fastFPTime += fastFPTime_Local;
									if (corners.size() == 4)
									{
										//if (validatePattern(newPattern,finderPatterns))
										//{
										newPattern->patternCorners = corners;
										exclusionZones.push_back(Point3i(finderPatternCenter.x,finderPatternCenter.y, fpRadiusExclude));
										finderPatterns.push_back(newPattern);
										if (FP_DEBUG_ENABLED && debugLevel > 0)
										{
											debugVector.push_back(new DebugCircle(finderPatternCenter,fpRadius,Colors::MediumSpringGreen,1,true));
											for (int i=0;i<corners.size();i++)
											{
												if (FP_DEBUG_ENABLED && debugLevel > 0)
													debugVector.push_back(new DebugCircle(corners[i],10,Colors::DodgerBlue,2));
											}
										}
										//}
										//else
										//{
										//	//LOGV(LOGTAG_QR,"Compare check failed");
										//	if (FP_DEBUG_ENABLED && debugLevel > 0)
										//		debugVector.push_back(new DebugCircle(finderPatternCenter,fpRadius,Colors::HotPink,2));
										//}
									}
									else
									{
										
										//LOGV(LOGTAG_QR,"FAST check failed");
										if (FP_DEBUG_ENABLED && debugLevel > 0)
											debugVector.push_back(new DebugCircle(finderPatternCenter,fpRadius,Colors::Red,2));
										delete newPattern;
									}
								}
								else
								{
									//LOGV(LOGTAG_QR,"Size check failed");
									//Size check failed
									if (FP_DEBUG_ENABLED && debugLevel > 1)
										debugVector.push_back(new DebugCircle(Point2i(tempXCenter,tempYCenter),13, Colors::HotPink,1));
								}
							}
							else
							{
								//LOGV(LOGTAG_QR,"Horizontal check failed");
								//Vertical check succeeded, but horizontal re-check failed
								if (FP_DEBUG_ENABLED && debugLevel > 1)
									debugVector.push_back(new DebugCircle(Point2i(tempXCenter,tempYCenter),12, Colors::OrangeRed,1));
							}
						}
						else
						{
							//LOGV(LOGTAG_QR,"Variance test failed. AllowedVariance = %d, yCenters = %d,%d,%d [avg=%d], AvgYSize=%d",allowedVariance,tempYCenterArray[0],tempYCenterArray[1],tempYCenterArray[2],tempYCenter,avgYSize);
							//Vertical variance test failed
							if (FP_DEBUG_ENABLED && debugLevel > 1)
								debugVector.push_back(new DebugCircle(Point2i(tempXCenter,tempYCenter),14, Colors::MediumSpringGreen,1));
						}

					} else
					{
						//Ratios were correct but vertical check failed
						if (FP_DEBUG_ENABLED && debugLevel > 2)
						{
							if (tempYCenter == 0) //ratio fail
								debugVector.push_back(new DebugCircle(Point2i(tempXCenter,y),10,Colors::Aqua,1));
							else if (tempYCenter == -1)	//topcheck fail				
								debugVector.push_back(new DebugCircle(Point2i(tempXCenter,y),10,Colors::Orange,1));
							else if (tempYCenter == -2)	//bottomcheck fail							
								debugVector.push_back(new DebugCircle(Point2i(tempXCenter,y),10,Colors::Lime,1));
						}
					}
				}
Ejemplo n.º 14
0
static void event_loop(ACL_EVENT *eventp)
{
	const char *myname = "event_loop";
	EVENT_SELECT_THR *event_thr = (EVENT_SELECT_THR *) eventp;
	ACL_EVENT_NOTIFY_FN worker_fn;
	void    *worker_arg;
	ACL_SOCKET sockfd;
	ACL_EVENT_TIMER *timer;
	int   select_delay, nready, i;
	ACL_EVENT_FDTABLE *fdp;
	ACL_RING timer_ring, *entry_ptr;
	struct timeval tv, *tvp;
	fd_set rmask;  /* enabled read events */
	fd_set wmask;  /* enabled write events */
	fd_set xmask;  /* for bad news mostly */

	acl_ring_init(&timer_ring);

	SET_TIME(eventp->event_present);
	THREAD_LOCK(&event_thr->event.tm_mutex);

	/*
	 * Find out when the next timer would go off. Timer requests are sorted.
	 * If any timer is scheduled, adjust the delay appropriately.
	 */
	if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		select_delay = (int) (timer->when - eventp->event_present + 1000000 - 1) / 1000000;
		if (select_delay < 0) {
			select_delay = 0;
		} else if (eventp->delay_sec >= 0 && select_delay > eventp->delay_sec) {
			select_delay = eventp->delay_sec;
		}
	} else {
		select_delay = eventp->delay_sec;
	}

	THREAD_UNLOCK(&event_thr->event.tm_mutex);

	THREAD_LOCK(&event_thr->event.tb_mutex);

	if (event_thr_prepare(eventp) == 0) {
		if (eventp->fdcnt_ready == 0) {
			if (select_delay <= 0)
				select_delay = 1;
			sleep(select_delay);
		}

		THREAD_UNLOCK(&event_thr->event.tb_mutex);
		goto TAG_DONE;
	}

	if (eventp->fdcnt_ready > 0) {
		tv.tv_sec  = 0;
		tv.tv_usec = 0;
		tvp = &tv;
	} else if (select_delay < 0) {
		tvp = NULL;
	} else {
		tv.tv_sec  = select_delay;
		tv.tv_usec = eventp->delay_usec;
		tvp = &tv;
	}

	rmask = event_thr->rmask;
	wmask = event_thr->wmask;
	xmask = event_thr->xmask;

	THREAD_UNLOCK(&event_thr->event.tb_mutex);

	event_thr->event.blocked = 1;
	nready = select(eventp->maxfd + 1, &rmask, &wmask, &xmask, tvp);
	event_thr->event.blocked = 0;

	if (nready < 0) {
		if (acl_last_error() != ACL_EINTR) {
			char  ebuf[256];
			acl_msg_fatal("%s(%d), %s: event_loop: select: %s",
				__FILE__, __LINE__, myname,
				acl_last_strerror(ebuf, sizeof(ebuf)));
		}
		goto TAG_DONE;
	} else if (nready == 0)
		goto TAG_DONE;

	THREAD_LOCK(&event_thr->event.tb_mutex);

	for (i = 0; i < eventp->fdcnt; i++) {
		fdp = eventp->fdtabs[i];

		/* if fdp has been set in eventp->fdtabs_ready ? */
		if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT)))
			continue;

		sockfd = ACL_VSTREAM_SOCK(fdp->stream);

		if (FD_ISSET(sockfd, &xmask)) {
			fdp->event_type |= ACL_EVENT_XCPT;
			fdp->fdidx_ready = eventp->fdcnt_ready;
			eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp;
			continue;
		}

		if (FD_ISSET(sockfd, &rmask)) {
			fdp->stream->sys_read_ready = 1;
			/* has been set in fdtabs_ready ? */
			if ((fdp->event_type & ACL_EVENT_READ) == 0) {
				fdp->event_type |= ACL_EVENT_READ;
				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp;
			}
		} else if (fdp->w_callback && FD_ISSET(sockfd, &wmask)) {
			fdp->event_type |= ACL_EVENT_WRITE;
			fdp->fdidx_ready = eventp->fdcnt_ready;
			eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp;
		}
	}

	THREAD_UNLOCK(&event_thr->event.tb_mutex);

TAG_DONE:

	/*
	 * Deliver timer events. Requests are sorted: we can stop when we reach
	 * the future or the list end. Allow the application to update the timer
	 * queue while it is being called back. To this end, we repeatedly pop
	 * the first request off the timer queue before delivering the event to
	 * the application.
	 */

	SET_TIME(eventp->event_present);

	THREAD_LOCK(&event_thr->event.tm_mutex);

	while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		if (timer->when > eventp->event_present)
			break;

		acl_ring_detach(&timer->ring);          /* first this */
		acl_ring_prepend(&timer_ring, &timer->ring);
	}

	THREAD_UNLOCK(&event_thr->event.tm_mutex);

	while (1) {
		entry_ptr = acl_ring_pop_head(&timer_ring);
		if (entry_ptr == NULL)
			break;

		timer         = ACL_RING_TO_TIMER(entry_ptr);
		worker_fn     = timer->callback;
		worker_arg    = timer->context;

		worker_fn(ACL_EVENT_TIME, worker_arg);

		acl_myfree(timer);
	}

	event_thr_fire(eventp);
}
Ejemplo n.º 15
0
static int load_lex(LEXICON *lex, char *tab)
{
    int ret;
    SPIPlanPtr SPIplan;
    Portal SPIportal;
    bool moredata = TRUE;
#ifdef DEBUG
    struct timeval t1, t2;
    double elapsed;
#endif
    char *sql;

    int ntuples;
    int total_tuples = 0;

    lex_columns_t lex_columns = {seq: -1, word: -1, stdword: -1, token: -1};

    int seq;
    char *word;
    char *stdword;
    int token;

    DBG("start load_lex\n");
    SET_TIME(t1);

    if (!tab || !strlen(tab)) {
        elog(NOTICE, "load_lex: rules table is not usable");
        return -1;
    }
    if (!tableNameOk(tab)) {
        elog(NOTICE, "load_lex: lex and gaz table names may only be alphanum and '.\"_' characters (%s)", tab);
        return -1;
    }
    sql = SPI_palloc(strlen(tab)+65);
    strcpy(sql, "select seq, word, stdword, token from ");
    strcat(sql, tab);
    strcat(sql, " order by id ");

    /* get the sql for the lexicon records and prepare the query */
    SPIplan = SPI_prepare(sql, 0, NULL);
    if (SPIplan == NULL) {
        elog(NOTICE, "load_lex: couldn't create query plan for the lex data via SPI (%s)", sql);
        return -1;
    }

    /* get the sql for the lexicon records and prepare the query */
    SPIplan = SPI_prepare(sql, 0, NULL);
    if (SPIplan == NULL) {
        elog(NOTICE, "load_lex: couldn't create query plan for the lexicon data via SPI");
        return -1;
    }

    if ((SPIportal = SPI_cursor_open(NULL, SPIplan, NULL, NULL, true)) == NULL) {
        elog(NOTICE, "load_lex: SPI_cursor_open('%s') returns NULL", sql);
        return -1;
    }

    while (moredata == TRUE) {
        //DBG("calling SPI_cursor_fetch");
        SPI_cursor_fetch(SPIportal, TRUE, TUPLIMIT);

        if (SPI_tuptable == NULL) {
            elog(NOTICE, "load_lex: SPI_tuptable is NULL");
            return -1;
        }

        if (lex_columns.seq == -1) {
            ret = fetch_lex_columns(SPI_tuptable, &lex_columns);
            if (ret)
                return ret;
        }

        ntuples = SPI_processed;
        //DBG("Reading edges: %i - %i", total_tuples, total_tuples+ntuples);
        total_tuples += ntuples;

        if (ntuples > 0) {
            int t;
            Datum binval;
            bool isnull;
            SPITupleTable *tuptable = SPI_tuptable;
            TupleDesc tupdesc = SPI_tuptable->tupdesc;

            for (t = 0; t < ntuples; t++) {
                //if (t%100 == 0) { DBG("    t: %i", t); }
                HeapTuple tuple = tuptable->vals[t];
                GET_INT_FROM_TUPLE(seq,lex_columns.seq,"load_lex: seq contains a null value");
                GET_TEXT_FROM_TUPLE(word,lex_columns.word);
                GET_TEXT_FROM_TUPLE(stdword,lex_columns.stdword);
                GET_INT_FROM_TUPLE(token,lex_columns.token,"load_lex: token contains a null value");
                lex_add_entry(lex, seq, word, stdword, token);
            }
            //DBG("calling SPI_freetuptable");
            SPI_freetuptable(tuptable);
            //DBG("back from SPI_freetuptable");
        }
        else
            moredata = FALSE;

    }

    SET_TIME(t2);
    ELAPSED_T(t1, t2);
    DBG("Time to read %i lexicon records: %.1f ms.", total_tuples, elapsed);

    return 0;
}

static int fetch_rules_columns(SPITupleTable *tuptable, rules_columns_t *rules_cols)
{
    int err = 0;
    FETCH_COL(rules_cols,rule,"rule");
    if (err) {
        elog(NOTICE, "rules queries must return column 'rule'");
        return -1;
    }
    CHECK_TYP(rules_cols,rule,TEXTOID);
    if (err) {
        elog(NOTICE, "rules column type must be: 'rule' text");
        return -1;
    }
    return 0;
}
Ejemplo n.º 16
0
void AugmentedView::Render(OpenGL * openGL)
{
	if (!canDraw)
		return;

	OpenGLRenderData renderData = openGL->renderData;

	struct timespec start,end;
	SET_TIME(&start);

	SetCameraPosition(renderData);	
	OpenGLSettings();
	

	SelectedObject * newSelection = SelectObjects(openGL);
	

	struct timespec now;
	SET_TIME(&now);
	double timediff = calc_time_double(lastSelectionTime,now);	
	
	if (unselectNext)
	{
		if (selectedObject != NULL)
			UpdateObjectPosition(projection,selectedObject);
		unselectNext = false;

	}
	//Only allowed to change selections every 1.0 seconds
	else if (newSelection != NULL && timediff > 800000.0)
	{
		//Unselect object if selected twice
		if (selectedObject != NULL && selectedObject->arObject == newSelection->arObject)
		{		
			UpdateObjectPosition(projection,selectedObject);
		}
		else
		{
			delete selectedObject;
			selectedObject = newSelection;
			//			
			//Point3f cameraPosition = getCameraPosition(projection);			
			//Point3f cameraOffset = selectedObject->arObject->position - cameraPosition;
			////Initial offset between object and camera
			selectedObject->objectPositionDelta = getObjectScreenCoord(selectedObject->arObject->position,projection);//scameraOffset;
			projection.copyTo(selectedObject->originalProjectionMat);
			cancelSelection->SetVisible(true);
			releaseSelection->SetVisible(true);

			//LOGD(LOGTAG_ARINPUT,"CameraPositionOffset(%f,%f,%f)",cameraOffset.x,cameraOffset.y,cameraOffset.z);
		}
		lastSelectionTime = now;
	}else if (newSelection != NULL)
	{
		LOGD(LOGTAG_ARINPUT,"Time spacing too short for unselect. Diff=%lf",timediff);
	}
	


	SET_TIME(&now);
	bool popVector = false;
	timediff = calc_time_double(cursorShowTime,now);
	if (timediff < 5000000.0)
	{
		objectVector.push_back(testObject);	
		popVector = true;
	}
	LOGV(LOGTAG_OPENGL,"Drawing %d ARObjects",objectVector.size());
	for (int i=0;i<objectVector.size();i++)
	{		
		ARObject * object = objectVector.at(i);

		//LOGV(LOGTAG_OPENGL,"Drawing ARObject at (%f,%f,%f)",object->position.x,object->position.y,object->position.z);
		//LOGV(LOGTAG_OPENGL,"With rotation (%f,%f,%f)",object->rotation.x,object->rotation.y,object->rotation.z);
		 
		Mat modelMatrix = Mat::eye(4,4,CV_32F);

		if (selectedObject != NULL && selectedObject->arObject == object)
		{			
			//Point3f cameraPosition = getCameraPosition(projection);			
			selectedObject->arObject->position =  getObject3DCoord(selectedObject->objectPositionDelta,projection);//selectedObject->objectPositionDelta + cameraPosition; 
		/*	Point3f cameraRotation = getCameraRotation();			
			selectedObject->arObject->rotation = selectedObject->objectRotationDelta + cameraRotation; */
		}

		OpenGLHelper::translate(modelMatrix,Point3f(object->position.x,object->position.y,object->position.z));
		OpenGLHelper::rotate(modelMatrix,object->rotation.x, Point3f(1.0f, 0.0f, 0.0f));
		OpenGLHelper::rotate(modelMatrix,object->rotation.y, Point3f(0.0f, 1.0f, 0.0f));
		OpenGLHelper::rotate(modelMatrix,object->rotation.z, Point3f(0.0f, 0.0f, 1.0f));


		Mat tmpModelMatrix;
		//Use seperate scale for selection indicator
		if (selectedObject != NULL && selectedObject->arObject == object)
		{
			modelMatrix.copyTo(tmpModelMatrix);
		}

		

		OpenGLHelper::scale(modelMatrix,object->scale);
		Mat mt = Mat(modelMatrix.t());
		glUniformMatrix4fv(renderData.modelMatrixLocation, 1, GL_FALSE, mt.ptr<float>(0));
		
		openGL->DrawGLObject(object->glObject);

		if (selectedObject != NULL && selectedObject->arObject == object)
		{
			float selectorSize = object->BoundingSphereRadius*2.25f;
			OpenGLHelper::scale(tmpModelMatrix,Point3f(selectorSize,selectorSize,selectorSize));

			Mat mt = Mat(tmpModelMatrix.t());
			glUniformMatrix4fv(renderData.modelMatrixLocation, 1, GL_FALSE, mt.ptr<float>(0));
			openGL->DrawGLObject(selectionIndicator->glObject);
		}
	}	
	//Get rid of test object
	if (popVector)
		objectVector.pop_back();
	ResetGLSettings();		

	SET_TIME(&end);
	LOG_TIME("AugmentedView Render",start,end);
	canDraw = false;
}
Ejemplo n.º 17
0
SelectedObject * AugmentedView::SelectObjects(OpenGL * openGL)
{	
	vector<Point2i> currentPoints = inputPoints;
	inputPoints.clear();
	SelectedObject * found = NULL;

	while (!currentPoints.empty())
	{
		Point3f p1,p2;

		getPickingRay(currentPoints.back(),openGL,projection,p1,p2,testObject,fieldOfView);

		vector<ARObject*> hitObjects;		
		Point3f p12 = p2-p1;
		//LOGD(LOGTAG_ARINPUT,"P12=(%f,%f,%f)",p12.x,p12.y,p12.z);

		float p12Mag = pow(p12.x,2) + pow(p12.y,2) + pow(p12.z,2);
		for (int i=0;i<objectVector.size();i++)
		{
			Point3f p0 = objectVector[i]->position;
			//Mat position = Mat(1,3,CV_32F);

			Point3f cross = p12.cross((p1-p0));
			float distance = pow(cross.x,2) + pow(cross.y,2) + pow(cross.z,2);
			distance /= p12Mag;
		
			distance = sqrt(distance);

			if (distance < objectVector[i]->BoundingSphereRadius)
			{
				hitObjects.push_back(objectVector[i]);
			}
			else
			{
				LOGV(LOGTAG_ARINPUT,"Did not collide with object %s at position %f,%f,%f with sphere of radius %f (distance=%f)",
					objectVector[i]->objectID.c_str(),p0.x,p0.y,p0.z,objectVector[i]->BoundingSphereRadius,distance);
			}
		}

		if (hitObjects.size() > 0)
		{
			if (hitObjects.size() > 1)
			{
				std::sort(hitObjects.begin(),hitObjects.end(),ARObjectDistanceSort_Ascending(p1));
			}
			struct timespec now;
			SET_TIME(&now);
			cursorShowTime.tv_sec = 0; //hide cursor if selection successful
			found = new SelectedObject(hitObjects.front(),now);
			break;
		}
		else
		{
			currentPoints.pop_back();
		}


		if (found == NULL)
			SET_TIME(&cursorShowTime);
	}

	return found;
}
Ejemplo n.º 18
0
static int load_rules(RULES *rules, char *tab)
{
    int ret;
    SPIPlanPtr SPIplan;
    Portal SPIportal;
    bool moredata = TRUE;
#ifdef DEBUG
    struct timeval t1, t2;
    double elapsed;
#endif
    char *sql;

    int rule_arr[MAX_RULE_LENGTH];

    int ntuples;
    int total_tuples = 0;

    rules_columns_t rules_columns = {rule: -1};

    char *rule;

    DBG("start load_rules\n");
    SET_TIME(t1);

    if (!tab || !strlen(tab)) {
        elog(NOTICE, "load_rules: rules table is not usable");
        return -1;
    }
    if (!tableNameOk(tab)) {
        elog(NOTICE, "load_rules: rules table name may only be alphanum and '.\"_' characters (%s)", tab);
        return -1;
    }
    sql = SPI_palloc(strlen(tab)+35);
    strcpy(sql, "select rule from ");
    strcat(sql, tab);
    strcat(sql, " order by id ");

    /* get the sql for the lexicon records and prepare the query */
    SPIplan = SPI_prepare(sql, 0, NULL);
    if (SPIplan == NULL) {
        elog(NOTICE, "load_rules: couldn't create query plan for the rule data via SPI (%s)", sql);
        return -1;
    }

    if ((SPIportal = SPI_cursor_open(NULL, SPIplan, NULL, NULL, true)) == NULL) {
        elog(NOTICE, "load_rules: SPI_cursor_open('%s') returns NULL", sql);
        return -1;
    }

    while (moredata == TRUE) {
        //DBG("calling SPI_cursor_fetch");
        SPI_cursor_fetch(SPIportal, TRUE, TUPLIMIT);

        if (SPI_tuptable == NULL) {
            elog(NOTICE, "load_rules: SPI_tuptable is NULL");
            return -1;
        }

        if (rules_columns.rule == -1) {
            ret = fetch_rules_columns(SPI_tuptable, &rules_columns);
            if (ret)
                return ret;
        }

        ntuples = SPI_processed;
        //DBG("Reading edges: %i - %i", total_tuples, total_tuples+ntuples);

        if (ntuples > 0) {
            int t;
            SPITupleTable *tuptable = SPI_tuptable;
            TupleDesc tupdesc = SPI_tuptable->tupdesc;

            for (t = 0; t < ntuples; t++) {
                int nr;
                //if (t%100 == 0) { DBG("    t: %i", t); }
                HeapTuple tuple = tuptable->vals[t];
                GET_TEXT_FROM_TUPLE(rule,rules_columns.rule);
                nr = parse_rule(rule, rule_arr);
                if (nr == -1) {
                    elog(NOTICE, "load_roles: rule exceeds 128 terms");
                    return -1;
                }
                ret = rules_add_rule(rules, nr, rule_arr);
                if (ret != 0) {
                    elog(NOTICE,"load_roles: failed to add rule %d (%d): %s",
                         total_tuples+t+1, ret, rule);
                    return -1;
                }
            }
            //DBG("calling SPI_freetuptable");
            SPI_freetuptable(tuptable);
            //DBG("back from SPI_freetuptable");
        }
        else
            moredata = FALSE;

        total_tuples += ntuples;
    }

    ret = rules_ready(rules);
    if (ret != 0) {
        elog(NOTICE, "load_roles: failed to ready the rules: err: %d", ret);
        return -1;
    }


    SET_TIME(t2);
    ELAPSED_T(t1, t2);
    DBG("Time to read %i rule records: %.1f ms.", total_tuples, elapsed);

    return 0;
}
Ejemplo n.º 19
0
static void event_loop(ACL_EVENT *eventp)
{
	const char *myname = "event_loop";
	EVENT_SELECT *ev = (EVENT_SELECT *) eventp;
	ACL_EVENT_NOTIFY_TIME timer_fn;
	void    *timer_arg;
	ACL_SOCKET sockfd;
	ACL_EVENT_TIMER *timer;
	int   nready, i;
	acl_int64 delay;
	ACL_EVENT_FDTABLE *fdp;
	struct timeval tv, *tvp;
	fd_set rmask;  /* enabled read events */
	fd_set wmask;  /* enabled write events */
	fd_set xmask;  /* for bad news mostly */

	delay = eventp->delay_sec * 1000000 + eventp->delay_usec;

	/* 调整事件引擎的时间截 */

	SET_TIME(eventp->present);

	/* 根据定时器任务的最近任务计算 select 的检测超时上限 */

	if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		acl_int64 n = timer->when - eventp->present;

		if (n <= 0)
			delay = 0;
		else if (n < delay)
			delay = n;
	}

	/* 调用 event_prepare 检查有多少个描述字需要通过 select 进行检测 */

	if (event_prepare(eventp) == 0) {
		if (eventp->ready_cnt == 0) {
			delay /= 1000000;
			if (delay <= 0)
				delay = 1;
			/* 为避免循环过快,休眠一下 */
			sleep((int) delay);
		}

		goto TAG_DONE;
	}

	if (eventp->ready_cnt > 0) {
		tv.tv_sec  = 0;
		tv.tv_usec = 0;
		tvp = &tv;
	} else if (delay >= 0) {
#if defined(ACL_WINDOWS)
		tv.tv_sec  = (long) delay / 1000000;
		tv.tv_usec = (unsigned long) (delay - tv.tv_sec * 1000000);
#else
		tv.tv_sec  = (time_t) delay / 1000000;
		tv.tv_usec = (suseconds_t) (delay - tv.tv_sec * 1000000);
#endif
		tvp = &tv;
	} else
		tvp = NULL;

	rmask = ev->rmask;
	wmask = ev->wmask;
	xmask = ev->xmask;

	/* 调用 select 系统调用检测可用描述字 */

#ifdef ACL_WINDOWS
	nready = select(0, &rmask, &wmask, &xmask, tvp);
#else
	nready = select(eventp->maxfd + 1, &rmask, &wmask, &xmask, tvp);
#endif

	if (eventp->nested++ > 0)
		acl_msg_fatal("%s(%d): recursive call(%d)",
			myname, __LINE__, eventp->nested);
	if (nready < 0) {
		if (acl_last_error() != ACL_EINTR) {
			acl_msg_fatal("%s(%d), %s: select: %s", __FILE__,
				__LINE__, myname, acl_last_serror());
		}
		goto TAG_DONE;
	} else if (nready == 0)
		goto TAG_DONE;

	/* 检查 select 的检测结果集合 */

	/* if some fdp was cleared from eventp->fdtabs in timer callback,
	 * which has no effection on the rest fdp in eventp->fdtabs
	 */

	for (i = 0; i < eventp->fdcnt; i++) {
		fdp = eventp->fdtabs[i];

		/* 如果该描述字对象已经在被设置为异常或超时状态则继续 */

		if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT)))
			continue;

		sockfd = ACL_VSTREAM_SOCK(fdp->stream);

		/* 检查描述字是否出现异常 */

		if (FD_ISSET(sockfd, &xmask)) {
			fdp->event_type |= ACL_EVENT_XCPT;
			fdp->fdidx_ready = eventp->ready_cnt;
			eventp->ready[eventp->ready_cnt++] = fdp;
			continue;
		}

		/* 检查描述字是否可读 */

		if (FD_ISSET(sockfd, &rmask)) {
			/* 给该描述字对象附加可读属性 */
			if ((fdp->event_type & (ACL_EVENT_READ
				| ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_READ;
				fdp->fdidx_ready = eventp->ready_cnt;
				eventp->ready[eventp->ready_cnt++] = fdp;
			}

			if (fdp->listener)
				fdp->event_type |= ACL_EVENT_ACCEPT;

			/* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而
			 * 触发 ACL_VSTREAM 流在读时调用系统的 read 函数
			 */
			else
				fdp->stream->read_ready = 1;
		}

		/* 检查描述字是否可写 */

		if (FD_ISSET(sockfd, &wmask)) {

			/* 给该描述字对象附加可写属性 */

			if ((fdp->event_type & (ACL_EVENT_READ
				| ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_WRITE;
				fdp->fdidx_ready = eventp->ready_cnt;
				eventp->ready[eventp->ready_cnt++] = fdp;
			}
		}
	}

TAG_DONE:

	/* 调整事件引擎的时间截 */

	SET_TIME(eventp->present);

	/* 优先处理定时器中的任务 */

	while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		if (timer->when > eventp->present)
			break;
		timer_fn  = timer->callback;
		timer_arg = timer->context;

		/* 如果定时器的时间间隔 > 0 且允许定时器被循环调用,
		 * 则再重设定时器
		 */
		if (timer->delay > 0 && timer->keep) {
			timer->ncount++;
			eventp->timer_request(eventp, timer->callback,
				timer->context, timer->delay, timer->keep);
		} else {
			acl_ring_detach(&timer->ring); /* first this */
			timer->nrefer--;
			if (timer->nrefer != 0)
				acl_msg_fatal("%s(%d): nrefer(%d) != 0",
					myname, __LINE__, timer->nrefer);
			acl_myfree(timer);
		}
		timer_fn(ACL_EVENT_TIME, eventp, timer_arg);
	}

	/* 处理准备好的描述字事件 */

	if (eventp->ready_cnt > 0)
		event_fire(eventp);

	eventp->nested--;
}
Ejemplo n.º 20
0
int main()
{
    RTTIMESPEC      Now;
    RTTIMESPEC      Ts1;
    RTTIMESPEC      Ts2;
    RTTIME          T1;
    RTTIME          T2;
#ifdef RTTIME_INCL_TIMEVAL
    struct timeval  Tv1;
    struct timeval  Tv2;
    struct timespec Tsp1;
    struct timespec Tsp2;
#endif
    RTTEST          hTest;

    int rc = RTTestInitAndCreate("tstRTTimeSpec", &hTest);
    if (rc)
        return rc;

    /*
     * Simple test with current time.
     */
    RTTestSub(hTest, "Current time (UTC)");
    CHECK_NZ(RTTimeNow(&Now));
    CHECK_NZ(RTTimeExplode(&T1, &Now));
    RTTestIPrintf(RTTESTLVL_ALWAYS, "   %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1));
    CHECK_NZ(RTTimeImplode(&Ts1, &T1));
    if (!RTTimeSpecIsEqual(&Ts1, &Now))
        RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now));

    /*
     * Simple test with current local time.
     */
    RTTestSub(hTest, "Current time (local)");
    CHECK_NZ(RTTimeLocalNow(&Now));
    CHECK_NZ(RTTimeExplode(&T1, &Now));
    RTTestIPrintf(RTTESTLVL_ALWAYS, "   %RI64 ns - %s\n", RTTimeSpecGetNano(&Now), ToString(&T1));
    CHECK_NZ(RTTimeImplode(&Ts1, &T1));
    if (!RTTimeSpecIsEqual(&Ts1, &Now))
        RTTestIFailed("%RI64 != %RI64\n", RTTimeSpecGetNano(&Ts1), RTTimeSpecGetNano(&Now));

    /*
     * Some simple tests with fixed dates (just checking for smoke).
     */
    RTTestSub(hTest, "Smoke");
    TEST_NS(INT64_C(0));
    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    TEST_NS(INT64_C(86400000000000));
    CHECK_TIME(&T1, 1970,01,02, 00,00,00,        0,   2, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    TEST_NS(INT64_C(1));
    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        1,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    TEST_NS(INT64_C(-1));
    CHECK_TIME(&T1, 1969,12,31, 23,59,59,999999999, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    /*
     * Test the limits.
     */
    RTTestSub(hTest, "Extremes");
    TEST_NS(INT64_MAX);
    TEST_NS(INT64_MIN);
    TEST_SEC(1095379198);
    CHECK_TIME(&T1, 2004, 9,16, 23,59,58,        0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    TEST_SEC(1095379199);
    CHECK_TIME(&T1, 2004, 9,16, 23,59,59,        0, 260, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    TEST_SEC(1095379200);
    CHECK_TIME(&T1, 2004, 9,17, 00,00,00,        0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    TEST_SEC(1095379201);
    CHECK_TIME(&T1, 2004, 9,17, 00,00,01,        0, 261, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);


    /*
     * Test normalization (UTC).
     */
    RTTestSub(hTest, "Normalization (UTC)");
    /* simple */
    CHECK_NZ(RTTimeNow(&Now));
    CHECK_NZ(RTTimeExplode(&T1, &Now));
    T2 = T1;
    CHECK_NZ(RTTimeNormalize(&T1));
    if (memcmp(&T1, &T2, sizeof(T1)))
        RTTestIFailed("simple normalization failed\n");
    CHECK_NZ(RTTimeImplode(&Ts1, &T1));
    CHECK_NZ(RTTimeSpecIsEqual(&Ts1, &Now));

    /* a few partial dates. */
    memset(&T1, 0, sizeof(T1));
    SET_TIME(  &T1, 1970,01,01, 00,00,00,        0,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1970,00,00, 00,00,00,        1,   1, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1970,01,01, 00,00,00,        1,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 2007,12,06, 02,15,23,        1,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1968,01,30, 00,19,24,        5,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1968,01,30, 00,19,24,        5,  30, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);

    SET_TIME(  &T1, 1969,01,31, 00, 9, 2,        7,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,01,31, 00, 9, 2,        7,  31, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,03,31, 00, 9, 2,        7,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,03,31, 00, 9, 2,        7,  90, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,12,31, 00,00,00,        9,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,31, 00,00,00,        9, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,12,30, 00,00,00,       30,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,30, 00,00,00,       30, 364, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,00,00, 00,00,00,       30, 363, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,29, 00,00,00,       30, 363, 0, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,00,00, 00,00,00,       30, 362, 6, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,28, 00,00,00,       30, 362, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,12,27, 00,00,00,       30,   0, 5, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,27, 00,00,00,       30, 361, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,00,00, 00,00,00,       30, 360, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,26, 00,00,00,       30, 360, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,12,25, 00,00,00,       12,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,25, 00,00,00,       12, 359, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 1969,12,24, 00,00,00,       16,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1969,12,24, 00,00,00,       16, 358, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    /* outside the year table range */
    SET_TIME(  &T1, 1200,01,30, 00,00,00,        2,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1200,01,30, 00,00,00,        2,  30, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);

    SET_TIME(  &T1, 2555,11,29, 00,00,00,        2,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2555,11,29, 00,00,00,        2, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 2555,00,00, 00,00,00,        3, 333, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2555,11,29, 00,00,00,        3, 333, 5, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    /* time overflow */
    SET_TIME(  &T1, 1969,12,30, 255,255,255, UINT32_MAX, 364, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 1970,01, 9, 19,19,19,294967295,   9, 4, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    /* date overflow */
    SET_TIME(  &T1, 2007,11,36, 02,15,23,        1,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 2007,10,67, 02,15,23,        1,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 2007,10,98, 02,15,23,        1,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2008,01,06, 02,15,23,        1,   6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);

    SET_TIME(  &T1, 2006,24,06, 02,15,23,        1,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    SET_TIME(  &T1, 2003,60,37, 02,15,23,        1,   0, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2008,01,06, 02,15,23,        1,   6, 6, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);

    SET_TIME(  &T1, 2003,00,00, 02,15,23,        1,1801, 0, 0, 0);
    CHECK_NZ(RTTimeNormalize(&T1));
    CHECK_TIME(&T1, 2007,12,06, 02,15,23,        1, 340, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);

    /*
     * Conversions.
     */
#define CHECK_NSEC(Ts1, T2) \
    do { \
        RTTIMESPEC TsTmp; \
        RTTESTI_CHECK_MSG( RTTimeSpecGetNano(&(Ts1)) == RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2))), \
                          ("line %d: %RI64, %RI64\n", __LINE__, \
                           RTTimeSpecGetNano(&(Ts1)),   RTTimeSpecGetNano(RTTimeImplode(&TsTmp, &(T2)))) ); \
    } while (0)
    RTTestSub(hTest, "Conversions, positive");
    SET_TIME(&T1, 1980,01,01, 00,00,00,        0,   1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    RTTESTI_CHECK(RTTimeSpecSetDosSeconds(&Ts2,    0) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetDosSeconds(&Ts2) == 0);
    CHECK_NSEC(Ts2, T1);

    SET_TIME(&T1, 1980,01,01, 00,00,00,        0,   1, 1, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_LEAP_YEAR);
    RTTESTI_CHECK(RTTimeSpecSetNtTime(&Ts2,    INT64_C(119600064000000000)) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetNtTime(&Ts2) == INT64_C(119600064000000000));
    CHECK_NSEC(Ts2, T1);

    SET_TIME(&T1, 1970,01,01, 00,00,01,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    RTTESTI_CHECK(RTTimeSpecSetSeconds(&Ts2,    1) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetSeconds(&Ts2) == 1);
    CHECK_NSEC(Ts2, T1);

    SET_TIME(&T1, 1970,01,01, 00,00,01,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    RTTESTI_CHECK(RTTimeSpecSetMilli(&Ts2,    1000) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetMilli(&Ts2) == 1000);
    CHECK_NSEC(Ts2, T1);

    SET_TIME(&T1, 1970,01,01, 00,00,01,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    RTTESTI_CHECK(RTTimeSpecSetMicro(&Ts2,    1000000) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000000);
    CHECK_NSEC(Ts2, T1);

    SET_TIME(&T1, 1970,01,01, 00,00,01,        0,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    RTTESTI_CHECK(RTTimeSpecSetNano(&Ts2,    1000000000) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000000);
    CHECK_NSEC(Ts2, T1);

#ifdef RTTIME_INCL_TIMEVAL
    SET_TIME(&T1, 1970,01,01, 00,00,01,     5000,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    Tv1.tv_sec  = 1;
    Tv1.tv_usec = 5;
    RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetMicro(&Ts2) == 1000005);
    CHECK_NSEC(Ts2, T1);
    RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2);
    RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec);
#endif

#ifdef RTTIME_INCL_TIMESPEC
    SET_TIME(&T1, 1970,01,01, 00,00,01,        5,   1, 3, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    Tsp1.tv_sec  = 1;
    Tsp1.tv_nsec = 5;
    RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2);
    RTTESTI_CHECK(RTTimeSpecGetNano(&Ts2) == 1000000005);
    CHECK_NSEC(Ts2, T1);
    RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2);
    RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec);
#endif


    RTTestSub(hTest, "Conversions, negative");

#ifdef RTTIME_INCL_TIMEVAL
    SET_TIME(&T1, 1969,12,31, 23,59,58,999995000, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    Tv1.tv_sec  = -2;
    Tv1.tv_usec = 999995;
    RTTESTI_CHECK(RTTimeSpecSetTimeval(&Ts2, &Tv1) == &Ts2);
    RTTESTI_CHECK_MSG(RTTimeSpecGetMicro(&Ts2) == -1000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2)));
    CHECK_NSEC(Ts2, T1);
    RTTESTI_CHECK(RTTimeSpecGetTimeval(&Ts2, &Tv2) == &Tv2);
    RTTESTI_CHECK(Tv1.tv_sec == Tv2.tv_sec); RTTESTI_CHECK(Tv1.tv_usec == Tv2.tv_usec);
#endif

#ifdef RTTIME_INCL_TIMESPEC
    SET_TIME(&T1, 1969,12,31, 23,59,58,999999995, 365, 2, 0, RTTIME_FLAGS_TYPE_UTC | RTTIME_FLAGS_COMMON_YEAR);
    Tsp1.tv_sec  = -2;
    Tsp1.tv_nsec = 999999995;
    RTTESTI_CHECK(RTTimeSpecSetTimespec(&Ts2, &Tsp1) == &Ts2);
    RTTESTI_CHECK_MSG(RTTimeSpecGetNano(&Ts2) == -1000000005, ("%RI64\n", RTTimeSpecGetMicro(&Ts2)));
    CHECK_NSEC(Ts2, T1);
    RTTESTI_CHECK(RTTimeSpecGetTimespec(&Ts2, &Tsp2) == &Tsp2);
    RTTESTI_CHECK(Tsp1.tv_sec == Tsp2.tv_sec); RTTESTI_CHECK(Tsp1.tv_nsec == Tsp2.tv_nsec);
#endif

    /*
     * Summary
     */
    return RTTestSummaryAndDestroy(hTest);
}
Ejemplo n.º 21
0
static void event_loop(ACL_EVENT *eventp)
{
	const char *myname = "event_loop";
	EVENT_KERNEL *ev = (EVENT_KERNEL *) eventp;
	ACL_EVENT_NOTIFY_TIME timer_fn;
	void    *timer_arg;
	ACL_EVENT_TIMER *timer;
	int   delay, nready;
	ACL_EVENT_FDTABLE *fdp;
	EVENT_BUFFER *bp;

	delay = (int) (eventp->delay_sec * 1000 + eventp->delay_usec / 1000);
	if (delay < 0)
		delay = 0; /* 0 milliseconds at least */

	/* 调整事件引擎的时间截 */

	SET_TIME(eventp->present);

	/* 根据定时器任务的最近任务计算 epoll/kqueue/devpoll 的检测超时上限 */

	if ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		acl_int64 n = (timer->when - eventp->present) / 1000;

		if (n <= 0)
			delay = 0;
		else if ((int) n < delay) {
			delay = (int) n;
			if (delay <= 0)  /* xxx */
				delay = 100;
		}
	}

	/* 设置描述字对象的状态,添加/删除之前设置的描述字对象 */

	event_set_all(eventp);

	if (eventp->fdcnt == 0) {
		if (eventp->fdcnt_ready == 0)
			sleep(1);
		goto TAG_DONE;
	}

	/* 如果已经有描述字准备好则检测超时时间置 0 */

	if (eventp->fdcnt_ready > 0)
		delay = 0;

	/* 调用 epoll/kquque/devpoll 系统调用检测可用描述字 */

	EVENT_BUFFER_READ(nready, ev->event_fd, ev->event_buf,
		ev->event_fdslots, delay);

	if (eventp->nested++ > 0)
		acl_msg_fatal("%s(%d): recursive call, nested: %d",
			myname, __LINE__, eventp->nested);
	if (nready < 0) {
		if (acl_last_error() != ACL_EINTR) {
			acl_msg_fatal("%s(%d), %s: select: %s", __FILE__,
				__LINE__, myname, acl_last_serror());
		}
		goto TAG_DONE;
	} else if (nready == 0)
		goto TAG_DONE;

	/* 检查检测结果 */

	for (bp = ev->event_buf; bp < ev->event_buf + nready; bp++) {
#ifdef	USE_FDMAP
		ACL_SOCKET sockfd;

		sockfd = EVENT_GET_FD(bp);
		fdp = acl_fdmap_ctx(ev->fdmap, sockfd);
		if (fdp == NULL || fdp->stream == NULL)
			continue;
		if (sockfd != ACL_VSTREAM_SOCK(fdp->stream))
			acl_msg_fatal("%s(%d): sockfd(%d) != %d", myname,
				__LINE__, sockfd, ACL_VSTREAM_SOCK(fdp->stream));
#else
		fdp = (ACL_EVENT_FDTABLE *) EVENT_GET_CTX(bp);
		if (fdp == NULL || fdp->stream == NULL)
			continue;
#endif

		/* 如果该描述字对象已经在被设置为异常或超时状态则继续 */

		if ((fdp->event_type & (ACL_EVENT_XCPT | ACL_EVENT_RW_TIMEOUT)))
			continue;

		/* 检查描述字是否可读 */

		if ((fdp->flag & EVENT_FDTABLE_FLAG_READ) && EVENT_TEST_READ(bp)) {

			/* 该描述字可读则设置 ACL_VSTREAM 的系统可读标志从而触发
			 * ACL_VSTREAM 流在读时调用系统的 read 函数
			 */

			fdp->stream->sys_read_ready = 1;

			/* 给该描述字对象附加可读属性 */

			if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_READ;
				if (fdp->listener)
					fdp->event_type |= ACL_EVENT_ACCEPT;

				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp;
			}
		}

		/* 检查描述字是否可写 */

		if ((fdp->flag & EVENT_FDTABLE_FLAG_WRITE) && EVENT_TEST_WRITE(bp)) {

			/* 给该描述字对象附加可写属性 */

			if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_WRITE;
				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp;
			}
		}

#ifdef	EVENT_TEST_ERROR
		if (EVENT_TEST_ERROR(bp)) {
			/* 如果出现异常则设置异常属性 */

			if ((fdp->event_type & (ACL_EVENT_READ | ACL_EVENT_WRITE)) == 0)
			{
				fdp->event_type |= ACL_EVENT_XCPT;
				fdp->fdidx_ready = eventp->fdcnt_ready;
				eventp->fdtabs_ready[eventp->fdcnt_ready++] = fdp;
			}
		}
#endif
	}

TAG_DONE:

	/*
	 * Deliver timer events. Requests are sorted: we can stop when we reach
	 * the future or the list end. Allow the application to update the timer
	 * queue while it is being called back. To this end, we repeatedly pop
	 * the first request off the timer queue before delivering the event to
	 * the application.
	 */

	/* 调整事件引擎的时间截 */

	SET_TIME(eventp->present);

	while ((timer = ACL_FIRST_TIMER(&eventp->timer_head)) != 0) {
		if (timer->when > eventp->present)
			break;
		timer_fn  = timer->callback;
		timer_arg = timer->context;

		/* 定时器时间间隔 > 0 且允许定时器被循环调用,则重设定时器 */
		if (timer->delay > 0 && timer->keep) {
			timer->ncount++;
			eventp->timer_request(eventp, timer->callback,
				timer->context, timer->delay, timer->keep);
		} else {
			acl_ring_detach(&timer->ring);	/* first this */
			timer->nrefer--;
			if (timer->nrefer != 0)
				acl_msg_fatal("%s(%d): nrefer(%d) != 0",
					myname, __LINE__, timer->nrefer);
			acl_myfree(timer);
		}
		timer_fn(ACL_EVENT_TIME, eventp, timer_arg);
	}

	/* 处理准备好的描述字事件 */

	if (eventp->fdcnt_ready > 0)
		event_fire(eventp);

	eventp->nested--;
}
Ejemplo n.º 22
0
void ARController::ProcessFrame(Engine * engine)
{
    if (!isInitialized)
        return;

    frameCount++;
    //Calc FPS
    struct timespec currentTime;
    SET_TIME(&currentTime);
    double frameTimeMicrosec = calc_time_double(lastFrameTime,currentTime);
    lastFrameTime = currentTime;
    float frameFps = (float)(1000000.0/frameTimeMicrosec);
    fpsAverage = (fpsAverage+frameFps)/2.0f;
    char fpsString[10];
    sprintf(fpsString,"%3.1f",fpsAverage);
    fpsLabel->SetText(fpsString);

    int debugLevel = debugUI->GetIntegerParameter("ARControllerDebug");
    bool useGuess = debugUI->GetBooleanParameter("UseGuess");
    bool showEntireBinary = debugUI->GetBooleanParameter("Show Entire Binary");


    //This section is the default per-frame operations
    FrameItem * item = frameList->next();
    item->clearOldData();
    //engine->getTime(&item->time);

    LOGV(LOGTAG_ARCONTROLLER,"Processing frame #%d, FPS=%f.",frameCount,fpsAverage);
    //Loose objects: QR=%d, Rect=%d, Circ=%d, FP=%d",
    //frameCount,fpsAverage,(int)QRCode::instanceCount,DebugRectangle::instanceCount,DebugCircle::instanceCount, FinderPattern::instanceCount);

    //If paused, keep reusing image until unpaused
    if (!paused)
    {
        getImages(engine);
    }
    else
    {
        //Need to refresh the RGB image
        cvtColor(*grayImage, *rgbImage, CV_GRAY2RGBA, 4);
    }

    vector<Drawable*> debugVector;

    item->qrCode = qrFinder->LocateQRCodes(*grayImage, debugVector, ( frameList->size() > 1) ? frameList->getRelative(-1)->qrCode : NULL);

    //What happens past here depends on the state
    if (controllerState == ControllerStates::Loading)
    {
        //Update world loader
        worldLoader->Update(engine);

        WorldStates::WorldState worldState = worldLoader->GetState();

        if (worldState == WorldStates::LookingForCode)
        {
            debugUI->SetLabelValue("State","Searching");

            if (item->qrCode != NULL && item->qrCode->isValidCode())
            {
                struct timespec decodeStart,decodeEnd;
                SET_TIME(&decodeStart);
                qrDecoder->DecodeQRCode(grayImage,binaryImage,item->qrCode,debugVector);
                SET_TIME(&decodeEnd);
                LOG_TIME("Decode",decodeStart,decodeEnd);
                if (item->qrCode->isDecoded())
                {
                    string codeText = "Code=";
                    codeText.append(item->qrCode->TextValue);
                    debugUI->SetLabelValue("CurrentCode",codeText);
                    currentCode = item->qrCode->TextValue;

                    if (debugUI->GetBooleanParameter("CodeOnly"))
                    {
                        LOGI(LOGTAG_ARCONTROLLER,"Code found (%s), still searching since we're in debug mode",currentCode.c_str());
                    }
                    else if (engine->communicator->IsConnected())
                    {
                        worldLoader->LoadRealm(item->qrCode->TextValue);
                    }
                    else //If not connected, just add a test object
                    {
                        LOGI(LOGTAG_ARCONTROLLER,"Starting in offline mode.");

                        debugUI->SetLabelValue("State","OfflineMode");
                        initializeARView(engine);

                        ARObject * myCube1 = new ARObject(OpenGLHelper::CreateMultiColorCube(20),Point3f(0,0,0));

                        //ARObject * myCube2 = new ARObject(OpenGLHelper::CreateMultiColorCube(20),Point3f(50,10,0));
                        //augmentedView->AddObject(myCube2);
                        //myCube2->BoundingSphereRadius = 30;
                        //ARObject * myCube3 = new ARObject(OpenGLHelper::CreateMultiColorCube(20),Point3f(-50,-10,0));
                        //augmentedView->AddObject(myCube3);
                        //myCube3->BoundingSphereRadius = 30;

                        augmentedView->AddObject(myCube1);
                        myCube1->BoundingSphereRadius = 12;

                        SetState(ControllerStates::Running);
                        delete worldLoader;
                        worldLoader = NULL;
                    }
                }
                else
                    LOGD(LOGTAG_ARCONTROLLER,"QRCode not decoded");
            }
        }
        else if (worldState == WorldStates::WaitingForRealm || worldState == WorldStates::WaitingForResources)
        {
            if (worldState == WorldStates::WaitingForRealm)
                debugUI->SetLabelValue("State","WaitRealm");
            else
                debugUI->SetLabelValue("State","WaitRsrc");

        }
        //The world is ready and loaded, so do normal AR processing
        else if (worldState == WorldStates::WorldReady)
        {
            debugUI->SetLabelValue("State","LoadCompl");
            initializeARView(engine);
            LOGD(LOGTAG_ARCONTROLLER,"Populating ARView using loaded world");
            worldLoader->PopulateARView(augmentedView);
            SetState(ControllerStates::Running);
            currentQRSize = debugUI->GetParameter("QRSize"); //Should be using value from server
            delete worldLoader;
            worldLoader = NULL;
        }
        else
        {
            char stateString[100];
            sprintf(stateString,"WrldState=%d",(int)worldState);
            debugUI->SetLabelValue("State",stateString);
            LOGW(LOGTAG_ARCONTROLLER,"Unexpected state");
        }
    }
    else if (controllerState == ControllerStates::Running)
    {
        debugUI->SetLabelValue("State","Run");

        bool doSkip = false;
        if (item->qrCode != NULL && item->qrCode->isValidCode())
        {

            if (recheckNext)
            {
                LOGD(LOGTAG_ARCONTROLLER,"Rechecking code. Current value = %s",currentCode.c_str());
                qrDecoder->DecodeQRCode(grayImage,binaryImage,item->qrCode,debugVector);

                if (item->qrCode->isDecoded() && item->qrCode->TextValue != currentCode)
                {
                    if (worldLoader == NULL)
                        worldLoader = new WorldLoader();
                    else
                    {
                        delete worldLoader;
                        worldLoader = new WorldLoader();
                    }
                    LOGD(LOGTAG_ARCONTROLLER,"Changing to code %s",currentCode.c_str());
                    currentCode = item->qrCode->TextValue;
                    worldLoader->LoadRealm(currentCode);
                    SetState(ControllerStates::Loading);
                    delete augmentedView;
                    augmentedView = NULL;
                    recheckNext = false;
                    doSkip = true;
                }
                else if (item->qrCode->isDecoded())
                    recheckNext = false;
            }
            else
            {
                if (useGuess)
                    positionSelector->GetPreviousResult(item);

                LOGV(LOGTAG_QR,"Getting position");
                currentQRSize = debugUI->GetParameter("QRSize"); //Should be using value from server
                item->qrCode->QRCodeDimension = currentQRSize;
                qrLocator->transformPoints(item->qrCode,*(item->rotationMatrix),*(item->translationMatrix),useGuess);
                debugUI->SetTranslation(item->translationMatrix);
                debugUI->SetRotation(item->rotationMatrix);
            }
        }

        certaintyIndicator->EnableOutline(recheckNext);
        if (!doSkip)
        {
            //Evaluate the position
            float resultCertainty = positionSelector->UpdatePosition(engine,item);
            certaintyIndicator->SetCertainty(resultCertainty);

            if (resultCertainty > 0 && augmentedView != NULL)
            {
                augmentedView->SetFOV(debugUI->GetParameter("FOV"));
                augmentedView->SetTransformations(item->translationMatrix,item->rotationMatrix,item->gyroRotation);
            }
            if (augmentedView != NULL)
                augmentedView->Update(rgbImage,engine);
        }
    }
    else
    {
        char stateString[100];
        sprintf(stateString,"ContState=%d",(int)controllerState);
        debugUI->SetLabelValue("State",stateString);
        LOGW(LOGTAG_ARCONTROLLER,"Unexpected state: %s",stateString);
    }

    if (debugUI->currentDrawMode == DrawModes::BinaryImage)
    {
        if (showEntireBinary)
        {
            ImageProcessor::SimpleThreshold(grayImage,binaryImage);
            cvtColor(*binaryImage, *rgbImage, CV_GRAY2RGBA, 4);
        }
        else
        {
            LOGD(LOGTAG_ARCONTROLLER,"Binary debug draw");
            cvtColor(*binaryImage, *rgbImage, CV_GRAY2RGBA, 4);
            LOGD(LOGTAG_ARCONTROLLER,"Binary debug draw complete");
        }
    }

    if (drawingLevel == 1 || drawingLevel == 3)
    {
        if (item->qrCode != NULL)
        {
            item->qrCode->SetDrawingLevel(debugLevel);
            item->qrCode->Draw(rgbImage);
        }

        struct timespec draw_start, draw_end;
        SET_TIME(&draw_start);
        while (!debugVector.empty())
        {
            debugVector.back()->Draw(rgbImage);
            delete debugVector.back();
            debugVector.pop_back();
        }
        SET_TIME(&draw_end);
        LOG_TIME_PRECISE("DebugDrawing",draw_start,draw_end);
    }
    else //Still need to clean up debug vector!!!!
    {
        struct timespec draw_start, draw_end;
        SET_TIME(&draw_start);
        while (!debugVector.empty())
        {
            delete debugVector.back();
            debugVector.pop_back();
        }
        SET_TIME(&draw_end);
        LOG_TIME_PRECISE("DebugCleanup",draw_start,draw_end);
    }


    //Do final processing
    Draw(rgbImage);
}