All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jsoar.debugger.ProductionTableModel Maven / Gradle / Ivy

/*
 * Copyright (c) 2008  Dave Ray 
 *
 * Created on Oct 28, 2008
 */
package org.jsoar.debugger;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.swing.SwingUtilities;
import javax.swing.table.AbstractTableModel;

import org.jsoar.kernel.Production;
import org.jsoar.kernel.ProductionType;
import org.jsoar.kernel.events.ProductionAddedEvent;
import org.jsoar.kernel.events.ProductionExcisedEvent;
import org.jsoar.runtime.ThreadedAgent;
import org.jsoar.util.events.SoarEvent;
import org.jsoar.util.events.SoarEventListener;
import org.jsoar.util.events.SoarEventManager;

/**
 * @author ray
 */
public class ProductionTableModel extends AbstractTableModel
{
    private static final long serialVersionUID = -6372714301859379317L;
    
    private final ThreadedAgent agent;
    private final Listener listener = new Listener();
    private final List productions = Collections.synchronizedList(new ArrayList());
    
    /**
     * @param agent
     */
    public ProductionTableModel(ThreadedAgent agent)
    {
        this.agent = agent;
    }
    
    public void initialize()
    {
        final SoarEventManager eventManager = this.agent.getEvents();
        eventManager.addListener(ProductionAddedEvent.class, listener);
        eventManager.addListener(ProductionExcisedEvent.class, listener);
        
        // TODO does this need to block for any reason?
        this.agent.execute(() ->
        {
            synchronized(productions)
            {
                for(ProductionType pt : ProductionType.values())
                {
                    // RPM: in general, justifications can come and go rapidly, so we're not going to try to show them in the debugger
                    //      we will also ignore them below where new rules are added/removed
                    //      in at least one project, this makes a significant performance/memory difference
                    if(pt == ProductionType.JUSTIFICATION)
                    {
                        continue;
                    }
                    productions.addAll(agent.getProductions().getProductions(pt));
                }
            }
        });
    }
    
    /**
     * Look up a production by name. This method may be safely called from any thread.
     * 
     * @param name the name of the production to find
     * @return the production, or {@code null} if not found
     */
    public Production getProduction(String name)
    {
        synchronized(productions)
        {
            for(Production p : productions)
            {
                if(name.equals(p.getName().toString()))
                {
                    return p;
                }
            }
            return null;
        }
    }
    
    /**
     * @return The list of productions in the model.
     */
    public List getProductions()
    {
        return productions;
    }

    /* (non-Javadoc)
     * @see javax.swing.table.AbstractTableModel#getColumnClass(int)
     */
    @Override
    public Class getColumnClass(int c)
    {
        switch(c)
        {
        case 0: return Production.class;
        case 1: return Long.class;
        case 2: return String.class;
        }
        return super.getColumnClass(c);
    }

    /* (non-Javadoc)
     * @see javax.swing.table.AbstractTableModel#getColumnName(int)
     */
    @Override
    public String getColumnName(int c)
    {
        switch(c)
        {
        case 0: return "Name";
        case 1: return "FC";
        case 2: return "Type";
        }
        return super.getColumnName(c);
    }

    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getColumnCount()
     */
    @Override
    public int getColumnCount()
    {
        return 3;
    }

    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getRowCount()
     */
    @Override
    public int getRowCount()
    {
        return productions.size();
    }

    /* (non-Javadoc)
     * @see javax.swing.table.TableModel#getValueAt(int, int)
     */
    @Override
    public Object getValueAt(int row, int column)
    {
        synchronized(productions)
        {
            Production p = productions.get(row);
            switch(column)
            {
            case 0: return p;
            case 1: return p.getFiringCount();
            case 2: return p.getType().getDisplayString();
            }
        }
        return null;
    }
    
    private void handleProductionAdded(Production p)
    {
        if(p.getType() == ProductionType.JUSTIFICATION)
        {
            return;
        }
        
        int row = 0;
        synchronized (productions)
        {
            row = productions.size();
            productions.add(p);
        }
        fireTableRowsInserted(row, row);
    }
    
    private void handleProductionExcised(Production p)
    {
        if(p.getType() == ProductionType.JUSTIFICATION)
        {
            return;
        }
        
        int row = 0;
        synchronized (productions)
        {
            row = productions.indexOf(p);
            if(row == -1)
            {
                return;
            }
            productions.remove(row);
        }
        fireTableRowsDeleted(row, row);
    }

    private class Listener implements SoarEventListener
    {
        @Override
        public void onEvent(final SoarEvent event)
        {
            Runnable runnable = () ->
            {
                if(event instanceof ProductionAddedEvent)
                {
                    handleProductionAdded(((ProductionAddedEvent) event).getProduction());
                }
                else
                {
                    handleProductionExcised(((ProductionExcisedEvent) event).getProduction());
                }
            };
            
            if(SwingUtilities.isEventDispatchThread())
            {
                runnable.run();
            }
            else
            {
                SwingUtilities.invokeLater(runnable);
            }
        }
        
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy