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;
}
Exemple #2
0
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 );
    }
}
Exemple #3
0
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 );
    }
}