Torque3D Documentation / _generateds / assetTagsManifest.cpp

assetTagsManifest.cpp

Engine/source/assets/assetTagsManifest.cpp

More...

Detailed Description

Public Functions

IMPLEMENT_CONOBJECT(AssetTagsManifest )

  1
  2//-----------------------------------------------------------------------------
  3// Copyright (c) 2013 GarageGames, LLC
  4//
  5// Permission is hereby granted, free of charge, to any person obtaining a copy
  6// of this software and associated documentation files (the "Software"), to
  7// deal in the Software without restriction, including without limitation the
  8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9// sell copies of the Software, and to permit persons to whom the Software is
 10// furnished to do so, subject to the following conditions:
 11//
 12// The above copyright notice and this permission notice shall be included in
 13// all copies or substantial portions of the Software.
 14//
 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 21// IN THE SOFTWARE.
 22//-----------------------------------------------------------------------------
 23
 24#ifndef _ASSET_TAGS_MANIFEST_H_
 25#include "assetTagsManifest.h"
 26#endif
 27
 28#ifndef _ASSET_MANAGER_H_
 29#include "assetManager.h"
 30#endif
 31
 32#ifndef _CONSOLETYPES_H_
 33#include "console/consoleTypes.h"
 34#endif
 35
 36// Script binding.
 37#include "assetTagsManifest_ScriptBinding.h"
 38
 39//-----------------------------------------------------------------------------
 40
 41IMPLEMENT_CONOBJECT( AssetTagsManifest );
 42
 43//-----------------------------------------------------------------------------
 44
 45AssetTagsManifest::AssetTagsManifest()
 46{
 47}
 48
 49//-----------------------------------------------------------------------------
 50
 51AssetTagsManifest::~AssetTagsManifest()
 52{
 53    // Iterate tags.
 54    for( typeTagNameHash::iterator tagNameItr = mTagNameDatabase.begin(); tagNameItr != mTagNameDatabase.end(); ++tagNameItr )
 55    {
 56        // Delete asset tag.
 57        delete tagNameItr->value;
 58    }
 59
 60    // Clear database.
 61    mTagNameDatabase.clear();
 62    mAssetToTagDatabase.clear();
 63}
 64
 65//-----------------------------------------------------------------------------
 66
 67StringTableEntry AssetTagsManifest::fetchTagName( const char* pTagName )
 68{
 69    // Sanity!
 70    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
 71
 72    return StringTable->insert( pTagName, true );
 73}
 74
 75//-----------------------------------------------------------------------------
 76
 77AssetTagsManifest::AssetTag* AssetTagsManifest::findAssetTag( const char* pTagName )
 78{
 79    // Fetch tag name.
 80    StringTableEntry tagName = fetchTagName( pTagName );
 81
 82    // Finish if the tag already exists.
 83    typeTagNameHash::iterator tagNameItr = mTagNameDatabase.find( tagName );
 84
 85    return tagNameItr == mTagNameDatabase.end() ? NULL : tagNameItr->value;
 86}
 87
 88//-----------------------------------------------------------------------------
 89
 90void AssetTagsManifest::renameAssetId( const char* pAssetIdFrom, const char* pAssetIdTo )
 91{
 92    // Sanity!
 93    AssertFatal( pAssetIdFrom != NULL, "Cannot rename from NULL asset Id." );
 94    AssertFatal( pAssetIdTo != NULL, "Cannot rename to NULL asset Id." );
 95
 96    // Fetch asset Ids.
 97    StringTableEntry assetIdFrom = StringTable->insert( pAssetIdFrom );
 98    StringTableEntry assetIdTo   = StringTable->insert( pAssetIdTo );
 99
100    while( true )
101    {
102        // Find asset Id.
103        typeAssetToTagHash::Iterator assetIdItr = mAssetToTagDatabase.find( assetIdFrom );
104
105        // Finish if no asset Id to rename.
106        if ( assetIdItr == mAssetToTagDatabase.end() )
107            return;
108
109        // Fetch asset tag.
110        AssetTag* pAssetTag = assetIdItr->value;
111
112        // Untag old asset Id.
113        untag( assetIdFrom, pAssetTag->mTagName );
114
115        // Tag new asset Id.
116        tag( assetIdTo, pAssetTag->mTagName );
117    }
118}
119
120//-----------------------------------------------------------------------------
121
122void AssetTagsManifest::onTamlCustomWrite( TamlCustomNodes& customNodes )
123{
124    // Call parent.
125    Parent::onTamlCustomWrite( customNodes );
126
127    // Finish if no tags.
128    if ( mTagNameDatabase.size() == 0 )
129        return;
130
131    // Add node.
132    TamlCustomNode* pTagsNode = customNodes.addNode( ASSETTAGS_TAGS_NODE_NAME );
133
134    // Iterate tags.
135    for( typeTagNameHash::iterator tagItr = mTagNameDatabase.begin(); tagItr != mTagNameDatabase.end(); ++tagItr )
136    {
137        // Add tag node.
138        TamlCustomNode* pTagNode = pTagsNode->addNode( ASSETTAGS_TAGS_TYPE_NAME );
139
140        // Add fields.
141        pTagNode->addField( ASSETTAGS_TAGS_NAME_FIELD, tagItr->key );
142    }
143
144    // Add node.
145    TamlCustomNode* pAssetTagsNode = customNodes.addNode( ASSETTAGS_ASSETS_NODE_NAME );
146
147    // Iterate asset locations.
148    for( typeAssetToTagHash::Iterator assetTagItr = mAssetToTagDatabase.begin(); assetTagItr != mAssetToTagDatabase.end(); ++assetTagItr )
149    {
150        // Add asset tag node.
151        TamlCustomNode* pAssetNode = pAssetTagsNode->addNode( ASSETTAGS_ASSETS_TYPE_NAME );
152
153        // Add fields.
154        pAssetNode->addField( ASSETTAGS_ASSETS_ASSETID_FIELD, assetTagItr->key );
155        pAssetNode->addField( ASSETTAGS_ASSETS_TAG_FIELD, assetTagItr->value->mTagName );
156    }
157}
158
159//-----------------------------------------------------------------------------
160
161void AssetTagsManifest::onTamlCustomRead( const TamlCustomNodes& customNodes )
162{
163    // Call parent.
164    Parent::onTamlCustomRead( customNodes );
165
166    // Find tags nodes.
167    const TamlCustomNode* pTagProperty = customNodes.findNode( ASSETTAGS_TAGS_NODE_NAME );
168
169    // Finish if we don't have a tags node name.
170    if ( pTagProperty == NULL )
171        return;
172
173    // Fetch node name.
174    StringTableEntry tagNodeName = StringTable->insert( ASSETTAGS_TAGS_TYPE_NAME );
175
176    // Fetch children asset nodes.
177    const TamlCustomNodeVector& tagNodes = pTagProperty->getChildren();
178
179    // Iterate tag nodes.
180    for( TamlCustomNodeVector::const_iterator tagNodeItr = tagNodes.begin(); tagNodeItr != tagNodes.end(); ++tagNodeItr )
181    {
182        // Fetch tag node.
183        const TamlCustomNode* pTagNode = *tagNodeItr;
184
185        // Skip if an unknown node name.
186        if ( pTagNode->getNodeName() != tagNodeName )
187            continue;
188
189        // Fetch "Name" field.
190        const TamlCustomField* pTagNameField = pTagNode->findField( ASSETTAGS_TAGS_NAME_FIELD );
191
192        // Do we find the field?
193        if ( pTagNameField == NULL )
194        {
195            // No, so warn.
196            Con::warnf( "AssetTagsManifest::onTamlCustomRead() - Could not find '%s' field.", ASSETTAGS_TAGS_NAME_FIELD );
197            continue;
198        }
199
200        // Create the tag.
201        createTag( pTagNameField->getFieldValue() );
202    }
203
204    // Find asset tags node.
205    const TamlCustomNode* pAssetTagProperty = customNodes.findNode( ASSETTAGS_ASSETS_NODE_NAME );
206
207    // Finish if we don't have an asset tags node name.
208    if ( pAssetTagProperty == NULL )
209        return;
210
211    // Fetch node name.
212    StringTableEntry assetTagNodeName = StringTable->insert( ASSETTAGS_ASSETS_TYPE_NAME );
213
214    // Fetch children asset tag nodes.
215    const TamlCustomNodeVector& assetTagNodes = pAssetTagProperty->getChildren();
216
217    // Iterate property alias.
218    for( TamlCustomNodeVector::const_iterator assetTagNodeItr = assetTagNodes.begin(); assetTagNodeItr != assetTagNodes.end(); ++assetTagNodeItr )
219    {
220        // Fetch asset node.
221        const TamlCustomNode* pAssetTagNode = *assetTagNodeItr;
222
223        // Skip if an unknown node name.
224        if ( pAssetTagNode->getNodeName() != assetTagNodeName )
225            continue;
226
227        // Fetch "AssetId" field.
228        const TamlCustomField* pAssetIdField = pAssetTagNode->findField( ASSETTAGS_ASSETS_ASSETID_FIELD );
229
230        // Do we find the field?
231        if ( pAssetIdField == NULL )
232        {
233            // No, so warn.
234            Con::warnf( "AssetTagsManifest::onTamlCustomRead() - Could not find '%s' field.", ASSETTAGS_ASSETS_ASSETID_FIELD );
235            continue;
236        }
237
238        // Fetch "Tag" field.
239        const TamlCustomField* pTagField = pAssetTagNode->findField( ASSETTAGS_ASSETS_TAG_FIELD );
240
241        // Do we find the field?
242        if ( pTagField == NULL )
243        {
244            // No, so warn.
245            Con::warnf( "AssetTagsManifest::onTamlCustomRead() - Could not find '%s' field.", ASSETTAGS_ASSETS_TAG_FIELD );
246            continue;
247        }
248
249        // Tag the asset.
250        tag( pAssetIdField->getFieldValue(), pTagField->getFieldValue() );
251    }
252}
253
254//-----------------------------------------------------------------------------
255
256const AssetTagsManifest::AssetTag* AssetTagsManifest::createTag( const char* pTagName )
257{
258    // Sanity!
259    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
260
261    // Finish if the tag already exists.
262    AssetTag* pAssetTag = findAssetTag( pTagName );
263
264    // Return asset tag if already created.
265    if ( pAssetTag != NULL )
266        return pAssetTag;
267
268    // Fetch tag name.
269    StringTableEntry tagName = fetchTagName( pTagName );
270
271    // Generate the asset tag.
272    pAssetTag = new AssetTag( tagName );
273
274    // Add the tag.
275    mTagNameDatabase.insert( tagName, pAssetTag );
276
277    return pAssetTag;
278}
279
280//-----------------------------------------------------------------------------
281
282bool AssetTagsManifest::renameTag( const char* pOldTagName, const char* pNewTagName )
283{
284    // Sanity!
285    AssertFatal( pOldTagName != NULL, "Cannot use a NULL tag name." );
286    AssertFatal( pNewTagName != NULL, "Cannot use a NULL tag name." );
287
288    // Find old asset tags.
289    AssetTag* pOldAssetTag = findAssetTag( pOldTagName );
290
291    // Did we find the asset tag?
292    if ( pOldAssetTag == NULL )
293    {
294        // No, so warn.
295        Con::warnf( "AssetTagsManifest: Cannot rename tag '%s' as it does not exist.", pOldTagName );
296        return false;
297    }
298
299    // Are the old and new tags the same?
300    if ( pOldAssetTag->mTagName == fetchTagName( pNewTagName ) )
301    {
302        // Yes, so warn.
303        Con::warnf( "AssetTagsManifest: Cannot rename tag '%s' to tag '%s' as they are the same.", pOldTagName, pNewTagName );
304        return false;
305    }
306
307    // Create new tag.
308    AssetTag* pNewAssetTag = const_cast<AssetTag*>( createTag( pNewTagName ) );
309
310    // Transfer asset tags.
311    for ( Vector<typeAssetId>::iterator assetIdItr = pOldAssetTag->mAssets.begin(); assetIdItr != pOldAssetTag->mAssets.end(); ++assetIdItr )
312    {
313        pNewAssetTag->mAssets.push_back( *assetIdItr );
314    }
315
316    // Delete old tag.
317    deleteTag( pOldTagName );
318
319    return true;
320}
321
322//-----------------------------------------------------------------------------
323
324bool AssetTagsManifest::deleteTag( const char* pTagName )
325{
326    // Sanity!
327    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
328
329    // Find asset tag.
330    AssetTag* pAssetTag = findAssetTag( pTagName );
331
332    // Did we find the asset tag?
333    if ( pAssetTag == NULL )
334    {
335        // No, so warn.
336        Con::warnf( "AssetTagsManifest: Cannot delete tag '%s' as it does not exist.", pTagName );
337        return false;
338    }
339
340    // Remove the tag.
341    mTagNameDatabase.erase( pAssetTag->mTagName );
342
343    // Remove the asset tags.
344    for ( Vector<typeAssetId>::iterator assetIdItr = pAssetTag->mAssets.begin(); assetIdItr != pAssetTag->mAssets.end(); ++assetIdItr )
345    {
346        // Find asset Id tag.
347        typeAssetToTagHash::Iterator assetItr = mAssetToTagDatabase.find( *assetIdItr );
348
349        // Iterate asset Id tags.
350        while( assetItr != mAssetToTagDatabase.end() && assetItr->key == *assetIdItr )
351        {
352            // Is this the asset tag?
353            if ( assetItr->value == pAssetTag )
354            {
355                // Yes, so erase it.
356                mAssetToTagDatabase.erase( assetItr );
357                break;
358            }
359
360            // Next entry.
361            assetItr++;
362        }
363    }
364
365    // Delete the asset tag.
366    delete pAssetTag;
367
368    return true;
369}
370
371//-----------------------------------------------------------------------------
372
373bool AssetTagsManifest::isTag( const char* pTagName )
374{
375    // Sanity!
376    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
377
378    // Check whether tag exists or not.
379    return findAssetTag( pTagName ) != NULL;
380}
381
382//-----------------------------------------------------------------------------
383
384StringTableEntry AssetTagsManifest::getTag( const U32 tagIndex )
385{
386    // Finish if invalid tag count.
387    AssertFatal( tagIndex < getTagCount(), "Tag index is out of bounds." );
388
389    // Fetch tag iterator.
390    typeTagNameHash::iterator tagItr = mTagNameDatabase.begin();
391
392    // Find asset tag by index.
393    // NOTE: Unfortunately this is slow as it's not the natural access method.
394    for( U32 index = 0; index  < tagIndex; ++index, ++tagItr ) {};
395
396    // Return tag name.
397    return tagItr->value->mTagName;
398}
399
400//-----------------------------------------------------------------------------
401
402U32 AssetTagsManifest::getAssetTagCount( const char* pAssetId )
403{
404    // Sanity!
405    AssertFatal( pAssetId != NULL, "Cannot use a NULL asset Id." );
406
407    // Fetch asset Id.
408    StringTableEntry assetId = StringTable->insert( pAssetId );
409
410    return (U32)mAssetToTagDatabase.count( assetId );
411}
412
413//-----------------------------------------------------------------------------
414
415StringTableEntry AssetTagsManifest::getAssetTag( const char* pAssetId, const U32 tagIndex )
416{
417    // Sanity!
418    AssertFatal( pAssetId != NULL, "Cannot use a NULL asset Id." );
419
420    // Fetch asset Id.
421    StringTableEntry assetId = StringTable->insert( pAssetId );
422
423    // Sanity!
424    AssertFatal( tagIndex < (U32)mAssetToTagDatabase.count( assetId ), "Asset tag index is out of bounds." );
425
426    // Find asset tag.
427    typeAssetToTagHash::Iterator assetItr = mAssetToTagDatabase.find( assetId );
428
429    // Find asset tag by index.
430    // NOTE: Unfortunately this is slow as it's not the natural access method.
431    for( U32 index = 0; index  < tagIndex; ++index, ++assetItr ) {};
432
433    // Return tag name.
434    return assetItr->value->mTagName;
435}
436
437//-----------------------------------------------------------------------------
438
439bool AssetTagsManifest::tag( const char* pAssetId, const char* pTagName )
440{
441    // Sanity!
442    AssertFatal( pAssetId != NULL, "Cannot use a NULL asset Id." );
443    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
444
445    // Find asset tag.
446    AssetTag* pAssetTag = findAssetTag( pTagName );
447
448    // Does the tag exist?
449    if ( pAssetTag == NULL )
450    {
451        // No, so warn.
452        Con::warnf("AssetTagsManifest: Cannot tag asset Id '%s' with tag name '%s' as tag name does not exist.", pAssetId, pTagName );
453        return false;
454    }
455
456    // Is the asset Id valid?
457    if ( !AssetDatabase.isDeclaredAsset( pAssetId ) )
458    {
459        // No, so warn.
460        Con::warnf( "AssetTagsManifest::onTamlCustomRead() - Ignoring asset Id '%s' mapped to tag name '%s' as it is not a declared asset Id.", pAssetId, pTagName );
461        return false;
462    }
463
464    // Fetch asset Id.
465    typeAssetId assetId = StringTable->insert( pAssetId );
466
467    // Find asset Id tag.
468    typeAssetToTagHash::Iterator assetItr = mAssetToTagDatabase.find(assetId);
469
470    // Iterate asset Id tags.
471    while( assetItr != mAssetToTagDatabase.end() && assetItr->key == assetId )
472    {
473        // Is the asset already tagged appropriately?
474        if ( assetItr->value == pAssetTag )
475            return true;
476
477        // Next entry.
478        assetItr++;
479    }
480
481    // No, so add tag.
482    mAssetToTagDatabase.insertEqual( assetId, pAssetTag );    
483
484    // Add to asset tag.
485    pAssetTag->mAssets.push_back( assetId );
486
487    return true;
488}
489
490//-----------------------------------------------------------------------------
491
492bool AssetTagsManifest::untag( const char* pAssetId, const char* pTagName )
493{
494    // Sanity!
495    AssertFatal( pAssetId != NULL, "Cannot use a NULL asset Id." );
496    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
497
498    // Find asset tag.
499    AssetTag* pAssetTag = findAssetTag( pTagName );
500
501    // Does the tag exist?
502    if ( pAssetTag == NULL )
503    {
504        // No, so warn.
505        Con::warnf("AssetTagsManifest: Cannot untag asset Id '%s' from tag name '%s' as tag name does not exist.", pAssetId, pTagName );
506        return false;
507    }
508
509    // Fetch asset Id.
510    typeAssetId assetId = StringTable->insert( pAssetId );
511
512    // Is the asset tagged?
513    if ( !pAssetTag->containsAsset( assetId ) )
514    {
515        // No, so warn.
516        Con::warnf("AssetTagsManifest: Cannot untag asset Id '%s' from tag name '%s' as the asset is not tagged with the tag name.", pAssetId, pTagName );
517        return false;
518    }
519
520    // Remove asset from assert tag.
521    pAssetTag->removeAsset( assetId );
522
523    // Find asset Id tag.
524    typeAssetToTagHash::Iterator assetItr = mAssetToTagDatabase.find(assetId);
525
526    // Iterate asset Id tags.
527    while( assetItr != mAssetToTagDatabase.end() && assetItr->key == assetId )
528    {
529        // Is this the asset tag?
530        if ( assetItr->value == pAssetTag )
531        {
532            // Yes, so remove it.
533            mAssetToTagDatabase.erase( assetItr );
534            break;
535        }
536
537        // Next entry.
538        assetItr++;
539    }
540
541    return true;
542}
543
544//-----------------------------------------------------------------------------
545
546bool AssetTagsManifest::hasTag( const char* pAssetId, const char* pTagName )
547{
548    // Sanity!
549    AssertFatal( pAssetId != NULL, "Cannot use a NULL asset Id." );
550    AssertFatal( pTagName != NULL, "Cannot use a NULL tag name." );
551
552    // Find asset tag.
553    AssetTag* pAssetTag = findAssetTag( pTagName );
554
555    // Does the tag exist?
556    if ( pAssetTag == NULL )
557    {
558        // No, so warn.
559        Con::warnf("AssetTagsManifest: Cannot check if asset Id '%s' has tag name '%s' as tag name does not exist.", pAssetId, pTagName );
560        return false;
561    }
562
563    // Return whether asset Id is tagged.
564    return pAssetTag->containsAsset( StringTable->insert( pAssetId ) );
565}
566