internal Precache some info
| 1662 | // internal |
| 1663 | // Precache some info |
| 1664 | void CScriptArray::Precache() |
| 1665 | { |
| 1666 | subTypeId = objType->GetSubTypeId(); |
| 1667 | |
| 1668 | // Check if it is an array of objects. Only for these do we need to cache anything |
| 1669 | // Type ids for primitives and enums only has the sequence number part |
| 1670 | if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) |
| 1671 | return; |
| 1672 | |
| 1673 | // The opCmp and opEquals methods are cached because the searching for the |
| 1674 | // methods is quite time consuming if a lot of array objects are created. |
| 1675 | |
| 1676 | // First check if a cache already exists for this array type |
| 1677 | SArrayCache *cache = reinterpret_cast<SArrayCache*>(objType->GetUserData(ARRAY_CACHE)); |
| 1678 | if( cache ) return; |
| 1679 | |
| 1680 | // We need to make sure the cache is created only once, even |
| 1681 | // if multiple threads reach the same point at the same time |
| 1682 | asAcquireExclusiveLock(); |
| 1683 | |
| 1684 | // Now that we got the lock, we need to check again to make sure the |
| 1685 | // cache wasn't created while we were waiting for the lock |
| 1686 | cache = reinterpret_cast<SArrayCache*>(objType->GetUserData(ARRAY_CACHE)); |
| 1687 | if( cache ) |
| 1688 | { |
| 1689 | asReleaseExclusiveLock(); |
| 1690 | return; |
| 1691 | } |
| 1692 | |
| 1693 | // Create the cache |
| 1694 | cache = reinterpret_cast<SArrayCache*>(userAlloc(sizeof(SArrayCache))); |
| 1695 | memset(cache, 0, sizeof(SArrayCache)); |
| 1696 | |
| 1697 | // If the sub type is a handle to const, then the methods must be const too |
| 1698 | bool mustBeConst = (subTypeId & asTYPEID_HANDLETOCONST) ? true : false; |
| 1699 | |
| 1700 | asITypeInfo *subType = objType->GetEngine()->GetTypeInfoById(subTypeId); |
| 1701 | if( subType ) |
| 1702 | { |
| 1703 | for( asUINT i = 0; i < subType->GetMethodCount(); i++ ) |
| 1704 | { |
| 1705 | asIScriptFunction *func = subType->GetMethodByIndex(i); |
| 1706 | |
| 1707 | if( func->GetParamCount() == 1 && (!mustBeConst || func->IsReadOnly()) ) |
| 1708 | { |
| 1709 | asDWORD flags = 0; |
| 1710 | int returnTypeId = func->GetReturnTypeId(&flags); |
| 1711 | |
| 1712 | // The method must not return a reference |
| 1713 | if( flags != asTM_NONE ) |
| 1714 | continue; |
| 1715 | |
| 1716 | // opCmp returns an int and opEquals returns a bool |
| 1717 | bool isCmp = false, isEq = false; |
| 1718 | if( returnTypeId == asTYPEID_INT32 && strcmp(func->GetName(), "opCmp") == 0 ) |
| 1719 | isCmp = true; |
| 1720 | if( returnTypeId == asTYPEID_BOOL && strcmp(func->GetName(), "opEquals") == 0 ) |
| 1721 | isEq = true; |
nothing calls this directly
no test coverage detected