PDA

View Full Version : Bind a variable to a function?


JkWhoSaysNi
08-27-2006, 09:46 PM
Ok, after my lack of success in the last thread I'm attempting to build an associative array manually. (Hopefully with more functionaility too, like being able to iterate through it.)

What I want to achieve is standard in OOP, but i'm not sure whether it's possible in GS.

The code will hopefully make more sense:

function array(indexes,values) {
this.inds = indexes;
this.vals = values;
this.item = item();
return this;
}

function item(ind) {
return this.vals[this.inds.index(ind)];
}

//then use like:
arr = array({"a","b","c"},{"one","two","three"});
var = arr.item("b"); //var should be "two"



Is this kind of thing possible? I'm trying to achieve some pretty basic OO functionality.

If this is possible it'd really help me with a lot of scripts.

Thanks.

Admins
08-27-2006, 11:48 PM
You can do things like this:


myvar = new TStaticVar();
myvar.join("myarrayclass");


and then add functions into myarrayclass.

JkWhoSaysNi
08-27-2006, 11:55 PM
ah. Thanks.

Joined classes dont seem to get updated when I press apply. I just added a function to one and it's not recongnised. The ones I added originally are.

Also, if I change something it doesn't seem to update.

ForgottenLegacy
08-28-2006, 02:32 PM
You need to recreate the TStaticVar. Call a destroy() to it in some script, then remake it. Should work.

JkWhoSaysNi
08-28-2006, 03:40 PM
Where should destroy go?

Heres what I have:

//#CLIENTSIDE

function onWeaponFired() {
arr = new TStaticVar();
arr.join("assocarray");
arr.make({"a","b","c"},{"one","two","three"});


echo(arr.put("d","four"));
arr.put("seven","nine");
echo("Has:" @ arr.has("notakey"));
echo(arr.keys());
arr.put("eight","ten");
echo("remove: " @ arr.remove("b"));
echo(arr.keys());

//for(arr.start();arr.off();arr.forth()){
//player.chat = player.chat @ arr.item_for_iteration;
//}

arr.start();
while(!(arr.off())) {
player.chat = player.chat @ " " @ arr.item_for_iteration();
arr.forth();
}
arr.destroy();
}


I update the assocarry class and this weapon npc never shows the changes. For example, remove isn't working so i changed..


public function remove(key) {
if (has(key)) {
this.values.delete(this.keys.index(key));
this.keys.delete(this.keys.index(key));
return 0;
}
else return 1;
}


to


public function remove(key) {
this.keys.delete(this.keys.index("b")); //in the example b exists as a key so this should work
this.values.delete(this.keys.index(key));
this.keys.delete(this.keys.index(key));
return "test..."; //return a string instead of a number
}

However, arr.remove("anything"); is still returning 0 instead of "test...".

I added arr.destroy(); to my NPC but it still never updates.

Is it because both the weapon NPC and the class npc have //#CLIENTSIDE ?


UPDATE: If I copy and paste the entire remove function and call it remove2, then call arr.remove2() it will execute as expected. remove() still executes as if it were never changed since the first time I called it even though the code is identical to remove2().

Any ideas? This is a bit strange and highly annoying because I don't know whether the script is working or not because I cant tell whether it's using the latest version of the function.

JkWhoSaysNi
08-28-2006, 07:48 PM
Fixed. I stopped using the function name remove() and all is fine. Is it a reserved function name or used for something else?

Anyway, it all seems to be working fine now.

Heres my associatve array class. Feel free to use it.


//Associative array by JkWhoSaysNi
//#CLIENTSIDE
function duplicates(array) {
//recursivly check for duplicates in an array
duplicate = false;
if(array.size() != 0) {
for (i = 1; i <= array.size()-1; i++ ) {
if (array[0] == array[i]) {
duplicate = true;
}
}
if (duplicate == false) {
array.delete(0);
duplicate = duplicates(array);
}
}
return duplicate;
}
/////////////////
//Constructor
/////////////////
public function make(keys,values) {

//required because keys is passed as a reference to duplicates, which then empties it.
this.tempkeys = keys;

if (keys.size() != values.size() || duplicates(this.tempkeys)) return false;
else {
this.cursor = 0;
this.keys = keys;
this.values = values;
return true;
}
}
/////////////////
//Access
/////////////////
public function has(key) {
return (this.keys.index(key) >= 0);
}
public function item(key) {
if (has(key)) return this.values[this.keys.index(key)];
else return false;
}
public function has_item(value) {
return (this.values.index(value) >= 0);
}
public function keys() {
return this.keys;
}
public function values() {
return this.values;
}
public function item_for_iteration() {
return this.values[this.cursor];
}
public function key_for_iteration() {
return this.keys[this.cursor];
}
public function cursor() {
return this.cursor;
}
public function count() {
return this.values.size();
}
public function off() {
//has the cursor reached the end of the array?
return (this.cursor > this.keys.size()-1);
}

/////////////////
//Element change
/////////////////
public function put(key,value) {
//add or replace
if (has(key)) {
this.values[this.keys.index(key)] = value;
return 1;
}
else {
this.keys.add(key);
this.values.add(value);
return 2;
}
}
public function remove_item(key) {
if (has(key)) {
this.values.delete(this.keys.index(key));
this.keys.delete(this.keys.index(key));
return true;
}
else return false;
}

public function replace_key(oldkey,newkey) {
if (has(oldkey)) {
this.keys[this.keys.index(oldkey)] = newkey;
return true;
}
else return false;
}
public function clear_all() {
this.keys.clear();
this.values.clear();
this.cursor = 0;
}
/////////////////
//Cursor movement
/////////////////
public function forth() {
if (!off()) {
this.cursor++;
return true;
}
else return false;
}
public function back() {
if (this.cursor > this.keys.size()-1) {
this.cursor--;
return true;
}
else return false;
}
public function start() {
//Move cursor back to the start
this.cursor = 0;
}
public function end() {
this.cursor = this.keys.size()-1;
}
//
//invariant this.keys.size() == this.values.size();
//invariant this.cursor < this.values.size();
// would be nice but not supported.


usage:

arr = new TStaticVar();
arr.join("associative_array");

//create the array. first param is an array of keys, .second is values.
//if it works will return true, if there is a problem (e.g. duplicate key) it will return false.
arr.make({"a","b","c"},{"one","two","three"});

//add another element
arr.put("d","four");

//retrieve value for key "d"
var = arr.item("d"); //var == "four"

//change value for key
arr.put("d","five"); //arr.item("d") == "five"

//remove item
arr.remove_item("d");

//iterate through the array
for(arr.start();!arr.off();arr.forth()) {
player.chat = player.chat @ " " @ arr.item_for_iteration();
}



and a few other functions which you can see by looking at the class.

ApothiX
09-11-2006, 04:03 PM
You can also do:

arr = array({"a","b","c"},{"one","two","three"});
with(arr) {
temp.var = item("b");
}