Re: Step by step tutorials for using bindings in D
On Monday, 27 March 2023 at 00:06:36 UTC, Inkrementator wrote: I'm surprised this worked, according to `man ld`, the -L flag takes a dir as input, not a full filepath. Can you please post your full dub config? I'm intrigued. Hello again and thank you very much. I got it now, I got OpenGL, ncurses, Lua and Imgui running. This is amazing. My dub.json file looked like this: ```json { "authors": [ "eXodiquas" ], "copyright": "Copyright © 2023, eXodiquas", "dependencies": { "bindbc-lua": "~>1.0.0" }, "lflags": ["-L/usr/local/lib/liblua.a"], "versions": ["LUA_53"], "description": "A minimal D application.", "license": "proprietary", "name": "test" } ``` And I don't know what I did last time but this does not work, like you said. Maybe I forgot to save and was a bit stupid. ```json { "authors": [ "eXodiquas" ], "copyright": "Copyright © 2023, eXodiquas", "dependencies": { "bindbc-lua": "~>0.5.1" }, "description": "A minimal D application.", "libs": ["lua"], "license": "proprietary", "name": "test", "versions": [ "LUA_53" ] } ``` This is working as it is supposed to do. Thanks again for your time!
Re: Step by step tutorials for using bindings in D
On Sunday, 26 March 2023 at 14:09:19 UTC, Inkrementator wrote: # Practical Walkthrough Two ways to go about this: 1. Get SFML dynamic library somewhere 2. Create a project called sfmltest 3. Add BindBC-SFML dependency via dub 4. Put SFML dynamic library files into the directory where you will execute your file. Here we see that the dynamic bindings looks for the lib in the current directory: https://github.com/BindBC/bindbc-sfml/blob/a1bc81da5c41ec49257228a29dc0f30ec7e5c788/source/bindbc/sfml/system.d#L215 You can also use static bindings, but that will involve telling your linker about the library. I won't go into detail but it basically boils down to installing SFML to system directory or LD_LIBRARY_PATH and compiling your test project with -lSFML flag, or whatever the option is for dub. If you can install it via your package-manager, static bindings might be less of a hassle. And learning the process is worth it, you'll need it in the future, since dynamic binding are the exception. Thank you very much for your detailed answer. I got dynamic bindings running now. But you said static bindings are the main portion of bindings we use. So I tried to get static Lua bindings going. I got the static library `liblua.a` and I told my linker in the dub.json file where to find it: ```json [...] "versions": ["LUA_52"], "lflags": ["-L/usr/local/lib/liblua.a"], [...] ``` This works perfectly fine. I can also use `"libs": ["lua"]` so I don't have to specify the complete path. But now I wonder, do I have to specify all static bindings via linker commands or is there a mechanism which allows me to specify a path where all the libraries can be found? And my other question is, if I have to specify all static libraries by name, how do I know the name of the library? Giving the system path as `lflag` is easy, but where does Lua get the `lua` name from which works in the `"libs": ["lua"]` string? Thanks for answering my noob questions. I've never dealt with bindings and compiler flags in the languages I come from. :P
Step by step tutorials for using bindings in D
Hello everyone, once again, I am here for your help. My last questions were answered really competently so I try again. :P So, maybe this is a stupid question, but I have read a lot about Bindings to C and C++ libraries for D. For example the Derelict project (or now [BindBC](https://github.com/BindBC/bindbc-sfml)) is full of them. Now I wanted to use the SMFL2 dynamic bindings. In my head this works like this: 1. I create a project called sfmltest 2. I have to get the original SFML2 from somewhere 3. I have to place some already compiled SFML2 files somewhere in the sfmltest project 4. I have to add the BindBC-SFML dependencies to the sfmltest project 5. I have to load the compiled SFML2 files from within my D code 6. I can use the bindings. But as you see, my idea about the whole workflow is pretty vague. - What files do I really need from SFML2? - Where do I have to store the files from SFML2? - How can I tell the D compiler where to find those SFML2 files? - Is the overall idea I have about those bindings correct at all? - How do dynamic bindings and static bindings differ from each other? Is there a good resource to learn about those bindings? I currently skim through the books "Web Development in D" and "D Cookbook" and there are also mentions of bindings in them, but they assume I know what I am doing, what I am not. :D I hope this question or the array of questions to be real is not too stupid. Thanks in advance and have a nice weekend! eXodiquas
Vibe.d serve files from filesystem
Hello everyone, I build a web tool that allows people to upload some files. Those files should not be public, so I copy them into a folder hidden away on the filesystem. But, I want an authenticated user to be able to look at them. Those files are PDFs and mp3/4s. So my idea was to use an `iframe` with a `src="path/to/file"` but this is not working, because vibed wants to map it to a route but there is and there should be none. Is there a way to use iframes in this way, or do I need to approach this problem differently? Thanks in advance. eXo
Re: Vibe.d MongoDB database connection
On Sunday, 25 December 2022 at 23:05:08 UTC, eXodiquas wrote: Hello everyone, I tried to fix this problem myself but I just can't get it to work and you guys were great help for me on the last problems I encountered, so I give it a shot again. :P [...] I looked a bit closer into the problem and I found an issue in the vibe.d repository that states that the current version of vibe.d is not compatible with MongoDB version >= 5.1 https://github.com/vibe-d/vibe.d/issues/2693. In the same comment there is also a hint that a fix is already merged into vibe.d. I'll open an issue, because this is probably a vibe.d problem. I got it to work by downgrading my MongoDB container.
Vibe.d MongoDB database connection
Hello everyone, I tried to fix this problem myself but I just can't get it to work and you guys were great help for me on the last problems I encountered, so I give it a shot again. :P I worked through the "D Web Development" book by Kai Nacke and I tried to setup a MongoDB connection for my application. I'm running vibe.d on version 0.9.5. ```d this.client = connectMongoDB("mongodb://root:abc@127.0.0.1:27017"); auto db = this.client.getDatabase("test"); MongoCollection users = db["users"]; foreach(d; users.find(Bson.emptyObject)) { d.writeln; } ``` This is close to the code I found in the [vibe.d documentation](https://vibed.org/docs#mongo). But it gives me a huge error message like this: ``` MongoDB reply was longer than expected, skipping the rest: 223 vs. 36 vibe.db.mongo.connection.MongoDriverException@../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/cursor.d(304): Query failed. Does the database exist? /usr/include/dlang/dmd/std/exception.d:518 @safe noreturn std.exception.bailOut!(vibe.db.mongo.connection.MongoDriverException).bailOut(immutable(char)[], ulong, scope const(char)[]) [0x560171989396] /usr/include/dlang/dmd/std/exception.d:439 @safe bool std.exception.enforce!(vibe.db.mongo.connection.MongoDriverException).enforce!(bool).enforce(bool, lazy const(char)[], immutable(char)[], ulong) [0x56017198930e] ../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/cursor.d:304 @safe void vibe.db.mongo.cursor.MongoCursorData!(vibe.data.bson.Bson).MongoCursorData.handleReply(long, vibe.db.mongo.flags.ReplyFlags, int, int) [0x5601719822b6] ../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/connection.d:462 @safe int vibe.db.mongo.connection.MongoConnection.recvReply!(vibe.data.bson.Bson).recvReply(int, scope void delegate(long, vibe.db.mongo.flags.ReplyFlags, int, int) @safe, scope void delegate(ulong, ref vibe.data.bson.Bson) @safe) [0x560171984a84] ../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/connection.d:322 @safe void vibe.db.mongo.connection.MongoConnection.query!(vibe.data.bson.Bson).query(immutable(char)[], vibe.db.mongo.flags.QueryFlags, int, int, vibe.data.bson.Bson, vibe.data.bson.Bson, scope void delegate(long, vibe.db.mongo.flags.ReplyFlags, int, int) @safe, scope void delegate(ulong, ref vibe.data.bson.Bson) @safe) [0x560171984147] ../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/cursor.d:367 @safe void vibe.db.mongo.cursor.MongoFindCursor!(vibe.data.bson.Bson, vibe.data.bson.Bson, ).MongoFindCursor.startIterating() [0x560171982ab3] ../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/cursor.d:233 @property @safe bool vibe.db.mongo.cursor.MongoCursorData!(vibe.data.bson.Bson).MongoCursorData.empty() [0x560171982106] ../../../../.dub/packages/vibe-d-0.9.5/vibe-d/mongodb/vibe/db/mongo/cursor.d:60 @property @safe bool vibe.db.mongo.cursor.MongoCursor!(vibe.data.bson.Bson).MongoCursor.empty() [0x560171981e33] source/database.d:12 database.DatabaseConnection database.DatabaseConnection.__ctor() [0x56017199dc7d] source/app.d:10 _Dmain [0x56017197044b] Error Program exited with code 1 ``` It asks me if the database exists in this error message and the answer is yes, because I can access it via mongo-express and I can see that the database, the collection and a user is in there. My MongoDB setup is a docker environment running a mongodb container and a mongodb-express container via docker-compose. ```yaml version: '3.1' services: db: image: mongo restart: always ports: - 27017:27017 environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: abc mongo-express: image: mongo-express restart: always ports: - 8081:8081 environment: ME_CONFIG_MONGODB_ADMINUSERNAME: root ME_CONFIG_MONGODB_ADMINPASSWORD: abc ME_CONFIG_MONGODB_URL: mongodb://root:abc@db:27017/ ``` I exposed the 27017 port to the host system, which should be sufficient for a connection via the given connection url `mongodb://root:abc@127.0.0.1:27017`. The only difference from my setup to the one in the book or in the documentation is the docker setup. But I can't figure out why this should be a problem. Does somebody know what's up with this problem? Thanks everyone in advance and happy holidays! eXodiquas
Re: Mixin programming foreach
On Monday, 27 September 2021 at 17:14:11 UTC, Ali Çehreli wrote: [...] Woah, thanks everyone for the ridiculous precise and helpful answers I got here. This forum never disappoints. :P I now try to fully understand the answers and implement the solution to the problem in a cleaner way. The reason I wanted to hold on to the single members, is because I implemented Vector2 and Vector3 by hand and I personally did not need higher dimensional vectors, but because I write this library as open source I could imagine some other developer may need more than 3 dimensions and it would be great if all those vectors behave exactly the same way. For example, the components of my `Vector2` are accessible via `v.x` and `v.y`. Otherwise I have to do something like `Vector4.components[0]` which doesn't look that nice imo. But with the new insight I got, I should be able to cook something up. Thanks again everyone. Have a great day, eXodiquas
Re: Mixin programming foreach
On Monday, 27 September 2021 at 16:49:15 UTC, Dga123 wrote: On Monday, 27 September 2021 at 16:23:50 UTC, eXodiquas wrote: Howdy ho everyone, I found this forum very helpful for my (maybe) stupid questions, so I give it a try again because I don't understand what's happening here. [...] But nevertheless, I copied the code and changed it a bit to something like this: ```d template Vector(int dimension) { string cps = ""; foreach(d; 0..dimension) { cps ~= "x" ~ d ~ " = 0;\n"; make a `string cps(){}` function. TemplateDeclaration can only contains DeclDefs, i.e declarations and no expressions. b.t.w `template Vector` can also be a string `Vector(int dimension){}` function. So finally to obtain something like this ```d import std; string vector(int dimension) { string cps; foreach(d; 0..dimension) { cps ~= "int x" ~ d.to!string ~ " = 0;\n"; } return "struct Vector" ~ dimension.to!string ~" {\n" ~ cps ~ "}"; } mixin(vector(5)); ``` function used in mixin are evaluated at compile time and are generally more perfomantly evaluated than eponymous template (that contains a single member named as the template). Also less constraint on what can be done. Have a great day, Dga. I see, thank you very much for the quick answer. So the "macro magic" does not happen in `template`, it happens in the `mixin` call, now I understand. But my last question still stands, how do I build functions that can work with those vectors because the type of those vectors is created at compile time. But I can start working on the problem now. Thanks again for helping me out here. :) Have a great day aswell, eXodiquas
Mixin programming foreach
Howdy ho everyone, I found this forum very helpful for my (maybe) stupid questions, so I give it a try again because I don't understand what's happening here. First of all, I'm not exactly sure what this code here, from the documentation at https://dlang.org/articles/mixin.html, does: ```d template GenStruct(string Name, string M1) { const char[] GenStruct = "struct " ~ Name ~ "{ int " ~ M1 ~ "; }"; } mixin(GenStruct!("Foo", "bar")); ``` In my understanding we create a template called `GenStruct` with compile time arguments `Name` and `M1`. We then create the `char[] GenStruct` which holds the source code for the `struct`. Afterwards we do the `mixin`call and create the source code during compile time to have it ready to go. But I don't understand why the `char[] GenStruct` is there. Is this the name of the `mixin` or is the `template GenStruct` the name of what we pass to the `mixin`? Can we create more than one const char[] in one `template` scope and what would it do if we could? So I'm a bit confused here. But nevertheless, I copied the code and changed it a bit to something like this: ```d template Vector(int dimension) { string cps = ""; foreach(d; 0..dimension) { cps ~= "x" ~ d ~ " = 0;\n"; } const char[] Vector = "struct Vector {\n" ~ dimension.to!string ~ cps ~ "}"; } ``` In my head a call to `mixin(Vector!5)` should result in something like this: ```d struct Vector5 { int x0; int x1; int x2; int x3; int x4; } ``` But it does not compile because `Error: declaration expected, not foreach` which I understand as "foreach is not possible during compile time", whereas I don't see any problem with compile time availability of anything in this template. Obviously I don't understand something here, so it would be awesome if someone could help me out here. :P And as a final question. Let's say the above problems are all solved and I construct such a template. How could I build functions that take any of those `Vector`s as an argument? For example I want to add two of those, the function would look something like this, or am I lost again? ```d Vector!T add(Vector!T lhs, Vector!T rhs) { return ?; } ``` How could I iterate over all components if such a `Vector`? I hope I am not on the completely wrong track to tackle this problem. Thanks in advance. :) eXodiquas
Re: Return complete multi-dimensional array after appending
On Wednesday, 15 September 2021 at 21:02:29 UTC, Paul Backus wrote: On Wednesday, 15 September 2021 at 20:32:12 UTC, eXodiquas wrote: ```d [1,0,3,4,0,5] .fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) [[],[]]) .flatten .writeln ``` This should sort all non 0s into the `a[0]` array and all 0s into the `a[1]` array. But it won't work because the `~` does not return the whole array (which is probably better for most of the cases). So the question, is there a way to do this kind of append, but getting the whole array back as a result in std? You need to use `~=` instead of `~` to mutate an existing array: ```d import std; void main() { [1, 0, 3, 4, 0, 5] .fold!((a, e) { e != 0 ? (a[0] ~= e) : (a[1] ~= e); return a; })(cast(int[][]) [[], []]) .joiner .writeln; } ``` Of course, a more idiomatic solution would be to use `std.algorithm.partition`: ```d import std; void main() { auto arr = [1, 0, 3, 4, 0, 5]; arr.partition!(e => e != 0); // in-place arr.writeln; } ``` Oooh, I totally forgot you can open blocks like this in anonymous functions. Now I look a bit stupid. Thanks. :) `partition` is also very nice. D std is so huge, I should sketch out a roadmap or something. That's why I asked the question in the first place because deep inside I knew there is a function in std that solves the problem. Thanks for the answer. :)
Return complete multi-dimensional array after appending
Howdy everyone. :) Today I came across a small problem (I mean, I could solve it by writing a function that solves my problem, but maybe there is something in std that can help me here). Let's say we have the following code: ```d void main() { int[][] a = [[],[]]; (a[0] ~ 5).writeln; // => [5] } ``` it's quite obvious that `[5]` is printed. Because I am a fan of one-liners (we do small code challenges, and I want to show what's possible with fold) and ridiculous stuff I tried to do something like this: ```d [1,0,3,4,0,5] .fold!((a, e) => e != 0 ? a[0] ~ e : a[1] ~ e)(cast(int[][]) [[],[]]) .flatten .writeln ``` This should sort all non 0s into the `a[0]` array and all 0s into the `a[1]` array. But it won't work because the `~` does not return the whole array (which is probably better for most of the cases). So the question, is there a way to do this kind of append, but getting the whole array back as a result in std? And another question, is there a way to tell `fold` about the initial value of an empty list without having to cast a `void[]` into the list of the desired type? Thanks in advance. :) eXodiquas
Re: Piping from terminal into D program
On Saturday, 4 September 2021 at 18:20:51 UTC, WebFreak001 wrote: On Saturday, 4 September 2021 at 15:41:51 UTC, eXodiquas wrote: [...] to extend on Brian Tiffin's reply, you can read from the standard input stream (the data piped to your program) using std.stdio's `stdin` [...] Brian Tiffin's and your reply really cleared things up for me. Thank you very much for the detailed answer and your time. Have a nice day. :)
Piping from terminal into D program
Hello everyone, I created a small little D program that reads in a string from the command line and shuffles the letters of the nouns a bit around. This is pretty straight forward, but what I see now happening is a bit strange, at least for me. I am reading the args out of the main function arguments. ```d void main(string[] args) { args.writeln(); } ``` this works fine whenever I call the program like `./nounscramble "Hello, my name is Earl!"` the string shows up in `args[1]`. But when I call `echo "Hello, my name is Earl!" | ./nounscramble` it does not show up in the args array, the only thing showing up is the name of the executable (which is expected). My question is now, can someone explain what I am doing wrong? Maybe I misunderstood the pipe in Linux systems and it is obvious for someone who knows how this works exactly, or maybe D works differently with pipes and I havn't found the correct documentation. Thanks in advance. :) eXodiquas
Re: (Maybe) Strange Behaviour of Field Initialization
On Wednesday, 28 April 2021 at 15:35:57 UTC, Adam D. Ruppe wrote: On Wednesday, 28 April 2021 at 15:09:36 UTC, eXodiquas wrote: ```d class Particle : Drawable { CircleShape shape = new CircleShape(5); This `new` is actually run at compile time, so every instance of Particle refers to the same instance of CircleShape (unless you rebind it). this.shape.position = Vector2f(x, y); this.shape.fillColor = Color.Green; Which means each constructor here overwrites the fields on the same object! What you probably want is to construct the shape in the constructor too, since that is run for each instance created, instead of just once at compile time and reused for each instance. This behavior D has is pretty useful... but also pretty surprising to people coming from other languages. I kinda wish the compiler made you be a little more explicit that you actually did intend to compile time construct it. The last time I wrote something in D is a few months back, but I cannot remember this behavior. In the code above `shape` acts like as if it were `static` without being `static`, obviously. Well, the instance is static, but the handle is not. If you were to do a `this.shape = new Shape;` then that object would refer to a new one, but if you don't it all uses the same object. The code you have is kinda like if you wrote: static Shape global_shape = (at ctfe) new Shape; (in the instance) Shape shape = global_shape; Thanks, this is a pretty good explanation. I get it now. :) This behavior sounds pretty neat, as long as you know about it. :P
(Maybe) Strange Behaviour of Field Initialization
Hello everyone, I am playing around with DSFML and drawing some stuff on the screen. It works like a charm but I got some unexpected behavior when building a `Particle` class. My class looks like this: ```d class Particle : Drawable { CircleShape shape = new CircleShape(5); this(int x, int y) { this.shape.position = Vector2f(x, y); this.shape.fillColor = Color.Green; } void draw(RenderTarget renderTarget, RenderStates renderStates) { renderTarget.draw(this.shape); } } ``` When I create an array of `Particle`s and try to draw them, all of them are drawn on the exact same location in my window. However, when I assign `shape` in the constructor with `this.shape = new CircleShape(5);` it works as expected. The last time I wrote something in D is a few months back, but I cannot remember this behavior. In the code above `shape` acts like as if it were `static` without being `static`, obviously. Is there something wrong with D in this case, or is there something wrong with DSFML or am I just stupid right now and not able to see the obvious. Thanks in advance.
Re: Operator Overloading with multiple return types
On Friday, 15 March 2019 at 21:46:50 UTC, Ali Çehreli wrote: On 03/15/2019 02:43 PM, Sebastiaan Koppe wrote: On Friday, 15 March 2019 at 21:35:12 UTC, eXodiquas wrote: Is there any way to achive this behaivour with D2? Yep. Just make the return type in the function declaration `auto`. You are then free to return a different type in each static branch. Or use template constraints: struct Vector { Vector opBinary(string op)(Vector rhs) if (op == "+") { return Vector(); } double opBinary(string op)(Vector rhs) if (op == "/") { return 0.5; } } Ali Thanks for the quick and simple answers, but I don't get this one. If I do it that way the compiler doesn't know which function to call, or am I doing something wrong? Vector2 opBinary(string op)(Vector2 rhs) { if (op == "+") { return Vector2(this.x + rhs.x, this.y + rhs.y); } else if (op == "-") { return Vector2(this.x - rhs.x, this.y - rhs.y); } } float opBinary(string op)(Vector2 rhs) { if (op == "*") { return this.x * rhs.x + this.y * rhs.y; } } This gives me the error: overloads (Vector2 rhs) and (Vector2 rhs) both match argument list for opBinary eXodiquas
Operator Overloading with multiple return types
Hi everyone, i'm currently working on a small physics engine and I thought it would be a nice feature to overload the operators of my vector struct so I don't have to make ugly function calls just to add and "multiply" my vectors. The problem now is that overloading the addition and subtraction of my vector struct is straight forward because both return and take a vector, dot product is not working for me because it is not possible to overload a function by return type (at least not that I am aware of). My code looks like the one from the dlang docs: Vector opBinary(string op)(Vector rhs) { static if (op == "+") return Vector(this.x + rhs.x, this.y + rhs.y); else static if (op == "-") return Vector(this.x - rhs.x, this.y - rhs.y); } As you can see for the dot product the return type has to be a float/double and not a vector. Is there any way to achive this behaivour with D2? The opMul() function is not D2 style and I don't want to use it. Thank you very much, eXodiquas