FMI functions call order(FMI 2.0) - fmi

Which call order is correct ?
1.
fmi2SetReal/Integer/Boolean/String
fmi2SetupExperiment
fmi2EnterInitializationMode
or
2.
fmi2SetupExperiment
fmi2SetReal/Integer/Boolean/String
fmi2EnterInitializationMode
As per the standard:
"Before calling fmi2EnterInitializationMode function, all variables with
attribute can be set with the
“fmi2SetXXX” functions.fmi2SetupExperiment must be called at least once before calling
fmi2EnterInitializationMode, in order that startTime is defined."
But the order is not specified.
Pseudo code in FMI standard has fmi2SetXXX followed by fmi2SetupExperiment
//communication step size
h = 0.01;
// set all variable start values (of "ScalarVariable / / start")
s1_fmi2SetReal/Integer/Boolean/String(s1, ...);
s2_fmi2SetReal/Integer/Boolean/String(s2, ...);
//Initialize slaves
s1_fmi2SetupExperiment(s1, fmi2False, 0.0, startTime, fmi2True, stopTime);
s2_fmi2SetupExperiment(s1, fmi2False, 0.0, startTime, fmi2True, stopTime);
s1_fmi2EnterInitializationMode(s1);
Which call order is correct and why ?
Thanks in advance.

In section 3.2.3 State Machine of Calling Sequence of the FMI Standard version 2.0.1 it's stated that you are allowed to call fmi2SetSEA and fmi2SetupExperiment, where SEA is one of Real, Integer, Boolean, String for a variable with variability not equal "constant", that has initial="exact" or "approx", while in state instantiated.
So the order does not matter and both ways must be supported by every implementation of the FMI 2.0 supporting tool.
And since fmi2SetupExperiment and fmiSetSEA don't change the same data it shouldn't matter any way, as long fmi2EnterInitializationMode wasn't called.

Related

Nodejs (Infinispan) : Does Infinispan put method returns null for key inserted in cache for first time?

I have been reviewing the infinispan documentation and overloaded put method returns the value being replaced, or null if nothing is being replaced.
I am using overloaded put method with nodejs and it's not returning expected data, getting undefined.
how can I achieve this with nodejs?
Looked at the documentation, need assistance to understand the behavior with Nodejs
Documentation Link : https://docs.jboss.org/infinispan/9.2/apidocs/org/infinispan/commons/api/BasicCache.html#put-K-V-
V put(K key,
V value,
long lifespan,
TimeUnit unit)
An overloaded form of put(Object, Object), which takes in lifespan parameters.
Parameters:
key - key to use
value - value to store
lifespan - lifespan of the entry. Negative values are interpreted as unlimited lifespan.
unit - unit of measurement for the lifespan
Returns:
the value being replaced, or null if nothing is being replaced.
Looked at the documentation, need assistance to understand the behavior with Nodejs
From https://github.com/infinispan/js-client/blob/main/lib/infinispan.js#L327 it looks like put's third argument opts can have property previous that makes it return the old value, so try:
const oldValue = client.put('key', 'value', { previous: true })

There is a problem in memory-management of object in lua programming

I'm making a shooting game with solar 2d, everything was working fine but after some time I feel that the games frame rate is dropping, but I did steps to delete my laser when the task finishes
local function fireLaser()
audio.play( fire sound )
newLaser = display.newImageRect( mainGroup, objectSheet, 5, 14, 40 )
physics.addBody( newLaser, "dynamic", { isSensor=true } )
newLaser.isBullet = true
newLaser.myName = "laser"
newLaser.x = ship.x
newLaser.y = ship.y
newLaser:toBack()
transition.to( newLaser, { y=400, time=500,
onComplete = function()display.remove( newLaser ) end
} )
end
I think what is happening, that onComplete calls the display.remove( newLaser ) after 600ms but the function again called but in less than 600ms , say 400ms, so display.remove( newLaser ) dump the first object which is called on first clicked and remove the second one or say latest one, but if the player continuously clicking the fire laser button, and each click has a difference of less than 600 ms, then nothing would be removed. Please Help me as soon as possible.
If you are only using newLaser inside of fireLaser you should define it as a local variable.
This will seem like a insignificant change, but when you do
onComplete = function() display.remove(newLaser) end
you are creating a enclosed function.
When a function is written enclosed in another function, it has full access to local variables from the enclosing function; this feature is called lexical scoping. Although that may sound obvious, it is not. Lexical scoping, plus first-class functions, is a powerful concept in a programming language, but few languages support that concept. - Programming in Lua: 6.1 – Closures
This does not work when newLaser is global because each call to fireLaser is acting on the same global variable of newLaser rather than a unique local variable.

