www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Error when using `import`.

reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
I am trying to make a tactical role-playing game which I am 
likely to open-source. Right now the code is very simple, with 
only 3 files each containing a class with the same name.

The files are `Map.d`, `Tile.d`, and `Unit.d`. Each of these 
files contains an `import` line to access one of the others. I 
got the following errors when trying to compile all 3 files with 
DMD, and the same errors after switching to DUB.

```
source/Unit.d(6,17): Error: import `Unit.Map` is used as a type
source/Unit.d(16,5): Error: import `Unit.Map` is used as a type
source/Tile.d(9,15): Error: import `Tile.Unit` is used as a type
source/Map.d(6,22): Error: import `Map.Tile` is used as a type
source/Map.d(19,11): Error: import `Map.Tile` is used as a type
```

I thought that the circular chain of imports may be the problem, 
but removing all references to `Unit` in `Tile.d` did not fix the 
problem.

Here are the contents of Tile.d:
```
import Unit;

class Tile
{
	private bool allowStand = true;
	private bool allowFly = true;
	public int stickyness = 0;
	
	public Unit* occupant;
	
	bool allowUnit(bool isFlyer) {
		if (isFlyer) return this.allowFly;
		else return this.allowStand;
	}
}
```

`Unit.d` & `Map.d` are longer files. `Map.d` begins with `import 
Tile;`, and `Unit.d` begins with `import Map;`.

Why are the errors happening? What's the problem? Why is it 
`currentclass.importedclass` instead of simply the imported class?
Feb 24
next sibling parent reply "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
A few things.

Module names should be lower case.

Each file, needs the full module declaration.


source/foo/bar.d:

```d

module foo.bar;

```


source/app.d:

```d

module app;

import foo.bar;

```


Directories matter, this allows the import path search (via the use of 
the -I switch) to locate modules based upon the filename relative to the 
directory in the search.
Feb 24
parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
On Saturday, 24 February 2024 at 10:34:25 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
 A few things.

 Module names should be lower case.
I capitalised the first letter in the class names so that I can make instances of them in lowercase. Should I rename the classes, modules, and filenames to all be lowercase? It appears to be solved now after adding module declarations to the beginning of each file in all-lowercase. This is despite the classes and the class names still being capitalized. I'm still getting errors, but they appear to be unrelated. Thank you.
Feb 24
parent "Richard (Rikki) Andrew Cattermole" <richard cattermole.co.nz> writes:
On 24/02/2024 11:51 PM, Liam McGillivray wrote:
 On Saturday, 24 February 2024 at 10:34:25 UTC, Richard (Rikki) Andrew 
 Cattermole wrote:
 A few things.

 Module names should be lower case.
I capitalised the first letter in the class names so that I can make instances of them in lowercase. Should I rename the classes, modules, and filenames to all be lowercase? It appears to be solved now after adding module declarations to the beginning of each file in all-lowercase. This is despite the classes and the class names still being capitalized. I'm still getting errors, but they appear to be unrelated. Thank you.
As far as naming goes, the recommendations from the D style guidelines are quite good. https://dlang.org/dstyle.html However I suspect that you are treating module names as symbols, and while this is the case it can be done, you should avoid doing that until you understand the basics. https://ddili.org/ders/d.en/modules.html
Feb 24
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Saturday, 24 February 2024 at 10:31:06 UTC, Liam McGillivray 
wrote:
 `Unit.d` & `Map.d` are longer files. `Map.d` begins with 
 `import Tile;`, and `Unit.d` begins with `import Map;`.

 Why are the errors happening? What's the problem? Why is it 
 `currentclass.importedclass` instead of simply the imported 
 class?
