I have tried to look up the "identifier not found" error only to find posts where the function must be moved outside the main loop or should use a forward declaration. However, my script is used as a module for a game engine thus has no real main loop and the function in question is called by a different function above the failing line with no issues:
// Create a Steam ID
CSteamID Steam::createSteamID(uint32 steamID, int accountType){
CSteamID cSteamID;
if(accountType < 0 || accountType >= k_EAccountTypeMax){
accountType = 1;
}
cSteamID.Set(steamID, EUniverse(k_EUniversePublic), EAccountType(accountType));
return cSteamID;
}
// Set a Steam user as someone recently played with
void Steam::setPlayedWith(int steamID){
if(SteamFriends() == NULL){
return;
}
CSteamID friendID = createSteamID(steamID);
SteamFriends()->SetPlayedWith(friendID);
}
// Get friend's Steam username
String getFriendPersonaName(int steamID){
if(SteamFriends() == NULL || steamID == 0){
return "";
}
CSteamID friendID = createSteamID(steamID);
bool isDataLoading = SteamFriends()->RequestUserInformation(friendID, true);
if(!isDataLoading){
return SteamFriends()->GetFriendPersonaName(friendID);
}
}
The ID creation function sits at the very top and these two functions come much later. The first one (setPlayedWith) succeeds no problem but the second one (getFriendPersonaName) fails with: 'createSteamID': identifier not found when compiling the script.
I'm kind of at a loss and hopefully someone can point me in the right direction.
if getFriendPersonaName() is a member function then you have forgotten to define it the correct way so it will look like:
string Steam::getFriendPersonaName(int steamID)...
if it is not a member then you can't access it. however you can Only access it if getFriendPersonaName() is a friend function where you should edit the signature to:
String getFriendPersonaName(int steamID, const steam& rhs);
Related
I have literally tried everything but still in vain. This here is InvoiceJournalExpParticipantProvider class that is supposed to provide me partici[ant names inside the workflow (all of this is custom code). Now what i want is to pass the LedgerJounalTrans table instead of the VendInvoiceInfoTable or VendInvoiceInfoLine table. I cannot seem to find a way to do this. I tried using the following code
else if (_context.parmTableId() == tableNum(LedgerJournalTrans))
{
ledgerJournalTrans = LedgerJournalTrans::findRecId(_context.parmRecId(),false);
}
But it constantly gives me an error either telling me that the operand types are of not the same types or the number of arguments passed are invalid although when i go and check the findRecId() method of ledgerJournalTrans table there are only two params being passed.
public WorkflowUserList resolve(WorkflowContext _Context, WorkflowParticipantToken _participantTokenName)
{
WorkflowUserList userList = WorkflowUserList::construct();
VendInvoiceInfoTable vendInvoiceInfoTable;
VendInvoiceInfoLine vendInvoiceInfoLine;
VendInvoiceInfoLine_Project vendInvoiceInfoLine_Project;
WorkflowParticipantExpenToken workflowParticipantExpenToken;
WorkflowParticipantExpenTokenLine workflowParticipantExpenTokenLine;
RefRecId dimensionAttributeSetRecId;
MarkupTrans markupTrans;
CompanyInfo legalEntity;
ProjTable projTable;
HcmWorker worker;
DirPersonUser personUser;
HcmPositionDetail hcmPositionDetail;
HcmPosition hcmPosition;
HcmPositionWorkerAssignment hcmPositionWorkerAssignment;
LedgerJournalTrans ledgerJournalTrans;
// check participant token name is given otherwise throw error
if(!_participantTokenName)
{
throw error('Participant name');
}
userList.add('Admin');
if (!_participantTokenName)
{
throw error("#SYS105453");
}
workflowParticipantExpenToken = WorkflowParticipantExpenToken::findName(
this.documentType(),
_participantTokenName);
if (!workflowParticipantExpenToken)
{
throw error(strFmt("#SYS313865", _participantTokenName));
}
if (_context.parmTableId() == tableNum(VendInvoiceInfoTable))
{
vendInvoiceInfoTable = VendInvoiceInfoTable::findRecId(_context.parmRecId());
}
else if (_context.parmTableId() == tableNum(VendInvoiceInfoLine))
{
vendInvoiceInfoTable = VendInvoiceInfoLine::findRecId(_context.parmRecId()).vendInvoiceInfoTable();
}
I'm new to the Unreal Engine and C++...
I'm trying to get the assigned Key of an Axis. I found out that the information are stored in the DefaultInput.ini file but how do i access these data programmatically?
There's a GetAxisValue(const FName) method but it does not return anything.
FString AxisName = "MoveForward";
auto value = PlayerInputComponent->GetAxisValue(FName(*AxisName));
What am I doing wrong? I would really appreciate your help.
Im not sure because I use Blueprints most of the time for this, but one way to get the value is to bind it to a method.
(Example of the AFPSCharacter Template)
PlayerInputComponent->BindAxis("MoveForward", this, &APawn::MoveForward);
And later use it in the method
void AFPSCharacter::MoveForward(float Value){
//for example print the val
UE_LOG(LogTemp, Warning, TEXT("%f"), Value);
}
this was my first thought too but unfortunately you can't get the Keys, you just bind the method to an axis name. The MoveForward's "Value" parameter hold the scale value but not the Key value. 1.0f for example when you press "W" or -1.0f when you press "S".
I've already found a solution for my issue. The GetAxisValue(FName) is the wrong method for this purpose.
Instead I found the UInputSettings class that contains a method named GetAxisMappingByName(FName, TArray)
Here a code snippet how it works:
// Get the instance of the InputSettings
UInputSettings* InputSettings = UInputSettings::GetInputSettings();
// AxisMappings with all the information will be stored here
TArray<FInputAxisKeyMapping> VerticalKeys;
TArray<FInputAxisKeyMapping> HorizontalKeys;
// Load the AxisMappings
InputSettings->GetAxisMappingByName(FName("MoveForward"), VerticalKeys);
InputSettings->GetAxisMappingByName(FName("MoveRight"), HorizontalKeys);
// Each MovementKey gets its own variable
FKey ForwardKey;
FKey BackKey;
FKey LeftKey;
FKey RightKey;
// Assign each key to the correct direction
for (FInputAxisKeyMapping verticalKey : VerticalKeys)
{
if (verticalKey.Scale == 1.0f)
ForwardKey = verticalKey.Key;
else if (verticalKey.Scale == -1.0f)
BackKey = verticalKey.Key;
}
for (FInputAxisKeyMapping horizontalKey : HorizontalKeys)
{
if (horizontalKey.Scale == 1.0f)
RightKey = horizontalKey.Key;
else if (horizontalKey.Scale == -1.0f)
LeftKey = horizontalKey.Key;
}
Is there a better solution for assigning the keys than using for loops? Feel free to correct my code since I'm not really an expert in C++. ;-)
My TestNG test implementation throws an error despite the expected value matches with the actual value.
Here is the TestNG code:
#Test(dataProvider = "valid")
public void setUserValidTest(int userId, String firstName, String lastName){
User newUser = new User();
newUser.setLastName(lastName);
newUser.setUserId(userId);
newUser.setFirstName(firstName);
userDAO.setUser(newUser);
Assert.assertEquals(userDAO.getUser().get(0), newUser);
}
The error is:
java.lang.AssertionError: expected [UserId=10, FirstName=Sam, LastName=Baxt] but found [UserId=10, FirstName=Sam, LastName=Baxt]
What have I done wrong here?
The reason is simple. Testng uses the equals method of the object to check if they're equal. So the best way to achieve the result you're looking for is to override the equals method of the user method like this.
public class User {
private String lastName;
private String firstName;
private String userId;
// -- other methods here
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!User.class.isAssignableFrom(obj.getClass())) {
return false;
}
final User other = (User) obj;
//If both lastnames are not equal return false
if ((this.lastName == null) ? (other.lastName != null) : !this.lastName.equals(other.lastName)) {
return false;
}
//If both lastnames are not equal return false
if ((this.firstName == null) ? (other.firstName != null) : !this.firstName.equals(other.firstName)) {
return false;
}
//If both lastnames are not equal return false
if ((this.userId == null) ? (other.userId != null) : !this.userId.equals(other.userId)) {
return false;
}
return true;
}
}
and it'll work like magic
It seems you are either comparing the wrong (first) object or equals is not correctly implemented as it returns false.
The shown values are just string representations. It doesn't actually mean that both objects have to be equal.
You should check if userDAO.getUser().get(0) actually returns the user you are setting before.
Posting the implementation of User and the userDAO type might help for further clarification.
NOTE: Note directly related to this question but it's answer to my issue that got me to this question. I am sure more ppl might end-up on this post looking for this solution.
This is not precisely the a solution if Equals method needs overriding but something that I very commonly find myself blocked due to:
If you have used Capture and are asserting equality over captured value, please be sure to get the captured value form captured instance.
eg:
Capture<Request> capturedRequest = new Capture<>();
this.testableObj.makeRequest(EasyMock.capture(capturedRequest))
Assert.assertEquals(capturedRequest.getValue(), expectedRequest);
V/S
Assert.assertEquals(capturedRequest, expectedRequest);
while the compiler wont complain in either case, the Assertion Obviously fails in 2nd case
I wanted to make a general function that would search for a class type in a node and returns its address. It is defined below
SoNode* searchandgive(SoType searchtype, SoNode* searchnode)
{
SoSearchAction mysearch;
mysearch.setType(searchtype);
mysearch.setInterest(SoSearchAction::FIRST);
mysearch.apply(searchnode);
if (mysearch.getPath() == NULL) {
std::cout<<"No property of this type was found";
}
SoPath* mypath=mysearch.getPath();
return mypath->getTail();
}
But when I pass a search type like SoCoordinate3::getClassTypeId() and the node to be searched for senode as given below:
SoCoordinate3 * mycoords=(SoCoordinate3*) searchandgive(SoCoordinate3::getClassTypeId(),senode);
const SbVec3f *s=mycoords->point.getValues(0);
std::cout<<" " <<s->getValue()[25]; // Some point
But the last line is generating a Unhandled Exception Error. Please tell what am I doing wrong here. The last line is valid since the same written inside the scope of the function works but not here.
With this you are standing that mysearch.getPath() could be null:
if (mysearch.getPath() == NULL) {
std::cout<<"No property of this type was found";
}
but below you are using that without any check:
SoPath* mypath=mysearch.getPath();
return mypath->getTail();
so this can raise an Unhandled Exception.
Another poitn is the line:
std::cout<<" " <<s->getValue()[25]; // Some point
There is no check about how many points are in the vector, and this as well could cause an exception.
I have a do-while loop that needs to log a message once (so it doesn't clutter the log) each time its status (e.g. pass/fail) changes, but still has to do other things each time it goes through the loop. Using a simple boolean variable can basically tell you if you've already logged that message, which works once you're in a known condition. However, if you want the message to be printed the first time in either case (pass/fail), you have to account for that. For example, if you default your condition to true, and it is, in fact, true the first time, it won't log the 'True' message b/c it thinks it was already true (and vice-versa for i.c. false).
This seems like it would be a good place for a nullable boolean with i.c.=Null, but in languages where those aren't present, what's one to do?
The simplest solution I could think of would be to use an extra boolean variable like 'firstTime = True', but using that always bothers me as an elementary workaround when I feel like there should be a more delicate way to handle it. Another option is to use the breakout condition of the do-while as your initial condition for whatever variable you're using as your conditional, but that can be confusing when someone reads int status = STATUS_QUIT, and it certainly requires more explanatory comments than bool firstTime = true. A third option would be to use an enum instead of a bool and have {firstTime, true, false} or something.
Are there other reasons for using one over the other, or are there better ways of doing this?
Code example with two options I came up with:
Using bool firsttime:
bool firstTime = true, infoFound = false;
do
{
if (getInfo())
{
if (!infoFound)
{
// log it (ONCE)(important)
infoFound = true;
}
// use info (every time)
}
else if (infoFound || firstTime)
{
// log it (ONCE)(important)
infoFound = false;
firstTime = false;
}
// FYI, WaitForStatusUpdate is a blocking call...
} while (STATUS_QUIT != WaitForStatusUpdate());
Use the while loop 'break-out condition' as the initial condition for a check variable:
(status is updated at the end of the do-while, so the do section will not be executed ever again if status == breakOutCondition; we can use this to our advantage here and set status = breakOutContition initially - the first time through it will be breakOutCondition but any subsequent loop will be something else... Still not sure I like this as it's kind of a hack...
bool infoFound = false;
int status = STATUS_QUIT;
do
{
if (getInfo())
{
if (!infoFound)
{
// log it (ONCE)(important)
infoFound = true;
}
// use info (every time)
}
else if (infoFound || firstTime)
{
// log it (ONCE)(important)
infoFound = false;
}
status = WaitForStatusUpdate();
} while (STATUS_QUIT != status);
(I'm tagging this as c++ since that's what I'm using, but this really could apply to any language with similar constructs)
Wouldn't an enum be clearer?
enum State { Unknown, Pass, Fail };
State state = Unknown;
...
State newState = getInfo() ? Pass : Fail;
if (newState != state) { log(); state = newState; }
C++ almost has nullable booleans, boost::optional<bool> would do the trick I believe.
One common way to do this in C++ is a stream wrapper that you create in the proper context, and it remembers for example how many times it's flushed and prevents further logging from happening. You just do your logging as normal and let the stream decide whether to send it on to the wrapped stream.