Page 6 of 7

Re: OXPConfig

Posted: Wed Nov 26, 2014 12:34 pm
by spara
Lone_Wolf wrote:
I see OxpConfig as a library/framework that allows PLAYERS to configure oxp options.
Oolite core code doesn't offer this functionality.
I think it should.

Re: OXPConfig

Posted: Wed Nov 26, 2014 9:18 pm
by Svengali
Lone_Wolf wrote:
Basically, OxpConfig tries to make things as easy as possible for oxps, but this comes with a rather steep price (complex code, slow performance) for OxPConfig itself.
OXPConfig was up to v1.77.1 a pretty fast OXP (see this post). I guess this is something that needs to be investigated.

Re: OXPConfig

Posted: Wed Nov 26, 2014 11:40 pm
by Lone_Wolf
I've checked on my system :
15 managed addons + 11 unmanaged
4 oxps that use oxpconfig

logearly 5 ms
displayall + logearly 9 ms

The time from F2 > game options until the message "OXPConfig prepared.\nStep to SYSTEM_DATA_SCREEN (F7) to activate."
appears however is atleast 1 second, possibly longer.
that message is displayed by this.doOxpCTimer , and that's what gives the impression of slowness.

Re: OXPConfig

Posted: Thu Nov 27, 2014 10:53 am
by Svengali
Lone_Wolf wrote:
that message is displayed by this.doOxpCTimer , and that's what gives the impression of slowness.
Ah, ok .-)
The trigger via timer stems from guiScreenChanged not being fired for the game options screen in older Oolite versions. You could remove it and trigger instead via guiScreenChanged.
Lone_Wolf wrote:
Oxps would then create a new instance of that template and pass that to OxpConfig on initialisation.
Doing it via literal will be faster - instantiating walks along the prototype chain. And the template would need to be adjusted by OXPs anyway.
Lone_Wolf wrote:
loading / storing the settings would then be a job for the oxp, not for OxpConfig.
Yep, sounds good. It would even open the option to handle more settings.

Re: OXPConfig

Posted: Thu Nov 27, 2014 11:14 am
by Lone_Wolf
Svengali wrote:
Lone_Wolf wrote:
that message is displayed by this.doOxpCTimer , and that's what gives the impression of slowness.
Ah, ok .-)
The trigger via timer stems from guiScreenChanged not being fired for the game options screen in older Oolite versions. You could remove it and trigger instead via guiScreenChanged.
looking into that
Svengali wrote:
Lone_Wolf wrote:
Oxps would then create a new instance of that template and pass that to OxpConfig on initialisation.
Doing it via literal will be faster - instantiating walks along the prototype chain. And the template would need to be adjusted by OXPs anyway.
understood, initialization will look something like this then :
worldScripts["OxpConfig"].activate_oxp(this.name,this.my_object_for_opxc_settings,this.my_oxpc_notify_handler)
this.my_object_for_opxc_settings = pointer to object
this.my_oxpc_notify_handler = pointer to eventhandler for notification

Using pointers allows arbitrary names and i expect will be easier to handle for oxpconfig.
Many fields in oxpcsettings (especially the Name fields) will likely become pointers also.
Svengali wrote:
Lone_Wolf wrote:
loading / storing the settings would then be a job for the oxp, not for OxpConfig.
Yep, sounds good. It would even open the option to handle more settings.
Glad you like it.


-----------------------------------------

Although i do understand OxpConfig high-level functionality many of the implementation details are still beyond me.
I am currently working on adjusting the code to improve readablitity, clarify the code and add comments.
Doing that slowly increases my familiarity with the code.
I intend to stick to small changes, no functionality changes.

Since the new interaction method is incompatible with the current method, it will become version 3.
I will look into adding version numbers to the list of supported oxps to help with the transition and making it possible for players to have both OxpConfig v2 & v3 installed at the same time.

Re: OXPConfig

