Show/Hide variables on Editor[Unreal engine 4] - unreal-engine4

I have a master class called Door, and this door has 3 variables, aimationDuration, Start Delay and an Enum with 2 options - ClosingDoor and OpeningDoor. Now, I would like to know if its possible when I choose ClosingDoor the editor will display only the animationDuration variable and hide the StartDelay variable, and then choose the openingDoor and hide the animationDuration and show the StartDelay. Is this possible or is there another way to accomplish this?

There were improvements related to MetaTags since this question was asked and answered.
Starting with UE4.23:
The EditCondition meta tag is no longer limited to a single boolean property. It is now evaluated using a full-fledged expression parser, meaning you can include a full C++ expression.
This means we can do things like disabling (or even hiding) a property based on the value of an enum UPROPERTY. Hiding can be achieved by using the EditConditionHides MetaTag. Example:
UENUM(BlueprintType)
enum class EInterpolationMode : uint8 { Linear, Curve };
USTRUCT(BlueprintType)
struct FBlendableInterpolationData
{
GENERATED_BODY()
UPROPERTY(BlueprintReadWrite, EditAnywhere)
EInterpolationMode InterpolationMode = EInterpolationMode::Linear;
UPROPERTY(EditAnywhere, meta = (EditCondition = "InterpolationMode == EInterpolationMode::Linear", EditConditionHides))
float Duration;
UPROPERTY(EditAnywhere, meta = (EditCondition = "InterpolationMode == EInterpolationMode::Curve", EditConditionHides))
UCurveFloat* Curve;
};
WARNING: There is a special case where EditConditionHides can crash the editor for engine versions 4.26 and 4.27.
More examples for property disabling/hiding can be found here: https://thomassampson.co.uk/posts/ue4-uproperty-editcondition/

There is infact exactly something for this, but it might require a little bit of hackery as you need ENUM values and the method seems to be for boolean values.
Unreal's metadata specifiers have a 'editcondition' specifier that lets you point to a boolean variable and say, when that variable is true, let me edit this property, and it doesn't matter what the property is it works for everything.
Here's an example from the Unreal answerhub with some code:
https://answers.unrealengine.com/questions/189864/hide-and-show-variable-in-property-window.html
If the boolean method works for you that's great, otherwise you'll need to look into overriding AActor::PostEditChangeProperty() in order to do a hack where when you change the enum values, it sets a boolean value in that function (which gets called after any change in the property window for an actor), and then should work as you need it to.
If you actually want proper hiding/showing that's more complicated and requires you to use Slate which I have no idea of but here's the documentation:
https://docs.unrealengine.com/latest/INT/Programming/Slate/DetailsCustomization/index.html

Related

In Katalon Studio, How to retrieve the values using the javascript executor. document.getElementsByTagName('input')[29].value

