internal Precache some info
| 1777 | // internal |
| 1778 | // Precache some info |
| 1779 | void CScriptArray::Precache() |
| 1780 | { |
| 1781 | subTypeId = objType->GetSubTypeId(); |
| 1782 | |
| 1783 | // Check if it is an array of objects. Only for these do we need to cache anything |
| 1784 | // Type ids for primitives and enums only has the sequence number part |
| 1785 | if( !(subTypeId & ~asTYPEID_MASK_SEQNBR) ) |
| 1786 | return; |
| 1787 | |
| 1788 | // The opCmp and opEquals methods are cached because the searching for the |
| 1789 | // methods is quite time consuming if a lot of array objects are created. |
| 1790 | |
| 1791 | // First check if a cache already exists for this array type |
| 1792 | SArrayCache *cache = reinterpret_cast<SArrayCache*>(objType->GetUserData(ARRAY_CACHE)); |
| 1793 | if( cache ) return; |
| 1794 | |
| 1795 | // We need to make sure the cache is created only once, even |
| 1796 | // if multiple threads reach the same point at the same time |
| 1797 | asAcquireExclusiveLock(); |
| 1798 | |
| 1799 | // Now that we got the lock, we need to check again to make sure the |
| 1800 | // cache wasn't created while we were waiting for the lock |
| 1801 | cache = reinterpret_cast<SArrayCache*>(objType->GetUserData(ARRAY_CACHE)); |
| 1802 | if( cache ) |
| 1803 | { |
| 1804 | asReleaseExclusiveLock(); |
| 1805 | return; |
| 1806 | } |
| 1807 | |
| 1808 | // Create the cache |
| 1809 | cache = reinterpret_cast<SArrayCache*>(userAlloc(sizeof(SArrayCache))); |
| 1810 | if( !cache ) |
| 1811 | { |
| 1812 | asIScriptContext *ctx = asGetActiveContext(); |
| 1813 | if( ctx ) |
| 1814 | ctx->SetException("Out of memory"); |
| 1815 | asReleaseExclusiveLock(); |
| 1816 | return; |
| 1817 | } |
| 1818 | memset(cache, 0, sizeof(SArrayCache)); |
| 1819 | |
| 1820 | // If the sub type is a handle to const, then the methods must be const too |
| 1821 | bool mustBeConst = (subTypeId & asTYPEID_HANDLETOCONST) ? true : false; |
| 1822 | |
| 1823 | asITypeInfo *subType = objType->GetEngine()->GetTypeInfoById(subTypeId); |
| 1824 | if( subType ) |
| 1825 | { |
| 1826 | for( asUINT i = 0; i < subType->GetMethodCount(); i++ ) |
| 1827 | { |
| 1828 | asIScriptFunction *func = subType->GetMethodByIndex(i); |
| 1829 | |
| 1830 | if( func->GetParamCount() == 1 && (!mustBeConst || func->IsReadOnly()) ) |
| 1831 | { |
| 1832 | asDWORD flags = 0; |
| 1833 | int returnTypeId = func->GetReturnTypeId(&flags); |
| 1834 | |
| 1835 | // The method must not return a reference |
| 1836 | if( flags != asTM_NONE ) |
nothing calls this directly
no test coverage detected