Beispiel #1
0
  //
  // Save
  //
  // Save a list of tasks
  //
  void SaveTasks(FScope *fScope, const char *name, const NList<Task> &tasks)
  {
    // Save nothing if no tasks in list
    if (tasks.GetCount())
    {
      // Write the name given
      fScope = fScope->AddFunction(name);

      // For each task in the list 
      for (NList<Task>::Iterator t(&tasks); *t; t++)
      {
        SaveTask(fScope, "Task", **t);
      }
    }
  }
  //
  // Init
  //
  // Initialize system
  //
  void Init()
  {
    ASSERT(!initialized)
    ASSERT(!items.GetCount())

    PTree pTree;

    // Process the configuration
    if (pTree.AddFile(configName))
    {
      FScope *fScope = pTree.GetGlobalScope();
      FScope *sScope;

      while ((sScope = fScope->NextFunction()) != NULL)
      {
        switch (sScope->NameCrc())
        {
          case 0x64FFFFD7: // "Place"
          {
            // Load the data
            const char *type = StdLoad::TypeString(sScope);
            F32 direction = StdLoad::TypeCompassAngle(sScope);
            F32 distance = StdLoad::TypeF32(sScope);
            F32 orientation = StdLoad::TypeCompassAngle(sScope);

            // Create the item
            items.Append(new Item(type, direction, distance, orientation));
            break;
          }
        }
      }
    }

    // System now initialized
    initialized = TRUE;
  }
      //
      // Request
      //
      // Request sound effect data from the cache
      //
      Item * Request(Record *record)
      {
        ASSERT(Initialized());
        ASSERT(record);
        ASSERT(record->valid);
        ASSERT(record->fastFind);

        // Is this effect too large for the cache
        if (record->fastFind->Size() > maxCacheSize)
        {
          LOG_WARN(("File '%s' is too large for the cache", record->Name()));
          record->valid = FALSE;
          return (NULL);      
        }

        // Record if first time being played
        if (!record->freq)
        {
          actuallyUsed++;
        }

        // Increment the frequency of this effect
        record->freq++;

        // Step through each cache item
        for (NList<Item>::Iterator i(&items); *i; i++)
        {
          // Is this the one we're after
          if ((*i)->record == record)
          {
            cacheHits++;
            return (*i);
          }
        }

        // Record a cache miss
        cacheMisses++;
 
        // Make space for this new effect (will also shrink cache if max size decreased)
        while (items.GetCount() && (maxCacheSize - curCacheSize < record->fastFind->Size()))
        {
          // Try and remove a sound effect out of the cache
          if (!FlushItem())
          {
            // Unable to remove any effects
            return (NULL);
          }
        }

        ASSERT(maxCacheSize - curCacheSize >= record->fastFind->Size());

        // Open the file
        FileSys::DataFile *dFile = FileSys::Open(record->fastFind);

        // Should be found since already checked
        if (!dFile)
        {
          LOG_WARN(("File '%s' has vanished!", record->Name()));
          record->valid = FALSE;
          return (NULL);
        }

        // Let's just be extra careful, someone might swap data files on a server
        if (dFile->Size() != record->fastFind->Size())
        {
          LOG_WARN(("File '%s' has changed size!", record->Name()));
          record->valid = FALSE;
          return (NULL);
        }
  
        // Allocate memory for file data
        void *data = AIL_mem_alloc_lock(record->fastFind->Size());

        if (!data)
        {
          return (NULL);
        }

        // Read the data from disk
        if (dFile->Read(data, record->fastFind->Size()) != record->fastFind->Size())
        {
          // Free the memory we just allocated
          AIL_mem_free_lock(data);

          // Close the file
          FileSys::Close(dFile);

          // We won't try this one again
          record->valid = FALSE;

          LOG_WARN(("Error reading effect '%s' into cache", record->Name()));
          return (NULL);
        }

        // Close the file
        FileSys::Close(dFile);

        // Return a new cache item
        return (new Item(record, data));
      }