enter image description here
I tried below code but not works.
a = WebUI.executeJavaScript('document.getElementsByTagName("input")[29].value', null)
Thread.sleep(5000)
System.out.println(a)
There is so much wrong with this question that I don't even know where to begin...
What are you trying to accomplish by using JavaScript (this is a testing code smell, for 99% of testing cases) to fetch a value ?
Why not do the following:
create a TestObject, preferably in the Object Repository, that points to the object in question.
give that Test Object the locator. This is, by default, some xpath.
In your case, give it xpath
(//input)[29]
. However, I advise you come up with a more meaningful selector for it (for example, select it by some class, data-* attribute, name) that is easier to maintain
use the built-in Keyword for getting attribute, like this:
WebUI.getAttribute(findTestObject('[whateverYourTestObjectNameIs]'), 'value')
this is just good code design, but write this to some Custom Keyword for this util:
// import statements here. Ctrl + Shift + O on your keyboard to bring those in
public final class GeneralWebUIUtils {
public static final String Value = "value";
public static final String GetValue(TestObject to) {
return WebUI.getAttribute(to, this.Value);
}
}
Also, why are you pausing runtime by some hard-coded time amount? That is a testing code smell. Stop it!
What exactly are you waiting on? Use the WebUI keywords for this thing you are waiting on, and if none of those suffice, hmu and I may have the wait method you're looking for ....
Oh, and looking at that image you linked, it looks like you solved your own question.

Xamarin Sport App - What does IsDirty do?

I am looking through the Xamarin Sport app code and trying to understand some of the cool things they are doing in it. I cannot understand what IsDirty is being used for exactly. It gets defined here and implemented here and used in many places, such as here.
I read a little about and ICommand's IsDirty property so maybe it is a way to call an entire model as being dirty, but what implications does that have?
I also see it being used here which I am assuming is why they created it in the first place.
Thanks for y'all's insight into it.
They're just using it as a clever way to handle modification detection. Consider a "Save Changes" feature; you don't actually want to enable the "Save" button until something has changed, and you can key off the IsDirty property to test that.
Technically, you could handle this yourself by having a base class hook INotifyPropertyChanged.PropertyChanged and maintaining a dirty bit of your own (possibly in a base class), but rather than require all of their classes to have an IsDirty property that they may or may not need, they've made it an optional feature that a class can implement. For example, take a look at GameResult for an example of something that can't be changed, and therefore, can't be marked as dirty.
With this approach, you've minimized the amount of code you need to write to implement this functionality. All your derived classes need to do is derive from BaseNotify, implement IDirty, and call SetPropertyChanged(...) as the setter to set the private tracking field, signal to any observers that a property has changed, and automatically set the dirty bit.
NOTE: I did just make an interesting observation: while the implementation of the SetProperty extension method does set the IsDirty flag, the BaseNotify class' IsDirty implementation doesn't call anything to bubble up a PropertyChanged event for IsDirty, which means bindings against it won't get updated when it changes. I believe the fix would be for that extension method to invoke PropertyChanged with the property name "IsDirty":
if(dirty != null) {
dirty.IsDirty = true;
handler.Invoke(sender, new PropertyChangedEventArgs("IsDirty"));
// Yes, I'm a bad person for hard-coding the name.
}
Alternately, you could defer signaling the IsDirty change until after you signal the original property has changed. I just chose to keep it with the original logic.
I think it's relatively simple and you're on the right track: the purpose of that property is to have an easy way to know whether some property has been changed, so the whole object has to be saved. It's baked in to the way property changes are propagated, so you don't have to set it by yourself whenever a property value is being set.
tl;dr: You can use it to check if you your (view)model is worth a save operation ,-).

Does a class variable have a right to exist if its value can be calculated using other data?

