on master help sign in
improve performance of the rouge game
d05afa1Corey O'Connor
src/Graphics/Vty/Image.hs+5−4
@@ -54,6 +54,7 @@ import Data.Monoid
54import qualified Data.Text as T
54import qualified Data.Text as T
55import qualified Data.Text.Encoding as T
55import qualified Data.Text.Encoding as T
56import qualified Data.Text.Lazy as TL
56import qualified Data.Text.Lazy as TL
57+import qualified Data.Text.Lazy.Builder as TL
57import qualified Data.Text.Lazy.Encoding as TL
58import qualified Data.Text.Lazy.Encoding as TL
58import Data.Word
59import Data.Word
59
60
@@ -63,7 +64,7 @@ infixr 4 <->
63-- | Append in the Monoid instance is equivalent to <->.
64-- | Append in the Monoid instance is equivalent to <->.
64instance Monoid Image where
65instance Monoid Image where
65 mempty = EmptyImage
66 mempty = EmptyImage
66− mappend = (<->)
67+ mappend = vert_join
67
68
68-- | combines two images side by side
69-- | combines two images side by side
69--
70--
@@ -150,11 +151,11 @@ background_fill w h
150
151
151-- | Compose any number of images horizontally.
152-- | Compose any number of images horizontally.
152horiz_cat :: [Image] -> Image
153horiz_cat :: [Image] -> Image
153−horiz_cat = foldr (<|>) EmptyImage
154+horiz_cat = foldr horiz_join EmptyImage
154
155
155-- | Compose any number of images vertically.
156-- | Compose any number of images vertically.
156vert_cat :: [Image] -> Image
157vert_cat :: [Image] -> Image
157−vert_cat = foldr (<->) EmptyImage
158+vert_cat = foldr vert_join EmptyImage
158
159
159-- | A Data.Text.Lazy value
160-- | A Data.Text.Lazy value
160text :: Attr -> TL.Text -> Image
161text :: Attr -> TL.Text -> Image
@@ -173,7 +174,7 @@ text' a txt
173-- | an image of a single character. This is a standard Haskell 31-bit character assumed to be in
174-- | an image of a single character. This is a standard Haskell 31-bit character assumed to be in
174-- the ISO-10646 encoding.
175-- the ISO-10646 encoding.
175char :: Attr -> Char -> Image
176char :: Attr -> Char -> Image
176−char a c =
177+char a c =
177 let display_width = safe_wcwidth c
178 let display_width = safe_wcwidth c
178 in HorizText a (TL.singleton c) display_width 1
179 in HorizText a (TL.singleton c) display_width 1
179
180
src/Graphics/Vty/Image/Internal.hs+2
@@ -13,6 +13,8 @@ import qualified Data.Text.Lazy as TL
13-- TODO(corey): hm. there is an explicit equation for each type which goes to a lazy text. Each
13-- TODO(corey): hm. there is an explicit equation for each type which goes to a lazy text. Each
14-- application probably uses a single type. Perhaps parameterize the entire vty interface by the
14-- application probably uses a single type. Perhaps parameterize the entire vty interface by the
15-- input text type?
15-- input text type?
16+-- TODO: Try using a builder instead of a TL.Text instance directly. That might improve performance
17+-- for the usual case of appending a bunch of characters with the same attribute together.
16type DisplayText = TL.Text
18type DisplayText = TL.Text
17
19
18-- TODO: store a skip list in HorizText(?)
20-- TODO: store a skip list in HorizText(?)
test/Rouge.hs+19−10
@@ -29,6 +29,9 @@ data Level = Level
29 { start :: (Int, Int)
29 { start :: (Int, Int)
30 , end :: (Int, Int)
30 , end :: (Int, Int)
31 , geo :: Array (Int, Int) LevelPiece
31 , geo :: Array (Int, Int) LevelPiece
32+ -- building the geo image is expensive. Cache it. Though VTY should go through greater lengths
33+ -- to avoid the need to cache images.
34+ , geo_image :: Image
32 }
35 }
33 deriving (Show,Eq)
36 deriving (Show,Eq)
34
37
@@ -47,8 +50,8 @@ main = do
47 shutdown vty
50 shutdown vty
48
51
49mkLevel _difficulty = do
52mkLevel _difficulty = do
50− level_width <- randomRIO (40,80)
53+ level_width <- randomRIO (200,300)
51− level_height <- randomRIO (40,80)
54+ level_height <- randomRIO (200,300)
52 start <- (,) <$> randomRIO (2, level_width-3) <*> randomRIO (2, level_height-3)
55 start <- (,) <$> randomRIO (2, level_width-3) <*> randomRIO (2, level_height-3)
53 end <- (,) <$> randomRIO (2, level_width-3) <*> randomRIO (2, level_height-3)
56 end <- (,) <$> randomRIO (2, level_width-3) <*> randomRIO (2, level_height-3)
54 -- first the base geography: all rocks
57 -- first the base geography: all rocks
@@ -56,7 +59,7 @@ mkLevel _difficulty = do
56 [((x,y),Rock) | x <- [0..level_width-1], y <- [0..level_height-1]]
59 [((x,y),Rock) | x <- [0..level_width-1], y <- [0..level_height-1]]
57 -- next the empty spaces that make the rooms
60 -- next the empty spaces that make the rooms
58 geo <- add_room start base_geo level_width level_height
61 geo <- add_room start base_geo level_width level_height
59− return $ Level start end geo
62+ return $ Level start end geo (build_geo_image geo)
60
63
61add_room (center_x, center_y) geo level_width level_height = do
64add_room (center_x, center_y) geo level_width level_height = do
62 size <- randomRIO (5,15)
65 size <- randomRIO (5,15)
@@ -122,10 +125,16 @@ world = do
122 the_dude <- gets dude
125 the_dude <- gets dude
123 the_level <- gets level
126 the_level <- gets level
124 let dude_image = translate (dude_x the_dude) (dude_y the_dude) (char pieceA '@')
127 let dude_image = translate (dude_x the_dude) (dude_y the_dude) (char pieceA '@')
128+ return [dude_image, geo_image the_level]
129+
130+build_geo_image geo =
125− (geo_width, geo_height) = snd $ bounds (geo the_level)
131+ let (geo_width, geo_height) = snd $ bounds geo
132+ -- seems like a the repeated index operation should be removable. This is not performing random
133+ -- access but (presumably) access in order of index.
126− geo_image = vert_cat [ geo_row | y <- [0..geo_height-1],
134+ in vert_cat [ geo_row
135+ | y <- [0..geo_height-1]
127− let geo_row = horiz_cat [ i | x <- [0..geo_width-1],
136+ , let geo_row = horiz_cat [ i
137+ | x <- [0..geo_width-1]
128− let i = image_for_geo (geo the_level ! (x,y))
138+ , let i = image_for_geo (geo ! (x,y))
129− ]
130− ]
139+ ]
131− return [dude_image, geo_image]
140+ ]