You can't give a class the same name as the file it's in. If you do, then when you try to use it from another file, the compiler will get confused and think you're referring to the file instead of the class (that's what "import is used as a type" means). The easiest way around this is to change the name of the file to lower case. So, for example, you could change the name of the file with the `Unit` class in it to `unit.d`, and then write `import unit;` to access it from your other files.
Feb 24
parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
On Sunday, 25 February 2024 at 03:23:03 UTC, Paul Backus wrote:
 You can't give a class the same name as the file it's in. If 
 you do, then when you try to use it from another file, the 
 compiler will get confused and think you're referring to the 
 file instead of the class (that's what "import is used as a 
 type" means).
Thank you. In PHP, I was told to put every class definition in a file of the same name (whether I like it or not). However, I actually now have it working *without* having done that. Both the file name and the class name are capitalized, and it's working. However, maybe that's because they each start with a `module` line that makes the module name lowercase. I will keep this in mind, and maybe rename the files.
Feb 26
next sibling parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
I don't know whether I should continue this topic or start a new 
one now that the problem mentioned in the title is fixed. I have 
now uploaded some of the code to [a GitHub 
repository](https://github.com/LiamM32/Open_Emblem).

To make this game usable, I will need a library for graphics and 
input. I don't have any experience with making GUI programs aside 
from a little bit with Qt and C++.

I have considered the following libraries:
- ~~SDL~~: Seems too low-level for me.
- Allegro via 
[DAllegro5](https://github.com/SiegeLord/DAllegro5): I found some 
C & C++ tutorials for this one, but I don't know how I would do 
it with D. This one looks difficult.
- ~~Imgui via 
[Dimgui](https://github.com/d-gamedev-team/dimgui)~~: While 
[Imgui](https://github.com/ocornut/imgui?tab=readme-ov-file) 
looks well-developed, the Dimgui readme links to [this 
repository](https://github.com/AdrienHerubel/imgui), which looks 
like a very old version of Imgui.
- Godot via 
[Godot-Dlang](https://github.com/godot-dlang/godot-dlang?tab=readme-ov-file#manuall
-creating-project): A well-developed game engine with an editor that may allow
me to get fancier graphics without a huge amount of effort. However, the
project page for Godot-Dlang gives a warning that it's unfinished. This may or
may not be a problem given that this is just a hobby project. I would be happy
to share any problems with the developers.
- SFML via [BindBC-SFML](https://github.com/BindBC/bindbc-sfml): 
SFML appears to be an easier way to get 2D graphics working 
compared to SDL & Allegro when using C++. However, it may take 
more effort to use it with D.
- [AE](https://github.com/CyberShadow/ae): This is a D library 
that provides graphics and other utilities using various C 
libraries. I am beginning to understand this one, as I've been 
looking at the provided demos. However, this one seems to SDL 
functions directly whenever an image is placed on-screen, which I 
don't understand the theory behind.

I have writing the code for the internal game logic as a library 
that can be used by various front-ends for graphics. This would 
let me experiment with different software for graphics, but it 
would make the code more complicated.

So far I have been attempting to get it working with AE for 
graphics, not using the library approach described above. I 
haven't committed it with git, as I have copied and pasted 
substantial code from the AE examples and I will need to look at 
the license before I share it. I have managed to get it to read a 
PNG using libpng, but not display it. I have had trouble with 
this. One of the demos uses a function `s.draw` for displaying an 
image, which isn't defined anywhere in AE, so it might be an SDL 
function. I don't know how it has access to it.

I chose to use D for this project because I have long wanted to 
learn the language, but I wonder if it's overkill for this 
project, given the low performance requirement. Maybe I would be 
better-off using a dynamic interpreted language. The benefit of D 
is largely for the learning experience.
Feb 26
parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On Monday, 26 February 2024 at 23:27:49 UTC, Liam McGillivray 
wrote:
 I don't know whether I should continue this topic or start a 
 new one now that the problem mentioned in the title is fixed. I 
 have now uploaded some of the code to [a GitHub 
 repository](https://github.com/LiamM32/Open_Emblem).

 To make this game usable, I will need a library for graphics 
 and input. I don't have any experience with making GUI programs 
 aside from a little bit with Qt and C++.
If you are going for game development, I would recommend raylib-d (https://code.dlang.org/packages/raylib-d), which is my wrapper around the very good raylib library. For doing GUI, raygui is supported, but I also can say I've seen some good things from fluid: https://code.dlang.org/packages/fluid -Steve
Feb 26
next sibling parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
On Tuesday, 27 February 2024 at 03:06:19 UTC, Steven 
Schveighoffer wrote:
 If you are going for game development, I would recommend 
 raylib-d (https://code.dlang.org/packages/raylib-d), which is 
 my wrapper around the very good raylib library.

 For doing GUI, raygui is supported, but I also can say I've 
 seen some good things from fluid: 
 https://code.dlang.org/packages/fluid

 -Steve
Raylib looks promising. I installed it along with your Raylib-d. I managed to build the example you provided with dub, but trying to use it in it's own dub project in a separate directory isn't working. Just copying and pasting `app.d` from the very example you provided results in a huge wall of errors, mostly "undefined reference to [some function]".
Feb 26
parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
On Tuesday, 27 February 2024 at 03:43:56 UTC, Liam McGillivray 
wrote:
 Raylib looks promising. I installed it along with your 
 Raylib-d. I managed to build the example you provided with dub, 
 but trying to use it in it's own dub project in a separate 
 directory isn't working. Just copying and pasting `app.d` from 
 the very example you provided results in a huge wall of errors, 
 mostly "undefined reference to [some function]".
Nevermind this. I just needed to add `libs "raylib"` to dub.sdl. I didn't think I would need to specify the libraries in the project when they are accessed through an external library. Now I know. Looking at the code examples on the Raylib and SFML website, they look similar in complexity of getting started, but I like it that the Raylib website has lots of simple demonstration programs on the website with the code provided. This is a great way to help with learning. https://www.raylib.com/examples.html So far it's been working when I try to do their C++ examples in D.
Feb 27
parent Danilo <codedan aol.com> writes:
On Tuesday, 27 February 2024 at 22:05:48 UTC, Liam McGillivray 
wrote:
 Looking at the code examples on the Raylib and SFML website, 
 they look similar in complexity of getting started, but I like 
 it that the Raylib website has lots of simple demonstration 
 programs on the website with the code provided. This is a great 
 way to help with learning.
 https://www.raylib.com/examples.html

 So far it's been working when I try to do their C++ examples in 
 D.
See also https://github.com/D-a-n-i-l-o/raylib-d_examples 😏 Just „dub run“ to execute each raylib example there.
Feb 27
prev sibling parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
There's something very strange going on when using Raylib-D.

I tried using the raylib function `LoadTexture` like this:
```
tileSprites[i] = LoadTexture("../sprites/" ~ spriteName);
```

I got the following error:
```
Error: function `raylib.LoadTexture(const(char)* fileName)` is 
not callable using argument types `(string)`
```

So it's not allowing me to use a D string, but wants me to use 
(what I believe to be) the archaic C-style string. Here is how 
this function, as well as `DrawText` is declared in the Raylib-D 
bindings:
```
void DrawText(const(char)* text, int posX, int posY, int 
fontSize, Color color); // Draw text (using default font)
Texture2D LoadTexture(const(char)* fileName); // Load texture 
from file into GPU memory (VRAM)
```

The weird thing is that both of these functions are declared only 
once and with these C-style strings as arguments, yet I have 
already successfully called `DrawText` using a D string, yet 
`Texture2D` results in an error.

```
DrawText("Open Emblem", 180, 300, 64, Colors.RAYWHITE);
```

So why is it that one of these functions, but not the other is 
allowing D strings in place of C-style strings?
Feb 27
next sibling parent reply Danilo <codedan aol.com> writes:
On Wednesday, 28 February 2024 at 07:56:16 UTC, Liam McGillivray 
wrote:
 ```
 DrawText("Open Emblem", 180, 300, 64, Colors.RAYWHITE);
 ```

 So why is it that one of these functions, but not the other is 
 allowing D strings in place of C-style strings?
C is expecting null-terminated chars. D string type is not null-terminated, but using directly a string literal like „Open Emblem“ is null-terminated. In D you use mystring.toStringz to create a null-terminated C char-array. Example for LoadTexture: https://github.com/D-a-n-i-l-o/raylib-d_examples/blob/main/examples/textures/047_textures_logo_raylib/source/app.d
Feb 28
parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
I now have the Raylib functions working by using `toStrinz`.

I pushed some updates to the repository. I made the main project 
a source library so that I can experiment with different graphics 
library front-ends. I put have the front-end using Raylib in the 
`raylib_frontend` directory. It doesn't yet have any 
interactivity, but it should build and run successfully IIRC.

I don't know how best to organize the code. So far I have been 
putting the loop that runs during gameplay in the `Mission` 
function in `mission.d`. This function contains the arrays where 
sprites are stored. The code for unloading data from files is 
split between this function and `maps.d`. I was going to have a 
file in the main `source/` (not `raylib_frontend/source`) called 
`loadData.d` which would handle unloading from files, but then I 
realized that those functions would need write access to multiple 
variables, making it a not very tidy approach.

One possibility is to turn `Mission` into a class. The Mission 
object would control the Map object and other things during 
gameplay. The other possibility is to make a derived class of Map 
with more graphics-related functionality and more.
Feb 29
parent monkyyy <crazymonkyyy gmail.com> writes:
On Friday, 1 March 2024 at 05:07:24 UTC, Liam McGillivray wrote:
 I don't know how best to organize the code. So far I have been 
 oo ideas
for a 2nd opinion: https://github.com/crazymonkyyy/raylib-2024/blob/master/docs/examplecode.md Theres not a good learning resource but "data oirented design": pick good data for your problem then do the simplest thing that makes it work
Mar 01
prev sibling parent Danilo <codedan aol.com> writes:
Examples were moved, so it‘s in the same place now:

- https://github.com/schveiguy/raylib-d
- https://github.com/schveiguy/raylib-d_examples
Feb 28
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On Monday, 26 February 2024 at 22:40:49 UTC, Liam McGillivray 
wrote:
 On Sunday, 25 February 2024 at 03:23:03 UTC, Paul Backus wrote:
 You can't give a class the same name as the file it's in. If 
 you do, then when you try to use it from another file, the 
 compiler will get confused and think you're referring to the 
 file instead of the class (that's what "import is used as a 
 type" means).
Thank you. In PHP, I was told to put every class definition in a file of the same name (whether I like it or not). However, I actually now have it working *without* having done that. Both the file name and the class name are capitalized, and it's working. However, maybe that's because they each start with a `module` line that makes the module name lowercase. I will keep this in mind, and maybe rename the files.
So D is weird about this. I always recommend you use a *package* (i.e. module foo.bar) instead of just a module (i.e. module bar). When you omit the module declaration, the compiler assumes the module name is the same as the file name *without the path taken into account*. What happens is if you have `Map` as a module, and then `Map` as the class name, using the name `Map` is going to be confusing (did you mean the module or the class?) However, if you have everything under a package, for example `foo`, i.e. a file `foo/Map.d` which contains the `Map` class, then when referring to `Map`, it can't be referring to the module, since you would have to refer to `foo.Map` for that. This means the class name `Map` by itself is unambiguous. A whole host of problems occurs with name lookup when you don't use packages. -Steve
Feb 26
prev sibling parent reply Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
I have made some progress on this. For the raylib front-end, I 
tried making a class called `Mission` which inherits `Map`. This 
class handles the graphics, input, and other game events. The 
program now compiles without errors, and there are some graphics. 
I have pushed these updates to the GitHub repository.
https://github.com/LiamM32/Open_Emblem

Currently, it just displays a map of grass tiles with one unit. 
Clicking on the unit causes a segmentation fault. There is 
something that's supposed to happen when clicked, but I don't 
know why it segfaults. The line where it segfaults appears to be 
roughly `oe-raylib/source/mission.d:125`.

I am continuing to work on this, but have been getting more 
strange runtime errors since the latest push.
Mar 05
parent Liam McGillivray <yoshi.pit.link.mario gmail.com> writes:
There's something that I'm trying to do that D may or may not be 
capable of.

In the Map class, there is a 2-dimensional array called `grid`, 
where the Tile objects are stored. The Mission class inherits the 
Map class.

In the Mission class, I want the `grid` array to instead be 
composed of a derivative of the Tile class. I tried making a 
derived class called `GridTile` which contains the additional 
property specific to the Raylib front-end.

I tried doing this, but it won't let me override `grid`, even if 
I change it from `private` to `protected` in the Map class.

Is there a way I can do this, without this additional 
functionality being put in the base Tile class?
Mar 05