View Full Version : problem with automatic generation of objects by using a user library and c++
Martin Saler
10-25-2007, 05:29 AM
Hi @all!
We have a problem with automatic generation of objects by using a user library and c++ code since we use Flexsim 4.
We created a user library “foo.fsl” with an object “bar”. This object has a message trigger in with we use some c++ code (code state is set to c++).
When we load the model we call a method “Initialize()” with is exported in a static library “myLib.lib”. This method loads the library “foo.fsl” and creates some “bar” objects. The problem is that during the creation of the bar-objects the code state switches from c++ to felxscript. I tried the method “toggleallcodestates(…, 1)” to set the state manually to c++ but this does also not work. I also tried to lock the state.
If I create the objects my hand (drag and drop) the failure does not occur and the code state is c++.
Is this a problem of Flexsim 4? What can I do? Are there some other methods to change the state?
Greets from sunny Austria
Martin
Steven Hamoen
10-25-2007, 06:46 AM
Hi Martin,
Have you tried to put the messagetrigger also in your dll/lib and toggle the message trigger as dll and call the messagetrigger from the dll?
I know it doesn't answer your question, but it might solve it and prevent you from the need of compiling.
Because unless you are able to make a small model to reproduce your problem it sounds like the problem could be quite deep or in the code you created so that is very difficult to solve from a distance.
Steven
Martin Saler
10-30-2007, 06:36 AM
Hi Steven!
How are you? Thx for your answer!
The messagetrigger just calls the code written in the dll/lib. So it is necessary that the code flag of the created object is c++ and not flexscript.
If I create an object out of the user library the flag will switch from c++ to flexscript. If I do the same with the mouse everything is fine.
The phenomenon does not occur with Flexsim 3 just with Flexsim 4.
Allthough I use the toggleallcodestaes-command the problem still occures.
Here are the main code snippets:
//load lib
if(!objectexists(node("MAIN://project//userlibrary//TransportLib")))
{
libname = concat(cdir(), "libraries//TransportatLib.fsl");
newlib = tonode(loaduserlibrary(tonum(apchar(libname)), 0, 0, 0));
}
...
//create object
fsnode *obj = createinstance(node("MAIN://project//userlibrary//Transportation//Branch"), model());
//toggle all code states to c++
toggleallcodestates(obj, 1);
...
Thanks for helping me and greets from Austria
Martin
Hi Martin,
Have you tried to put the messagetrigger also in your dll/lib and toggle the message trigger as dll and call the messagetrigger from the dll?
I know it doesn't answer your question, but it might solve it and prevent you from the need of compiling.
Because unless you are able to make a small model to reproduce your problem it sounds like the problem could be quite deep or in the code you created so that is very difficult to solve from a distance.
Steven
Anthony Johnson
10-30-2007, 08:40 AM
If you are using a user library object, you should not use the createinstance() command. Instead either use the createcopy() command or the dropuserlibraryobject() command. Also, your paths do not need the double forward slash //. Only the backslash needs to be doubled because the backslash is an escape character in c++.
Steven Hamoen
10-31-2007, 07:51 AM
Hi Martin,
I'm doing fine, thanx.
The messagetrigger just calls the code written in the dll/lib. So it is necessary that the code flag of the created object is c++ and not flexscript.
That is the fun part of it, if you toggle a node as dll, you can call your function from within the DLL directly, so the node doesn't have to be toggled as C++, you can toggle it as DLL. (ofcourse you have to do it the Flexsim way)
Again this doesn't help your initial question. Did Anthony's anwers help you a little further?
Regards,
Steven
AlanZhang
10-31-2007, 09:38 AM
If you are using a user library object, you should not use the createinstance() command. Instead either use the createcopy() command or the dropuserlibraryobject() command. Also, your paths do not need the double forward slash //. Only the backslash needs to be doubled because the backslash is an escape character in c++.
Can you explain a bit more about the logic behind not using createinstance() command? In the manual, it says "createcopy() is different from createinstance() in that it does not attempt to establish any links between thenode and any class.". In what case we need the link between the node and the class?
Thanks.
Alan
Anthony Johnson
11-01-2007, 09:14 AM
I should probably change that documentation. createcopy() is different from createinstance() because createinstance populates the instance with all the variables from each class that the object is a member of. For example, the Conveyor object's inheritance is as follows: Conveyor -> FixedResource -> FlexsimObject. Each class has its own set of variables associated with it: the conveyor has things like speed, conveyor layout, etc. while the FixedResource has things like the sendto and pull strategy variables, while the FlexsimObject has things like variables for managing stopobject(), resumeobject(), etc. When you call createinstance, it creates an instance of the object, and then gives that instance the variables for the Conveyor, then the FixedResource, then the FlexsimObject. When you add an object to a user library, it already has all of those variables, so it doesn't make sense to call createinstance() on the user library object because its variables tree has already been populated according to the classes the object is a member of. So you call createcopy() to just create a straight copy of that object. So createcopy and createinstance are inherently different.
AlanZhang
11-01-2007, 10:08 AM
Thanks Anthony.
It seems that the misuse of createinstance for user library objects is exactly the reason why Martin has the problem on the code state when create objects from the library.
I create a simple model to demonstrate this. Please see my attachment. There are one model file and one library file. Firstly, load the library, then open the model, and then run the code in the script window. You will see difference between the two commands in the output window, which duplicates Martin's problem.
Alan
juan alberto
06-04-2009, 09:38 AM
Hi all,
I want to automatic generation og objects that are read in a database.
The problem I have encountered is:
If I put the database in an object that is in the standard library, if it works, but when I try to do the same but for some object by using a user library not get what I want.
For instance:
automatic generation of objects that are in the standard library : source,processor, sink.
utomatic generation of objects that are in the user library:
Queuetwo
dbclose();
dbopen("Conexion","select * from Objetos",0);
for (int i=1; i<=dbgetnumrows(); i++){
string name = dbgettablecell(i,2);
int x = stringtonum(dbgettablecell(i,3));
int y = stringtonum(dbgettablecell(i,4));
int z = stringtonum(dbgettablecell(i,5));
treenode object= node (name,library(),model());
createinstance(object,model());
setloc(object,x,y,z);
}
Thank's
Steven Hamoen
06-05-2009, 01:01 AM
Juan,
You can't generate an object from the userlibrary with createinstance(object,model()); because the objects in a userlibrary are already instances. If you want to generate an object from a userlibrary you have to use createcopy();
Also you're pointer to the userlibrary was incorrect (but I expect that you knew that). It should be something like:
treenode object = node("/project/userlibrary/YourLibrary/YourObjectName" , maintree() );
juan alberto
06-05-2009, 04:13 AM
Juan,
You can't generate an object from the userlibrary with createinstance(object,model()); because the objects in a userlibrary are already instances. If you want to generate an object from a userlibrary you have to use createcopy();
Also you're pointer to the userlibrary was incorrect (but I expect that you knew that). It should be something like:
treenode object = node("/project/userlibrary/YourLibrary/YourObjectName" , maintree() );
Thank's,
Yes, I was able to generate the object of userlibrary with the following code:
treenode mynode = node("MAIN:/project/userlibrary/mylibrary/Processortwo");
createcopy(mynode,model());
but , How can I generate an object that is read from the database?
(the object name will be written to the database and not in the "script code")
I tried the following:
dbclose();
dbopen("Conexion","select * from Objetos",0);
for (int i=1; i<=dbgetnumrows(); i++){
string nombre = dbgettablecell(i,2);
int x = stringtonum(dbgettablecell(i,3));
int y = stringtonum(dbgettablecell(i,4));
int z = stringtonum(dbgettablecell(i,5));
treenode objectstandar= node (nombre,library(),model());
createinstance(objectstandar,model());
treenode mynode= node(nombre,"MAIN:/project/userlibrary/mylibrary",maintree());
createcopy(mynode,maintree());
setloc(objeto,x,y,z);
}
Lars-Olof Leven
06-05-2009, 04:40 AM
Hi,
This is one way.
string nombre = dbgettablecell(i,2);
string newobject = concat("/project/userlibrary/mylibrary",nombre);
treenode mynode= node(newobject,maintree());
createcopy(mynode,model());
I have not tested it, but I think you get the idea.
Lars-Olof
juan alberto
06-05-2009, 05:14 AM
Hi,
This is one way.
string nombre = dbgettablecell(i,2);
string newobject = concat("/project/userlibrary/mylibrary",nombre);
treenode mynode= node(newobject,maintree());
createcopy(mynode,model());
I have not tested it, but I think you get the idea.
Lars-Olof
Thank's Lars, but not working.
another idea??
Tom David
06-05-2009, 05:26 AM
Did you already had a look into my model Sample_Database_TD ? :eek:
http://www.flexsim.com/community/forum/downloads.php?do=file&id=148
In this model I use the command executestring() where I read a string from the database and concat it to a full flexscript command and excute the command with executestring().
I did not test it, but I guess this could be the solution for your little problem.
Have a look and make your own executestring command and tell us what you found out.
Steven Hamoen
06-05-2009, 05:26 AM
Hi,
This is one way.
string nombre = dbgettablecell(i,2);
string newobject = concat("/project/userlibrary/mylibrary",nombre);
treenode mynode= node(newobject,maintree());
createcopy(mynode,model());
I have not tested it, but I think you get the idea.
Lars-Olof
I would add the extra slash, like:string newobject = concat("/project/userlibrary/mylibrary/",nombre);
Lars-Olof Leven
06-05-2009, 05:31 AM
Hi,
Are you sure that nombre is not empty?
Check that nombre is assigned "/ProcessorTwo", if not the code will not work.
I download the example in this thread and created my own script like this:
string obj="/Queue2";
string lib="/project/userlibrary/UserLibrary 1";
string newobj=concat(lib,obj);
treenode mynode = node(newobj,maintree());
pt("library object is "); pt(getname(mynode));pr();
createinstance(mynode,model());And it worked, the only different is that I not have a database connection.
It looks like you do not get the name to your object in your user library correct.
Will I was writing this Steven come up with an answer. Depending on how you store the name in the database
you need to add the extra slash or not.
Your string should look like this: "/project/userlibrary/mylibrary/Processortwo"
Lars-Olof
Steven Hamoen
06-05-2009, 06:23 AM
Sorry I didn't check the thumbnail so I assumed the name didn't have the slash.Sorry for that.
Maybe in addition to Lars-Olof, please also check if the names are exactly the same because Flexsim is case sensitive.
juan alberto
06-05-2009, 09:56 AM
Sorry I didn't check the thumbnail so I assumed the name didn't have the slash.Sorry for that.
Maybe in addition to Lars-Olof, please also check if the names are exactly the same because Flexsim is case sensitive.
Thank you very much,
finally it works!!! :D;)
The solution.
newobject string = concat ( "/ project / userlibrary / mylibrary /", name);
was correct!!
vBulletin® v3.8.7, Copyright ©2000-2012, vBulletin Solutions, Inc.