Posted: Thu Nov 27, 2014 10:53 pm
by Svengali
Lone_Wolf wrote:
Although i do understand OxpConfig high-level functionality many of the implementation details are still beyond me.
Most of the complexity has to do with loading/storing functionality. The consequence was that OXPConfig had to care for loading- and script execution- order, order of fired handlers, possible changes in OXPs, Oolites timelimiter, etc. Ok, sometimes it was the attempt to see how much complexity I can handle. But with a little bit distance now I really don't think that you need to explore the code beyond the point of screen functionality for the new approach.
Lone_Wolf wrote:
worldScripts["OxpConfig"].activate_oxp(this.name,this.my_object_for_opxc_settings,this.my_oxpc_notify_handler)
Sounds good. I guess .activate_oxp() is a simple registering method which pushes into an array?

Then it may be a good idea to reduce the passed arguments to a single object which holds all members. This way you have all data in one place. Sorting the array for screen output based on properties is possible whenever OXPConfig gets activated by the user. Adding a unregistering method is probably not a bad idea too.
Lone_Wolf wrote:
Since the new interaction method is incompatible with the current method, it will become version 3.
I will look into adding version numbers to the list of supported oxps to help with the transition and making it possible for players to have both OxpConfig v2 & v3 installed at the same time.
The internal list of supported OXPs was only necessary to avoid startUp chains and I doubt that you'd still need it .-) The currently supported OXPs should degrade nicely to their default functionality, none registers. It shouldn't be necessary to keep v2.x alive and the required changes for OXPs would be - based on your approach above - minimal.
Lone_Wolf wrote:
Using this method does feel like a 'natural' evolution of OxpConfig,<snip>
Bring it to the next stage then! :-)

Re: OXPConfig

Posted: Fri Nov 28, 2014 5:03 pm
by Lone_Wolf
Svengali wrote:
The internal list of supported OXPs was only necessary to avoid startUp chains and I doubt that you'd still need it .-) The currently supported OXPs should degrade nicely to their default functionality, none registers. It shouldn't be necessary to keep v2.x alive and the required changes for OXPs would be - based on your approach above - minimal.
Lone_Wolf wrote:
Using this method does feel like a 'natural' evolution of OxpConfig,<snip>
Bring it to the next stage then! :-)
OxpConfig version 2.x is now officially put in "Maintenance Mode" .
it doesn't have any outstanding bugs, so the current 2.3.1 version will likely be the last release of the 2 series.


-----------------------------------------------------------------------------------

OxpConfig v3

In version 3 OxpConfig will use a client/server model.

I intend to split the code in 3 components :

OxpConfig_Server
OxpConfig_Library
OxpConfig_UI

These components may become separate oxps in the future, but will be developed in 1 oxp for the time being.

OxpConfig_Server will deal with registering / unregistering clients, notifiying clients of changes, data type & value verification etc.
All communication between clients & server will be handled by this component.

OxpConfig_Library will hold functionality to ease the use of missionscreens for displaying & changing of values.
Initially it will be used by OxpConfig_UI only, but in time it will be usable for any oxp.

OxpConfig_UI
This will act like a frontend and provide the user interface.
It will also be an OxpConfig_Server client.

-----------------

In every client-server model where client & server share data, there's a risk of clashes.
OxpConfig_UI will take care of user-originating changes and use OxpConfig_server to notify the client of this.
I'm currently thinking about having 3 options for notification :

dynamic - every change will trigger a notification event

dynamicgroup - triggers when user leaves a page related to a group (boolean, integer, bitmasks)

changes_completed - triggers when user leaves the configuration pages for a specific client oxp

This takes care of changes on server side.

OxpConfig_Library & OxpConfig_UI will have to read the client-stored data before using them.
There is a small chance the client changes values while OxpConfigLib/OxpConfigUI are processing them, leading to clashes.
Not sure how to prevent this.

Re: OXPConfig

Posted: Wed Dec 10, 2014 11:45 pm
by Lone_Wolf
OxpConfig v3 documentation

Note : this is just a combination of notes i made about how OxpConfig might work, hope they make some sense.

Code: Select all

Methods

