Пример #1
0
void PAGE_SwitchAssignInit(int page)
{
    (void)page;
    PAGE_SetActionCB(_action_cb);
    PAGE_SetModal(0);
    PAGE_RemoveAllObjects();
    refresh_switches();

    PAGE_ShowHeader(_tr("Press ENT to change"));
    GUI_CreateScrollable(&gui->scrollable, 0, ITEM_HEIGHT + 1, LCD_WIDTH, LCD_HEIGHT - ITEM_HEIGHT -1,
                     ITEM_SPACE, SWITCHFUNC_LAST, row_cb, getobj_cb, NULL, NULL);
    GUI_SetSelected(GUI_ShowScrollableRowOffset(&gui->scrollable, 0));
}
Пример #2
0
//responsible for displaying all the necessary information to the screen many times per second.
//runs at fairly low priority by design.
//output includes:
// * switch states
// * sensor triggering timestamps
// * current positions of up to 3 trains relative to parts of the track
// almost never blocks, just keeps spinning when nothing higher-priority needs to run
void display_server(void){

	TrainState trains[MAX_TRAINS];
	int train_count = 0;
	
	SensorState sensors[SENSOR_HISTORY_LEN];
	int sensor_start = 0;
	int sensor_len   = 0;
	SwitchState switches[18+4];

	int active = 0;

	int i;
	// initialze switches 1-18
	for(i=0; i < 18; i++){
		switches[i].number = i+1;
		switches[i].state  = '?';
	}

	// and switches 153-156
	for(i=0; i < 4; i++){
		switches[i+18].number = i+153;
		switches[i+18].state  = '?';
	}

	RegisterAs("displayserver");

	int clockserverTid = WhoIs("clockserver");
	if(clockserverTid < 0){
		bwprintf(COM2, "Display server got tid %d for clocckserver\n\r", clockserverTid);
		Halt();
	}

	Create(PRIORITY_MID, &display_notifier);
	Create(PRIORITY_MID, &display_sensor_notifier);

	int tid, len;
	MsgPrintf msg;
	int printf_col = 0;

	// now we can start drawing and receiving messages in a loop. 
	FOREVER {
		len = Receive(&tid, (char*) &msg, sizeof(msg));
		
		if(len > 0){
			// I never have a useful Reply, so Reply immediately
			Reply(tid, NULL, 0);

			switch(msg.type){
				case MSG_DISPLAY_REGISTER: ;
					// add a train with the provided number and speed 0

					// if this is the first train, initialize the display
					if(train_count == 0){
						clear_screen();

						initialize_scrolling();

						refresh_switches(switches);
						refresh_sensors(sensors, sensor_start, sensor_len);

						active = 1;
					}

					MsgRegister *msgReg = (MsgRegister*) &msg;
					trains[train_count].number = msgReg->train;
					trains[train_count].speed  = 0;
					trains[train_count].route_len = 0;
					train_count++;

					break;

				case MSG_DISPLAY_DEREGISTER: ;
					// look up the train in the trains array, and pack the ones after it
					// special case for the last train

					msgReg = (MsgRegister*) &msg;

					if(train_count == 1){
						//clear_screen();
						restore_scrolling();
						move_cursor(SCREEN_BOTTOM, 1);

						active = 0;
						train_count = 0;
					} else if(train_count == 0){
						// do nothing
					} else {
						int i = 0;
						for(i=0; i < train_count; i++){
							if(trains[i].number == msgReg->train){
								break;
							}
						}

						// if we find the train, shift the rest of the array down
						if(i < train_count){
							for(i=i+1; i < train_count; i++){
								//copy to the previous one
								trains[i-1] = trains[i];
							}

							train_count--;
						}
					}

					break;

				case MSG_DISPLAY_SPEED: ;
					// update the given train's speed
					MsgSpeed *msgSpeed = (MsgSpeed*) &msg;
					// flip through my trains for this number
					for(i = 0; i < train_count; i++){
						if(trains[i].number == msgSpeed->train){
							trains[i].speed = msgSpeed->speed;
							break;
						}
					}
					// will be redisplayed below

					break;

				case MSG_DISPLAY_SWITCH: ;
					MsgSwitch *msgSwitch = (MsgSwitch*) &msg;
					if(msgSwitch->number <= 18){
						switches[msgSwitch->number-1].state = msgSwitch->state;
					} else {
						switches[msgSwitch->number-153+18].state = msgSwitch->state;
					}

					if(active){
						refresh_switches(switches);
					}

					break;

				case MSG_DISPLAY_ROUTE: ;
					// somewhat more complicated. copy the route for the given train
					// first find the train index
					MsgRouteSegment *msgRoute = (MsgRouteSegment*) &msg;

					for(i = 0; i < train_count; i++){
						if(trains[i].number == msgRoute->train){
							trains[i].route_len = msgRoute->route_len;
							int j;
							for(j = 0; j < msgRoute->route_len; j++){
								trains[i].route[j] = msgRoute->route[j];
							}
						}
					}

					break;

				case MSG_SENSOR_CLIENT: ; // message from the sensor server
					// work through the array from the sensor server, and update my list of sensors
					// remember that the sensors array starts at start and start gets decremented
					MsgSensorResponse *msgResp = (MsgSensorResponse*) &msg;
					int timestamp = Time(clockserverTid);
					for(i = 0; i < msgResp->length; i++){
						sensor_start--;
						if(sensor_start < 0) sensor_start = SENSOR_HISTORY_LEN-1;
						if(sensor_len < SENSOR_HISTORY_LEN) sensor_len++;

						getSensorName(msgResp->triggered[i], &(sensors[sensor_start]));
						sensors[sensor_start].time = timestamp;
					}

					if(active && msgResp->length > 0){
						refresh_sensors(sensors, sensor_start, sensor_len);
					}

					break;

				case MSG_DISPLAY_PRINTF: ;
					move_cursor(SCREEN_BOTTOM, printf_col);

					switch(msg.argc){
						case 0: aprintf(COM2, msg.format); break;
						case 1: aprintf(COM2, msg.format, msg.argv[0]); break;
						case 2: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1]); break;
						case 3: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1], msg.argv[2]); break;
						case 4: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1], msg.argv[2], msg.argv[3]); break;
						case 5: aprintf(COM2, msg.format, msg.argv[0], msg.argv[1], msg.argv[2], msg.argv[3], msg.argv[4]); break;
						default: aprintf(COM2, "Bad argc: %d\n\r", msg.argc); break;
					}

					int len = strlen(msg.format);
					if(msg.format[len-1] == '\n' || msg.format[len-1] == '\r'){
						printf_col = 0;
					} else {
						printf_col += len;
					}


					break;
				
				case MSG_TICK: ;
					// display the train position
					// very crude for now. also only handling one train
					if(active){
						int i;
						int base_row;
						for(i = 0; i < train_count; i++){
							base_row = TRAIN_TOP + TRAIN_SIZE*i;
							move_and_clear(base_row, TRAIN_LEFT);
							aprintf(COM2, "Train %2d: ", trains[i].number);

							move_and_clear(base_row+1, TRAIN_LEFT);
							aprintf(COM2, "Speed: %2d ", trains[i].speed);

							if(trains[i].route_len > 0){
								SensorState ss;
								Sensor *s = (Sensor*) (trains[i].route[0]);
								getSensorName(s->alignment == 'F' ? s->forward_num : s->backward_num, &ss);
								move_and_clear(base_row+2, TRAIN_LEFT);
								aprintf(COM2, "Current sensor:\t%c%2d ", ss.module, ss.number);

								s = (Sensor*) (trains[i].route[ trains[i].route_len-1 ]);
								getSensorName(s->alignment == 'F' ? s->forward_num : s->backward_num, &ss);
								move_and_clear(base_row+3, TRAIN_LEFT);
								aprintf(COM2, "Next sensor:\t%c%2d ", ss.module, ss.number);
							} else {
								move_and_clear(base_row+2, TRAIN_LEFT);
								aprintf(COM2, "No route supplied.");
							}
						}
					}

					break;

				default: ;
					aprintf(COM2, "Display server: bogus type %d\n\r", msg.type);

			}

		}


	}


}