[SOLVED]Module variable storage, pseudo global variables? something like that...

Started by Darius Poyer, Thu 29/12/2011 13:20:31

Previous topic - Next topic

Darius Poyer

I'm wondering how module variables are stored.

I would like to declare global-esque variables in my module headers, but I am not sure that's really possible.

For instance, I am using a lot of structs for data and my modules basically look like this:

//Module Header
struct Data{
 int data1;
 int data2;
};

Then in the actual module script i begin by instantiating that struct

Data something[4]; or Data something; w/e.

That then becomes a local variable... Could I make it global and persistent somehow? how would I access it from other scripts, do I have to declare it in some other way?

I am a bit confused as to how and what I am asking, but I hope it's not too confusing.

monkey0506

You need to check out the import and export keywords. Variables, pointers, and struct instances have to be both imported (in the script header) and exported (from the script itself) to be made global. If you want to make a global function it only has to be imported.

Code: ags
// Script.ash

struct Data
{
  int data1;
  int data2;
};

import Data something[4]; // import requires the type, name, and for arrays, the size

// Script.asc

Data something[4];
export something; // export requires only the name


Depending what your module is for, you may want to consider using one struct internally for storing the data, and using a global struct with functions to access that data. In some cases giving direct access is a good alternative, but if you need encapsulation, there's several ways of achieving it in AGS (including unsupported but fully functional accessor functions).

P.S. Great job on not falling prey to the rookie mistake of putting the instance definition directly in the script header. The reason you never want to define anything in a script header is that the way AGS utilizes headers, it would actually create a separate copy of said item for every script. So good job there. ;)

Darius Poyer

Thanks Monkey


So I would have to do this.
Code: ags

//header
struct ModuleName{
  import static function setVar();
  import static function getVar();

  int var;
};
struct Vars{
  int number;
  int number2;
};


//module
ModuleName Module;
Vars variables[2];

static function Module::setVar(){
  var = 5;
  //or
  //variables[1].number = 4;
}
static function Module::getVar(){
  return var;
  //or
  //return variables[1].number;
}


And call the get function in order to use the info? and whatever I set in an earlier function within the module is then sort of global?

could i return a whole struct? I guess I'd have to instantiate a copy somewhere in order to catch that. Is it possible to set a whole struct in one go?

Like:
Code: ags
structName = structname2;

Darius Poyer

man, that^ must be all wrong...

Simpler question. How can I use a variable that's a part of a module struct, declared in the header and set in the main module script, in a room script?

I have this now, basically:

.ash
Code: ags

struct ModuleName{
  String Name;
  import static function setString();
};


.asc
Code: ags

ModuleName moduleName;
static function ModuleName::setString(){
  moduleName.Name = "PlayerName"
}


ROOM
Code: ags

ModuleName moduleName;

function room_Load(){
  ModuleName.setString();
}
function room_AfterFadeIn(){
  lLabel.Text = String.Format("%s",moduleName.Name);
}


But i get a Null reference error on this line:
Code: ags
lLabel.Text = String.Format("%s",moduleName.Name);


whats going on?

monkey0506

What's going on is that you're using two completely separate struct instances.

Code: ags
// Module.asc
ModuleName moduleName; // creates an instance of ModuleName called moduleName
// note that moduleName is never exported, it exists ONLY within this script

static function ModuleName::setString()
{
  moduleName.Name = "PlayerName"; // the Name property of the moduleName instance (that exists only in this script) is updated
  // no other instances are ever used
}


Code: ags
// roomX.asc

ModuleName moduleName; // creates a NEW instance of ModuleName, also called moduleName, but in no way related to moduleName from the module script
// note that String variables initialize to null
// moduleName.Name is null

function room_Load()
{
  ModuleName.setString(); // sets ONLY the LOCAL (to the module script) moduleName.Name, ignoring the one that exists in this script, because it can't see it
}


You need to reference the same instance if you want to use the same instance. Just because two instances have the same name doesn't mean they are the same instance. Also, the only pointer you can create to a custom struct is the this pointer:

Code: ags
// Module.ash

struct ModuleName
{
  writeprotected String Name; // added writeprotected so that it becomes read-only to the end-user
  import bool SetName(String name=0); // changed the function name to something more sensible, added a parameter to increase versatility,
 // made parameter optional to match original function, changed return type to bool, removed static access
 // note, pointers can be made optional only by substituting the value 0 for null, which is the only time integers and pointers can be exchanged in AGS
};

import ModuleName moduleName; // import the single instance, making it global

// Module.asc

ModuleName moduleName;
export moduleName;

bool ModuleName::SetName(String name)
{
  if (String.IsNullOrEmpty(name)) name = "PlayerName"; // validate data
  this.Name = name; // use 'this' to reference the instance that called the function
}

// roomX.asc

function room_Load()
{
  moduleName.SetName();
}

RickJ

All you need to know is here below.  Start with the "Script Module Guidelines" in the Technical forum which is a summary of the original document. 


Modules, Plugins and Technical FAQ:

http://www.adventuregamestudio.co.uk/yabb/index.php?topic=26283.0

The original and more detailed version of the Script Module Guidelines can be found in the AGS Wiki.
AGS Wiki:
http://americangirlscouts.org/agswiki/Category:Advanced_Tutorials

There are also templates that can be used to create script modules and that reflect the recommendations in the script module guidelines.
DemoQuest GIP Thread:
http://demo.agspace.ws/project/documents/ModuleProgrammingGuidlines-V0100.txt
http://demo.agspace.ws/project/documents/ModuleHeaderTemplate-V0101.txt
http://demo.agspace.ws/project/documents/ModuleScriptTemplate-V0100.txt

Once you have an understanding of what you are doing then feel free to ask questions and to take monkey's advice.

Darius Poyer

This is great, so many questions answered. I will have to go over my function declarations to make them more specific from now on. I really didn't know about return types, I'm used to Javascript with being able to just catch return values with a variable.

Anyway, thank you both. You have helped me immensely.

SMF spam blocked by CleanTalk