How to get list of StaticMesh from path? - c++

I am trying to get list of Staticmesh from the specific path and set the Staticmesh to RootComponent. Please help on this issues. Code is below;
TArray<UObject*> MeshAssets;
EngineUtils::FindOrLoadAssetsByPath(TEXT("/Game/StarterContent/Meshs/"), MeshAssets, EngineUtils::ATL_Regular);
StaticMeshComponent->SetStaticMesh(MeshAssets.GetData);
StaticMeshComponent->AttachTo(RootComponent);
The Error is
Error 2 error C3867: 'TArray::GetData': function call missing argument list; use '&TArray::GetData' to create a
pointer to member<

StaticMeshComponent->SetStaticMesh(MeshAssets.GetData);
You're calling a function without the ( ) and possible parameters.
StaticMeshComponent->SetStaticMesh( MeshAssets.GetData( ) );
should work depending on whether there also have to be any parameters.

Some problems with your code:
Your Array is of type UObject*, but you need objects with the type UStaticMesh* for your component. The SetStaticMesh-method does not UObject* as parameter.
You can only set one item from your array as the mesh of your component, e.g. MeshAssets[0].
GetData is a method, not a variable. You have to call MeshAssets.GetData() if you want to use it.
So, your code should look more like this:
TArray<UObject*> MeshAssets;
EngineUtils::FindOrLoadAssetsByPath(TEXT("/Game/StarterContent/Meshs/"), MeshAssets, EngineUtils::ATL_Regular);
for (auto asset : MeshAssets) {
UStaticMesh* mesh = Cast<UStaticMesh>(asset);
if (mesh != nullptr) {
// do something with the mesh, create a component with it, etc.
}
}

Related

Updating data on a XML DOM c++ using tinyxml-2

