Thread overview
foreach(ubyte j;0 .. num) is bugging out
Sep 23, 2021
Ruby The Roobster
Sep 23, 2021
jfondren
Sep 23, 2021
Ruby The Roobster
Sep 23, 2021
jfondren
September 23, 2021

So, I have the following function:

	public Sprite ReadSpriteFromFile(immutable(char)[] filename)	{ //Reads a sprite in my made up .spr format(trash, why does this even exist)
		ubyte[] ftext;
		Color[] colors;
		Point[][] points;
		import std.file;
		import std.stdio;
		ftext = cast(ubyte[])read(filename);
		foreach(i;0 .. cast(uint)ftext.length)	{ //Parse the file...
			long main;
			short exp;
			uint x = 0;
			++colors.length;
			++points.length;
			colors[x].r = ftext[i]; //Set r color...
			++i;
			colors[x].g = ftext[i];
			++i;
			colors[x].b = ftext[i];
			++i;
		ubyte tempcolor = ftext[i];
		++i;
		long temp;
	        writeln(tempcolor); //For this matter, the program correctly reports tempcolor as 1...
		for(ubyte j = 0;j < tempcolor; j++ /*trying ++j has same effect*/ )	{ //tempcolor is 1, yet this sloop gets executed twice...
			writeln();
			posfunc(ftext, main, exp, temp, i, j, points , x);                                        //Orignally foreach loop, but switching to for loop has same effect...
		}
	}
	return Sprite(colors, points);
}

Here is the rest of the source:

/*sprite.d by Ruby The Roobster*/
/*Version 0.3.5 Release*/
/*Last Update: 08/23/2021*/
/*Module for sprites in the D Programming Language 2.0*/
module dutils.sprite;
import skeleton : Point;

version(USE_BUILT_IN_SPRITES)	{ //Use built in sprites(garbage .spr format coded by me, that still needs an editor: Editor using GtKD for .spr comes out later this year, if I can get myself to do it)...
	public struct Color	{
		ubyte r = 0;
		ubyte g = 0;
		ubyte b = 0;
		void opAssign(Color rhs)	{
			this.r = rhs.r;
			this.g = rhs.g;
			this.b = rhs.b;
		}
	}

	public struct Sprite	{
		Color[] colors;
		Point[][] points;
		invariant()	{
			assert(colors.length == points.length, "Assertion failure: Sprite.colors.length and Sprite.points.length must always be equal...");
		}
		void opAssign(Sprite rhs)	{
			this.colors.length = rhs.colors.length;
			this.points.length = rhs.points.length;
			foreach(i;0 .. this.colors.length)	{
				this.colors[i] = rhs.colors[i];
			}
			foreach(i;0 .. this.points.length)	{
				this.points[i].length = rhs.points[i].length;
				foreach(j;0 .. this.points[i].length)	{
					this.points[i][j] = rhs.points[i][j];
				}
			}
		}
		package void ChangeLengths(uint c)	{ //Change both lengths so invariant doesn't get triggered...
			this.colors.length = c;
			this.points.length = c;
		}
	}

//ReadSpriteFromFile was here...
	
	package void posfunc(const ubyte[] ftext, ref long main, ref short exp, ref long temp, ref uint i, const ubyte j, ref Point[][] points, ref uint x)	{
		++points[x].length;
		import std.stdio;
		writeln(__LINE__);
		foreach(z;0 .. 3)	{
			short shift = 56;
			main = ftext[i];
			main <<= shift;
			++i;
			shift -= 8;
			while(shift >= 0)	{
				writeln(shift);
				writeln(i);
				temp = ftext[i];
				main = (main <= (-0)) ? (main - temp) : (main + temp);
				++i;
				shift -= 8;
			}
			exp = ftext[i];
			exp <<= 8;
			++i;
			exp += ftext[i];
			if(i+1 == ftext.length)	{
			}
			else	{
			++i;
			}
			switch(z)	{
				case 0:
					points[x][j].x = (main * 10^^exp);
					break;
				case 1:
					points[x][j].y = (main * 10^^exp);
					break;
				case 2:
					points[x][j].z = (main * 10^^exp);
					break;
				default:
					assert(false); //bruh...
			}
		}
	}
}

version(USE_OTHER_SPRITE)	{ //If the user wants to work with sprites their own way...
	public alias Sprite = uint function();
}

version(USE_FILE_SPRITE)	{  //If the user wants to read the sprites from a file and do it that way...
	public alias Sprite = wchar[];
}

skeleton.d source:

/*skeleton.d by Ruby The Roobster*/
/*Version 1.0 Release*/
/*Module for representing skeletons in the D Programming Language 2.0*/

