Slick Forums

Discuss the Slick 2D Library
It is currently Thu May 23, 2013 2:38 pm

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sun Dec 20, 2009 2:59 am 
Offline
Regular
User avatar

Joined: Tue Apr 03, 2007 9:27 pm
Posts: 100
Location: Canada
I'm using AngelCodeFont because I couldn't get UnicodeFont to work on my first few tries.

I'm getting weird behavior where I pass in a string and another string is printed. The following screen shot shows "region..." being printed in the incorrect location and map name be completely wrong.
Image

I investigated a bit in the source. I think I found the problem (I haven't tried it since I don't have the slick build configured on here):
Code:
DisplayList displayList = (DisplayList)displayLists.get(text+""+startIndex+""+endIndex);

The following line is very inefficient (using string cat to build a key) and has an unneeded risk of collision:
The key "(...)4011" can be refer to many different text output, even if it is improbable.

The following snippet is a simple solution that is very efficient for the frequent case of printing a string from start to finish and is more like to find an item in cache ( {"aheya",start=1,end=4} == {"hey",start=0,end=3}. Another solution is to create an object key and implement equals/hashcode correctly.
Code:
String key = text;
if( startIndex != 0 || endIndex != key.length() ) key = text.substring(...);
DisplayList displayList = (DisplayList)displayLists.get(key);


The real bug however happens when the cache is full. I don't understand how eldestDisplayListID/eldestDisplayList is being populated. Its getting invoked from an overwritten protected method so it might be worth while double checking it. Assuming it is correct the remove is done on eldestDisplayList.text which is not the correct key format (text+startIndex+endIndex):
Code:
            // Compile a new display list.
            displayList = new DisplayList();
            displayList.text = text;
            int displayListCount = displayLists.size();
            if (displayListCount < DISPLAY_LIST_CACHE_SIZE) {
               displayList.id = baseDisplayListID + displayListCount;
            } else {
               displayList.id = eldestDisplayListID;
               displayLists.remove(eldestDisplayList.text);
            }
            
            displayLists.put(text+""+startIndex+""+endIndex, displayList);

            GL.glNewList(displayList.id, SGL.GL_COMPILE_AND_EXECUTE);
            render(text, startIndex, endIndex);
            GL.glEndList();


So what I believe happens is the remove is incorrect so it believes the string is still in the cache when the id now belongs to a new string.


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 21, 2009 3:34 pm 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
Let me know if your solution works and apply the patch.

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Mon Dec 21, 2009 8:54 pm 
Offline
Regular
User avatar

Joined: Tue Apr 03, 2007 9:27 pm
Posts: 100
Location: Canada
I don't have write access. The following solution fixes my problem, I've just fixed the key to be consistent and remove unneeded string cat (startIndex is always 0 and endIndex is always length()-1, other the IF condition is false):

Code:
Index: src/org/newdawn/slick/AngelCodeFont.java
===================================================================
--- src/org/newdawn/slick/AngelCodeFont.java   (revision 1281)
+++ src/org/newdawn/slick/AngelCodeFont.java   (working copy)
@@ -345,7 +345,7 @@

      GL.glTranslatef(x, y, 0);
      if (displayListCaching && startIndex == 0 && endIndex == text.length() - 1) {
-         DisplayList displayList = (DisplayList)displayLists.get(text+""+startIndex+""+endIndex);
+         DisplayList displayList = (DisplayList)displayLists.get(text);
         if (displayList != null) {
            GL.glCallList(displayList.id);
         } else {
@@ -360,7 +360,7 @@
               displayLists.remove(eldestDisplayList.text);
            }
            
-            displayLists.put(text+""+startIndex+""+endIndex, displayList);
+            displayLists.put(text, displayList);

            GL.glNewList(displayList.id, SGL.GL_COMPILE_AND_EXECUTE);
            render(text, startIndex, endIndex);


I hadn't seen in my previous post that caching is only done if start/endIndex draws the whole string so this solution is much simpler.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jan 06, 2010 6:27 pm 
Offline

Joined: Wed Jan 06, 2010 4:32 pm
Posts: 3
Thank you for the patch ! It works :)


Top
 Profile  
 
 Post subject:
PostPosted: Sat Jan 09, 2010 12:18 am 
Offline
Regular
User avatar

Joined: Tue Apr 03, 2007 9:27 pm
Posts: 100
Location: Canada
Yea, it is the same issue, I haven't been watching these forums otherwise I would of told you.

The problem only occurs when you draw many different strings. In my case I draw word by word because I have color codes and smileys that can appear in the text so the problem occurs after only a minute.

I'm hoping the patch will be included in the next build.


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 03, 2010 9:05 pm 
Offline
Site Admin
User avatar

Joined: Thu Jan 01, 1970 12:00 am
Posts: 3143
Sorry for the delay guys, especially given the patch being provided. Real life worries.

In SVN

Kev


Top
 Profile  
 
 Post subject:
PostPosted: Sat Apr 03, 2010 9:19 pm 
Offline
Slick Zombie

Joined: Fri Jan 29, 2010 7:02 pm
Posts: 1172
BTW: you can always call substring - it has checks inside to return the string itself if start==0 and end==length()

_________________
TWL - The Themable Widget Library


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group