diff options
-rw-r--r-- | Spear.cabal | 28 | ||||
-rw-r--r-- | Spear.lkshw | 4 | ||||
-rw-r--r-- | Spear/IDStore.hs | 107 |
3 files changed, 123 insertions, 16 deletions
diff --git a/Spear.cabal b/Spear.cabal index ccbf846..c683c09 100644 --- a/Spear.cabal +++ b/Spear.cabal | |||
@@ -16,19 +16,19 @@ library | |||
16 | StateVar -any, base -any, bytestring -any, directory -any, | 16 | StateVar -any, base -any, bytestring -any, directory -any, |
17 | mtl -any, transformers -any, resource-simple -any, parsec >=3.1.3, | 17 | mtl -any, transformers -any, resource-simple -any, parsec >=3.1.3, |
18 | containers -any, vector -any, array -any | 18 | containers -any, vector -any, array -any |
19 | exposed-modules: Spear.Physics.Types Spear.Physics.World Spear.App | 19 | exposed-modules: Spear.IDStore Spear.Physics.Types |
20 | Spear.App.Application Spear.App.Input Spear.Assets.Image | 20 | Spear.Physics.World Spear.App Spear.App.Application Spear.App.Input |
21 | Spear.Assets.Model Spear.Collision Spear.Collision.AABB | 21 | Spear.Assets.Image Spear.Assets.Model Spear.Collision |
22 | Spear.Collision.Collision Spear.Collision.Collisioner | 22 | Spear.Collision.AABB Spear.Collision.Collision |
23 | Spear.Collision.Sphere Spear.Collision.Triangle | 23 | Spear.Collision.Collisioner Spear.Collision.Sphere |
24 | Spear.Collision.Types Spear.Game Spear.GLSL Spear.GLSL.Buffer | 24 | Spear.Collision.Triangle Spear.Collision.Types Spear.Game |
25 | Spear.GLSL.Error Spear.GLSL.Management Spear.GLSL.Texture | 25 | Spear.GLSL Spear.GLSL.Buffer Spear.GLSL.Error Spear.GLSL.Management |
26 | Spear.GLSL.Uniform Spear.GLSL.VAO Spear.Math.Camera | 26 | Spear.GLSL.Texture Spear.GLSL.Uniform Spear.GLSL.VAO |
27 | Spear.Math.Entity Spear.Math.Matrix3 Spear.Math.Matrix4 | 27 | Spear.Math.Camera Spear.Math.Entity Spear.Math.Matrix3 |
28 | Spear.Math.MatrixUtils Spear.Math.Octree Spear.Math.Plane | 28 | Spear.Math.Matrix4 Spear.Math.MatrixUtils Spear.Math.Octree |
29 | Spear.Math.Quaternion Spear.Math.Spatial Spear.Math.Vector3 | 29 | Spear.Math.Plane Spear.Math.Quaternion Spear.Math.Spatial |
30 | Spear.Math.Vector4 Spear.Physics Spear.Physics.Rigid | 30 | Spear.Math.Vector3 Spear.Math.Vector4 Spear.Physics |
31 | Spear.Render.AnimatedModel | 31 | Spear.Physics.Rigid Spear.Render.AnimatedModel |
32 | Spear.Render.Material Spear.Render.Model Spear.Render.Program | 32 | Spear.Render.Material Spear.Render.Model Spear.Render.Program |
33 | Spear.Render.Renderable Spear.Render.StaticModel | 33 | Spear.Render.Renderable Spear.Render.StaticModel |
34 | Spear.Render.Texture Spear.Scene.Graph Spear.Scene.Light | 34 | Spear.Render.Texture Spear.Scene.Graph Spear.Scene.Light |
@@ -56,4 +56,4 @@ library | |||
56 | Spear/Sys | 56 | Spear/Sys |
57 | hs-source-dirs: . | 57 | hs-source-dirs: . |
58 | ghc-options: -O2 -rtsopts | 58 | ghc-options: -O2 -rtsopts |
59 | 59 | \ No newline at end of file | |
diff --git a/Spear.lkshw b/Spear.lkshw index c76f434..ef77439 100644 --- a/Spear.lkshw +++ b/Spear.lkshw | |||
@@ -1,10 +1,10 @@ | |||
1 | Version of workspace file format: | 1 | Version of workspace file format: |
2 | 1 | 2 | 1 |
3 | Time of storage: | 3 | Time of storage: |
4 | "Tue Aug 7 23:05:20 CEST 2012" | 4 | "Wed Aug 8 12:06:13 CEST 2012" |
5 | Name of the workspace: | 5 | Name of the workspace: |
6 | "Spear" | 6 | "Spear" |
7 | File paths of contained packages: | 7 | File paths of contained packages: |
8 | ["demos/simple-scene/simple-scene.cabal","Spear.cabal"] | 8 | ["demos/simple-scene/simple-scene.cabal","Spear.cabal"] |
9 | Maybe file path of an active package: | 9 | Maybe file path of an active package: |
10 | Just "demos/simple-scene/simple-scene.cabal" \ No newline at end of file | 10 | Just "Spear.cabal" \ No newline at end of file |
diff --git a/Spear/IDStore.hs b/Spear/IDStore.hs new file mode 100644 index 0000000..9762438 --- /dev/null +++ b/Spear/IDStore.hs | |||
@@ -0,0 +1,107 @@ | |||
1 | module Spear.IDStore | ||
2 | ( | ||
3 | ID | ||
4 | , IDStore | ||
5 | , emptyIDStore | ||
6 | , newID | ||
7 | , freeID | ||
8 | ) | ||
9 | where | ||
10 | |||
11 | |||
12 | import Data.Vector.Unboxed as U | ||
13 | import Control.Monad.State -- test | ||
14 | import Text.Printf -- test | ||
15 | import Debug.Trace | ||
16 | |||
17 | |||
18 | type ID = Int | ||
19 | |||
20 | |||
21 | data IDStore = IDStore | ||
22 | { assigned :: Vector Bool -- ^ A bit array indicating used IDs. | ||
23 | , last :: Int -- ^ The greatest ID assigned so far. | ||
24 | } | ||
25 | deriving Show | ||
26 | |||
27 | |||
28 | -- | Create an empty ID store. | ||
29 | emptyIDStore :: IDStore | ||
30 | emptyIDStore = IDStore U.empty (-1) | ||
31 | |||
32 | |||
33 | -- | Request an ID from the ID store. | ||
34 | newID :: IDStore -> (ID, IDStore) | ||
35 | newID store@(IDStore assigned last) = | ||
36 | if last == U.length assigned - 1 | ||
37 | then case findIndex (==False) assigned of | ||
38 | Just i -> assign i store | ||
39 | Nothing -> newID $ IDStore (assigned U.++ U.replicate (max 1 last+1) False) last | ||
40 | else | ||
41 | assign (last+1) store | ||
42 | |||
43 | |||
44 | -- Assign the given ID in the ID store. | ||
45 | assign :: ID -> IDStore -> (ID, IDStore) | ||
46 | assign i (IDStore assigned last) = | ||
47 | let assigned' = assigned // [(i,True)] | ||
48 | in (i, IDStore assigned' (max last i)) | ||
49 | |||
50 | |||
51 | -- | Free the given ID from the ID store. | ||
52 | freeID :: ID -> IDStore -> IDStore | ||
53 | freeID i (IDStore assigned last) = | ||
54 | let assigned' = assigned // [(i,False)] | ||
55 | in if i == last | ||
56 | then case findLastIndex (==True) assigned' of | ||
57 | Just j -> IDStore assigned' j | ||
58 | Nothing -> IDStore assigned' 0 | ||
59 | else | ||
60 | IDStore assigned' last | ||
61 | |||
62 | |||
63 | findLastIndex :: Unbox a => (a -> Bool) -> Vector a -> Maybe Int | ||
64 | findLastIndex p v = findLastIndex' p v Nothing 0 | ||
65 | where | ||
66 | findLastIndex' p v current i = | ||
67 | if i >= U.length v then current | ||
68 | else if p $ v U.! i then let x = Just i in x `seq` findLastIndex' p v x (i+1) | ||
69 | else findLastIndex' p v current (i+1) | ||
70 | |||
71 | |||
72 | -- test | ||
73 | test :: IO () | ||
74 | test = evalStateT test' emptyIDStore | ||
75 | |||
76 | |||
77 | test' :: StateT IDStore IO () | ||
78 | test' = do | ||
79 | x <- request | ||
80 | y <- request | ||
81 | z <- request | ||
82 | w <- request | ||
83 | free y | ||
84 | request | ||
85 | free w | ||
86 | request | ||
87 | a <- request | ||
88 | free a | ||
89 | request | ||
90 | return () | ||
91 | |||
92 | |||
93 | request :: StateT IDStore IO ID | ||
94 | request = do | ||
95 | store <- get | ||
96 | let (i, store') = newID store | ||
97 | put store' | ||
98 | lift $ printf "ID requested, got %d; %s\n" i (show store') | ||
99 | return i | ||
100 | |||
101 | |||
102 | free :: ID -> StateT IDStore IO () | ||
103 | free i = do | ||
104 | store <- get | ||
105 | let store' = freeID i store | ||
106 | put store' | ||
107 | lift $ printf "ID %d freed; %s\n" i (show store') | ||