data.lua 9.06 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
--[[
The MIT License (MIT)
Copyright (c) 2017 Graham Ranson - www.grahamranson.co.uk / @GrahamRanson

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial
portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--]]

21 22 23 24 25 26 27 28 29 30 31
--- Middleclass library.
local class = require( "puggle.ext.middleclass" )

--- Class creation.
local Data = class( "Data" )

--- Required libraries.

--- Localised functions.

--- Initiates a new Data object.
32
-- @param params Paramater table for the object.
33 34 35 36 37 38 39 40
-- @return The new object.
function Data:initialize( params )

	-- Set the name of this manager
	self.name = "data"

	-- Initiate the required data
	self._contents = {}
41
	self._path = "puggle.io"
42 43 44 45

	-- Enable autosave by default
	self:enableAutosave()

46 47
	-- Disable preference storage by default
	self:disablePreferenceStorage()
48

49 50 51
	-- Add the 'system' event listener
	Runtime:addEventListener( "system", self )

52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
end

--- Post init function for the Data manager.
function Data:postInit()

	-- Load the data
	self:load()

	-- Immediately save it out so that the first version is created
	self:save()

end

--- Loads the data.
-- @return True if it was loaded, false otherwise.
function Data:load()

69 70
	-- Create a blank contents table
	self._contents = {}
71

72 73
	-- Load te encoded data from preferences
	local encodedPreferenceData = system.getPreference( "app", "encodedData", "string" )
74

75 76
	-- Do we have some data?
	if encodedPreferenceData then
77

78 79 80 81 82
		-- Now binary 64 decode it
		local data = puggle.utils:b64Decode( encodedPreferenceData )

		-- Decode the data from json into a table
		local jsonData = puggle.utils:jsonDecode( data ) or {}
83

84 85
		for k, v in pairs( jsonData ) do
			self._contents[ k ] = v
86
		end
87 88 89 90 91 92 93 94 95 96 97
	end


	-- Pre declare the encoded data
	local encodedData

	-- Check that a path is set and that the file exists
	if self._path and puggle.utils:fileExists( self._path, system.DocumentsDirectory ) then

		-- Load the encoded data from a file
		encodedData = puggle.utils:readInFile( self._path, system.DocumentsDirectory )
98 99 100 101

	end

	if encodedData then
102 103

		-- Now binary 64 decode it
104
		local data = puggle.utils:b64Decode( encodedData )
105 106

		-- Decode the data from json into a table
107 108 109 110 111
		local jsonData = puggle.utils:jsonDecode( data ) or {}

		for k, v in pairs( jsonData ) do
			self._contents[ k ] = v
		end
112 113 114 115 116 117 118 119 120 121 122 123 124

		return true

	end

	return false

end

--- Saves the data.
-- @return True if it was saved, false otherwise.
function Data:save()

125 126
	-- Encode the data into json format
	local data = puggle.utils:jsonEncode( self._contents )
127

128 129
	-- Now binary 64 encode it
	data = puggle.utils:b64Encode( data )
130

131 132
	-- Save out the data to preferences
	local preferenceSaveResult = system.setPreferences( "app", { encodedData = data } )
133

134 135
	-- Check that we have a path set
	if self._path then
136

137 138
		-- Save it out to the file
		puggle.utils:writeOutFile( data, self._path, system.DocumentsDirectory )
139

140
		return true
141 142 143

	end

144
	return preferenceSaveResult
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173

end

--- Sets a value. Calling this will automatically save the data out, if this causes issues then diable the autosave via puggle.data:disableAutosave()
-- @param name The name of the value.
-- @param value The value to set.
function Data:set( name, value )

	-- Set the value
	self._contents[ name ] = value

	-- Automatically save the data out
	if self:isAutosaveEnabled() then
		self:save()
	end

end

--- Gets a value.
-- @param name The name of the value. If none specified then all values will be retrieved.
-- @return The retrieved value, or values if no name specified.
function Data:get( name )

	-- If a name is specified then return that value, if not then return all of them
	if name then
		return self._contents[ name ]
	else
		return self._contents
	end
174

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
end

--- Deletes a value.
-- @param name The name of the value.
function Data:delete( name )
	self._contents[ name ] = nil
end

--- Sets a value if it is higher than the already existing one, or if the existing one isn't set.
-- @param name The name of the value.
-- @param value The value to set.
-- @return True if it was set, false otherwise.
function Data:setIfHigher( name, value )

	if not self:isSet( name ) or self:isSet( name ) and self:isHigher( name, value ) then
190

191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
		self:set( name, value )

		return true

	end

	return false

end

--- Sets a value if it is higher than the already existing one, or if the existing one isn't set.
-- @param name The name of the value.
-- @param value The value to set.
-- @return True if it was set, false otherwise.
function Data:setIfLower( name, value )
206

207
	if not self:isSet( name ) or self:isSet( name ) and self:isLower( name, value ) then
208

209 210 211
		self:set( name, value )

		return true
212

213 214 215 216 217 218 219 220 221 222 223
	end

	return false

end

--- Sets a value if it hasn't been set before.
-- @param name The name of the value.
-- @param value The value to set.
-- @return True if it was set, false otherwise.
function Data:setIfNew( name, value )
224

225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289
	if not self:isSet( name ) then

		self:set( name, value )

		return true

	end

	return false

end

--- Increments a value.
-- @param name The name of the saved value.
-- @param amount The amount to increment it by. Optional, defaults to 1.
-- @return True if it was incremented, false otherwise.
function Data:increment( name, amount )

	if self:isNumber( name ) or not self:isSet( name ) then

		self:set( name, ( self:get( name ) or 0 ) + ( amount or 1 ) )

		return true

	end

	return false

end

--- Decrements a value.
-- @param name The name of the saved value.
-- @param amount The amount to decrement it by. Optional, defaults to 1.
-- @return True if it was incremented, false otherwise.
function Data:decrement( name, amount )

	if self:isNumber( name ) or not self:isSet( name ) then

		self:set( name, ( self:get( name ) or 0 ) - ( amount or 1 ) )

		return true

	end

	return false

end

--- Checks if a value is a number.
-- @param name The name of the saved value.
-- @return True if the value is a number, false otherwise.
function Data:isNumber( name )

	if self:isSet( name ) and type( tonumber( self:get( name ) ) ) == "number" then
		return true
	end

	return false

end

--- Checks if a value has been set.
-- @param name The name of the saved value.
-- @return True if the value is set, false otherwise.
function Data:isSet( name )
290
	return self:get( name ) ~= nil
291 292 293 294 295 296 297
end

--- Checks if a value is higher than an already saved value.
-- @param name The name of the saved value.
-- @param value The value to check.
-- @return True if the value is higher than the saved value, false otherwise.
function Data:isHigher( name, value )
298

299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
	if self:isSet( name ) and self:isNumber( name ) and value > self:get( name ) then
		return true
	end

	return false

end

--- Checks if a value is lower than an already saved value.
-- @param name The name of the saved value.
-- @param value The value to check.
-- @return True if the value is lower than the saved value, false otherwise.
function Data:isLower( name, value )

	if self:isSet( name ) and self:isNumber( name ) and value < self:get( name ) then
		return true
	end

	return false

end

321 322 323 324 325 326 327 328 329 330 331 332 333
-- Wipes all stored data.
function Data:wipe()

	-- Clear the contents
	self._contents = {}

	-- Save the newly empty file out
	if self:isAutosaveEnabled() then
		self:save()
	end

end

334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
--- Disables autosave.
function Data:disableAutosave()
	self._autosaveEnabled = false
end

--- Enables autosave.
function Data:enableAutosave()
	self._autosaveEnabled = true
end

--- Checks if autosave is enabled.
-- @return True if it is, false otherwise.
function Data:isAutosaveEnabled()
	return self._autosaveEnabled
end

350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
--- Disables preference storage.
function Data:disablePreferenceStorage()
	self._preferenceStorageEnabled = false
end

--- Enables preference storage.
function Data:enablePreferenceStorage()
	self._preferenceStorageEnabled = true
end

--- Checks if preference storage is enabled.
-- @return True if it is, false otherwise.
function Data:isPreferenceStorageEnabled()
	return self._preferenceStorageEnabled
end

366 367 368 369 370 371 372 373 374 375
--- The 'system' event handler.
-- @param event The 'system' event.
function Data:system( event )

	if event.type == "applicationExit" or event.type == "applicationSuspend" then
		self:save()
	end

end

376 377
--- Destroys this Data object.
function Data:destroy()
378

379 380
	self._contents = nil
	self._path = nil
381 382 383 384

	-- Add the 'system' event listener
	Runtime:removeEventListener( "system", self )

385 386 387
end

--- Return the Data class definition.
388
return Data