I am currently working in a multithreaded environment where I need to pass a reference as a global variable. The basic structure would look something like this:
Worker::JoyInit(TSet<Worker>& w)
{
UE_LOG(LogTemp, Warning, TEXT("w.num() = %d"), w.Num());
}
But the editor crashes every time I try to play it! I am not very comfortable with pointers so any quick advice would be greatly appreciated
I am calling JoyInit like so:
Worker::JoyInit(*queue);
and queue is defined as:
TSet<Worker>* queue = nullptr;
Ok so I figured out what I did wrong. My method call and initialization of queue variable were wrong. I changed the code to:
Worker::JoyInit(queue);
and
TSet<Worker> queue;
and it compiles.
Related
I am implementing logging functionality in Unreal Engine 4.27 (in C++). A key part of my code is a function that is called once per game-tick. This function is responsible for iterating over an array of actors that I would like to log data for, checking whether a new log entry should be written at this point in time and calling the necessary functions to do that.
I am iterating over elements of a TArray of UStructs: LogObject->LoggingInfo = TArray<FActorLoggingInformation>. This array is defined as a UProperty of LogObject. In the loop I have to change the values of the elements so I want to work with the original items and "label" the current item as "ActorLoggingInfo". I have seen this done generally in cpp and also with TArrays. And yet my code does not work, there is no error message, but ActorLoggingInfo is undefined, thus the if-condition is never met.
This is the for-loop:
for (FActorLoggingInformation& ActorLoggingInfo : LogObject->LoggingInfo) {
if (ActorLoggingInfo.LogNextTick == true) {
ActorLoggingInfo.LogNextTick = false;
...
}
...
}
This is the definition of FActorLoggingInformation:
USTRUCT(BlueprintType)
struct FActorLoggingInformation
{
GENERATED_BODY()
public:
FActorLoggingInformation()
{
}
FActorLoggingInformation(int32 LogTimer, AActor* Actor, FString LogName)
{
this->LogTimer = LogTimer;
this->LogNextTick = false;
...
}
// Specifies Logging Frequency in ms
UPROPERTY(BlueprintReadOnly, VisibleAnywhere)
int32 LogTimer;
bool LogNextTick;
...
};
This is the debugger at run-time:
Additional Notes:
1. Something that consistently works for me is omitting the &, using:
for (FActorLoggingInformation ActorLoggingInfo : LogObject->LoggingInfo)
However, this is creating useless duplicates on a per-tick basis and complicates applying changes to the original objects from within in the for-loop, so it is not a viable option.
2. I have also tried auto& instead of FActorLoggingInformation& as used in the examples above, but I encountered the same issue, so I thought it would be best to be as explicit as possible.
I would be very thankful if you had any ideas how I can fix this :)
Thanks in advance!
Thanks to Avi Berger for helping me find my problem!
In fact, ActorLoggingInfo was actually never undefined and the code within the body of the if-clause was also executed (it just didn't do what it was intended to do).
When stepping through the code in the debugger it never showed the steps within the if-body and ActorLoggingInfo was shown as undefined so when no logs were written, I assumed it was something to do with that instead of my output function not working properly. So lesson learnt, do not blindly trust the debugger :)
I've been trying to get a persistent object from a thread for hours.
I want to write a shared library in C++ that starts a persistent loop in a function.
In the following code snippets there is a class called Process. Process initializes a TCP/IP interface to read and write data from a Simulink model.
This is only for declaration and should not be important for this problem, but now you know what I talk about when mentioning the processes.
main.cpp
I know, it looks kinda ugly/unprofessional, but I'm fairly new to C++..
// frustrated attempt to make everything persistent
static vector<std::thread> processThreads;
static ProcessHandle processHandle;
static vector<std::promise<Process>> promiseProcess;
static vector<std::future<Process>> futureProcess;
EXPORT int initializeProcessLoop(const char *host, int port)
{
std::promise<Process> promiseObj;
futureProcess.push_back(std::future<Process>(promiseObj.get_future()));
processThreads.push_back(std::thread(&ProcessHandle::addProcess, processHandle, host, port, &promiseProcess[0]));
Process val = futureProcess[0].get();
processHandle.handleList.push_back(val);
return (processHandle.handleList.size() - 1);
}
ProcessHandle.cpp
The addProcess function from ProcessHandle creates the Process that should be persistent, adds it to a static vector member of ProcessHandle and passes the promise to the execution loop.
int ProcessHandle::addProcess(const char *address, int port, std::promise<Process> * promiseObj) {
Process process(address, port);
handleList.push_back(process);
handleList[handleList.size() - 1].exec(promiseObj);
return handleList.size() - 1;
}
To the main problem now...
If I change "initializeProcessLoop" to include:
if(processHandle.handleList[0].isConnected())
{
processHandle.handleList[0].poll("/Compare To Constant/const");
}
after i've pushed "val" to the processHandle.handleList everything works fine and I can poll the data as it should be.
If I instead poll it from - for examle - the main function, the loop crashes inside of the "initializeProcessLoop" because "Process val" is reassigned (?) with futureProcess[0].get().
How can I get the Process variable and the threaded loop to be consistent after the function returns?
If there are any questions to the code (and I bet there will be), feel free to ask. Thanks in advance!
PS: Obligatory "English is not my native language, please excuse any spelling errors or gibberish"...
Okay, first I have to declare, that the coding style above and following are by any means not best practice.
While Sam Varshavchik is still right with how to learn C++ the right way, just changing
Process val = futureProcess[0].get();
to
static Process val = futureProcess[0].get();
did the job.
To be clear: don't do this. It's a quick fix but it will backfire in the future. But I hope that it'll help anyone with a similar problem.
If anyone has a better solution (it can't get any worse, can it?), feel free to add your answer to this question.
I'm updating my V1 cocos2d-x app to V3 and I'm stuck on callbacks.
I can do call backs with lambdas like this, works fine -
auto mcb = CallFunc::create([this](){
this->doCallback(kEVENT_MENU_IS_ONSCREEN);
});
hex->runAction(Sequence::create(somethingthattakestime, mcb, NULL) );
However, I want to pass a CallFunc variable into a function, store it in my object, then use/call it at some point in the future.
In a class I define -
CallFunc * callfunc;
Set with a simple -
item->callfunc = callfunc;
Within a function -
void LBMenuAddMenuItemName( CallFunc * callfunc );
I also declare the CallFunc variable as static so it hangs around -
static auto doSoloPlay = CallFunc::create([this](){
CCLOG("doSoloPlay variable");
this->menuSoloPlay();
});
Later when I wish to use this, I do -
Sequence * seq = Sequence::create(callfunc,NULL);
somesprite->runAction(seq);
However, this ends badly with a SIGSEGV (GLThread).
Using typeid(callfunc).name() shows that callfunc is a CallFunc. Using setTag(69) in declaration and then getTag() before SIGSEGV does not return a sensible value.
Can someone explain what I'm doing wrong and the correct method for delayed callbacks?
Thank you!
LB
Tried many things then found this error goes away when I do a 'retain()' after the declaration -
doSoloPlay->retain();
This increases the reference count.
I don't quite know why I need this. My guess is that cocos2d-x classes may do some clever garbage collection?
If the function is called later as a callback, you need to retain the callback when you save it and release it at the right time.
The static declaration only save the address of your CCCallFunc but the class is destroyed before you wish to execute it.
hello everyone I have this snippet of the code:
void* Init(int N) {
Hand * DS = new Hand(N);
return (void*)DS;
//DS is static defined somewhere...
every time when I check in Debugger I receive the same error:
mi_cmd_var_create: unable to create variable objec
can somebody please explain why?
P.S. I know that this implementation of the function is not good, but it is what I have... Constructor of the Hand works perfectly!
This guy with the same problem solved it like:
If you have variables in your watch
window that you later eliminate from
your code then attempt to debug again
this error is generated. The fix is to
also delete the variable from the
watch list. At least this is how it
works in Eclipse Europa.
Im having a problem with a loop inside a C++ dll being called from VB. I want this loop to update a global variable, but when I call the function the variable does not update the first time round, but does so every subsequent time.
This is how I am trying to update the variable.
else
{
::nScore = nHighest;
if (nScore != 0)
{
::nColourOn++;
}
}
As a workaroud I am forcing the variable to be what I want in the VB code, but am not happy with this solution. Does anyone have any idea what might be causing this?
Many Thanks.
If the value of nHighest isn't initialized, nScore will be 0 and nColorOn won't be incremented. Is that the error you're seeing? If so, set nHighest, otherwise, it's working fine. :)