Some suggections

This is where you talk about the NXJ software itself, installation issues, and programming talk.

Moderators: 99jonathan, roger, imaqine

Some suggections

Postby vladra » Sat Nov 24, 2007 7:06 am

1 TextMenu

It isn't possible to select item. Sometimes it is necessary.
For example see http://lejos.sourceforge.net/forum/viewtopic.php?t=576. Instead of TextMenu I use SimpleMenu. This one allows to select item.
Last edited by vladra on Mon Nov 26, 2007 10:28 am, edited 1 time in total.
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby vladra » Sat Nov 24, 2007 7:08 am

2 Timer

Is there reason to create a thread for each timer instance?
I think no. The following class use single thread for all timer instances. This class almost entirely copy-pasted from swing.

Code: Select all
public class Timer
{
    private static final TimerQueue QUEUE = new TimerQueue();

    private final TimerListener _listener;
    private int _delay;

    private boolean _scheduled;
    private Timer _nextTimer;
    private int _expirationTime;

    public Timer(int delay, TimerListener listener)
    {
        _delay = delay;
        _listener = listener;
    }

    public int getDelay()
    {
        return _delay;
    }

    public void setDelay(int delay)
    {
        _delay = delay;
    }

    public void start()
    {
        QUEUE.addTimer(this, ((int) System.currentTimeMillis()) + _delay);
    }

    public void stop()
    {
        QUEUE.removeTimer(this);
    }

    public void fireEvent()
    {
        _listener.timedOut(this);
    }

    private static class TimerQueue extends Thread
    {
        private Timer _firstTimer = null;

        private TimerQueue()
        {
            setDaemon(true);
        }

        public synchronized void run()
        {
            int timeToWait;

            while(true)
            {
                timeToWait = getWaitTime();
                try { wait(timeToWait); }
                catch(InterruptedException ignored) {}
            }
        }

        public synchronized void addTimer(Timer timer, int expirationTime)
        {
            if( timer._scheduled )
                return;

            Timer previousTimer = null;
            Timer nextTimer = _firstTimer;

            while( nextTimer!=null )
            {
                if( nextTimer._expirationTime > expirationTime )
                    break;

                previousTimer = nextTimer;
                nextTimer = nextTimer._nextTimer;
            }

            if( previousTimer == null )
            {
                _firstTimer = timer;
            }
            else
            {
                previousTimer._nextTimer = timer;
            }

            timer._expirationTime = expirationTime;
            timer._nextTimer = nextTimer;
            timer._scheduled = true;
            notify();

            if( !isAlive() )
                start();
        }

        public synchronized void removeTimer(Timer timer)
        {
            if( !timer._scheduled )
                return;

            Timer previousTimer = null;
            Timer nextTimer = _firstTimer;

            while( nextTimer != null )
            {
                if( nextTimer == timer )
                    break;

                previousTimer = nextTimer;
                nextTimer = nextTimer._nextTimer;
            }

            timer._scheduled = false;
            if( nextTimer==null )
                return;     // not found

            if( previousTimer == null )
                _firstTimer = timer._nextTimer;
            else
                previousTimer._nextTimer = timer._nextTimer;

            timer._expirationTime = 0;
            timer._nextTimer = null;
        }

        private synchronized int getWaitTime()
        {
            Timer timer = _firstTimer;
            int currentTime;
            int timeToWait;

            if( timer==null )
                return 0;

            while(true)
            {
                currentTime = (int) System.currentTimeMillis();
                timeToWait = timer._expirationTime - currentTime;

                if( timeToWait<=0 )
                {
                    timer.fireEvent();

                    removeTimer(timer);
                    addTimer(timer, currentTime + timer.getDelay());

                    try { wait(1); }
                    catch(InterruptedException e) {}
                }
                else
                    break;
            }

            return timeToWait;
        }
    }
}

public interface TimerListener
{
    void timedOut(Timer timer);
}
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby vladra » Sat Nov 24, 2007 7:09 am

3 Motor

When motor is regulated it isn't possible to stop it before reach target distance (angle). For example:

