I've been working on a PC Developer project that saves and loads component properties to a config file via PropertyManager. I've run into a consistent, repeatable issue, and having dug into it, I believe I now understand the actual cause.
Whenever I call PropertyManager1::Save / PropertyManager1::Load, or other multi-step component macros, from inside an event handler — tested across Ev_Property, Ev_Initialise, Ev_Start, Ev_Stop, Ev_PostInitialise and Ev_ProjectClosedown — it either silently fails (e.g. a 0-byte config file, no error) or doesn't complete properly. Simple calculations and flag assignments inside the same event handlers work fine every time.
This is standard interrupt behaviour: the wiki describes an event as functioning "similarly to an Interrupt," and specifically as "a simulation-side interrupt." Events are interrupts, and interrupt rules apply — you can call a component's macro from one so long as it's fairly simple and not something that could already be running elsewhere at the same time. Property Manager's Save/Load and CSV Read/Write are multi-step and share state with the rest of the project, so calling them from an event risks the interrupt cutting in mid-sequence — exactly matching the failures I've seen.
The workaround, and the correct way to do this: set a flag inside the event handler, then consume that flag afterwards from Main, in a normal execution context — that works reliably every time.
Could you confirm this is indeed how events are implemented under the hood? If so, it'd be worth stating plainly in the docs, since it isn't spelled out anywhere currently and cost a fair bit of time to track down. Original save/load symptom for reference can be found here
Thanks.
Are API/broadcast events restricted from calling component or user macros?
-
medelec35
- Valued Contributor
- Posts: 2422
- http://meble-kuchenne.info.pl
- Joined: Wed Dec 02, 2020 11:07 pm
- Has thanked: 773 times
- Been thanked: 833 times
-
Steve-Matrix
- Matrix Staff
- Posts: 2031
- Joined: Sat Dec 05, 2020 10:32 am
- Has thanked: 302 times
- Been thanked: 471 times
Re: Are API/broadcast events restricted from calling component or user macros?
Are you able to distil the issue you are having into a very simple project and then explain what you're seeing?
-
Steve-Matrix
- Matrix Staff
- Posts: 2031
- Joined: Sat Dec 05, 2020 10:32 am
- Has thanked: 302 times
- Been thanked: 471 times
Re: Are API/broadcast events restricted from calling component or user macros?
Sorry - I see that there's a succinct project in the linked post. I'll have a look. Although you seem to have solved the issue anyway and so hopefully you're good to continue?
Historically, Events and a lot of the simulation API have been solely for internal use to allow us to create components. For this reason, the public documentation surrounding them is probably lacking. I'll see if we can find some time to improve this.
-
medelec35
- Valued Contributor
- Posts: 2422
- Joined: Wed Dec 02, 2020 11:07 pm
- Has thanked: 773 times
- Been thanked: 833 times
Re: Are API/broadcast events restricted from calling component or user macros?
Hi Steve.
Thanks.
I will create a short example for a demonstration,
Yes, Property manger is now working, so at least can nnow save and load properties within my apps.
Thanks.
I will create a short example for a demonstration,
Yes, Property manger is now working, so at least can nnow save and load properties within my apps.
Martin
-
medelec35
- Valued Contributor
- Posts: 2422
- Joined: Wed Dec 02, 2020 11:07 pm
- Has thanked: 773 times
- Been thanked: 833 times
Re: Are API/broadcast events restricted from calling component or user macros?
Hi Steve.
I have attached a simplest version to demo the issue I'm referring to.
The idea is to save a property to a cfg file as soon as its changed, then display value when sim has stopped.
If macros to do that is placed within property, the file generated will be blank at 0B.
If I disable all within Ev_property event, an enable all within main, it works as expected.
I have attached a simplest version to demo the issue I'm referring to.
The idea is to save a property to a cfg file as soon as its changed, then display value when sim has stopped.
If macros to do that is placed within property, the file generated will be blank at 0B.
If I disable all within Ev_property event, an enable all within main, it works as expected.
- Attachments
-
- csv save property test.fcpcd
- (15.17 KiB) Downloaded 6 times
- (view online)
Martin
-
Steve-Matrix
- Matrix Staff
- Posts: 2031
- Joined: Sat Dec 05, 2020 10:32 am
- Has thanked: 302 times
- Been thanked: 471 times
Re: Are API/broadcast events restricted from calling component or user macros?
Thanks, Martin.
I can see the issue and it seems to be because an error is returned when trying to open the file within the component. BTW I debugged this by essentially recreating the CSV_ReadWrite1 calls as their base FileSCADA1 calls and monitoring the return values. In the Ev_Property, the error occurs and it also occurs in the Main macro.
Erasing the file is done by deleting the file and then recreating it, and I think the problem is the deletion and file creation are not blocking functions, which causes an error because the file cannot be opened shortly after it is deleted.
If you change your project and pass "0" as the second parameter to the CSV_ReadWrite1::OpenFile call (i.e. don't erase the file), then you will see the writes occurring ok. Obviously reading the file will read the first 'cell' and not the latest entry, so this is not a solution.
I think a proper fix for this would be to add a way of erasing an open file rather than deleting the file and creating a new one. Or allow the CSV_ReadWrite component to write to specific 'cells'. I'll ask Ben and see what he thinks as he knows these components better than I do.
I can see the issue and it seems to be because an error is returned when trying to open the file within the component. BTW I debugged this by essentially recreating the CSV_ReadWrite1 calls as their base FileSCADA1 calls and monitoring the return values. In the Ev_Property, the error occurs and it also occurs in the Main macro.
Erasing the file is done by deleting the file and then recreating it, and I think the problem is the deletion and file creation are not blocking functions, which causes an error because the file cannot be opened shortly after it is deleted.
If you change your project and pass "0" as the second parameter to the CSV_ReadWrite1::OpenFile call (i.e. don't erase the file), then you will see the writes occurring ok. Obviously reading the file will read the first 'cell' and not the latest entry, so this is not a solution.
I think a proper fix for this would be to add a way of erasing an open file rather than deleting the file and creating a new one. Or allow the CSV_ReadWrite component to write to specific 'cells'. I'll ask Ben and see what he thinks as he knows these components better than I do.
-
medelec35
- Valued Contributor
- Posts: 2422
- Joined: Wed Dec 02, 2020 11:07 pm
- Has thanked: 773 times
- Been thanked: 833 times
Re: Are API/broadcast events restricted from calling component or user macros?
Thanks, Steve.
Brilliant, that does work.
It's amazing what a binary number can do.
If the error occurs in the main macro, how comes there is not an issue?
Brilliant, that does work.
It's amazing what a binary number can do.
If the error occurs in the main macro, how comes there is not an issue?
Martin
-
BenR
- Matrix Staff
- Posts: 2300
- Joined: Mon Dec 07, 2020 10:06 am
- Has thanked: 635 times
- Been thanked: 842 times
Re: Are API/broadcast events restricted from calling component or user macros?
Event macros essentially call all the code but strip out delays because they need to be fast to avoid hanging Flowcode.
So any delay that allowed time for the file to be erased and then recreated would be gone in a macro called from an event compared to the same macro called from the simulation.
Would this explain things?
You could use a timer event to effectively create the same delay using events.
So any delay that allowed time for the file to be erased and then recreated would be gone in a macro called from an event compared to the same macro called from the simulation.
Would this explain things?
You could use a timer event to effectively create the same delay using events.
Regards Ben Rowland - MatrixTSL
Flowcode Online Code Viewer (Beta) - Flowcode Product Page - Flowcode Help Wiki - My YouTube Channel
Flowcode Online Code Viewer (Beta) - Flowcode Product Page - Flowcode Help Wiki - My YouTube Channel
-
medelec35
- Valued Contributor
- Posts: 2422
- Joined: Wed Dec 02, 2020 11:07 pm
- Has thanked: 773 times
- Been thanked: 833 times
Re: Are API/broadcast events restricted from calling component or user macros?
Ah, that explains the issue, thanks Ben.
Steve's solution works well, but if using timer method, would the Ev_Timer call be immediately after CSV_ReadWrite::Openfile, then CSV_ReadWrite::AddString will be removed from properties and placed within Ev_timer set to 50ms?
Steve's solution works well, but if using timer method, would the Ev_Timer call be immediately after CSV_ReadWrite::Openfile, then CSV_ReadWrite::AddString will be removed from properties and placed within Ev_timer set to 50ms?
Martin