Object Queries

Cr4zyb4rd

Active Member
(this is mostly for Ama)
I noticed in your initial release notes that you're using your "standard" style of index/search parameters, and wondered if you had any plans or interest in implementing the new object query methods that were introduced to Innerspace a few versions ago.

Code:
1.09 Build 4419
* Object query support has been added. Extensions can use ISXDK 30a (or later) for direct
   access to this functionality. An object query is a math formula where all variables
   are relative to a specific object, and results in a boolean value -- the query is either
   true, or it is false. Query math can compare and manipulate text, decimals, or integers 
   (note that bool counts as an integer for this purpose) with standard math operators. Text
   comparisons are not case sensitive. One intended use for object queries is a uniform search 
   mechanism, to find an object or set of objects from a larger set of objects (compare to a 
   SQL SELECT statement, where a LavishScript object query is the WHERE clause).
I poked around at ISXDK 3.0, and while Lax's documentation is a bit sparse at the moment, these don't seem hard at all to implement. This would give us a much more powerful search mechanism, while (it seems to me) making less work for you in the process, as you wouldn't have to write/maintain a new argument handler each time you add an indexed datatype.

(for those not familiar with object-query indexing, or for whom Lax's description is a bit opaque, it works something like this: With isxgames extensions, we're used to indexing an array like this -

Actor[radius, 10, name, David]

Under the hood, those index arguments are passed and handled much like the arguments to a command. We as users have to make sure that the index we're using is supported, and that we're passing all of the commands in the right order. If somebody requests that we be able to say search for the nearest corpse, Ama would have to add code to parse for the new "corpse" argument, as well as a few lines to actually do the work of checking each actor to see if it's a corpse. With object queries, instead of a fixed list of search parameters, we can pass in an expression, a "mini-function" if you will, that gets evaluated at run-time. Something along the lines of -

Actor[Radius <= 10 && Name=="David" && (Type=="Corpse" || Type=="Pet")]

where we can build our queries out of any members within the datatype. In the example above, if we later decide that we want to further limit our search to only actors outside of a radius of 5, all we have to do is add && Radius > 5 to our query.)
 

Amadeus

The Maestro
Staff member
Once there is an example extension posted on ismods or the documentation is fully implemented with example source, I will consider it. I have too many things going on than to try and figure out something for which examples aren't available.

Persuade lax to update mkext.exe. Honestly innerspace could benefit from a slow down in development and some documentation/example source code loving. There are a lot of features that have been added for which are not being used by many people because they just don't know how.
 

v01d

Well-Known Member
I would love to see this type of functionality in isxeq2. It is something I would definitely make use of if implemented. Just my 2cp.

v01d
 

Cr4zyb4rd

Active Member
Once there is an example extension posted on ismods or the documentation is fully implemented with example source, I will consider it. I have too many things going on than to try and figure out something for which examples aren't available.

Persuade lax to update mkext.exe. Honestly innerspace could benefit from a slow down in development and some documentation/example source code loving. There are a lot of features that have been added for which are not being used by many people because they just don't know how.
Agreed. Lax seems a bit less responsive in general lately, and the ISMods forums are almost dead (save 30 people a day asking "how am u the warcraft bott?!?").
 

Lax

LavishSoft/InnerSpace Guru
I've been insanely busy.

Anyway here's the jist of implementing it. I'm 99% sure i already gave amadeus a full working example when it was done, but here you go.

There's 4 functions, you only need to use 3. This is pasted out of ISXDK.h.
Code:
	virtual unsigned int CreateQuery(const char *Text)=0;
	virtual bool RetrieveQueryExpression(unsigned int ID,char *buf, unsigned int buflen)=0;
	virtual bool QueryEvaluate(unsigned int ID,LSOBJECT &Object, bool &bResult)=0;
	virtual bool FreeQuery(unsigned int ID)=0;
CreateQuery returns the query ID, which is used for the other 3 functions. The parameter is a string, which from cr4zyb4rd's example...
Actor[Radius <= 10 && Name=="David" && (Type=="Corpse" || Type=="Pet")]
would be this:
Radius <= 10 && Name=="David" && (Type=="Corpse" || Type=="Pet")

If the ID returned is 0, then it failed to create the query.