worldScripts["OxpConfig Server"]._register(pointer_to_my_object)
// add oxp to list of oxps oxpconfig does handle
worldScripts["OxpConfig Server"]._unregister(pointer_to_my_object)
// remove from list
worldScripts["OxpConfig Server"]._changed(pointer_to_my_object)
// notify OxpConfig_Server that oxp has changed values

/* my_object is a wrapper object to hold all data that is needed for OxpConfig_Server.
      properties
        name              type          optional  meaning
        General           object
          Script_name     string                  oxp worldscript name, normally equal to this.name of calling script
          Display_name    string                  the name you want OxpConfig to display to the user
          Display_on      string                  used to determine where OxpConfig will show the values. 
                                                  "Game options" = show on F2 - F7 screen
                                                  "Ship/Station Interface" = show on F4 screen through interface OxpConfig
          Notify_type     string                  tells OxpConfig when to send notifications
                                                  "Dynamic" = at every change
                                                  "Dynamic_group" = when user leaves group page
                                                  "Changes_completed" = when user leaves oxp configuration pages
          Notify_handler  pointer                 points to a function that will be called by OxpConfig_Server when user has changed values
          Bool_info       string        y         description shown when user goes to "change booleans" page, defaults to empty
          Number_info     string        y         shown when user goes to "change numbers" page, defaults to empty
          Bitmask_info    string        y         shown when user goes to "change bitmasks" page, defaults to empty
        Booleans          array         y         
          Parent          pointer   
          Child           string                  Parent & Child are combined to access variable
          Hide            boolean                 false = variable will be shown to user
          Default         boolean                 used for "set to default" option
          Description     string                  user-visible description
        Numbers           array         y         
          Parent          pointer
          Child           string                  Parent & Child are combined to access variable
          Hide            boolean                 false = variable will be shown to user
          Default         integer                 used for "set to default" option
          Max             integer                 highest value allowed for number
          Description     string                  user-visible description
        Bitmasks          array         y         
          Parent          pointer
          Child           string                  Parent & Child are combined to access variable
          Hide            boolean                 false = variable will be shown to user
          Default         integer                 used for "set to default" option
          Max             integer                 highest value allowed for bitmask, should be a (power of 2) -1
          Description     string array            user-visible descriptions
          
examples

this._sc_oxpconfig =
  {
    General:
      {
        Script_name: "Shield Cycler",
        Display_name: "Shield Cycler",
        Display_on: "Ship/Station Interface"
        Notify_type: "Dynamic",
        Notify_handler: this._sc_user_changed_values,
        Bool_info: "enable / disable Shield Cycler oxp functionality & the devices it manages",
        Number_info: "Threshold % determines when adjusting is done. 100 = always, 0 = never. Start configuration is the configuration that will be set upon launch (3 = equal, 2 = fwd, 1= aft, 0 = disabled).",
        Bitmask_info: "enable / disable the availability of the settings for manual cycling. Note : if you disable all, Shield Cycler oxp will enable the disabled setting"
      },
    Booleans:
      [
        { Parent:this._sc_settings.general, Child:"disabled", Default:false, Hide:false, Description:"disable SC OXP." },
        { Parent:this._sc_settings.general, Child:"sc_disabled", Default:false, Hide:false, Description:"disable cycler devices." }
      ],
    Numbers:
      [
        { Parent:this._sc_settings.sc, Child:"threshold", Default:100, Max:100, Hide:true, Description:"threshold %" },
        { Parent:this._sc_settings.sc, Child:"start_configuration", Default:3, Max:3, Hide:true, Description:"launch setting" }
      },
    Bitmasks:
      [
        { Parent: this._sc_settings.sc, Child:"cycler_mask", Default:0x001, Max:0x00f, Hide:true, Description:["Disabled","Aft","Forward","Equal"] }
      ]
  };


worldScripts["OxpConfig Server"]._register(this._sc_oxpconfig)
worldScripts["OxpConfig Server"]._unregister(this._sc_oxpconfig)
worldScripts["OxpConfig Server"]._changed(this._sc_oxpconfig)

this._sc_user_changed_values = function(bitmask)
{
// process user changes to variables
};

Re: OXPConfig

Posted: Thu Dec 11, 2014 2:47 pm
by Lone_Wolf
Made some changes to previous post :

- removed Bool_amount, Numbers_amount, Bitmasks_amount as they can be easily be determined at run time
- clarified Notify_Type

After thinking about whether to use F2-F7 or F4 ship/station interface for OxpConfig, i've decided to use both.
Some of the settings handled by OxpConfig are game-related like BGS settings) , others are ship related like those of my shieldcycler.
I feel OxpConfig should allow both types, thus i added a Display_on field.
-------------------------------

OxpConfig properties

collectAll, displayAll & logEarly are no longer needed because of the new interaction.

logging
This could be useful for trouble shooting, though my personal style is to add logging when needed only.
If i keep this, i'll have to make sure it is useful.

--------------------------------------------
this.deactivated (calling oxp property)

I think it's purpose was to allow oxps to disable configuration through OpxConfig.
The new method allow several options to disable configuration :
- change the .Hide property
- delete elements from Booleans, Numbers & Bitmasks
- delete Booleans , Numbers & Bitmasks arrays
- Unregister the oxp

I see no point in keeping this.activated around.

-------------------------------------

OxpCSettings removed flags :

MinVersion , EarlyCall , EarlySet, LeaveData : obsolete because of new interaction method between OxpConfig & clients

Notify, DynamicNotify : replaced by Notify_type field

InfoB, InfoS, InfoE : names changed

--------------------------------------

Parent / Child

I looked at ways to pass-parameter-by-reference with javascript and found this is not possible.
JS only passes values of paramaters.
However, the value of an object is a pointer to the instance of the object, and this is exactly what i need.

let's say the client script "A" has this in it's body :
this.something = 10

To access that variable we can use the well-known worldScripts["A"].something expression , but that's not very flexible.
we can also access that var if we know where it is located and what name it has.

Parent: this
Child: "something"

If those 2 are passed as parameters to OxpConfig, OxpConfig can access the var like this :
Parent.[Child] .
(note : i'm mot 100% sure i've written that correctly, haven't tested it yet).

A big benefit of this method is that Parent is a pointer and can point to any object known to Oolite.

In theory this would allow oxps to refer objects in other scripts and pass them to OxpConfig .
these other scripts could even be from different OXPs !

I can't think of a pratical use for this, but it shows the flexibility of this approach (and of JS...).

Re: OXPConfig

Posted: Mon Dec 22, 2014 6:34 pm
by Svengali
Lone_Wolf wrote:
this.deactivated (calling oxp property)
I think it's purpose was to allow oxps to disable configuration through OpxConfig.
The flag is not related to OXPConfig. I'm using it to flag OXPs which have deleted their properties (either because requirements are not fulfilled or if the OXP has nothing to do anymore). OXPConfig has only checked this flag (like a few other scripts).

Re: OXPConfig

Posted: Mon Dec 22, 2014 9:22 pm
by Lone_Wolf
Thanks, then i didn't fully understand what this.deactivated does.

removed from previous post.

Re: OXPConfig

Posted: Tue Jun 02, 2015 8:59 pm
by Lone_Wolf
OxpConfig 2.3.3 released

Changes :

Added Hyperspave Hangar to list of supported oxps

(2.3.2 had a typo)

Re: OXPConfig

Posted: Wed Jun 03, 2015 7:14 pm
by Ramen
Actually, I screwed up and gave you the wrong name.
It's actually "HyperspaceHangar" not "hyperhangar.js".
Sorry.

Re: OXPConfig

Posted: Wed Jun 03, 2015 10:41 pm
by Lone_Wolf
hyperhangar.js appears to be the scriptname you use.
I'm not 100% sure if the list of supported oxps requires the this.name value of a script OR the full scriptname but will check it.

Re: OXPConfig

Posted: Wed Jun 03, 2015 11:28 pm
by Ramen
If it helps,
hyperhangar.js is the scriptname, HyperspaceHangar is the this.name