I opened a thread yesterday about getting null pointer errors with falsely exported struct variables.
I went on and changed it and it worked fine - in one script. I did exactly the same thing in another and get a script link error
I have three modules with the following hierachy
- Rectangle.asc/h
-Rectangle_Operation.asc/h
-GlobalScript.asc/h
the headers contain struct declarations and struct variable imports
Well lets take a look at it
Rectangle.ash
struct Rects
{
...
};
import Rects Rect;
Rectangle.asc
Rects Rect;
...lots of fancy stuff...
(end of script)
export Rect;
This works perfect so far (thanks again khris!)
Now I did this in the rectangle_operations script as well
Rectangle_operations.ash
struct Rectangles
{
...
};
import Rectangles Rectangle;
Rectangle_operations.asc
Rectangles Rectangle;
...lots of fancy stuff...
(end of script)
export Rectangle;
As you see this is done in exactly the same manner as the first one, however when
GlobalScript.asc calls any memeber function of Rectangle ags throws a script link failed error at me.
It seems completely random as i can access members of Rect without a problem. Please Help!
Not sure if just a typo:
import Rectangle Rectangles;
should be
import Rectangles Rectangle;
Could you post the complete error meessage? Because it mentions the import that fails.
You can move the export unter the declaration btw, no need to have it at the end of the script.
It was only a type it's spelled correctly in the script
The complete error reads
"script link failed: Runtime Error: Unresolved import 'Rectangle'"
it's if rectangle was never properly exported...
With functions, the syntax is slightly different:
// header
struct Rectangles {
import function DoSomething(...);
}
// main script
function Rectangles::DoSomething(...) {
...
};
Since you say "when GlobalScript.asc calls any member function", it sounds like you're getting the error during the game, but I guess it IS a compile time error, right?
It is a compile error but I've tracked to the extend that it only occurs when I try to access a member of Rectangle
I think i did it right..
have a look
Header
struct Rectangles
{
import function Move(int ID, int toX, int toY, float seconds);
import bool IsIntersecting(int left1,int top1,int right1,int bottom1,int left2,int top2,int right2,int bottom2);
import function HandleCollision(int ID1, int ID2);
};
import Rectangles Rectangle;
Script (partial)
Rectangles Rectangle;
export Rectangle;
function Rectangles::Move(int ID, int toX, int toY, float seconds)
{
float time = IntToFloat(GetGameSpeed())*seconds;
float xoffset = IntToFloat(toX)-IntToFloat(Rect.GetX(ID));
float yoffset = IntToFloat(toY)-IntToFloat(Rect.GetY(ID));
if (time < 1.0) time = 1.0;
float xrate = xoffset/time;
float yrate = yoffset/time;
Rect.AddMovement(ID, xrate, yrate, FloatToInt(time));
}
bool Rectangles::IsIntersecting(int left1,int top1,int right1,int bottom1,int left2,int top2,int right2,int bottom2)
{
return !(left1 > right2 || right1 < left2 ||
top1 > bottom2 || bottom1 < top2);
}
function Rectangles::HandleCollision(int ID1, int ID2)
{
int stepsX = Rect.GetNextX(ID1)-Rect.GetX(ID1);
int stepsY = Rect.GetNextY(ID1)-Rect.GetY(ID1);
int Top1 = Rect.GetNextY(ID1);
int Top2 = Rect.GetNextY(ID2);
int Bottom1 = Rect.GetNextY(ID1)+Rect.GetHeight(ID1);
int Bottom2 = Rect.GetNextY(ID2)+Rect.GetHeight(ID2);
int Left1 = Rect.GetNextX(ID1);
int Left2 = Rect.GetNextX(ID2);
int Right1 = Rect.GetNextX(ID1)+Rect.GetWidth(ID1);
int Right2 = Rect.GetNextX(ID1)+Rect.GetWidth(ID2);
if (Rectangle.IsIntersecting(Left1, Top1, Right1, Bottom1, Left1, Top1, Right2, Bottom2)) Display ("Collision!");
}
I'm not sure exactly why the error occurs at this point but try removing these lines:
import Rectangles Rectangle;
Rectangles Rectangle;
export Rectangle;
Since there's no data in the struct, you don't need an instance. You're simply using the struct to group the functions. Now add "static" in front of "function" and "bool", both in the header and main script.
Do the same for your Rect script, then change the struct names from "Rects" to "Rect" and from "Rectangles" to "Rectangle". Then all calls will point directly to the static struct, not the instance.
Now it should compile and run fine.
-----
I'd have done things slightly differently. Maybe that doesn't work for you due to what you're doing but here goes:
// header
struct str_rectangle {
int x, y, width, height;
float xrate, yrate;
import int GetNextX();
import int GetNextY();
...
};
import str_rectangle Rectangle[200];
// main
str_rectangle Rectangle[200];
export Rectangle;
int str_rectangle::GetNextX() {
return this.x + FloatToInt(this.xrate*time_step);
}
Then a static struct like described for functions concerning not a single rectangle:
static bool Rectangles::AreIntersecting(int ID1, int ID2) {
return !(Rectangle[ID1].x > Rectangle[ID2].x ...
}
Thanks Khris, you saved my day once again. Even though this is a kind of workaround its perfectly suitable for my structs as data structs are handled internal and only passed through to the public struct.
I didnt knew you could use structs this way.
Now everthing works fine.