Maybe im tired and cant see whats causing this but the following is what code ive got.
I cannot work out why the FindByPredicate is causing an access violation.
bool ASMFactionBase::DoesObjectClassMeetResourceRequirements(TSubclassOf<UObject> ObjectClass)
{
if (!ObjectClass)
{
return false;
}
if (FactionTechTree)
{
//Find the GraphNode that the ObjectClass exists on so that we can query what its resource requirements are.
UTechTreeGraphNode* ObjectNode = *(FactionTechTree->AllNodes.FindByPredicate([&](UTechTreeGraphNode* InNode)
{
return InNode->NodeAssetObject->IsChildOf(ObjectClass);
}));
if (ObjectNode && ResourceManagerComponent)
{
TArray<ASMResourceTypeBase*> Resources = ResourceManagerComponent->GetResources();
for (const TPair<TSubclassOf<ASMResourceTypeBase>, int32>& ResourceRequirement : ObjectNode->ResourceRequirements)
{
//Find out if the Resource exists in the ResourceManager, if it doesnt then we cant continue because we obviously dont have the required resource.
ASMResourceTypeBase* ResourceFromResourceManager = *(Resources.FindByPredicate([&](ASMResourceTypeBase* InResource) // <--------------- Access Violation on this Line.
{
return InResource->IsA(ResourceRequirement.Key);
}));
//If we do have the required resource, then find out if we have enough of it.
if (ResourceFromResourceManager)
{
if (ResourceRequirement.Value > ResourceFromResourceManager->ResourceAmount)
{
return false;
}
}
else
{
return false;
}
}
}
else
{
return false;
}
}
return true;
}
If there is someone that can point out a possible issue with this please do reply
If you need more information let me know, i hope the comments are enough.
Ok, found the answer, you are dereferencing a null pointer (thx captain obvious )
explanation :
you said : “it seems to be caused when there is an Element in ResourceRequirement that is not in Resources”
and indeed, the find by predicate would return NULL in that case, but you still try to dereference the pointer ( of pointer ) in that case
Solution :
ASMResourceTypeBase* ResourceFromResourceManager =NULL;
auto result = Resources.FindByPredicate([&](ASMResourceTypeBase* InResource)
{
return InResource->IsA(ResourceRequirement.Key);
});
if(result)
ResourceFromResourceManager =*(result);