I'll give a minimalist example to explain my question.
Suppose that there is a Shape class:
public class Shape {
User user;
int color;
}
and a User class:
public class User {
int mood;
}
Now suppose that a shape's color depends on the user's mood. Is it redundant for Shape to have a color field since it can be calculated by accessing its user's mood?
Consider that in a more realistic example accessing the necessary data to calculate the color can be more complex or via a longer sequence of accessors (color = user.getCat().getCousin().getMood()). Consider further that these classes may be mapped to a database and (in a way) duplicate data. On the other hand they can be marked as transient.
Color depends on the mood but color is not the same as the mood at all. So including color field seems only logical to me, however I cannot wholly justify this design.
Does a class variable have a right to exist if its value can be calculated using other data?
I would suggest you make color a property, that way you can calculate it or not and the rest of the program won't change.
Calculating it everytime will be slower, add extra code everytime it is being called. Keeping the value will be faster (don't need to calculate everytime) but you add the risk of not having the right value if it isn't updated properly.

MEF: metadata seem to override interface when using GetExports

I'm building a MEF-based plugin-centric WPF application and I'm facing an issue with GetExports, maybe it's just my ignorance but I find an odd behaviour. I have a number of exported parts, all derived from 2 different interfaces (let's name them A and B), but all marked with the same metadata attribute X. So I have code like:
[Export(typeof(A))]
[TheXAttributeHere...]
public class SomePart1 : A { ... }
for each part, and the same for classes implementing B:
[Export(typeof(B))]
[TheXAttributeHere...]
public class SomePart2 : B { ... }
Now, when I try getting all the parts implementing A and decorated by attribute X with some values, MEF returns not only the A-implementing parts, but ALSO the B-implementing parts. So, when I expect to deal with A-objects I get a B, whence a cast exception.
In the real world, interfaces are named IItemPartEditorViewModel and IItemPartEditorView, while their common attribute is named ItemPartEditorAttribute and exposes a PartType string property on which I do some filtering. My code to get parts is thus like e.g.:
var p = (from l in container.GetExports<IItemPartEditorViewModel, IItemPartEditorMetadata>()
where l.Metadata.PartType == sPartType
select l).FirstOrDefault();
When looking for IItemPartEditorViewModel whose PartType is equal to some value, I get the IItemPartEditorView instead of IItemPartEditorViewModel implementing object. If I comment out the attribute in the IItemPartEditorView object instead, I correctly get the IItemPartEditorViewModel implementing object.
Update the suggested "templated" method was used, but I mistyped it here as I forgot to change lessthan and greaterthan into entities. Anyway, reviewing the code I noticed that in the attribute I had "ViewModel" instead or "View" for the interface type, so this was the problem. Shame on me, sorry for bothering :)!
I think I'd need to see more of the code to know for sure what's going on. However, I'd suggest you call GetExports like this:
// Get exports of type A
container.GetExports<A>();
// Get exports of type B
container.GetExports<B>();
Then do your filtering on the list returned. This will probably fix the cast issues you are having. I'd also be interested in seeing the code for the custom metadata attribute. If it derives from ExportAttribute for example, that might be part of the problem.

VBA Referring to a container object--syntax and object-oriented methodology