Your query can remain there for as long as you want to use it. It's up to you to free it. If it's a popular query built into your extension, then you would keep it open. But, for your purposes, they will likely be freed immediately after looping through some objects. Don't make a query object type for script developers, I was going to do that. Just use the functions.

So after you create the query and you have the query ID, you can determine if any given LSOBJECT (e.g. type and value combination, you know how to use this) matches the query. To do this, use QueryEvaluate. The function returns false if the query could not be evaluated for some reason, such as an invalid field name. Otherwise, it returns true. The 3rd parameter (bResult) is what tells you if the object matches.

Then once you're done using the query, FreeQuery(ID).

Example:
Code:
bool CreateActorListUsingQuery(const char *Query)
{
  // call CreateQuery with the text given from the user
   unsigned int MyQueryID = pISInterface->CreateQuery(Query);
   if (!MyQueryID)
  {
     // could not create query
      return false;
  }

  // loop through actors
  Actor *pActor = pActorList;
  while(pActor)
  {
    bool bResult;

    // create a LSOBJECT for the query to use
    LSOBJECT Object;
    Object.Ptr=pActor; // our actor
    Object.pType=pActorType; // the type, which operates on Actor *

     if (pISInterface->QueryEvaluate(MyQueryID,Object,bResult) && bResult)
    {
       // actor matches!
       ActorList.Add(pActor);   
    }

    // continue with the next actor in the list, if there is one
     pActor=pActor->pNext;
  }

  // free the query
  FreeQuery(MyQueryID);
  return true;
}

As you can see, this simple function replaces the entire search mechanism used by MQ2, ISXEQ2, etc, and it works on ANY LS objects. CreateQuery is the function that creates the "spawn search", and QueryEvaluate is the "matches search" function.
 

Amadeus

The Maestro
Staff member
There aren't THAT many people using isxeq2, and the scripts that are available for isxeq2 do just about everything a person could want.

I would like to see a few examples of how people would utilize this functionality before I would spend time on it. I've added several big things over the years by request and they were never used because people didn't want to redo scripts that were already working.

And I'm not interested in how cool it is or whatever, I'm interested in how you would actually USE this functionality to do things that are currently NOT possible and how it would improve life beyond what is already available.
 

Cr4zyb4rd

Active Member
I would like to see a few examples of how people would utilize this functionality before I would spend time on it. I've added several big things over the years by request and they were never used because people didn't want to redo scripts that were already working.
I'm fairly sure that I originally posted this in the new Eve forum, thus my initial comments/questions. As I tried to point out in my explanation, this is something i feel will save YOU time in the long run, as you'll only have to write index argument handlers when there's some exceptional case that a query can't handle, (things like EQ2UIPage? I'm not quite sure how that works or would/could work with this) and I wanted to bring it to your attention before you created a dozen new isxEve objects using your standard handling.

As for adding it to EQ2 and/or ISXVG, that would indeed be "cool", but it's certainly understandable if you're unwilling to spend time on it. For what it's worth, I've talked to ALL FOUR somewhat-active EQ2 scripters, and we're all in favor of it and would use it in anything new we wrote, should that actually hapen :cool: Most of our use of the Custom* TLO objects is to do just this type of pruning, so if you *were* to backport this into ISXEQ2, you could probably just create QueryActor and QueryInventory, leave the old stuff intact, and call it a day. (Alternatively, I suppose you could train your existing handler(s) to check the first argument for a leading & or somesuch to indicate a query). I haven't felt out the VG community, but I'm sure it would find more favor there where there's some active bot developers. (Killing time waiting for the game to die off the rest of the way, no doubt. Oh the irony.)

I'm not going to do any more arm-twisting on this. I brought it to your attention, and I've hopefully explained why I think it would be beneficial to start using it in your future projects, which is all I set out to do.
 

Pygar

EQ2Bot Specialist
Actually, if this doesn't provide ordering and sorting of the object quickly and painlessly, I'm not so sure I'd use it all that much.

It would be nice in inventory and actor searches to be able to query it more abjectly as this method suggests, but generally we've found working sollutions around it with what is already provided.

Thinking more on it, being able to query abilities like this would allow me to do some cooler things with spell and art selections, but I'd want to join the query data from the extension with refference data that isn't available there and query that combined object to get something I can work with. The data exposed on ability alone wouldn't get me all the way there.

$0.02
 
Top Bottom