1 -- This file is part of Intricacy
2 -- Copyright (C) 2013 Martin Bays <mbays@sdf.org>
4 -- This program is free software: you can redistribute it and/or modify
5 -- it under the terms of version 3 of the GNU General Public License as
6 -- published by the Free Software Foundation, or any later version.
8 -- You should have received a copy of the GNU General Public License
9 -- along with this program. If not, see http://www.gnu.org/licenses/.
11 module BinaryInstances
where
14 import Data
.Int (Int8
)
15 import qualified Data
.Vector
as Vector
22 newtype SmallInt
= SmallInt
{fromSmallInt
:: Int}
23 newtype SmallNat
= SmallNat
{fromSmallNat
:: Int}
24 instance Binary SmallNat
where
25 put
(SmallNat n
) = if n
< 255 then putWord8
(fromIntegral n
) else putWord8
255 >> put n
27 n
' <- get
:: Get Word8
28 if n
' == 255 then SmallNat
<$> get
else return . SmallNat
$ fromIntegral n
'
30 instance Binary SmallInt
where
31 put
(SmallInt n
) = if abs n
< 127 then put
(fromIntegral n
:: Int8
) else put
(127::Int8
) >> put n
34 if n
' == 127 then SmallInt
<$> get
else return . SmallInt
$ fromIntegral n
'
36 putPackedNat
,putPackedInt
:: Int -> Put
37 putPackedNat n
= put
$ SmallNat n
38 putPackedInt n
= put
$ SmallInt n
39 getPackedNat
,getPackedInt
:: Get
Int
40 getPackedNat
= fromSmallNat
<$> get
41 getPackedInt
= fromSmallInt
<$> get
43 newtype ShortList a
= ShortList
{fromShortList
:: [a
]}
44 instance Binary a
=> Binary
(ShortList a
) where
45 put
(ShortList
as) = putPackedNat
(length as) >> mapM_ put
as
48 ShortList
<$> getMany n
50 -- | 'getMany n' get 'n' elements in order, without blowing the stack.
51 -- [ copied from source of package 'binary' by Lennart Kolmodin ]
52 getMany
:: Binary a
=> Int -> Get
[a
]
55 go xs
0 = return $! reverse xs
57 -- we must seq x to avoid stack overflows due to laziness in
59 x `
seq` go
(x
:xs
) (i
-1)
60 {-# INLINE getMany #-}
62 instance Binary HexVec
where
63 put
(HexVec x y _
) = putPackedInt x
>> putPackedInt y
67 return $ tupxy2hv
(x
,y
)
68 instance Binary g
=> Binary
(PHS g
) where
71 instance Binary GameState
where
72 put
(GameState pps conns
) = put
(ShortList
$ Vector
.toList pps
) >> put
(ShortList conns
)
73 get
= liftM2 GameState
(Vector
.fromList
. fromShortList
<$> get
) (fromShortList
<$> get
)
74 instance Binary PlacedPiece
where
75 put
(PlacedPiece ppos p
) = put ppos
>> put p
76 get
= liftM2 PlacedPiece get get
77 instance Binary Piece
where
78 put
(Block patt
) = put
(0::Word8
) >> put
(ShortList patt
)
79 put
(Pivot arms
) = put
(1::Word8
) >> put
(ShortList arms
)
80 put
(Hook arm stiffness
) = put
(2::Word8
) >> put arm
>> put stiffness
81 put
(Wrench mom
) = put
(3::Word8
) >> put mom
82 put Ball
= put
(4::Word8
)
84 tag
<- get
:: Get Word8
86 0 -> Block
. fromShortList
<$> get
87 1 -> Pivot
. fromShortList
<$> get
88 2 -> liftM2 Hook get get
91 instance Binary Connection
where
92 put
(Connection
(ri
,rp
) (ei
,ep
) l
) = putPackedInt ri
>> put rp
>> putPackedInt ei
>> put ep
>> put l
98 Connection
(ri
,rp
) (ei
,ep
) <$> get
99 instance Binary Link
where
100 put
(Free p
) = put
(0::Word8
) >> put p
101 put
(Spring d l
) = put
(1::Word8
) >> put d
>> putPackedInt l
103 tag
<- get
:: Get Word8
106 1 -> liftM2 Spring get getPackedInt
107 instance Binary HookForce
where
108 put NullHF
= put
(0::Word8
)
109 put
(TorqueHF dir
) = put
(1::Word8
) >> putPackedInt dir
110 put
(PushHF v
) = put
(2::Word8
) >> put v
112 tag
<- get
:: Get Word8
115 1 -> TorqueHF
<$> getPackedInt
117 instance Binary Frame
where
118 put
(BasicFrame s
) = putPackedInt s
119 get
= BasicFrame
<$> getPackedInt
121 instance Binary PlayerMove
where
122 put NullPM
= put
(0::Word8
)
123 put
(HookPush v
) = put
(1::Word8
) >> put v
124 put
(HookTorque dir
) = put
(2::Word8
) >> putPackedInt dir
125 put
(WrenchPush v
) = put
(3::Word8
) >> put v
127 tag
<- get
:: Get Word8
130 1 -> HookPush
<$> get
131 2 -> HookTorque
<$> getPackedInt
132 3 -> WrenchPush
<$> get