I was wondering how could I update the data on the DOM for a certain attribute? I've searched but I couldn't find anything. Basically, I have an attribute called Hour(for example it's "11:03") and I want the text from that specific attribute to be changed to something like "11:04" or any other different text.
if( strcmp(Code1,Code2) == 0 )
{
strcpy(New,NewHour);
Element->FindAttribute("Hour")->SetAttribute(New); // here I want it to be changed in the DOM but I dont know how to do it
}
Later edit: This is what I've tried, but it's telling me FindAttribute() is private..
It is true that you can use SetAttribute which accepts the attribute name and value as parameters.
However, TinyXml2 does have a methodology for using FindAttribute because I have this code in my application:
// We need to get the assistant
const XMLAttribute *pAttrAssistant = const_cast<const XMLElement*>(pStudent)->FindAttribute("Assistant");
if (pAttrAssistant != nullptr)
{
LPCTSTR szAssistant = CA2CT(pAttrAssistant->Value(), CP_UTF8);
SetStudentInfo(eSchool, eAssign, strStudent, szAssistant, iStudyPoint);
}
else
{
// TODO: Throw exception if Assistant attribute missing
}
As you can see, I use the FindAttribute method and I have no compilation errors. If you look closely you will see that I am using const and that is the key.
The class exposes two methods:
One of them is set to private as you have already found out. But the const overload is set as public:

Was it possible to get a pointer to member from an instance of an object?

I was porting some legacy code to VS 2015 when this compiler error halted the build:
error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member
Going to the corresponding file and line, I saw this:
Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
mgr->SetSymm(...
GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:
class Manager {
...
bool GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
....
};
class OptDlg {
...
void GetFullModel() { return m_bFullModel; }
void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}
Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...
C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:
&OptDlg::GetFullModel // Standard-compliant
vs
OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems
vs
dlg.GetFullModel // ?
Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?
&OptDlg::GetFullModel // Standard-compliant
If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:
mgr->SetFullModel(dlg.GetFullModel());
if (dlg.GetFullModel())
mgr->SetSymm(...
Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.
Is this just another one of those VS 6 "extensions"?
It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.
It strongly looks to me like someone mis-typed dlg.GetFullModel() (which would call the function), not that they were trying to get a member function pointer.
Presumably the legacy compiler let it slide, taking the address of the function without using & and converting the non-null function pointer to bool (with value true) to pass into the set function.

How do I check if System::Collections::ArrayList exists / is empty

I'm trying to access a handle to a ::Collections::ArrayList with a two simple accessor/mutator functions:
/** --------------------------------------------
* public accessor for RX message queue
* --------------------------------------------- */
System::Collections::ArrayList^ peak_lib::rx_queue(void)
{
return this->m_Queue_Mes_RX;
}
/** --------------------------------------------
* public mutator for RX message queue
* --------------------------------------------- */
void peak_lib::rx_queue( System::Collections::ArrayList^ inList )
{
if ( inList->Count != 0 ) // <-- error line
{
this->m_Queue_Mes_RX = inList;
}
}
My compiler throws An unhandled exception of type 'System.NullReferenceException' occurred in my.exe and adds that the reference was not called on an object ( or something along these lines, I have to translate it from polish :/ ) when I try to access the ->Count property ( see error line in code ) as somebody told me to here to check if the inList variable exists.
What's the right (or at least a better :D) way to check if an ArrayList exists when I'm using C++/CLI Visual Studio 2008?
Initially, check for null before checking for count
if (inList != nullptr)
{
if(inList->count)
{}
}
Check for the null pointer before actually accessing its member.
if (inList)
{
if(inList->count)
{}
}
Also, as stated by Konrad in the comments, System::Collections::ArrayList is obsolete so try using vector instead
A property setter should either set the property to the value passed or indicate an error. There are two ways to indicate an error: Either throw an argument exception (common) or change the object to an invalid state that is exposed in future operations with the object (rare, e.g., classes intended to be used with data binding).
It could be that setting the property to null should not be an error but your question implies you want to disallow that. So, passing null where a non-null list is expected is a Boneheaded Exception. It is something that should be corrected before release and not ignored by the called code or "handled" by the calling code.
Here's the check in that case:
if (inList == nullptr) throw gcnew ArgumentNullException(L"value");
On the other hand, passing an empty list doesn't seem exceptional at all. You should consider accepting an empty list as the property value. If that doesn't make sense, perhaps you should design your class without that read-write property and instead use a method and a read-only property or the like.
Other issues:
Consider Systems::Collections::Generic::List<T> instead of System::Collections::ArrayList
Consider exposing the list as a read-only collection.

C++ Linked List Error: lvalue required as left operand of assignment

Alright, I'm trying to write a program in C++ that deals with a double-linked list. Specifically, the list contains a collection of artwork objects as its nodes. In this particular function, I'm trying to remove nodes through the "sell" command, but I'm getting this error on several lines:
Error: lvalue required as left operand of assignment
I've done my research and I've found that this type of error commonly arises when you try to assign values when you actually want to compare them, or if you're trying to assign values to a constant. However, I don't think that's my problem. Here's the problem code:
// Sell At Function: This function sells the specified artwork.
void CR_ArtCollection::sell_at(string title, ostream& log)
{
CR_ArtWorks* walker = first;
while(walker != NULL)
{
if(title == walker->get_title())
{
walker->get_next()->get_prev() = walker->get_prev(); // Error
walker->get_prev()->get_next() = walker->get_next(); // Error
delete walker;
walker = NULL;
}
else walker = walker->get_next();
}
}
If anyone can point me in the right direction, I would be incredibly appreciative.
It's quite obvious - get_prev and get_next return r-values. That means you can't assign to them.
Check your interface for a method similar to set_next and set_prev and call it as:
walker->get_next()->set_prev(walker->get_prev());
walker->get_prev()->set_next(walker->get_next());
As the names suggest - get_xxxx, those methods are there so you can get the values, not also set them.
Alright, if a function returns a primitive type such as a integer or a pointer it is not legal to assign to the result of the function. That's the error you have.
One possibility would be to change your get_prev and get_next function to return references to pointers.
But I don't suggest you do that. Your code clearly needs redesigning. You should add an erase function to your linked list class. That way the pointer manipulation code will be in the CR_ArtWorks class where it belongs, instead of the CR_ArtCollection class where it doesn't.

Parameters with and without arguments in boost::program_options

I wrote a small app that uses boost::program_options for command-line parsing.
I'd like to have some options that set a value if the argument is present, and alternately prints the current value if the parameter is given but no argument is present. So "set-mode" would look like:
dc-ctl --brightness 15
and "get mode" would be:
dc-ctl --brightness
brightness=15
The problem is, I don't know how to handle the second case without catching this exception:
error: required parameter is missing in 'brightness'
Is there an easy way to avoid having it throw that error? It happens as soon as the arguments are parsed.
I got a partial solution from How to accept empty value in boost::program_options which suggests using the implicit_value method on those parameters that may or may not have arguments present.
So my call to initialize the "brightness" parameter looks like this:
("brightness,b", po::value<string>()->implicit_value(""),
I then iterate over the variable map and for any argument that's a string, I check if it's empty and if so I print the current value. That code looks like this:
// check if we're just printing a feature's current value
bool gotFeature = false;
for (po::variables_map::iterator iter = vm.begin(); iter != vm.end(); ++iter)
{
/// parameter has been given with no value
if (iter->second.value().type() == typeid(string))
if (iter->second.as<string>().empty())
{
gotFeature = true;
printFeatureValue(iter->first, camera);
}
}
// this is all we're supposed to do, time to exit
if (gotFeature)
{
cleanup(dc1394, camera, cameras);
return 0;
}
UPDATE: this changes the aforementioned syntax, when using implicit values, now arguments, when given, must be of the form:
./dc-ctl -b500
instead of
./dc-ctl -b 500
Hope this is helpful to someone else.