public struct Point	{ //Point structure...
	real x;
	real y;
	real z;
	void opAssign(Point rhs)	{
		this.x = rhs.x;
		this.y = rhs.y;
		this.z = rhs.z;
	}
	void opOpAssign(string op)(Point rhs)	{
		mixin("this.x " ~ op ~ "= rhs.x;");
		mixin("this.y " ~ op ~ "= rhs.y;");
		mixin("this.z " ~ op ~ "= rhs.z;");
	}
}

public struct Face	{ //Face(of a 3D shape) structure...
	Line[] lines;
	Point center;
	void opAssign(Face rhs)	{
		this.lines.length = rhs.lines.length;
		foreach(i;0 .. this.lines.length)	{
			this.lines[i] = rhs.lines[i];
		}
	}
}

public struct Skeleton	{ //Skeleton of a 3D structure...
	Face[] faces;
	Point center;
	void opAssign(Skeleton rhs)	{
		this.faces.length = rhs.faces.length;
		foreach(i;0 .. this.faces.length)	{
			this.faces[i] = rhs.faces[i];
		}
		this.center = rhs.center;
	}
}


public struct Line	{ //Line struct...
	Point[] mid_points;
	Point start;
	Point stop;
	void opAssign(Line rhs)	{
		this.start = rhs.start;
		this.stop = rhs.stop;
		this.mid_points.length = rhs.mid_points.length;
		foreach(i;0 .. this.mid_points.length)	{
			this.mid_points[i] = rhs.mid_points[i];
		}
	}
}

Here is my test program for these:

//This file is called nid.d
import dutils.sprite;
import std.stdio;
void main()	{
	Sprite sprite = ReadSpriteFromFile("abc.txt");
	writeln(sprite);
}

abc.txt in hexadecimal:

00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 01

Compiler Version: DMD 2.097.2

Command line: dmd nid.d sprite.d skeleton.d -version=USE_BUILT_IN_SPRITES

Sorry for this being long, but whole source files were provided for clarity. Why the heck is the loop being executed twice(check output for blank lines).

Also, if this is somehow relevant, I am on Windows 10 20H1 build 19043.1237.

September 23, 2021

On Thursday, 23 September 2021 at 00:06:42 UTC, Ruby The Roobster wrote:

>

So, I have the following function:

	        writeln(tempcolor); //For this matter, the program correctly reports tempcolor as 1...
		for(ubyte j = 0;j < tempcolor; j++ /*trying ++j has same effect*/ )	{ //tempcolor is 1, yet this sloop gets executed twice...
			writeln();
			posfunc(ftext, main, exp, temp, i, j, points , x);                                        //Orignally foreach loop, but switching to for loop has same effect...
		}

Needs more print in your print debugging:

writeln("tempcolor: ", tempcolor);
...
writeln("in tempcolor with j: ", j);

output:

tempcolor: 1
in tempcolor with j: 0
...
... numbers
...
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 1
in tempcolor with j: 0
...
... numbers
...

Here's a oneliner to reproduce to abc.txt:

rdmd --eval '"00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00 00 01".split(" ").map!(s => cast(char) s.to!ubyte).write' > abc.txt
September 23, 2021

On Thursday, 23 September 2021 at 00:17:49 UTC, jfondren wrote:

>

On Thursday, 23 September 2021 at 00:06:42 UTC, Ruby The Roobster wrote:

>

So, I have the following function:

	        writeln(tempcolor); //For this matter, the program correctly reports tempcolor as 1...
		for(ubyte j = 0;j < tempcolor; j++ /*trying ++j has same effect*/ )	{ //tempcolor is 1, yet this sloop gets executed twice...
			writeln();
			posfunc(ftext, main, exp, temp, i, j, points , x);                                        //Orignally foreach loop, but switching to for loop has same effect...
		}

Needs more print in your print debugging:

writeln("tempcolor: ", tempcolor);
...
writeln("in tempcolor with j: ", j);

output:

tempcolor: 1
in tempcolor with j: 0
...
... numbers
...
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 0
tempcolor: 1
in tempcolor with j: 0

I figured out something weird. The variable 'i' is passed by reference, yet the variable 'i' of the loop isn't being incremented by posfunc. I assume foreach creates a new i variable at the start of each new loop. Swapping the original loop with a while loop fixes the problem. Thank you very much for trying to help.

September 23, 2021

On Thursday, 23 September 2021 at 00:30:45 UTC, Ruby The Roobster wrote:

>

I figured out something weird. The variable 'i' is passed by reference, yet the variable 'i' of the loop isn't being incremented by posfunc. I assume foreach creates a new i variable at the start of each new loop.

Yep:

$ rdmd --eval 'foreach (i; 0 .. 5) { writeln(i); i++; }'
0
1
2
3
4