This is as much a question about learning object-oriented methodology, for me, as it is about VBA syntax. Suppose I create several classes, like Car, Truck, Bus, etc. And I create another class SpeedCalculator, which instances of my vehicles will instantiate and contain. (As a newbie, let me note that this strikes me as a good time to declare a class as static and not instantiate it--which vba can't do I don't think... .) Now this speed calculator will be no simple speedometer. Rather it will calculate speed from temperature, windspeed, RPMs, etc, etc--go along with this please, just for the sake of the example.
Now the question is how for the contained object to collect its inputs, which are only available in the container objects (the vehicle objects might implement an interface (if VBA can even do that...)). "Parent." is wrong, I figured out eventually, b/c parent-child is an inheritance relation (which VBA doesn't have, again), not a containment relation, and the parent of the contained object is an Excel Application (not my object). So it seems it would be nice if there were another keyword to refer to container properties. I hope I haven't just missed something simple. Or is it more the case that that sort of reference would break object-oriented encapsultaion principles?
I guess a second approach would be to pass the container to the contained, via "Me" as an argument. But then you have to multiply all of the contained's methods, either to overload them (if VBA can even do that...), or with variously named versions--due to the different types of the containers (can we be more idealist and avoid declaring as variant or "Object"?).
And then door #3 would be the last door standing, I guess? Which would be to pass an (annoying) litany of arguments. The definition of all of which would tend to defeat the purpose of having my tidy little calculator class?
It's not clear to me from your question whether or not you already know VBA and/or OO, and are just asking how to use the object-oriented features of VBA. If you are new to both VBA and OO, see below for some thoughts on why VBA isn't a very good vehicle for learning OOD/OOP.
To address the general part of your question, VBA classes can implement interfaces. This is how you express inheritance of interface (an "is-a" relationship) in VBA. There is no direct way to express inheritance of implementation in VBA. Instead, to make one class inherit the implementation of another, you have the first implement the interface of the second, contain an instance of the second, and then delegate calls to that instance. See this answer for more:
VBA inheritance, analog of super
There is a link there, that I will repeat here, to the Visual Studio 6.0 Programmer's Guide:
http://msdn.microsoft.com/en-us/library/aa240846(v=VS.60).aspx
It's as good a short introduction as any on the "VBA way" of OOP (although it's written for VB6, not VBA).
Now, for your specific question about design: "how for the contained object to collect its inputs, which are only available in the container objects".
You need to think about what you are actually modeling here. Regardless of how you implement it, a "speed calculator" should only get to know about a very specific set of inputs, not the entire internal state of whatever vehicle is using it. In VBA, as you note, there are no static classes. Instead, use a regular code module and have a function that you call from inside your vehicle class(es):
Public Function calcSpeed(temp, windspeed, rpm)
'do calc based only on parms passed in...
End Function
If it needs to take a zillion parameters because that's how the calculation works, so be it. Don't try to hide it. Of course, you can wrap them up in a Type or in a class if there are too many.
Now, does every different kind of vehicle calculate speed in the exact same way from the exact same set of state parameters? If so, then have a speed property or method that is implemented by your "base vehicle" class and call calcSpeed from there.
But maybe it's the case that different kinds of vehicles have different state parameters, or use different calculation methods, or the calculation is the same but not every vechicle type supplies every parameter. In that case, put the speed method in the base vehicle interface, but "override" it as needed in the implementation of each subclass. (Maybe then calcSpeed is too simplistic, and you'd end up with a library of speed calculation helper functions.)
One thing I would not do, is have a generic SpeedCalculator class that takes a Vehicle argument and then interrogates it for its state in order to do the calc. The reason why not is expressed very well in these classic articles:
http://media.pragprog.com/articles/may_04_oo1.pdf
http://pragprog.com/articles/tell-dont-ask
http://www.cmcrossroads.com/bradapp/docs/demeter-intro.html
There's also this:
http://www.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/paper-boy/demeter.pdf
which has a quote I like:
So, what's so bad about this code
(besides being a horribly contrived
example)? Well, lets translate what
the code is actually doing into
real-language:
Apparently, when the
paperboy stops by and demands payment,
the customer is just going to turn
around, let the paperboy take the
wallet out of his back pocket, and
take out two bucks.
I don't know about
you, but I rarely let someone handle
my wallet. There are a number of
'realworld' problems with this, not to
mention we are trusting the paperboy
to be honest and just take out what
he's owed. If our future Wallet object
holds credit cards, the paperboy has
access to those too... but the basic
problem is that “the paperboy is being
exposed to more information than he
needs to be”.
Thats an important
concept... The 'Paperboy' class now
'knows' that the customer has a
wallet, and can manipulate it. When we
compile the Paperboy class, it will
need the Customer class and the Wallet
class. These three classes are now
'tightly coupled'. If we change the
Wallet class, we may have to make
changes to both of the other classes.
ADDED AS PROMISED IN COMMENTS:
It's not that you couldn't readily have an instance of a class Speedometer contained within your Vehicles. (My example of a simple function might be too simplistic. Maybe you need a class to model the other things about speedometers - they have mass, take up space, etc.) It's how the two classes depend on each other. In this example, Vehicle needs to know about Speedometer. But why should the reverse be true? If Speedometer takes a Vehicle as a parameter, and then asks it for the particular things it needs to know to calculate speed, the code will certainly work. However, you've coupled Speedometer to Vehicle more tightly than necessary.
One of the reasons to use an OO approach in the first place is because it lets you be more exact about how concepts relate to each other. It's better to have Vehicle tell Speedometer, "Here are some facts about the world. Give me back a speed.", rather than, "Here I am, Me, the Vehicle that contians you. Ask me whatever you need to about anything related to me, and then give me back a speed." (Note that whether the "facts about the world" are raw temp, windspeed, etc., or an instance of some SpeedometerInput Type/Class isn't the issue. It's that speedometers don't need to know all about vehicles.)
Using the most exact interface you can get away with doesn't make that big of a deal in a simple example. But it becomes huge when added up over many design decisions.
Finally, If you have a choice, I wouldn't use VBA as a vehicle for learning object-oriented design or programming. You can do "OOP" in VBA, but in a Microsoft-/COM-specific way that is literally a relic from the mid-1990s. You can browse around stackoverflow for plenty of examples of things that are normally done in OO programming languages (and with their much better libraries) that are cumbersome and tricky in VBA. Here are a few off the top of my head that I've either asked or answered:
Is there a way to overload the constructor / initialize procedure for a class in VBA?
Is there a way to write an equality test for a VBA class with private members without exposing knowledge of the existence of those private members?
Restrict type in a Collection inside a class module
Excel-VBA - Is there anything like Javas Set container in VBA?
So, unless you're either constrained to learn with VBA because you can't install anything but MS Office on your machine, or you plan to be doing a lot of VBA work becuase you're using Excel, Access, etc. and have some problems where OOP can help, I'd look elsewhere. Python, .NET, or Java are all available for free on Windows and have tons of resources available for the beginner.
I'm not sure if this is what you're looking for, but I'll give it a shot. If Car class contains one Speedometer class, Car contains Windspeed and Acceleration properties, Speedometer contains a Mass property, and speed is defined as Windspeed times Acceleration divided by Mass, then here's how I would set it up.
In class CCar
Private mlCarID As Long
Private mdWindSpeed As Double
Private mdAcceleration As Double
Private mclsSpeedometer As CSpeedometer
'Getters and setters
Public Property Get CarID() As Long: CarID = mlCarID: End Property
Public Property Let CarID(ByVal lCarID As Long): mlCarID = lCarID: End Property
Public Property Get Acceleration() As Double: Acceleration = mdAcceleration: End Property
Public Property Let Acceleration(ByVal dAcceleration As Double): mdAcceleration = dAcceleration: End Property
Public Property Get WindSpeed() As Double: WindSpeed = mdWindSpeed: End Property
Public Property Let WindSpeed(ByVal dWindSpeed As Double): mdWindSpeed = dWindSpeed: End Property
'read only property to the speedometer class
Public Property Get Speedometer() As CSpeedometer
Set Speedometer = mclsSpeedometer
End Property
'create the child and set the parent property
Private Sub Class_Initialize()
Set mclsSpeedometer = New CSpeedometer
Set mclsSpeedometer.Parent = Me
End Sub
Private Sub Class_Terminate()
Set mclsSpeedometer.Parent = Nothing
Set mclsSpeedometer = Nothing
End Sub
'pass through property
Public Property Get Speed() As Double
Speed = Me.Speedometer.Speed
End Property
In class CSpeedometer
Private mdMass As Double
Private mclsParent As CCar
Public Property Get Mass() As Double: Mass = mdMass: End Property
Public Property Let Mass(ByVal dMass As Double): mdMass = dMass: End Property
Public Property Get Parent() As CCar
Set Parent = mclsParent
End Property
Public Property Set Parent(clsCar As CCar)
Set mclsParent = clsCar
End Property
Public Property Get Speed() As Double
'references to parent properties
Speed = Me.Parent.WindSpeed * Me.Parent.Acceleration / Me.Mass
End Property
In a standard module
Sub GetSpeed()
Dim clsCar As CCar
Set clsCar = New CCar
clsCar.CarID = 1
clsCar.WindSpeed = 10
clsCar.Acceleration = 5
clsCar.Speedometer.Mass = 100
Debug.Print clsCar.Speed
End Sub
You have to make sure you destroy your parent/child relationship properly or you'll get a memory leak. I use CopyMemory to set up parent properties to avoid that particular problem. It's described here http://www.dailydoseofexcel.com/archives/2007/12/28/terminating-dependent-classes/#comment-29661