GameMonkey Script

GameMonkey Script Forums
It is currently Sun Jan 20, 2019 11:58 pm

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Sat Jul 04, 2009 5:36 am 
Offline

Joined: Fri Jan 14, 2005 2:28 am
Posts: 439
I've added a library to gmscript ex that I've dubbed gmSchemaLib, which provides a few custom objects that can be used to set up validation of fields, field types, and values for a table or user object. I am currently using it in my bot project in order to simplify the implementation of customizable goals for the bots, and to save the user the need to do a bunch of custom type checking, conversion, and validation of the data themselves. Here is an example, pretty much directly out of the script I'm using it in currently.
Code:
//////////////////////////////////////////////////////////////////////////
// Schema is a 'blueprint' of expected data that the object needs to operate.
// It is used for validating the expected fields and field values for correctness.

// Couple callbacks to enforce additional constraints on property values.
// Callbacks are called after normal validation, so it should not be necessary to
// verify type or range here if the schema field is already set up with type and range properties.
CheckMinCamp = function(var)
{
   if(var <= this.MaxCampTime)
   {
      return true;
   }
   // returning any string is an error string
   return "MinCampTime must be <= MaxCampTime";
};
CheckMaxCamp = function(var)
{
   if(var >= this.MinCampTime)
   {
      return true;
   }
   // returning any string is an error string
   return "MaxCampTime must be >= MinCampTime";
};
this.Schema = Schema();
this.Schema.AimVectors = Validate.TableOf("vector3").Default({});
this.Schema.Weapons = Validate.TableOf(WEAPON).Default({});
this.Schema.Stance = Validate.Enum("stand","crouch","prone").Default("stand");
this.Schema.MinCampTime = Validate.NumRange(0,60).Default(2).CheckCallback(CheckMinCamp);
this.Schema.MaxCampTime = Validate.NumRange(0,60).Default(6).CheckCallback(CheckMaxCamp);


In this example, I'm creating the Schema object and storing in a custom user type, which is what 'this' is.

Later on in the script, such as after data is loaded onto the object from a save file, you can do this
Code:
this.Schema.Check(this); // supports passing user types
this.Schema.Check(propertytable); // also supports passing tables


When this call is made, the Schema will verify that all the fields that have been defined in the schema exist in the user object/table, and that they are of the expected values as defined by how the schema was set up. In this example, the object must have an AimVectors table that can only contain vector3, a Weapons table that can only contain values that match values in a global WEAPON table, a Stance field that can be 1 of 3 values, and a Min/Max Camp field that must be a number between 0 and 60 inclusive. In addition, since the 2 camp time fields are related, it uses a script callback to do additional validation to make sure the MinCampTime can't be set greater than the max and vice versa.

Default values are also set on the schema, which allows non existing fields to be automatically applied to the table or user object. In this example, every field has a default, which has an interesting side effect that the schema can also be used to create and initialize a new object of this type. It also means that as long as default values are added to each field of the schema, versioning the data becomes much simpler, since reading in old data will result in newly added fields being default initialized, essentially providing free versioning.
Code:
this.InitNewGoal = function()
{
   // the schema will initialize all fields with a default
   // so as long as everything has a default, we can let the schema
   // set up the data for us.
   this.Schema.Check(this);
};


In addition to checking the schema as a whole, individual fields may be verified independently. I use this to verify individual fields that can be set by the user when setting up the objects.
Code:
this.SetProperty = function(property, value)
{
   proplower = property.Lower(0);
   switch(proplower)
   {
      case "mincamptime":
      {
         v = ToFloat(value);
         if(this.Schema.MinCampTime.CheckPrintErrors(this,v))
         {
            this.MinCampTime = v;
         }
      }
      case "maxcamptime":
      {
         v = ToFloat(value);
         if(this.Schema.MaxCampTime.CheckPrintErrors(this,v))
         {
            this.MaxCampTime = v;
         }
      }
      ...


The schema verification works on user objects as well as tables, as long as the user object has setdot and getdot defined. This is nice as it allows the schema to verify data that may ultimately be directly bound to variables inside your user object type, and that aren't necessarily in a table.

What you see here is committed to the gmscript ex repository, along with most of the user mods you have seen around these forums(switch statements, fork, index table initialization, iterator support on types, etc). Feel free to give it a shot. I maintain this version of GM closely, as I use it extensively in my project. If you see anything this library or others can benefit from, feature requests, etc, just let me know. I'm sure there are more that would be useful in the schema library, but I haven't thought of them yet since I haven't had need for much more than what is shown here so far. I've just started using it though, so I'm sure more will come up. Comments/criticisms/feedback welcome.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group