int main(int argc, char *argv[]){ NAtom *value1 = NAtom::get("value1"); NAtom *value2 = NAtom::get("value2"); NList list; NObject *ptr = &list; assert(ptr->equals(ptr)); assert(ptr->equals(&list)); assert(list.equals(&list)); assert(list.equals(ptr)); list << value1; list << value2; assert(list.size() == 2); assert(list.popLast() == value2); assert(list.popLast() == value1); assert(list.size() == 0); list.shift(value2); list.shift(value1); assert(list.size() == 2); assert(list.popFirst() == value1); assert(list.popFirst() == value2); assert(list.size() == 0); return 0; }
bool NProj::setModules(const NOpt<NProj> &opts) { NString tmp; NList<NString> validModules; validModules.append("NBase"); validModules.append("NEvents"); validModules.append("NNetwork"); validModules.append("NSecurity"); validModules.append("NXml"); validModules.append("NDBal"); validModules.append("NMySQL"); tmp = opts.getValues().at(0); addOpt(&m_modules, tmp); for (nuint64 i = 0; i < m_modules.size(); i++) { if (!validModules.contains(m_modules.at(i))) { NString msg; msg = msg + "Module " + m_modules.at(i) + " is not a " "valid module"; throw NException(msg, NException::TOOLS); } } return true; }
NList<NString> NHostAddress::aliases(void) { NList<NString> ret; NString tmp; while (*m_host.h_aliases) { tmp = *m_host.h_aliases; ret.append(tmp); m_host.h_aliases++; } return ret; }
// // Constructor // Item::Item(Record *record, void *data) : record(record), data(data) { items.Append(this); // Update cache size curCacheSize += record->fastFind->Size(); }
// // Destructor // Item::~Item() { ASSERT(curCacheSize - record->fastFind->Size() >= 0); curCacheSize -= record->fastFind->Size(); items.Unlink(this); AIL_mem_free_lock(data); }
// // Done // // Shutdown the game babel system // void Done() { ASSERT(sysInit); // Delete all registered babel data babels.DisposeAll(); // System is now shutdown sysInit = FALSE; }
NList<nuint32> NHostAddress::addresses(void) { NList<nuint32> ret; nuint32 tmp = 0; for (int i = 0; m_host.h_addr_list[i]; i++) { tmp |= (unsigned char) m_host.h_addr_list[i][3]; tmp <<= 8; tmp |= (unsigned char) m_host.h_addr_list[i][2]; tmp <<= 8; tmp |= (unsigned char) m_host.h_addr_list[i][1]; tmp <<= 8; tmp |= (unsigned char) m_host.h_addr_list[i][0]; ret.append(tmp); } return ret; }
// // Done // // Shutdown system // void Done() { ASSERT(initialized) // Delete all items items.DisposeAll(); // System now shutdown initialized = FALSE; }
// // Shutdown Logging System // void Done() { ASSERT(initialized) // Shutdown the destinations destinations.DisposeAll(); // Clear the initialized flag initialized = FALSE; }
// // RegisterBabel // // Register a babel callback // void RegisterBabel(BabelCallBack *callBack) { ASSERT(sysInit); // Create new babel data BabelData *babel = new BabelData; // Set the callback babel->callBack = callBack; // Add to the list babels.Prepend(babel); }
// // Load // // Load a list of tasks // void LoadTasks(GameObj *subject, FScope *fScope, NList<Task> &tasks) { // Iterate the scope FScope *sScope; while ((sScope = fScope->NextFunction()) != NULL) { switch (sScope->NameCrc()) { case 0x40B71B7D: // "Task" tasks.Append(LoadTask(subject, sScope)); break; } } }
// // 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; }
// // 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); } } }
/* ~IsRecordTypeList~ checks if the given type list is a record type list. This is needed in several places like ~In~, ~Out~, ~Save~, ~Open~.... Three type lists a common nowadays: 1 (72 0) 2 ((72 0)) 3 ((72 0) ...) With this information a crosscheck is done with the Secondo catalogue. */ bool Record::IsRecordTypeList(ListExpr typeInfo) { bool isRecord = false; NList list = typeInfo; #ifdef RECORD_DEBUG cerr << "Record::IsRecordTypeList(" << nl->ToString(typeInfo) << ")" << endl; #endif // check type info list expression, it has to be // "(72 0)" // or "((72 0))" // or "((72 0) ...)" if (list.length() >= 1) { // extact the algebra and type id from the given list int listAlgebraId; int listTypeId; if (list.first().isAtom()) { // case: "(72 0)" listAlgebraId = list.first().intval(); listTypeId = list.second().intval(); } else { // case: "((72 0))" or "((72 0) ...)" listAlgebraId = list.first().first().intval(); listTypeId = list.first().second().intval(); } // retrieve record ids from secondo cataloge int scAlgebraId; int scTypeId; SecondoCatalog* sc = SecondoSystem::GetCatalog(); sc->GetTypeId(Record::BasicType(), scAlgebraId, scTypeId); // compare the list ids with secondo record ids if (listAlgebraId == scAlgebraId && listTypeId == scTypeId) { isRecord = true; } } return isRecord; }
// // 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)); }
int SimpleNbmtr::fetch_neighbor_list(NList &nb_list) { nb_list.assign(nl.begin(), nl.end()); return nb_list.size(); }
namespace SidePlacement { /////////////////////////////////////////////////////////////////////////////// // // Struct Item - Data for the placement of a single generic unit type // struct Item { // List node NList<Item>::Node node; // Type to place GameIdent type; // Position data F32 direction, distance, orientation; // Constructor Item(const char *type, F32 direction, F32 distance, F32 orientation) : type(type), direction(direction), distance(distance), orientation(orientation) { } }; /////////////////////////////////////////////////////////////////////////////// // // System Functions // // Is the system initialized static Bool initialized = FALSE; // The name of the config file static const char *configName = "placement.cfg"; // The list of items static NList<Item> items(&Item::node); // // 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; } // // Done // // Shutdown system // void Done() { ASSERT(initialized) // Delete all items items.DisposeAll(); // System now shutdown initialized = FALSE; } // // Place // // Place units for the given team // void Place(Team *team) { ASSERT(initialized) ASSERT(team) // Get the side for this team Sides::Side &side = Sides::GetSide(team->GetSide()); // Get the start region for this team if (RegionObj *region = team->GetStartRegion()) { // Get the midpoint from the region Point<F32> startPoint(region->GetMidPoint()); // Ensure point is in the playfield WorldCtrl::ClampPlayFieldPoint(startPoint); // Adjust so point is always in the centre of a cell Point<U32> startPointCells; WorldCtrl::MetresToCellPoint(startPoint, startPointCells); WorldCtrl::CellToMetrePoint(startPointCells, startPoint); // Get the vector from the start point to the centre of the map Vector centre ( Vector(WorldCtrl::MetreMapX() * 0.5F, 0.0F, WorldCtrl::MetreMapZ() * 0.5F) - Vector(startPoint.x, 0.0F, startPoint.z) ); // Normalize it centre.Normalize(); // Work out the initial direction VectorDir dir; centre.Convert(dir); WorldCtrl::CompassDir compassDir = WorldCtrl::GetCompassDirection(centre); F32 startDirection = -WorldCtrl::GetCompassAngle(compassDir); // Place each item for (NList<Item>::Iterator i(&items); *i; i++) { // Get the item Item &item = **i; // Get the type mapping for this item if (const char *typeName = side.GetMapping(item.type.crc)) { // Try and find the specified type if (UnitObjType *type = GameObjCtrl::FindType<UnitObjType>(typeName)) { // Calculate the direction from the start point F32 direction = startDirection + item.direction; VectorDir::FixU(direction); // Calculate the orientation of the unit F32 orientation = startDirection + item.orientation; VectorDir::FixU(orientation); // Calculate final position Vector pos; pos.x = F32(cos(direction)); pos.y = 0.0f; pos.z = F32(sin(direction)); pos *= item.distance; pos.x += startPoint.x; pos.z += startPoint.z; pos.y += TerrainData::FindFloorWithWater(pos.x, pos.z); // Ensure the resources are initialized for this type type->InitializeResources(); // Create the unit if (!type->SpawnClosest(pos, team, FALSE, orientation)) { LOG_DIAG(("Unable to spawn [%s] for team [%s]", typeName, team->GetName())); } } } } } } }
/* ~In~ function to create a record instance through a nested list. According to the assigned type and value list the record is created. Before that the lists are checked regarding there correctness in the following order: 1 check whether the given type list is a record type list at all 2 check if in case of a non empty value list the two lists have the same number of elements. 3 If the value list is empty an empty record with only the given element types is created In all other cases an appropriate error message is populated and the creation aborts. After preliminary research both lists will be run through parallel in order to create the single elements. To simplify the parallel run through a list iterator ~ListIterator~ class has been created. More information about the iterator can be found in ~ListIterator.h~ document. At the run through the following cases have to be differentiated: First of all the current type list has to contain 2 elements. Example: * case 1: (string (int int)) 1 element name 1 element type list, with two integer values 1.1 algebraId 1.2 typeId or * case 2: (string ((int int) ...)) 2 element name 2 element type as list, first list item contains two integer values (see above) The first possibility reflects a simple Secondo type whereas the second illustrates a complex type likewise a ~record~. The element name has to start with a capital letter. The list elements have to conform these guidelines otherwise an error is detected. Once the list item is correct the new element is created. Therefore the belonging algebraId and typeId is read out from the Secondo catalogue. Elements that are marked with NULL are created as well but are ~undefined~. After the successful element creation this element is appended to the record by AppendElement method. The whole procedure is repeated as long as element information is available in the given ~typeInfo~ list. */ Word Record::In(const ListExpr typeInfo, const ListExpr instance, const int errorPos, ListExpr& errorInfo, bool& correct) { #ifdef RECORD_DEBUG cerr << "Record::In(" << nl->ToString(typeInfo) << ", " << nl->ToString(instance) << ", ..., ..., " << correct << ")" << endl; #endif Word w = SetWord(Address(0)); correct = false; const string nullSymbol = "NULL"; if (Record::IsRecordTypeList(typeInfo)) { // create an empty record instance Record* record = new Record(0); bool hasValueList; if(listutils::isSymbolUndefined(instance)){ // an undefined record: record->SetDefined(false); correct = true; return w; } // in case of a not empty value list: // case 1: value list has to be a list // case 2: type list and value list have to be of the same length if (nl->ListLength(instance) == 0) { hasValueList = false; } else { hasValueList = true; // case 1 if (nl->IsAtom(instance)){ #ifdef RECORD_DEBUG cerr << "Record::In: value list is of kind atom but " "a list is expected!" << endl; #endif cmsg.inFunError("Record::In: Value list is of kind atom but " "a list is expected! "); return w; } // case 2 if (nl->ListLength(instance) != nl->ListLength(nl->Rest(typeInfo))) { #ifdef RECORD_DEBUG cerr << "Record::In: different number of elements in " "type list and value list " << endl; #endif cmsg.inFunError("Record::In: different number of elements in " "type list and Value list "); return w; } } // create type and value list iteratoren ListIterator typeIter = nl->Rest(typeInfo); ListIterator valueIter = instance; // variables used inside the iteration loop string elemName; string elemTypeName; int elemAlgebraId; int elemTypeId; Word elemWord; Attribute* elem; // iterate synchrone through the type and value list elements while(typeIter.HasNext() && valueIter.HasNext()) { // assign the current type list element NList curType = typeIter.NextNList(); // assign the current value list element ListExpr curValue; if (hasValueList) { curValue = valueIter.NextListExpr(); } else { curValue = nl->OneElemList(nl->SymbolAtom(nullSymbol)); } #ifdef RECORD_DEBUG cerr << "Record::In: curType=" << curType.convertToString() << endl; cerr << "Record::In: curValue=" << nl->ToString(curValue) << endl; #endif // the current type list has to contain 2 elements // case 1: (string (int int)) // 1. element name // 2. element type list with two integer values // 2.1 algebraId // 2.2 typeId // case 2: (string ((int int) ...)) // 1. element name // 2. element type as list, first list item contains // two integer values if ( !( curType.length() == 2 && curType.second().length() == 2 && curType.second().first().isInt() && curType.second().second().isInt()) && !( curType.length() == 2 && curType.second().length() > 0 && curType.second().first().length() == 2 && curType.second().first().first().isInt() && curType.second().first().second().isInt())) { #ifdef RECORD_DEBUG cerr << "Record::In: wrong subtype info" << endl; #endif cmsg.inFunError("Record::In: wrong subtype info: " + curType.convertToString()); return w; } // extraxt the element name from current type list element elemName = curType.first().convertToString(); // extraxt the element type ids from current type list element if (curType.second().first().isAtom()) { // case 1 elemAlgebraId = curType.second().first().intval(); elemTypeId = curType.second().second().intval(); } else { // case 2 elemAlgebraId = curType.second().first().first().intval(); elemTypeId = curType.second().first().second().intval(); } // retrieve the type name of the ids from secondo catalog SecondoCatalog* sc = SecondoSystem::GetCatalog(); elemTypeName = sc->GetTypeName(elemAlgebraId, elemTypeId); // the element name has to start with a capital letter if (isupper(elemName[0]) == 0) { cmsg.inFunError("Record::In: element name has to start with a " "capital letter: " + elemName); return w; } // check if curValue is a Atom of value NULL (TEXT or Symbol) // if true -> create a default object if (nullSymbol.compare(nl->ToString(curValue)) == 0) { elemWord = (am->CreateObj(elemAlgebraId, elemTypeId)) (curType.second().listExpr()); // cast the read type instance to an attribute elem = static_cast<Attribute*>(elemWord.addr); // make elem as undefined elem->SetDefined(false); } else { // read element by registered IN function of the current type elemWord = (am->InObj(elemAlgebraId, elemTypeId)) (curType.second().listExpr(), curValue, errorPos, errorInfo, correct); // cast the read type instance to an attribute elem = static_cast<Attribute*>(elemWord.addr); } // check of existing object elem if (elem == NULL) { cmsg.inFunError("Record::In: In function of type " + elemTypeName +" for element " + elemName + " has delivered a NULL pointer for value " + nl->ToString(curValue)); return w; } // append the read attribute to the record and check the result if (record->AppendElement(elem, elemTypeName, elemName) == false) { cmsg.inFunError("Record::In: Cannot append element " + elemName + " of type " + elemTypeName); elem->DeleteIfAllowed(); return w; } elem->DeleteIfAllowed(); elem=0; } // End of: iterate synchrone through the type and value list elements // set the created record as return value w = SetWord(record); correct = true; } //IsRecordTypeList #ifdef RECORD_DEBUG cerr << "Record::In: correct=" << correct << ", w.addr=" << w.addr << endl; #endif return w; }
namespace GameBabel { // // CoreGameBabel // // Babel for all core game code-classes // static GameObjType* CoreGameBabel(GameIdent &classId, const char *name, FScope *fScope) { GameObjType *newType = NULL; // Allocate type specified in identifier switch (classId.crc) { case 0x9BC68378: // "Prop" newType = new PropObjType(name, fScope); break; case 0xD9A182E4: // "Unit" newType = new UnitObjType(name, fScope); break; case 0x4CD1BE27: // "Resource" newType = new ResourceObjType(name, fScope); break; case 0xFEA41B2C: // "Projectile" newType = new ProjectileObjType(name, fScope); break; case 0x219C4693: // "Explosion" newType = new ExplosionObjType(name, fScope); break; case 0x03515E3F: // "DeliveryProjectile" newType = new DeliveryProjectileObjType(name, fScope); break; case 0x56505D1E: // "Objective" newType = new Objective::Type(name, fScope); break; case 0xF4645984: // "OffMapTeam" newType = new OffMapTeamObjType(name, fScope); break; case 0x39C8F28B: // "OffMapBomb" newType = new OffMapBombObjType(name, fScope); break; case 0x49BDBF48: // "OffMapSpawn" newType = new OffMapSpawnObjType(name, fScope); break; case 0x96519EAE: // "OffMapStrike" newType = new OffMapStrikeObjType(name, fScope); break; case 0x5463CB0D: // "Restore" newType = new RestoreObjType(name, fScope); break; case 0xA98F22B7: // "Spy" newType = new SpyObjType(name, fScope); break; case 0xDFB7F0C8: // "Transport" newType = new TransportObjType(name, fScope); break; case 0x88AD3389: // "Trap" newType = new TrapObjType(name, fScope); break; case 0x93515F2D: // "Wall" newType = new WallObjType(name, fScope); break; case 0xDC7624D3: // "Parasite" newType = new ParasiteObjType(name, fScope); break; case 0xB1A0801B: // "Marker" newType = new MarkerObjType(name, fScope); break; } return (newType); } // Is system initialized static Bool sysInit = FALSE; // Used for callback registration struct BabelData { // The babel function BabelCallBack *callBack; // NList node NList<BabelData>::Node node; }; // List of all registered babels static NList<BabelData> babels(&BabelData::node); // // RegisterBabel // // Register a babel callback // void RegisterBabel(BabelCallBack *callBack) { ASSERT(sysInit); // Create new babel data BabelData *babel = new BabelData; // Set the callback babel->callBack = callBack; // Add to the list babels.Prepend(babel); } // // NewGameObjectType // // Returns a new object type instance, or NULL if the class id is not recognized // GameObjType* NewGameObjType(GameIdent &classId, const char *name, FScope *fScope) { ASSERT(sysInit); GameObjType *newType = NULL; // Step through each registered babel for (NList<BabelData>::Iterator i(&babels); *i && !newType; i++) { // See if this babel knows about this control class newType = (*i)->callBack(classId, name, fScope); } return (newType); } // // Init // // Initialize the game babel system // void Init() { ASSERT(!sysInit); // System is now initialized sysInit = TRUE; // Register the core game babel RegisterBabel(CoreGameBabel); } // // Done // // Shutdown the game babel system // void Done() { ASSERT(sysInit); // Delete all registered babel data babels.DisposeAll(); // System is now shutdown sysInit = FALSE; } }
NLocalisationList::NLocalisationList(const NList<NLocalisationEntry *> & entries) { m_Entries = new NList<NLocalisationEntry *>(); for (nlong i = 0; i < entries.getSize(); i++) m_Entries->add(entries.get(i)); }
NUserDataList::NUserDataList(const NList<NUserData *> & users) { m_Users = new NList<NUserData *>(); for (nlong i = 0; i < users.getSize(); i++) m_Users->add(new NUserData(*users.get(i))); }
// // RemoveDestination // // Remove a global destination // void RemoveDestination(Destination *destination) { ASSERT(destination) destinations.Unlink(destination); }
// // AddDestination // // Add a global destination // void AddDestination(Destination *destination) { ASSERT(destination) destinations.Append(destination); }
namespace Cache { // // Static data // static NList<Item> items(&Item::node); static U32 maxCacheSize; static U32 curCacheSize; static S32 actuallyUsed; static S32 cacheHits; static S32 cacheMisses; /////////////////////////////////////////////////////////////////////////////// // // Struct Item - A single cache item // // // Constructor // Item::Item(Record *record, void *data) : record(record), data(data) { items.Append(this); // Update cache size curCacheSize += record->fastFind->Size(); } // // Destructor // Item::~Item() { ASSERT(curCacheSize - record->fastFind->Size() >= 0); curCacheSize -= record->fastFind->Size(); items.Unlink(this); AIL_mem_free_lock(data); } /////////////////////////////////////////////////////////////////////////////// // // System Functions // // // FlushItem // // Removes the least used sound effect from the cache. // static Bool FlushItem() { Item *least = NULL; // Step through the cache for (NList<Item>::Iterator i(&items); *i; i++) { // Is this less used than the last one if (!least || ((*i)->record->freq < least->record->freq)) { // Must not be currently in use if (!Output::RecordInUse((*i)->record)) { least = *i; } } } // If we found one if (least) { delete least; return (TRUE); } return (FALSE); } // // Init // // Initialize the cache // void Init() { maxCacheSize = DEF_MAXCACHESIZE; curCacheSize = 0; actuallyUsed = 0; cacheHits = 0; cacheMisses = 0; } // // Done // // Shutdown the cache // void Done() { Clear(); } // // Clear // // Clear all items // void Clear() { // Stop all voices before clearing cache Output::Stop(); // Dispose of all cache items NList<Item>::Iterator i(&items); Item *item; while ((item = i++) != NULL) { delete item; } } // // 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)); } }
namespace Logging { /////////////////////////////////////////////////////////////////////////////// // // Definitions // #define LOG_BUFFERSIZE 1024 /////////////////////////////////////////////////////////////////////////////// // // Internal Data // static Bool initialized = FALSE; static char buffer[LOG_BUFFERSIZE]; static NList<Destination> destinations(&Destination::node); static U32 startTime; const char *levelDescShort[5] = { " ", "!", "?", "-", "+" }; const char *levelDescVerbose[5] = { "DISABLED", "ERR ", "WARN", "DIAG", "DEV " }; Win32::Mutex mutex; // // Initialize Logging System // void Init() { ASSERT(!initialized) // Grab the start time startTime = Clock::Time::Ms(); // Set the initialized flag initialized = TRUE; } // // Shutdown Logging System // void Done() { ASSERT(initialized) // Shutdown the destinations destinations.DisposeAll(); // Clear the initialized flag initialized = FALSE; } // // AddDestination // // Add a global destination // void AddDestination(Destination *destination) { ASSERT(destination) destinations.Append(destination); } // // RemoveDestination // // Remove a global destination // void RemoveDestination(Destination *destination) { ASSERT(destination) destinations.Unlink(destination); } /////////////////////////////////////////////////////////////////////////////// // // Class Client // // // Client::Client // // Constructor // Client::Client(const char *name) : name(name) { } // // Client::~Client // // Destructor // Client::~Client() { } // // Client::Write // void Client::Write() { // Get the message text const char *message = stream.str(); // Get the filename const char *fileName = Utils::Strrchr(file, '\\') + 1; // Get the time U32 time = Clock::Time::Ms() - startTime; /* // Is this an warning or error ? if (level == WARN || level == ERR) { // Compose buffer into exception information U32 arguments[4]; arguments[0] = (U32) message; arguments[1] = (U32) file; arguments[2] = (U32) line; arguments[3] = level == WARN ? 1 : 0; RaiseException(1, level == ERR ? EXCEPTION_NONCONTINUABLE_EXCEPTION : 0, 4, arguments); } else */ { // Write to the destinations NList<Destination>::Iterator dests(&destinations); for (!dests; dests.IsValid(); ++dests) { (*dests)->Write(level, name, fileName, line, time, message); } } stream.freeze(0); stream.seekp(0); } }