bool TransitionHandler::moveTransition(QString type, int startTrack, int newTrack, int newTransitionTrack, GenTime oldIn, GenTime oldOut, GenTime newIn, GenTime newOut) { double fps = m_tractor->get_fps(); int new_in = (int)newIn.frames(fps); int new_out = (int)newOut.frames(fps) - 1; if (new_in >= new_out) return false; int old_in = (int)oldIn.frames(fps); int old_out = (int)oldOut.frames(fps) - 1; bool doRefresh = true; // Check if clip is visible in monitor int position = mlt_producer_position(m_tractor->get_producer()); int diff = old_out - position; if (diff < 0 || diff > old_out - old_in) doRefresh = false; if (doRefresh) { diff = new_out - position; if (diff < 0 || diff > new_out - new_in) doRefresh = false; } QScopedPointer<Mlt::Field> field(m_tractor->field()); field->lock(); mlt_service nextservice = mlt_service_get_producer(field->get_service()); mlt_properties properties = MLT_SERVICE_PROPERTIES(nextservice); QString resource = mlt_properties_get(properties, "mlt_service"); int old_pos = (int)(old_in + old_out) / 2; bool found = false; mlt_service_type mlt_type = mlt_service_identify( nextservice ); while (mlt_type == transition_type) { Mlt::Transition transition((mlt_transition) nextservice); nextservice = mlt_service_producer(nextservice); int currentTrack = transition.get_b_track(); int currentIn = (int) transition.get_in(); int currentOut = (int) transition.get_out(); if (resource == type && startTrack == currentTrack && currentIn <= old_pos && currentOut >= old_pos) { found = true; if (newTrack - startTrack != 0) { Mlt::Properties trans_props(transition.get_properties()); Mlt::Transition new_transition(*m_tractor->profile(), transition.get("mlt_service")); Mlt::Properties new_trans_props(new_transition.get_properties()); // We cannot use MLT's property inherit because it also clones internal values like _unique_id which messes up the playlist cloneProperties(new_trans_props, trans_props); new_transition.set_in_and_out(new_in, new_out); field->disconnect_service(transition); plantTransition(field.data(), new_transition, newTransitionTrack, newTrack); } else transition.set_in_and_out(new_in, new_out); break; } if (nextservice == NULL) break; properties = MLT_SERVICE_PROPERTIES(nextservice); mlt_type = mlt_service_identify( nextservice ); resource = mlt_properties_get(properties, "mlt_service"); } field->unlock(); if (doRefresh) refresh(); //if (m_isBlocked == 0) m_mltConsumer->set("refresh", 1); return found; }
void install_complete_transitions( int i, struct itemset * current_itemset, struct parser_generator * self ) { struct list * table = self->TABLE; struct list * complete_items = current_itemset->complete; char * lhs; struct item * complete_item; struct list * complete_production; int j; int k; struct hash * table_row = listlookup( self->TABLE, i ); for ( j = 0; j < complete_items->next_index; j++ ) { complete_item = listlookup( complete_items, j ); int prod_num = complete_item->prod_num; complete_production = GRAMMAR[prod_num].production; lhs = listlookup( complete_production, 0 ); // Loop all terminals which can follow this lhs. struct list * key_list = new_list(); list_keys_in_hash( hashlookup( FOLLOW, lhs )->data, key_list, "" ); for ( k = 0; k < key_list->next_index; k++ ) { struct list * trans_list; char * follower = listlookup( key_list, k ); // Add a reduce transition on each follower token. struct hash * looked_up = hashlookup( table_row, follower ); if ( ! looked_up ) { trans_list = new_list(); add_to_hash( table_row, follower, (void *) trans_list ); } else { trans_list = looked_up->data; } struct transition * reduce_transition = new_transition(); reduce_transition->action = "reduce"; reduce_transition->arg = prod_num; append_to_list( trans_list, reduce_transition ); } destroy_key_list( key_list ); } }
void install_incomplete_transition( int i, char * symbol, int destination, struct parser_generator * self ) { struct hash * table_row = listlookup( self->TABLE, i ); struct hash * goto_row = listlookup( self->GOTO, i ); struct list * trans_list; struct hash * looked_up; if ( ( (int *) hashlookup( IS_TERMINAL, symbol )->data ) == &TRUE ) { // Transitions on terminals go in TABLE. looked_up = hashlookup( table_row, symbol ); if ( ! looked_up ) { trans_list = new_list(); add_to_hash( table_row, symbol, (void *) trans_list ); } else { trans_list = looked_up->data; } struct transition * terminal_transition = new_transition(); terminal_transition->action = "shift"; terminal_transition->arg = destination; if ( ! strcmp( symbol, "end" ) ) { terminal_transition->action = "accept"; } append_to_list( trans_list, (void *) terminal_transition ); } else { // Transitions on nonterminals go in GOTO. looked_up = hashlookup( goto_row, symbol ); if ( ! looked_up ) { trans_list = new_list(); add_to_hash( goto_row, symbol, (void *) trans_list ); } else { trans_list = looked_up->data; } append_to_list( trans_list, (void *) (long int) destination ); } }