Code: Select all
// thread one
_pilot.travel(200f);

// thread two
_pilot.stop();


but the vehicle is still running after stop. It is strange.
It will be right if travel function returns immediately after stop occurs. Maybe it is necessary to have a flag, that true when distance has been reach:

Code: Select all
if( _pilot.travel(200f) )
   // all right
else
   // travel has been interrupted
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby vladra » Sat Nov 24, 2007 7:40 am

about motor stop - it's my mistake. All work properly. Sorry.
But is there some way to determine reason of travel method completion?
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby lawrie » Sun Nov 25, 2007 11:47 pm

1 TextMenu

It isn't possible to select item. Sometimes it is necessary.


What do you mean by this? Selecting items from a menu is what TextMenu does.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Postby vladra » Mon Nov 26, 2007 7:35 am

The menu cursor points to the first item when menu is displayed.
But I want to select some item in my code before menu displaying.

There are two alternatives:

1. signature of TextMenu class isn't changed

Code: Select all
public int select()
{
   return select(0);
}

public int select(int selectedIndex)
{
   _selectedIndex = selectedIndex;
   ...
}


2. It looks like my SimpleMenu class (see viewtopic.php?t=576)

Code: Select all
public int getSelectedIndex()
{
   return _selectedIndex;
}

public void setSelectedIndex(int selectedIndex)
{
   // TODO: validate selectedIndex range
   _selectedIndex = selectedIndex;
   
}

/**
 * @return false if user press Escape button
 */
public boolean select()
{
   ...
}
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby lawrie » Mon Nov 26, 2007 11:27 pm

Your option 1 for Textmenu is a simple change. Do you want me to add this to the next release? I don't want to change the interface to TextMenu unless there is a good reason to as it is is used by StartUpText, the View sample etc.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Postby lawrie » Mon Nov 26, 2007 11:43 pm

On your Timer class suggestion: The Timer class was written years ago for the RCX version of leJOS, and has not been changed recently. A thread per timer does not seem a problem to me as I guess that most programs will only use one timer. There is more code in your class than the existing Timer class. Do you think it is a significant improvement?

Do you want to be added as a leJOS developer? You seem to be investigating and improving quite a few leJOS classes.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Postby vladra » Tue Nov 27, 2007 5:29 am

lawrie wrote:Your option 1 for Textmenu is a simple change. Do you want me to add this to the next release?


Why not? This modification improves usability of TextMenu. If I would have a select(int selectedIndex) method then I won't need to create a SimpleMenu class.
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby vladra » Tue Nov 27, 2007 5:58 am

lawrie wrote:A thread per timer does not seem a problem to me as I guess that most programs will only use one timer.


And each motor also uses a timer.


lawrie wrote:There is more code in your class than the existing Timer class. Do you think it is a significant improvement?


I don't know. How many resources (memory, processor time, etc) are required for one thread? I will investigate virtual machine code...


lawrie wrote:Do you want to be added as a leJOS developer?


Maybe. But what developer have to do? I haven't enought time to produce a lot of code.
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia

Postby lawrie » Thu Nov 29, 2007 5:31 pm

I have applied your TextMenu change to the development version in Subversion.

I forgot that the Motor class uses Timer. Your Timer change probably is worthwhile, but I have not applied it yet as I will need time to test that it works will all existing leJOS classes and samples.

Being a developer does not commit you to doing anything - it just means that you can apply changes to the development version of leJOS in Subversion. The main responsibility of developers is to agree any developments they are going to do on leJOS developers mailing list, and test any changes they make to ensure that nothing gets broken.
lawrie
leJOS Team Member
 
Posts: 929
Joined: Mon Feb 05, 2007 1:27 pm

Postby vladra » Fri Nov 30, 2007 5:21 am

lawrie wrote:I have applied your TextMenu change to the development version in Subversion.


Thank you.

About Timer. Thread isn't so expensive as I expected. Let's stay it as is.
vladra
New User
 
Posts: 24
Joined: Fri Nov 16, 2007 6:18 pm
Location: Russia


Return to NXJ Software

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 2 guests

more stuff