This optional callback is called when the template type is first used by the compiler. It allows the application to validate if the template can be instantiated for the requested subtype at compile time, instead of at runtime. The output argument dontGarbageCollect allow the callback to tell the engine if the template instance type shouldn't be garbage collected, i.e. no asOBJ_GC flag.
| 99 | // allow the callback to tell the engine if the template instance type shouldn't be garbage collected, |
| 100 | // i.e. no asOBJ_GC flag. |
| 101 | static bool ScriptGridTemplateCallback(asITypeInfo *ti, bool &dontGarbageCollect) |
| 102 | { |
| 103 | // Make sure the subtype can be instantiated with a default factory/constructor, |
| 104 | // otherwise we won't be able to instantiate the elements. |
| 105 | int typeId = ti->GetSubTypeId(); |
| 106 | if( typeId == asTYPEID_VOID ) |
| 107 | return false; |
| 108 | if( (typeId & asTYPEID_MASK_OBJECT) && !(typeId & asTYPEID_OBJHANDLE) ) |
| 109 | { |
| 110 | asITypeInfo *subtype = ti->GetEngine()->GetTypeInfoById(typeId); |
| 111 | asQWORD flags = subtype->GetFlags(); |
| 112 | if( (flags & asOBJ_VALUE) && !(flags & asOBJ_POD) ) |
| 113 | { |
| 114 | // Verify that there is a default constructor |
| 115 | bool found = false; |
| 116 | for( asUINT n = 0; n < subtype->GetBehaviourCount(); n++ ) |
| 117 | { |
| 118 | asEBehaviours beh; |
| 119 | asIScriptFunction *func = subtype->GetBehaviourByIndex(n, &beh); |
| 120 | if( beh != asBEHAVE_CONSTRUCT ) continue; |
| 121 | |
| 122 | if( func->GetParamCount() == 0 ) |
| 123 | { |
| 124 | // Found the default constructor |
| 125 | found = true; |
| 126 | break; |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | if( !found ) |
| 131 | { |
| 132 | // There is no default constructor |
| 133 | ti->GetEngine()->WriteMessage("array", 0, 0, asMSGTYPE_ERROR, "The subtype has no default constructor"); |
| 134 | return false; |
| 135 | } |
| 136 | } |
| 137 | else if( (flags & asOBJ_REF) ) |
| 138 | { |
| 139 | bool found = false; |
| 140 | |
| 141 | // If value assignment for ref type has been disabled then the array |
| 142 | // can be created if the type has a default factory function |
| 143 | if( !ti->GetEngine()->GetEngineProperty(asEP_DISALLOW_VALUE_ASSIGN_FOR_REF_TYPE) ) |
| 144 | { |
| 145 | // Verify that there is a default factory |
| 146 | for( asUINT n = 0; n < subtype->GetFactoryCount(); n++ ) |
| 147 | { |
| 148 | asIScriptFunction *func = subtype->GetFactoryByIndex(n); |
| 149 | if( func->GetParamCount() == 0 ) |
| 150 | { |
| 151 | // Found the default factory |
| 152 | found = true; |
| 153 | break; |
| 154 | } |
| 155 | } |
| 156 | } |
| 157 | |
| 158 | if( !found ) |
nothing calls this directly
no test coverage detected