How does the update diff work in AzerothCore?

The worldserver source code is full of Update methods that take as input a diff integer value:
How does it work?
And how is this linked to the "Update time diff" from the .server info command?
To fully understand how this works, it's necessary to have a look at the main World run process.
WorldRunnable::run()
File: src/server/worldserver/WorldThread/WorldRunnable.cpp
The method void WorldRunnable::run() is the "Main heartbeat for the World". This method runs the whole world process.
Inside it, there is a while loop that runs as long as the world is supposed to keep running:
void WorldRunnable::run()
{
uint32 realCurrTime = 0;
uint32 realPrevTime = getMSTime();
///- While we have not World::m_stopEvent, update the world
while (!World::IsStopped())
{
++World::m_worldLoopCounter;
realCurrTime = getMSTime();
uint32 diff = getMSTimeDiff(realPrevTime, realCurrTime);
sWorld->Update( diff );
realPrevTime = realCurrTime;
uint32 executionTimeDiff = getMSTimeDiff(realCurrTime, getMSTime());
devDiffTracker.Update(executionTimeDiff);
avgDiffTracker.Update(executionTimeDiff > WORLD_SLEEP_CONST ? executionTimeDiff : WORLD_SLEEP_CONST);
// ... some more code here
}
// at this point the world process is terminating
// ... some more code here
What this loop really does is basically:
1) calculate the elapsed time (in milliseconds) since the previous iteration, this will be the diff
2) call the sWorld->Update( diff ); function, that contains all the world process logic (see below) and passing the diff to it
3) calculate how much time it took to run sWorld->Update( diff ); and update the devDiffTracker and its average avgDiffTracker. These values will be displayed by the .server info command.
World::Update(uint32 diff)
File: src/server/game/World/World.cpp
The World::Update(uint32 diff) function gets constantly called by the main worldserver loop process and every time it takes in input the amount diff of elapsed time since the last call.
This function is responsible for constantly updating the world, this is where all the magic happens.
Timers
There are a set of timers (defined in World.h that are being updated within the World::Update function:
/// Timers for different object refresh rates
enum WorldTimers
{
WUPDATE_AUCTIONS,
WUPDATE_WEATHERS,
WUPDATE_UPTIME,
WUPDATE_CORPSES,
WUPDATE_EVENTS,
WUPDATE_CLEANDB,
WUPDATE_AUTOBROADCAST,
WUPDATE_MAILBOXQUEUE,
WUPDATE_PINGDB,
WUPDATE_5_SECS,
WUPDATE_COUNT
};
For example, WUPDATE_AUTOBROADCAST is responsible for the period global messages defined in the acore_auth.autobroadcast table.
Tasks
The World::Update function also takes care of many timed-tasks, for example:
/// Handle daily quests reset time
if (m_gameTime > m_NextDailyQuestReset)
ResetDailyQuests();
Calling Update(diff) functions of Managers
In AzerothCore there are singleton classes called Managers (Mgr) that handle specific parts of the game. For example BattlegroundMgr handles the Battlegrounds (BGs).
Those classes have their own Update(uint32 diff) functions and they are called by World::Update that passes down the diff to them, for example:
sBattlegroundMgr->Update(diff);
sOutdoorPvPMgr->Update(diff);
sBattlefieldMgr->Update(diff);
/// ... there are more!
OnWorldUpdate hook
Last but not least, it calls sScriptMgr->OnWorldUpdate(diff);.
This is part of the AzerothCore Module System, and defines a hook that can be used by third-part modules to attach custom logic to the World::Update function.

My segmented picker has normal Int values as tags, How is this passed to and from CoreData?

My SwiftUI segmented control picker uses plain Int ".tag(1)" etc values for its selection.
CoreData only has Int16, Int32 & Int64 options to choose from, and with any of those options it seems my picker selection and CoreData refuse to talk to each other.
How is this (??simple??) task achieved please?
I've tried every numeric based option within CoreData including Int16-64, doubles and floats, all of them break my code or simply just don't work.
Picker(selection: $addDogVM.gender, label: Text("Gender?")) {
Text("Boy ♂").tag(1)
Text("?").tag(2)
Text("Girl ♀").tag(3)
}
I expected any of the 3 CoreData Int options to work out of the box, and to be compatible with the (standard) Int used by the picker.
Each element of a segmented control is represented by an index of type Int, and this index therefore commences at 0.
So using your example of a segmented control with three segments (for example: Boy ♂, ?, Girl ♀), each segment is represented by three indexes 0, 1 & 2.
If the user selects the segmented control that represents Girl ♀, then...
segmentedControl.selectedSegmentIndex = 2
When storing a value using Core Data framework, that is to be represented as a segmented control index in the UI, I therefore always commence with 0.
Everything you read from this point onwards is programmer preference - that is and to be clear - there are a number of ways to achieve the same outcome and you should choose one that best suits you and your coding style. Note also that this can be confusing for a newcomer, so I would encourage patience. My only advice, keep things as simple as possible until you've tested and debugged and tested enough to understand the differences.
So to continue:
The Apple Documentation states that...
...on 64-bit platforms, Int is the same size as Int64.
So in the Core Data model editor (.xcdatamodeld file), I choose to apply an Integer 64 attribute type for any value that will be used as an Int in my code.
Also, somewhere, some time ago, I read that if there is no reason to use Integer 16 or Integer 32, then default to the use of Integer 64 in object model graph. (I assume Integer 16 or Integer 32 are kept for backward compatibility.) If I find that reference I'll link it here.
I could write about the use of scalar attribute types here and manually writing your managed object subclass/es by selecting in the attribute inspector Class Codegen = Manual/None, but honestly I have decided such added detail will only complicate matters.
So your "automatically generated by Core Data" managed object subclass/es (NSManagedObject) will use the optional NSNumber? wrapper...
You will therefore need to convert your persisted/saved data in your code.
I do this in two places... when I access the data and when I persist the data.
(Noting I assume your entity is of type Dog and an instance exists of dog i.e. let dog = Dog())
// access
tempGender = dog.gender as? Int
// save
dog.gender = tempGender as NSNumber?
In between, I use a "temp" var property of type Int to work with the segmented control.
// temporary property to use with segmented control
private var tempGender: Int?
UPDATE
I do the last part a little differently now...
Rather than convert the data in code, I made a simple extension to my managed object subclass to execute the conversion. So rather than accessing the Core Data attribute directly and manipulating the data in code, now I instead use this convenience var.
extension Dog {
var genderAsInt: Int {
get {
guard let gender = self.gender else { return 0 }
return Int(truncating: gender)
}
set {
self.gender = NSNumber(value: newValue)
}
}
}
Your picker code...
Picker(selection: $addDogVM.genderAsInt, label: Text("Gender?")) {
Text("Boy ♂").tag(0)
Text("?").tag(1)
Text("Girl ♀").tag(2)
}
Any questions, ask in the comments.

UltraNumericEditor allows values larger than MaxValue setting

Using infragistics UltraNumericEditor, if I set the .MaxValue to 50, the control will allow me to enter decimals larger than the limit (for example, 50.99)
I see the same behavior if I set the .MaxValue property to 50.01 (can set values larger)
I can obviously resolve this in code but resetting the value, but it seems like the control should do this on its own.
Is there something I'm missing in how to use these properties correctly?
I suppose you are using the UltraNumericEditor with the property Style set to Decimal (or Double).
In this case the control allows you to insert digits that render the input invalid with respect to the property MaxValue. However, by default, you are not able to exit the control until the value is correct.
If you want, you can use the event ValidationError that gives your the ValidationErrorEventArgs parameter. This parameter contains the LastValidValue property to reset the wrong value, the RetainFocus to let your user exit from the editor (or, if you prefer, display an error message)
private void ultraNumericEditor1_ValidationError(object sender, ValidationErrorEventArgs e)
{
// Reset the content to the last valid value and allow the exit from the editor
ultraNumericEditor1.Value = e.LastValidValue;
e.RetainFocus = false;
// In alternative display a message, but leave the wrong value to be reedited
// DisplayValidationMessage("The max value allowed is 50.00");
}
The problem was a result of the IEditorDataFilter for percentage values.
Infragistics recommends, and I had implemented, an IEditorDataFilter which converts decimal percentages (.5 = 50%) into percentages for display.
This filter is applied before the validation for the control takes place. Therefore, setting the MaxValue to "50" allowed me to enter "50.99" but not "51"... normally this would have caused a validation error as per Steve's answer. However, because of the IEditorDataFilter applied to this control, the value was automatically converted to .5099 and this new value does not violate the constraint.
The solution I implemented was to check the value in the Validated event to see if it was larger than the MaxValue / 100, and if so to set it equal to the same.

Resources