|  | /* | 
|  | * $Id: AbstractTableList.java 38 2012-01-04 22:44:15Z andre@naef.com $ | 
|  | * See LICENSE.txt for license terms. | 
|  | */ | 
|  |  | 
|  | package com.naef.jnlua.util; | 
|  |  | 
|  | import java.util.AbstractList; | 
|  | import java.util.RandomAccess; | 
|  |  | 
|  | import com.naef.jnlua.LuaState; | 
|  | import com.naef.jnlua.LuaValueProxy; | 
|  |  | 
|  | /** | 
|  | * Abstract list implementation backed by a Lua table. | 
|  | */ | 
|  | public abstract class AbstractTableList extends AbstractList<Object> implements | 
|  | RandomAccess, LuaValueProxy { | 
|  | // -- Construction | 
|  | /** | 
|  | * Creates a new instance. | 
|  | */ | 
|  | public AbstractTableList() { | 
|  | } | 
|  |  | 
|  | // -- List methods | 
|  | @Override | 
|  | public void add(int index, Object element) { | 
|  | LuaState luaState = getLuaState(); | 
|  | synchronized (luaState) { | 
|  | int size = size(); | 
|  | if (index < 0 || index > size) { | 
|  | throw new IndexOutOfBoundsException("index: " + index | 
|  | + ", size: " + size); | 
|  | } | 
|  | pushValue(); | 
|  | luaState.tableMove(-1, index + 1, index + 2, size - index); | 
|  | luaState.pushJavaObject(element); | 
|  | luaState.rawSet(-2, index + 1); | 
|  | luaState.pop(1); | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Object get(int index) { | 
|  | LuaState luaState = getLuaState(); | 
|  | synchronized (luaState) { | 
|  | int size = size(); | 
|  | if (index < 0 || index >= size) { | 
|  | throw new IndexOutOfBoundsException("index: " + index | 
|  | + ", size: " + size); | 
|  | } | 
|  | pushValue(); | 
|  | luaState.rawGet(-1, index + 1); | 
|  | try { | 
|  | return luaState.toJavaObject(-1, Object.class); | 
|  | } finally { | 
|  | luaState.pop(2); | 
|  | } | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Object remove(int index) { | 
|  | LuaState luaState = getLuaState(); | 
|  | synchronized (luaState) { | 
|  | int size = size(); | 
|  | if (index < 0 || index >= size) { | 
|  | throw new IndexOutOfBoundsException("index: " + index | 
|  | + ", size: " + size); | 
|  | } | 
|  | Object oldValue = get(index); | 
|  | pushValue(); | 
|  | luaState.tableMove(-1, index + 2, index + 1, size - index - 1); | 
|  | luaState.pushNil(); | 
|  | luaState.rawSet(-2, size); | 
|  | luaState.pop(1); | 
|  | return oldValue; | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public Object set(int index, Object element) { | 
|  | LuaState luaState = getLuaState(); | 
|  | synchronized (luaState) { | 
|  | int size = size(); | 
|  | if (index < 0 || index >= size) { | 
|  | throw new IndexOutOfBoundsException("index: " + index | 
|  | + ", size: " + size); | 
|  | } | 
|  | Object oldValue = get(index); | 
|  | pushValue(); | 
|  | luaState.pushJavaObject(element); | 
|  | luaState.rawSet(-2, index + 1); | 
|  | luaState.pop(1); | 
|  | return oldValue; | 
|  | } | 
|  | } | 
|  |  | 
|  | @Override | 
|  | public int size() { | 
|  | LuaState luaState = getLuaState(); | 
|  | synchronized (luaState) { | 
|  | pushValue(); | 
|  | try { | 
|  | return luaState.rawLen(-1); | 
|  | } finally { | 
|  | luaState.pop(1); | 
|  | } | 
|  | } | 
|  | } | 
|  | } |