Page 1 of 1
classes using one another in library
Posted: 23 Mar 2012 13:49
by griffin71
Hi,
I'm trying to write a library that contains a few classes. One of them needs to use an instance of one of the other classes in the library. My question is: how do I create the instance?
I've tried things like this:
Code: Select all
myclass_one class {
...
}
myclass_two class {
inst_once = myclass_one(); // Here I want to create the instance of class 1, but I receive a compile error
var1 = null;
....
}
but for some reason (unclear to me) myclass_two doesn't recognise the definition of myclass_one that preceded it.
In particular, when I put the same code in main.nut of the AI, rather than the main.nut of a library, it will compile and run.
Any ideas?
Re: classes using one another in library
Posted: 23 Mar 2012 16:37
by krinn
Within its constructor definition
myclass_two class { b= null; constructor() { b = myclass_one(); } } // run once for each new myclass_two create
myclass_two class { static b = myclass_one(); constructor() { } } // run once for every instance of myclass_two
Re: classes using one another in library
Posted: 23 Mar 2012 19:25
by Zuu
Mind that your main class might get renamed when it is imported. The others don't. This is due to the library system was mainly designed for small libraries composed of one class.
Then *someone* came and made a huge library containing lots of classes (SuperLib). In SuperLib this is solved that there is a main class which only acts as a namespace. It only contains public static variables that point on the other classes. All other classes use the name _SuperLib_<class> internally but are published as SuperLib.<class> through this main class. If a user import SuperLib as SillyLibName then it will access the sub libraries as SillyLibName.<class>. The reason for the _SuperLib_ prefix for the internal names is that there is actually not anything as a library scope. When a library is imported the global scope of the library is merged with the global scope of the AI/GS. Thus library writers who have more than one class have to take care to not use class names that have moderate to high chance of conflicting with what AI/GS authors would name their classes.
Edit: Also mind that the library system don't support cyclic references. Thus if you make lib A and lib B, they can't both import the other library.
Edit2: If you want to make a library that both support AI and GS, it is actually fairly easy. All you need is a script that renames AI -> GS at the beginning of names and changes the library.nut a little bit. There might be other things too that I've forgotten. The script for SuperLib looks like this:
nogo_translator.py
Re: classes using one another in library
Posted: 23 Mar 2012 20:19
by griffin71
Okay, thanks!
Especially zuu's answer sheds clear light on my problem. However,
Zuu wrote:Mind that your main class might get renamed when it is imported. The others don't. This is due to the library system was mainly designed for small libraries composed of one class.
does not say it is forbidden to use two classes in one lib (as is the case in what I'm trying to do).
My problem is that I am not happy to make a library with some auxiliary functionality to the main library class available to the AI.
With the explanations above, I still don't get why I receive the following AI-console errors in the example I have attached:
Your script made an error: the index 'MyClass_One' does not exist
*FUNCTION[constructor()] libraryTestLibGriff.1main.nut line [38]
*FUNCTION[constructor()] TestAImain.nut line [58]
TestAI creates the instance of MyClass_Two in line 58.
If any one would like to take a look at it, I'd much appreciate that
Thanks for your help!
Re: classes using one another in library
Posted: 23 Mar 2012 22:34
by krinn
look here, you'll see a limitation to create multi-class for a library, and a sample to create sub-class for library
http://wiki.openttd.org/AI:Library
class one{} class two{} --> class one{} class one.two{}
and look here, you'll see except static function, function should be declare outside the class definition :
http://wiki.openttd.org/AI:SQ_pitfalls
class that { function what() {} } --> class that { } function that::what() {}
class that { static function what() {} }
take also a deep look at context usage and scope there, you'll suffer from it for sure (the Squirrel lacks a way to mark methods as static or private part)
Re: classes using one another in library
Posted: 31 Mar 2012 18:25
by griffin71
Thanks for the responses received in this thread. I decided to follow the exactly same structure as superlib.
I must admit it took me a few days to get over my objections against singling each class out into a separate file, and 'require' these into main.nut of the library. However, everything works smoothly. I have run a test script for the lib that indeed works. In the script, one of the classes creates an instance of one of the othes classes in the library, which is the problem I looked to solve in the first post in this thread.
Practically this means that it looks as though the biggest obstacles in creating my AI have now been overcome, as far as it concerns restructuring the code I created 5 years ago.
My objects for the coming year or so will be to construct an AI that seeks for an optimal place for two stations (first road, then railroad), each in a different town, and then to connect the stations with a smooth and efficient route. I intend to add some functionality to the roadpathfinder I wrote 5 years ago, and then extend it to finding railroad paths, as I see that finding the latter is one of the weaknesses of today's AIs.
Once this is all done, I hope to find time to write an AI that uses it, and that is able to give some competition to human players. It should especially do so in the later stage of the game, when the gamemap gets more clogged up with other players' stations and pieces of (rail)road. (But this is still future music. Let's see how the Almighty guides me in this huge project...)
Re: classes using one another in library
Posted: 31 Mar 2012 21:43
by Zuu
It took me some time to settle for how to sort things out in SuperLib too. I don't say that my way is the best, but it was the way I ended up after thinking about different possibilities. I have been thinking a bit lately about splitting SuperLib into a utility part and a high-level part but so far that has not been done. A split will require that the low level part is separate enough that it doesn't use anything of the high level part as cyclic dependencies are not allowed for libraries.
Re: classes using one another in library
Posted: 31 Mar 2012 22:14
by griffin71
Yes, I see what you mean. In addition, it's never the most intellectually rewardig work to do such things.