.
Results 1 to 14 of 14

Thread: TNI SDK update

  1. #1
    Join Date
    Nov 2006
    Location
    Australia, QLD, Brisbane
    Posts
    7,067
     

    Default TNI SDK update

    http://dl1.n3vgames.com/misc/TNISample_Nov_21.zip

    This one includes the necessary assets; no other changes.

    chris

  2. #2
    Join Date
    Feb 2011
    Location
    United States of America
    Posts
    30
     

    Default

    Thank you Chris for the update with the sample rule and library.

    It pointed out what I was doing wrong so now I think I can actually make some progress in getting my code to work.

    --Grant

  3. #3
    Join Date
    Nov 2006
    Location
    Australia, QLD, Brisbane
    Posts
    7,067
     

    Default

    No problems. The ball's in your hands now, so give me a yell with any progress you make or problems that you encounter.

    There's obviously a lot more to be done on our side, but we'll only proceed with that once we're sure that the basics are working.

    chris

  4. #4
    Join Date
    Nov 2006
    Location
    Canberra, Australia
    Posts
    8,734
    Blog Entries
    30
     

    Default

    Quote Originally Posted by WindWalkr View Post
    http://dl1.n3vgames.com/misc/TNISample_Nov_21.zip

    This one includes the necessary assets; no other changes.

    chris

    Thanks. Reading about it is fine, but doing something practical is better...

    Paul


  5. #5

    Default

    I compiled the sample and moved the TNISample.dll in the same folder as TANE.exe, added the sample rule to a session but it doesn't seems to be working.
    Is it something wrong with what I've done ?

  6. #6
    Join Date
    Feb 2011
    Location
    United States of America
    Posts
    30
     

    Default

    Quote Originally Posted by peter997 View Post
    I compiled the sample and moved the TNISample.dll in the same folder as TANE.exe, added the sample rule to a session but it doesn't seems to be working.
    Is it something wrong with what I've done ?
    I did get it to work, but it took several steps.

    First, I had to make sure that the logging on the Trainz Settings -> Dev tab was enabled.

    Next, I started surveyor and added the rule to a session.

    Then I did Developer -> Clear Logs and Devloper -> Show Logs.

    Finally I clicked edit with the Sample rule highlighted.

    This is the result in the log:
    Attached Images Attached Images

  7. #7

    Default

    Thanks, I will try this and report if it works. I think I was not looking at the right things.
    The end of the doc we had last week speak about posting messages to access scripts. Chris, can you confirm this is not implemented yet?

  8. #8

    Default

    It works for me, too. I also managed to attach Visual Studio debugger to the TANE process, set breakpoints and debug TNISample.cpp. All four functions were called in the expected order. Unfortunately, there is no pdb (symbol) file for the TNI classes declared in the header files. That would be quite helpful when debugging your own plugin.

  9. #9

    Default

    Now working fine for me.
    I also found that the sample send TrainzScript message but I don't understand exactly how.
    It seems to just store the name of the fonction (here PostMessage) and then use the TNICallLibraryFonction fonction. What does exactly do this and is it possible to do this with any TrainzScript fonction ?

  10. #10
    Join Date
    Nov 2006
    Location
    Canberra, Australia
    Posts
    8,734
    Blog Entries
    30
     

    Default

    Quote Originally Posted by geophil View Post
    It works for me, too. I also managed to attach Visual Studio debugger to the TANE process, set breakpoints and debug TNISample.cpp. All four functions were called in the expected order. Unfortunately, there is no pdb (symbol) file for the TNI classes declared in the header files. That would be quite helpful when debugging your own plugin.
    That's useful to know. Thanks.

    Paul


  11. #11
    Join Date
    Nov 2006
    Location
    Australia, QLD, Brisbane
    Posts
    7,067
     

    Default

    Quote Originally Posted by peter997 View Post
    I also found that the sample send TrainzScript message but I don't understand exactly how.
    It seems to just store the name of the fonction (here PostMessage) and then use the TNICallLibraryFonction fonction. What does exactly do this and is it possible to do this with any TrainzScript fonction ?
    No; it has nothing to do with TrainzScript functions as such. I've added a new "TNILibrary" section to the "TNI Development Process" google doc, which might help you understand this process better. You'll also find that the existing documentation regarding the TNITrainzScript library is probably relevant here.

    chris

  12. #12
    Join Date
    Nov 2006
    Location
    Australia, QLD, Brisbane
    Posts
    7,067
     

    Default

    Quote Originally Posted by geophil View Post
    It works for me, too. I also managed to attach Visual Studio debugger to the TANE process, set breakpoints and debug TNISample.cpp. All four functions were called in the expected order. Unfortunately, there is no pdb (symbol) file for the TNI classes declared in the header files. That would be quite helpful when debugging your own plugin.
    What exactly are you seeing as missing in your debug view, that you expect to get from the PDB files?

    chris

  13. #13

    Default

    Quote Originally Posted by WindWalkr View Post
    What exactly are you seeing as missing in your debug view, that you expect to get from the PDB files?
    I'd like to inspect the member variables - if there are any - of the instances of the classes derived from TNIObject which are passed to the plugin public functions. But if it's all done via some sort of "properties" pattern, i.e. interfaces, getters/setters, then that wouldn't bring any benefits, of course.

    One other thing: You have designed TNI to support non-OO plugin implementations. Have you thought about any recommended pattern for the plugin developer to convert the procedural interface into an OO interface? The approach I would possibly take is do create a class that holds my implementation. Then manage it via a static std:map with the TNIContext* as the key and an instance of my class as the value. All static TNI function calls would be routed to member function calls, through a dispatcher that works with "delegates", presumably implemented as functors or lambda expressions. There are a number of options, some quick and dirty, some more elegant, and a guideline might be helpful to developers.

    A minor detail: The sample introduces the usage of the platform-independent C++11 std::mutex class, but the sample explicitly calls its lock() and unlock() functions. While this is certainly fine for a "Hello World" type of application, it should not be done that way in production code. C++11 offers the the lock_guard class to handle mutexes. lock_guard implements the RAII programming idiom (an idiotic acronym and name, nobody would associate automatic release functionality with it). The C++ example in the Wikipedia article explains its features.

  14. #14
    Join Date
    Nov 2006
    Location
    Australia, QLD, Brisbane
    Posts
    7,067
     

    Default

    Quote Originally Posted by geophil View Post
    One other thing: You have designed TNI to support non-OO plugin implementations.
    Yes and no. C++ doesn't make for a good plugin architecture because of the fragile base class problem. As a result, we avoid OOP in the actual API, however that doesn't mean that you can call into the TNI functions easily from other languages. It's likely that most problems could be solved by repurposing the class forward declarations to an empty struct type (for C) or similar, but we haven't specifically tested for this, nor do we have any current plans in this direction. Even if somebody made an interface module for Delphi or VB, we don't accept plugins written in other languages anyway.


    Have you thought about any recommended pattern for the plugin developer to convert the procedural interface into an OO interface? The approach I would possibly take is do create a class that holds my implementation. Then manage it via a static std:map with the TNIContext* as the key and an instance of my class as the value. All static TNI function calls would be routed to member function calls, through a dispatcher that works with "delegates", presumably implemented as functors or lambda expressions. There are a number of options, some quick and dirty, some more elegant, and a guideline might be helpful to developers.
    As far as I'm concerned, this is a plugin implementation detail. There are numerous ways to solve it, and it might make sense for people who have similar goals to get together and write up a common approach rather than each reimplement it. My main suggestion would be that you keep it simple; we will be code reviewing any submissions and if we think it's overly complex for what it achieves then that will likely come up as a flaw in the review. There's no problems with using a std::map<>, but if you're working with statics then be careful of startup/shutdown/thread safety.


    A minor detail: The sample introduces the usage of the platform-independent C++11 std::mutex class, but the sample explicitly calls its lock() and unlock() functions. While this is certainly fine for a "Hello World" type of application, it should not be done that way in production code. C++11 offers the the lock_guard class to handle mutexes. lock_guard implements the RAII programming idiom (an idiotic acronym and name, nobody would associate automatic release functionality with it). The C++ example in the Wikipedia article explains its features.
    Use whatever approach you like. RAII is a solid paradigm but it is not the only paradigm.

    chris

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •