/* * Process a program configuration message */ boolean ProgramManager::handle_msg(msg_program_t *msg) { DEBUG4_VALUE("handle_msg: program=", msg->type); DEBUG4_VALUELN(" output=", msg->hdr.output); /* Find the program to be executed */ hmtl_program_t *program = lookup_function(msg->type); if (program == NULL) { DEBUG1_VALUELN("handle_msg: invalid type: ", msg->type); return false; } /* Setup the tracker */ if (msg->hdr.output > num_outputs) { DEBUG1_VALUELN("handle_msg: invalid output: ", msg->hdr.output); return false; } if (outputs[msg->hdr.output] == NULL) { DEBUG1_VALUELN("handle_msg: NULL output: ", msg->hdr.output); return false; } program_tracker_t *tracker = trackers[msg->hdr.output]; if (program->type == HMTL_PROGRAM_NONE) { /* This is a message to clear the existing program so free the tracker */ free_tracker(msg->hdr.output); return true; } if (tracker != NULL) { DEBUG5_PRINTLN("handle_msg: reusing old tracker"); if (tracker->state) { DEBUG5_PRINTLN("handle_msg: deleting old state"); free(tracker->state); } } else { tracker = (program_tracker_t *)malloc(sizeof (program_tracker_t)); trackers[msg->hdr.output] = tracker; } tracker->program = program; tracker->flags = 0x0; tracker->program->setup(msg, tracker); return true; }
/* * Execute all configured program functions */ boolean ProgramManager::run() { boolean updated = false; for (byte i = 0; i < num_outputs; i++) { program_tracker_t *tracker = trackers[i]; if (tracker != NULL) { if (tracker->flags & PROGRAM_TRACKER_DONE) { /* If this program has been set as done then free its tracker */ free_tracker(i); continue; } if (tracker->program->program(outputs[i], objects[i], tracker)) { updated = true; } } } return updated; }
/* * Process a program configuration message */ boolean ProgramManager::handle_msg(msg_program_t *msg) { DEBUG4_VALUE("handle_msg: program=", msg->type); DEBUG4_VALUELN(" output=", msg->hdr.output); /* Find the program to be executed */ byte program = lookup_function(msg->type); if (program == NO_PROGRAM) { DEBUG1_VALUELN("handle_msg: invalid type: ", msg->type); return false; } /* Setup the tracker */ int starting_output, stop_output; if (msg->hdr.output == HMTL_ALL_OUTPUTS) { /* This should be applied to all outputs that can handle the message type */ starting_output = 0; stop_output = num_outputs; } else if (msg->hdr.output > num_outputs) { DEBUG1_VALUELN("handle_msg: invalid output: ", msg->hdr.output); return false; } else if (outputs[msg->hdr.output] == NULL) { DEBUG1_VALUELN("handle_msg: NULL output: ", msg->hdr.output); return false; } else { /* Only apply to the specified output */ starting_output = msg->hdr.output; stop_output = starting_output + 1; } for (int output = starting_output; output < stop_output; output++) { if (outputs[output] == NULL) continue; if (msg->type == HMTL_PROGRAM_NONE) { /* This is a message to clear the existing program so free the tracker */ DEBUG3_VALUELN("handle_msg: clear ", output); free_tracker(output); continue; } program_tracker_t *tracker; if (functions[program].program == NULL) { /* * This is an initialization-only command, set tracker to null */ DEBUG4_PRINTLN("handle_msg: trackerless") tracker = NULL; } else { /* If there was an active program on this output then clear the tracker */ free_tracker(output); /* Setup a tracker for this program */ tracker = get_tracker(output); tracker->program_index = program; tracker->flags = 0x0; } if (tracker) { // Record the output and object in the tracker tracker->output = outputs[output]; tracker->object = objects[output]; } /* Attempt to setup the program */ boolean success = functions[program].setup(msg, tracker, outputs[output], objects[output], this); if (!success) { if (tracker) { DEBUG4_VALUELN("handle_msg: NA on ", output); free_tracker(output); } continue; } DEBUG4_VALUELN("handle_msg: setup on ", output); } return true; }