Thread: EntityList/Entitys indices

Page 1 of 2 12 LastLast
Results 1 to 10 of 17
  1. #1 EntityList/Entitys indices 
    Registered Member
    Join Date
    Jun 2015
    Posts
    323
    Thanks given
    21
    Thanks received
    11
    Rep Power
    7
    How does the entity.index work? Can someone explain the concept and how it is utilised

    Here is matrix's entity list class:
    Code:
    package com.rs.game;
    
    import java.util.AbstractCollection;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class EntityList<T extends Entity> extends AbstractCollection<T> {
    	private static final int MIN_VALUE = 1;
    	public Object[] entities;
    	public Set<Integer> indicies = new HashSet<Integer>();
    	public int curIndex = MIN_VALUE;
    	public int capacity;
    	private final Object lock = new Object();
    
    	public EntityList(int capacity) {
    		entities = new Object[capacity];
    		this.capacity = capacity;
    	}
    
    	@Override
    	public boolean add(T entity) {
    		synchronized (lock) {
    			add(entity, curIndex);
    			return true;
    		}
    	}
    
    	public void remove(T entity) {
    		synchronized (lock) {
    			entities[entity.getIndex()] = null;
    			indicies.remove(entity.getIndex());
    			decreaseIndex();
    		}
    	}
    
    	@SuppressWarnings("unchecked")
    	public T remove(int index) {
    		synchronized (lock) {
    			Object temp = entities[index];
    			entities[index] = null;
    			indicies.remove(index);
    			decreaseIndex();
    			return (T) temp;
    		}
    	}
    
    	@SuppressWarnings("unchecked")
    	public T get(int index) {
    		synchronized (lock) {
    			if (index >= entities.length)
    				return null;
    			return (T) entities[index];
    		}
    	}
    
    	public void add(T entity, int index) {
    		if (entities[curIndex] != null) {
    			increaseIndex();
    			add(entity, curIndex);
    		} else {
    			entities[curIndex] = entity;
    			entity.setIndex(index);
    			indicies.add(curIndex);
    			increaseIndex();
    		}
    	}
    
    	@Override
    	public Iterator<T> iterator() {
    		synchronized (lock) {
    			return new EntityListIterator<T>(entities, indicies, this);
    		}
    	}
    
    	public void increaseIndex() {
    		curIndex++;
    		if (curIndex >= capacity) {
    			curIndex = MIN_VALUE;
    		}
    	}
    
    	public void decreaseIndex() {
    		curIndex--;
    		if (curIndex <= capacity)
    			curIndex = MIN_VALUE;
    	}
    
    	public boolean contains(T entity) {
    		return indexOf(entity) > -1;
    	}
    
    	public int indexOf(T entity) {
    		for (int index : indicies) {
    			if (entities[index].equals(entity)) {
    				return index;
    			}
    		}
    		return -1;
    	}
    
    	@Override
    	public int size() {
    		return indicies.size();
    	}
    }
    How come a whole class is created to handle something that can essentially be handled like this?
    Code:
    public static int CURRENT_PLAYER_INDEX = 0;
    public static int CURRENT_NPC_INDEX = 0;
    
    add(Object o){ 
      if (o instanceof Player){
        o.setIndex(CURRENT_PLAYER_INDEX++);
      }
    }
    Am I missing something?


    Also can someone explain the usage of the synchronized(lock)?
    Reply With Quote  
     

  2. #2  
    Registered Member
    hc747's Avatar
    Join Date
    Dec 2013
    Age
    26
    Posts
    1,474
    Thanks given
    3,312
    Thanks received
    691
    Rep Power
    1098
    Quote Originally Posted by new2rsps View Post
    How does the entity.index work? Can someone explain the concept and how it is utilised

    Here is matrix's entity list class:
    Code:
    package com.rs.game;
    
    import java.util.AbstractCollection;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class EntityList<T extends Entity> extends AbstractCollection<T> {
        private static final int MIN_VALUE = 1;
        public Object[] entities;
        public Set<Integer> indicies = new HashSet<Integer>();
        public int curIndex = MIN_VALUE;
        public int capacity;
        private final Object lock = new Object();
    
        public EntityList(int capacity) {
            entities = new Object[capacity];
            this.capacity = capacity;
        }
    
        @Override
        public boolean add(T entity) {
            synchronized (lock) {
                add(entity, curIndex);
                return true;
            }
        }
    
        public void remove(T entity) {
            synchronized (lock) {
                entities[entity.getIndex()] = null;
                indicies.remove(entity.getIndex());
                decreaseIndex();
            }
        }
    
        @SuppressWarnings("unchecked")
        public T remove(int index) {
            synchronized (lock) {
                Object temp = entities[index];
                entities[index] = null;
                indicies.remove(index);
                decreaseIndex();
                return (T) temp;
            }
        }
    
        @SuppressWarnings("unchecked")
        public T get(int index) {
            synchronized (lock) {
                if (index >= entities.length)
                    return null;
                return (T) entities[index];
            }
        }
    
        public void add(T entity, int index) {
            if (entities[curIndex] != null) {
                increaseIndex();
                add(entity, curIndex);
            } else {
                entities[curIndex] = entity;
                entity.setIndex(index);
                indicies.add(curIndex);
                increaseIndex();
            }
        }
    
        @Override
        public Iterator<T> iterator() {
            synchronized (lock) {
                return new EntityListIterator<T>(entities, indicies, this);
            }
        }
    
        public void increaseIndex() {
            curIndex++;
            if (curIndex >= capacity) {
                curIndex = MIN_VALUE;
            }
        }
    
        public void decreaseIndex() {
            curIndex--;
            if (curIndex <= capacity)
                curIndex = MIN_VALUE;
        }
    
        public boolean contains(T entity) {
            return indexOf(entity) > -1;
        }
    
        public int indexOf(T entity) {
            for (int index : indicies) {
                if (entities[index].equals(entity)) {
                    return index;
                }
            }
            return -1;
        }
    
        @Override
        public int size() {
            return indicies.size();
        }
    }
    How come a whole class is created to handle something that can essentially be handled like this?
    Code:
    public static int CURRENT_PLAYER_INDEX = 0;
    public static int CURRENT_NPC_INDEX = 0;
    
    add(Object o){ 
      if (o instanceof Player){
        o.setIndex(CURRENT_PLAYER_INDEX++);
      }
    }
    Am I missing something?


    Also can someone explain the usage of the synchronized(lock)?
    Not that it's a good example of any of the concepts that you're asking to have explained, but, you're using an object oriented language, so use object oriented concepts. Whilst you "could" do it as you've described below, any modifications you with to make later may require you to drastically change your code or reimplement it, and it can become quite complex to maintain - it's not extensible. The usage of synchronisation is an attempt at thread safety through pessimistic locking, i.e., ensuring that modifications are only made from one thread at any given time - however, it's implemented poorly and inefficiently. Could and should be written in a much better way.
    Reply With Quote  
     

  3. #3  
    Registered Member
    Join Date
    Jun 2015
    Posts
    323
    Thanks given
    21
    Thanks received
    11
    Rep Power
    7
    Quote Originally Posted by hc747 View Post
    Not that it's a good example of any of the concepts that you're asking to have explained, but, you're using an object oriented language, so use object oriented concepts. Whilst you "could" do it as you've described below, any modifications you with to make later may require you to drastically change your code or reimplement it, and it can become quite complex to maintain - it's not extensible. The usage of synchronisation is an attempt at thread safety through pessimistic locking, i.e., ensuring that modifications are only made from one thread at any given time - however, it's implemented poorly and inefficiently. Could and should be written in a much better way.
    Can we have an example of how you would/have done it
    Reply With Quote  
     

  4. #4  
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,788
    Thanks given
    706
    Thanks received
    702
    Rep Power
    570
    The client has arrays based on the entity lists. These arrays have a limit to how many entities they can hold. Using your method, after a certain amount of Player/NPCs have been added to the game, it would start sending invalid entity index (out of bound) which would most likely result in crashing every client receiving these indexes.
    Project thread
    Reply With Quote  
     

  5. #5  
    Registered Member
    Join Date
    Jun 2015
    Posts
    323
    Thanks given
    21
    Thanks received
    11
    Rep Power
    7
    Quote Originally Posted by clem585 View Post
    The client has arrays based on the entity lists. These arrays have a limit to how many entities they can hold. Using your method, after a certain amount of Player/NPCs have been added to the game, it would start sending invalid entity index (out of bound) which would most likely result in crashing every client receiving these indexes.
    Yes but you only need one check to fix that. I'm wondering why a whole class is devoted to essentially one threadsafe list?
    Reply With Quote  
     

  6. #6  
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,788
    Thanks given
    706
    Thanks received
    702
    Rep Power
    570
    Quote Originally Posted by new2rsps View Post
    Yes but you only need one check to fix that. I'm wondering why a whole class is devoted to essentially one threadsafe list?
    Matrix doesn't queue all packets so I'm guessing it's because the entity list could be acessed by the main world thread while a packet is being processed. Plus, it's easier to iterate over this entity list. With the array you have to check every index, but with this entity list you can iterate over the specific keys.
    Project thread
    Reply With Quote  
     

  7. #7  
    Registered Member

    Join Date
    Dec 2009
    Posts
    774
    Thanks given
    367
    Thanks received
    455
    Rep Power
    927
    This has to do with entity updating. The class is created because all the methods of the list implementation must use 'synchronized' to avoid problems in player and npc updating.
    link removed
    Reply With Quote  
     

  8. #8  
    Registered Member
    Join Date
    Jun 2015
    Posts
    323
    Thanks given
    21
    Thanks received
    11
    Rep Power
    7
    Quote Originally Posted by Admiral Slee View Post
    This has to do with entity updating. The class created because all the methods of the list implementation must use 'synchronized' to avoid problems in player and npc updating.
    But updating is read-only right?
    Reply With Quote  
     

  9. #9  
    Registered Member

    Join Date
    Dec 2009
    Posts
    774
    Thanks given
    367
    Thanks received
    455
    Rep Power
    927
    Quote Originally Posted by new2rsps View Post
    But updating is read-only right?
    Yes.
    link removed
    Reply With Quote  
     

  10. #10  
    Contributor

    clem585's Avatar
    Join Date
    Sep 2013
    Posts
    3,788
    Thanks given
    706
    Thanks received
    702
    Rep Power
    570
    Quote Originally Posted by new2rsps View Post
    But updating is read-only right?
    What do you mean by "updating"? Technically, if a logout isn't queued properly it could edit this list during the "updating" by removing a player.
    Project thread
    Reply With Quote  
     

Page 1 of 2 12 LastLast

Thread Information
Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)


User Tag List

Similar Threads

  1. Dophert's entity based combat system
    By WH:II:DOW in forum Tutorials
    Replies: 22
    Last Post: 01-11-2009, 12:17 AM
  2. [508] reset local entity animations
    By veer in forum RS 503+ Client & Server
    Replies: 3
    Last Post: 01-03-2009, 10:35 PM
  3. D-level indicator fullscreen [508 HD]
    By mige5 in forum Show-off
    Replies: 5
    Last Post: 11-26-2008, 10:04 PM
  4. working d-level indicator [fixed] [508]
    By mige5 in forum Tutorials
    Replies: 5
    Last Post: 09-30-2008, 07:16 PM
  5. server status indicator for your website
    By fabjan in forum Tutorials
    Replies: 12
    Last Post: 07-11-2008, 12:47 AM
Posting Permissions
  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •