v1.1.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Groups Pages
loader.h
1 /* -*- mode: C; c-basic-offset: 4; intent-tabs-mode: nil -*-
2  *
3  * This file is part of the public interface to the Sifteo SDK.
4  * Copyright <c> 2012 Sifteo, Inc. All rights reserved.
5  */
6 
7 #pragma once
8 #ifdef NOT_USERSPACE
9 # error This is a userspace-only header, not allowed by the current build.
10 #endif
11 
12 #include <sifteo/asset/group.h>
13 #include <sifteo/math.h>
14 #include <sifteo/array.h>
15 #include <sifteo/abi.h>
16 
17 namespace Sifteo {
18 
24 class Volume;
25 
34  _SYSAssetConfiguration sys;
35 
36  /*
37  * @brief Initialize this node with an AssetSlot and AssetGroup
38  *
39  * This initializes the AssetConfigurationNode with instructions for
40  * the AssetLoader to make sure the AssetGroup 'group' is available in the AssetSlot
41  * 'slot' by the time the load finishes.
42  *
43  * If the AssetGroup is part of a different Volume, you must provide that volume
44  * handle as the 'volume' parameter, and the 'group' must be mapped via MappedVolume.
45  * If you are loading assets packaged with your own game, you do not need to provide
46  * a volume.
47  */
48  void init(_SYSAssetSlot slot, AssetGroup &group, _SYSVolumeHandle volume = 0)
49  {
50  sys.pGroup = reinterpret_cast<uintptr_t>(&group);
51  sys.volume = volume;
52  sys.dataSize = group.compressedSize();
53  sys.numTiles = group.numTiles();
54  sys.ordinal = group.sysHeader()->ordinal;
55  sys.slot = slot;
56  }
57 
61  AssetSlot slot() const {
62  return AssetSlot(sys.slot);
63  }
64 
68  AssetGroup *group() const {
69  return reinterpret_cast<AssetGroup*>(sys.pGroup);
70  }
71 
75  _SYSVolumeHandle volume() const {
76  return sys.volume;
77  }
78 
82  unsigned numTiles() const {
83  return sys.numTiles;
84  }
85 
91  unsigned tileAllocation() const {
92  return roundup<unsigned>(numTiles(), _SYS_ASSET_GROUP_SIZE_UNIT);
93  }
94 
98  unsigned compressedSize() const {
99  return sys.dataSize;
100  }
101 };
102 
103 
118 template <unsigned tCapacity>
119 class AssetConfiguration : public Array<AssetConfigurationNode, tCapacity, uint8_t> {
121 public:
122 
135  void append(_SYSAssetSlot slot, AssetGroup &group, _SYSVolumeHandle volume = 0)
136  {
137  super::append().init(slot, group, volume);
138  }
139 };
140 
141 
209 struct AssetLoader {
210  _SYSAssetLoader sys;
211  _SYSAssetLoaderCube cubes[CUBE_ALLOCATION];
212 
214  operator const _SYSAssetLoader& () const { return sys; }
215  operator _SYSAssetLoader& () { return sys; }
216  operator const _SYSAssetLoader* () const { return &sys; }
217  operator _SYSAssetLoader* () { return &sys; }
218 
227  void init() {
228  bzero(*this);
229  }
230 
240  void finish() {
241  _SYS_asset_loadFinish(*this);
242  }
243 
261  void cancel(_SYSCubeIDVector cubes = -1) {
262  _SYS_asset_loadCancel(*this, cubes);
263  }
264 
297  template < typename T >
298  void start(T& configuration, _SYSCubeIDVector cubes = -1)
299  {
300  // Limit to cubes that we've allocated _SYSAssetLoaderCubes for
301  STATIC_ASSERT(CUBE_ALLOCATION <= _SYS_NUM_CUBE_SLOTS);
302  cubes &= 0xFFFFFFFF << (32 - CUBE_ALLOCATION);
303  _SYS_asset_loadStart(*this, &configuration.begin()->sys, configuration.count(), cubes);
304  }
305 
318  unsigned cubeProgress(_SYSCubeID cubeID, unsigned max) const
319  {
320  ASSERT(cubeID < CUBE_ALLOCATION);
321  // NB: Division by zero on ARM (udiv) yields zero.
322  return cubes[cubeID].progress * max / cubes[cubeID].total;
323  }
324 
333  float cubeProgress(_SYSCubeID cubeID) const
334  {
335  ASSERT(cubeID < CUBE_ALLOCATION);
336  unsigned progress = cubes[cubeID].progress;
337  unsigned total = cubes[cubeID].total;
338  return total ? (progress / float(total)) : 0.0f;
339  }
340 
353  unsigned averageProgress(unsigned max) const
354  {
355  unsigned progress = 0, total = 0;
356  for (unsigned i = 0; i < CUBE_ALLOCATION; ++i) {
357  progress += cubes[i].progress;
358  total += cubes[i].total;
359  }
360  return progress * max / total;
361  }
362 
371  float averageProgress() const
372  {
373  unsigned progress = 0, total = 0;
374  for (unsigned i = 0; i < CUBE_ALLOCATION; ++i) {
375  progress += cubes[i].progress;
376  total += cubes[i].total;
377  }
378  return total ? (progress / float(total)) : 0.0f;
379  }
380 
384  _SYSCubeIDVector busyCubes() const {
385  return sys.busyCubes;
386  }
387 
399  bool isComplete(_SYSCubeIDVector vec) const {
400  return (sys.busyCubes & vec) == 0;
401  }
402 
408  bool isComplete(_SYSCubeID cubeID) const {
409  return isComplete(_SYSCubeIDVector(0x80000000 >> cubeID));
410  }
411 
415  bool isComplete() const {
416  return sys.busyCubes == 0;
417  }
418 };
419 
420 
431 public:
432  ScopedAssetLoader() { init(); }
433  ~ScopedAssetLoader() { finish(); }
434 };
435 
440 }; // namespace Sifteo