Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote: On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote: [...] Nonetheless, this usually used with Objects (new class/struct instances), like so: ```d import std; [...] Fluent Interface 😀
Re: Setting field of struct object
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote: On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`. Apparently comments about module visibility issues are no longer allowed on the D forum. I wonder why your comment was not deleted though ?? No wonder there is now a fork of D.
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` I had reason to need this to work a while ago and `opDispatch` came in very handy. I was able to cook up one that forwarded calls to other members in a struct, while returning `this` by ref, allowing for chaining calls. I use it with UDAs. (Scroll to the unit tests for examples.) ```d /++ Mixin template generating an `opDispatch` redirecting calls to members whose names match the passed variable string but with an underscore prepended. +/ mixin template UnderscoreOpDispatcher() { ref auto opDispatch(string var, T)(T value) { import std.traits : isArray, isAssociativeArray, isSomeString; enum realVar = '_' ~ var; alias V = typeof(mixin(realVar)); static if (isAssociativeArray!V) { // Doesn't work with AAs without library solutions } else static if (isArray!V && !isSomeString!V) { mixin(realVar) ~= value; } else { mixin(realVar) = value; } return this; } auto opDispatch(string var)() inout { enum realVar = '_' ~ var; return mixin(realVar); } } /// unittest { struct Foo { int _i; string _s; bool _b; string[] _add; alias wordList = _add; mixin UnderscoreOpDispatcher; } Foo f; f.i = 42; // f.opDispatch!"i"(42); f.s = "hello";// f.opDispatch!"s"("hello"); f.b = true; // f.opDispatch!"b"(true); f.add("hello"); // f.opDispatch!"add"("hello"); f.add("world"); // f.opDispatch!"add"("world"); assert(f.i == 42); assert(f.s == "hello"); assert(f.b); assert(f.wordList == [ "hello", "world" ]); auto f2 = Foo() .i(9001) .s("world") .b(false) .add("hello") .add("world"); assert(f2.i == 9001); assert(f2.s == "world"); assert(!f2.b); assert(f2.wordList == [ "hello", "world" ]); } ``` You could trivially adapt it to use a `withName`, `withEmail` calling scheme instead of the underscore thing.
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:47:23 UTC, bachmeier wrote: On Monday, 22 January 2024 at 15:45:45 UTC, zjh wrote: On Monday, 22 January 2024 at 15:33:01 UTC, ryuukk_ wrote: it only took me 1 project to never want to touch C++ again.. D language used to have no `copy constructor`, isn't it now added in again? You have to admit the good aspects of `C++`. You should take a look at the `latest C++`. C++ has already learned many advantages of `D`, but D has not made `significant progress`! As a user, `C++` is really not much different from D, and even surpasses D `in many aspects`. `RAII `, `variable parameter` template, `coroutine, concept`, `value semantics`, very easy to understand. Moreover, the `inheritance` of C++ is very enjoyable to use in many aspects. Sounds like you should be using C++. Why are you here? Everyone who uses D should be welcome, even if they have a preference for another language, or a preference for features in another language. This is how D will evolve and improve. And this should include people who don't like the untyped universe of the D module (specifically, its lack of an optional mechanism for information hiding within a module). People can think of it as if it were typed, but this is just an illusion. This illusion can easily lead to type confusion and inconsistent and erroneous interactions - i.e. bugs. To avoid this in D one needs to literally reorganise that untyped universe into into a typed system. Now your types impose constraints which will help to enforce their correctness. Organisation is important of course, but for using types in D, its vital - if strong typing is your objective. I think D is clumsy in many other areas as well. btw. I too prefer multiple inheritance.
Re: Setting field of struct object
On Thursday, 25 January 2024 at 08:46:34 UTC, Renato wrote: ```d void main() { Person p = { "Joe", "j...@ab.com", 30}; writeln(p); } ``` I just tested it and it works. It's `great`!
Re: Setting field of struct object
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote: On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`. You know you can use struct literals in initializers, right? ```d import std.stdio; struct Person { string name, email; ulong age; } void main() { Person p = {name: "Joe", email: "j...@example.com", age: 30}; writeln(p); } ```
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:56:59 UTC, zjh wrote: On Monday, 22 January 2024 at 15:51:37 UTC, zjh wrote: I spent `too much time` on D. And some of the inherent `drawbacks` of `C++` are too hateful. It's a package deal. Everything in C++ is there because there were benefits when they added it, but those benefits came with downsides. D will end up in the same place if it emulates C++.
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:51:37 UTC, zjh wrote: I spent `too much time` on D. And some of the inherent `drawbacks` of `C++` are too hateful.
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:47:23 UTC, bachmeier wrote: Sounds like you should be using C++. Why are you here? I spent `too much time` on D.
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:14:32 UTC, Bkoie wrote: D is totally different from C++ in D you usually you wont construct the struct directly use alias as. Stop being `unconventional` and quickly copy their `good things`. Otherwise, the `development speed` of the D language is really `too slow`!
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:45:45 UTC, zjh wrote: On Monday, 22 January 2024 at 15:33:01 UTC, ryuukk_ wrote: it only took me 1 project to never want to touch C++ again.. D language used to have no `copy constructor`, isn't it now added in again? You have to admit the good aspects of `C++`. You should take a look at the `latest C++`. C++ has already learned many advantages of `D`, but D has not made `significant progress`! As a user, `C++` is really not much different from D, and even surpasses D `in many aspects`. `RAII `, `variable parameter` template, `coroutine, concept`, `value semantics`, very easy to understand. Moreover, the `inheritance` of C++ is very enjoyable to use in many aspects. Sounds like you should be using C++. Why are you here?
Re: Setting field of struct object
On Monday, 22 January 2024 at 15:33:01 UTC, ryuukk_ wrote: it only took me 1 project to never want to touch C++ again.. D language used to have no `copy constructor`, isn't it now added in again? You have to admit the good aspects of `C++`. You should take a look at the `latest C++`. C++ has already learned many advantages of `D`, but D has not made `significant progress`! As a user, `C++` is really not much different from D, and even surpasses D `in many aspects`. `RAII `, `variable parameter` template, `coroutine, concept`, `value semantics`, very easy to understand. Moreover, the `inheritance` of C++ is very enjoyable to use in many aspects.
Re: Setting field of struct object
I should note that it only took me 1 project to never want to touch C++ again.. that must be telling something, either about the language, or me, or both lol
Re: Setting field of struct object
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote: On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`. I used to want this feature too, but i then got hit by a bug when i reordered the fields in the struct.. i don't want to deal with that stuff anymore But we now have named arguments, so this feature could be make use of it, it's similar with enums, perhaps one day this could be revived: https://github.com/dlang/DIPs/blob/e2ca557ab9d3e60305a37da0d5b58299e0a9de0e/DIPs/DIP1044.md There is even a working implementation: https://github.com/dlang/dmd/pull/14650
Re: Setting field of struct object
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote: On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`. i think D module base system is fine wished some other lang had the same you can avoid circular import ref. dry? well he can easily turn that into a generic config static factory which its look like hes trying to do. D is totally different from C++ in D you usually you wont construct the struct directly use alias as.
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` C++ can achieve ultimate `simplicity` without violating `DRY`, And here, D violates the `DRY` principle! Moreover, as the `package level, module level, class level, member level`, D language violates integrity. Because D has no `class level` limit. These are all not `serious states`.
Re: Setting field of struct object
On Monday, 22 January 2024 at 11:31:11 UTC, zjh wrote: D language violates integrity. Because D has no `class level` limit. These are all not `serious states`. It seems that D language is not `professional`.
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` D: ```d import std.stdio; struct Person { string name, email; ulong age; } void main() { Person p = Person(name: "n", email: "email", age: 33); writefln!"%s"(p); } ```
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` It's not much different in D. ;) ```d import std; struct Person { string name, email; ulong age; } void main() { auto p = Person("Tom", "joel...@gmail.com", 44); writeln(p); } ```
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:21 UTC, Danilo wrote: It's common OOP style in some frameworks. With latest D you can also just use named parameters: ```d import std; struct Person { /*private*/ string name, email; /*private*/ ulong age; } void main() { auto p = Person( name: "Tom", email: "joel...@gmail.com", age: 44, ); writeln(p); } ```
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` What about in D: auto a=Person(“n”, “email”, 33);
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ```
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:35:01 UTC, Joel wrote: I've lost interest in the video, looks like horrible syntax (F#). Nonetheless, this usually used with Objects (new class/struct instances), like so: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { auto p = (new Person).withName("Tom") .withEmail("joel...@gmail.com") .withAge(44); writeln(p); } ``` If you convert it to a class, add an `static opCall` for initialization, and a toString() method, it's even nicer: ```d module app; import std; class Person { private string name, email; private ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } static Person opCall() => new Person(); override string toString() { return "Person{ name: "~name~", age: "~age.to!string~", email: "~email~" }"; } } void main() { auto p = Person() .withName("Tom") .withEmail("joel...@gmail.com") .withAge(44); writeln(p); } ``` It's common OOP style in some frameworks.
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: I've been watching a video (YouTube - "Pipeline-oriented programming - Scott Wlaschin - NDC Porto 2023") with something like the following code. This only sets the first method call, so I'm wanting to know how to make this work, for the subsequent methods. ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` I've lost interest in the video, looks like horrible syntax (F#).
Setting field of struct object
I've been watching a video (YouTube - "Pipeline-oriented programming - Scott Wlaschin - NDC Porto 2023") with something like the following code. This only sets the first method call, so I'm wanting to know how to make this work, for the subsequent methods. ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ```
Re: Building a wasm library, need to override .object._d_newitemT!T
On Sunday, 24 December 2023 at 10:50:41 UTC, Johan wrote: _d_newitemT!T is fairly new, what compiler version are you using? -Johan Nevermind, I managed to get it working but I had to compile without including druntime and phobos and move everything into the library. I'm using ldc 1.36.0-beta1
Re: Building a wasm library, need to override .object._d_newitemT!T
On Saturday, 23 December 2023 at 20:42:37 UTC, Etienne Cimon wrote: I'm having a problem implementing the `new` keyword, so that I can start importing more libraries with minimal change. However, LDC calls .object._d_newitemT!T from the original druntime - which I need for compile-time function execution, but my implementation in `module object` doesn't override it in the compiler and the original implementation tries import core.stdc.time which errors out in wasm (with good reasons). Is there a compiler flag than I can use to override module templates? _d_newitemT!T is fairly new, what compiler version are you using? -Johan
Building a wasm library, need to override .object._d_newitemT!T
Hello, I've been developing a library[1] based on spasm for which I've implemented the druntime and currently it compiles web apps properly with TypeInfo, no GC, and it even uses diet templates. I'm having a problem implementing the `new` keyword, so that I can start importing more libraries with minimal change. However, LDC calls .object._d_newitemT!T from the original druntime - which I need for compile-time function execution, but my implementation in `module object` doesn't override it in the compiler and the original implementation tries import core.stdc.time which errors out in wasm (with good reasons). Is there a compiler flag than I can use to override module templates? Thanks in advance. [1] https://github.com/etcimon/libwasm
Re: SIGSEGV (Segmentation Fault) upon setting character in char array (object member var)
On Tuesday, 19 December 2023 at 14:01:31 UTC, John Kiro wrote: Thanks Adam. I agree, the behavior associated with the initialization here is confusing (compared for example to a similarly-looking code in Java). Also I don't get why an array of characters would be considered as an immutable array of characters (that is a **string**). I agree this could be a compiler bug, specially that it's not caught by the compiler. I mean: specially that **attempting to update it** is not caught by the compiler.
Re: SIGSEGV (Segmentation Fault) upon setting character in char array (object member var)
Thanks Adam. I agree, the behavior associated with the initialization here is confusing (compared for example to a similarly-looking code in Java). Also I don't get why an array of characters would be considered as an immutable array of characters (that is a **string**). I agree this could be a compiler bug, specially that it's not caught by the compiler.
Re: SIGSEGV (Segmentation Fault) upon setting character in char array (object member var)
On Tuesday, 19 December 2023 at 13:10:40 UTC, John Kiro wrote: class Test { static enum MAX = 10; uint index = 0; auto intArray = new int[MAX]; auto charArray = new char[MAX]; This is run at compile time, and the compiler treats any char array at compile time as an immutable string literal when it crosses the barrier into run time. Moreover, this would be a static instance of the initial array; the default reference is shared across all objects created (so if you modify intArray then `new` another object, you'll see the modified intArray!). You almost never want to assign arrays or objects at compile time like this in a class definition; use constructors instead. I think the `new char[]` thing being immutable in runtime is a compiler bug, it makes it immutable but it is still typed as mutable in the type system. but this whole static init thing is probably not what you want anyway.
SIGSEGV (Segmentation Fault) upon setting character in char array (object member var)
Hello there, First time to experiment with DLang, after a long time. I'm getting a weird behavior with an **array of chars**, where I get a segmentation fault upon writing to it (see code and output below). What makes this problem weird it two things: 1) Why there is no problem with the **int** array (unlike the **char** array)? 2) Why reading the array element (**charArray[index]**) works, unlike writing to it? The problem is gone if I uncomment the constructor code. Code: import std.stdio; void main() { (new Test).runit(); } class Test { static enum MAX = 10; uint index = 0; auto intArray = new int[MAX]; auto charArray = new char[MAX]; this() { /* charArray = new char[MAX]; */ } void runit() { debug writefln("IntArray initially: %s", intArray); intArray[index] = 40; //OK debug writefln("IntArray becomes: %s", intArray); debug writefln("Adding char in place of (%c) at index (%d)..", charArray[index], index); charArray[index] = 'a'; //ERROR: segmentation fault (code -11)! debug writefln("CharArray becomes %s (PROGRAM ABORTS BEFORE IT ACTUALLY!)", charArray); } } Output: $ dub run Starting Performing "debug" build using /home/john/dlang/dmd-2.106.0/linux/bin64/dmd for x86_64. Building hello-dlang ~master: building configuration [application] Linking hello-dlang Running hello-dlang IntArray initially: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] IntArray becomes: [40, 0, 0, 0, 0, 0, 0, 0, 0, 0] Adding char in place of (�) at index (0).. Error Program exited with code -11
Re: allocated object address as high as 46th bit (i.e in the 131072 GB range)
The reason high bits are often set is because an address layout is actually 4 indicies into the page table and a page byte offset. So all the way to bit 48 there is index info the cpu uses.
Re: allocated object address as high as 46th bit (i.e in the 131072 GB range)
On Monday, 9 October 2023 at 05:57:47 UTC, Richard (Rikki) Andrew Cattermole wrote: As far as I'm aware, no cpu that you can get ahold of support more than 48bit of address space at the hardware level. There is simply no reason at this time to support more, due to the fact that nobody has implemented anywhere near that maximum. Also worth noting, the address a block of memory is, has no relation to the hardware. A kernel will instruct the cpu to map it wherever it pleases per process. Thanks for the info. I'm surprised that kernel set virtual space that high.
Re: allocated object address as high as 46th bit (i.e in the 131072 GB range)
As far as I'm aware, no cpu that you can get ahold of support more than 48bit of address space at the hardware level. There is simply no reason at this time to support more, due to the fact that nobody has implemented anywhere near that maximum. Also worth noting, the address a block of memory is, has no relation to the hardware. A kernel will instruct the cpu to map it wherever it pleases per process.
allocated object address as high as 46th bit (i.e in the 131072 GB range)
https://dlang.org/library/core/bitop/bsr.html I'm trying to find out allocated object's address' space: ``` import std.stdio; import core.bitop; void main() { const size_t ONE_G = 1 << 30; char[][128] ptrs; foreach (i, ref ptr; ptrs) { ptr = new char[ONE_G]; if (ptr is null) { break; } writeln(i, ": ", bsr(cast(size_t)ptr.ptr)); } } ``` I tried on a few 64-bit machines (all of them have less than 128GB memory), and the result are about all the same: ``` $ uname -m x86_64 $ ./bit_op 0: 46 1: 46 2: 46 3: 46 4: 46 5: 46 6: 46 7: 46 8: 46 9: 46 10: 46 Killed ``` What puzzled me is that the highest set bit of the allocated address are all 46! i.e in the in the 2^47 ~= 131072 GB range! I know this could be an OS thing, but just wonder if anyone can give me some explanation? Thanks.
Re: change object class
On 23.09.23 05:11, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian Thank, Christian ! True nice tasty solution with ```VTable```! And further... the project is growing. ``` void Draw() { DrawBG(); DrawFG(); } ``` And we want use ```DrawBG()``` code from ```initial``` in other states, like ```Selected```. How to use some functions from ```initial``` via ```VTable``` ? I see solution in ```classes``` and methods with ```override``` keyword. ```VTable``` does the same thing as ```__vptr``` ? VTable is your structure .. it does exactly what you want it to do. __vptr is the internal implementation of virtual methods in the dlang object model. Line 20 and 21 in my example initialize the two `VTable`s Initial and Hovered. You can change VTable to contain two function pointers and initialize those as you like for the instances of the VTable structs. e.g. ```d struct DrawVTable { void function(Chip, Renderer) background; void function(Chip, Renderer) foreground; } // define functions to draw the different fore and backgrounds ... ... VTable initial = VTable(&drawInitialBackground, &drawInitialForeground); VTable hovered = VTable(&drawHoveredBackground, &drawHoveredForeground); VTable selected = VTable(&drawInitialBackground, &drawHoveredForegtround); ``` Kind regards, Christian
Re: change object class
On 23.09.23 05:25, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: On 17.09.23 17:05, Vitaliy Fadeev wrote: Hi! You could model it oop style like this: https://run.dlang.io/is/MJb5Fk This solution might not be to your taste, as it involves interfaces, and classes and objects and garbage (all the news) ... another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian ```Behavior``` is beautiful code! But it contains a second ```new``` when ```Chip``` is created. One ```new``` is possible? Christian, really nice code! Here a solution with less `new`s: https://run.dlang.io/is/iV1qVq. It really depends on the program that you are doing if creating those news is a problem. Kind regards, Christian
Re: change object class
On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: On 17.09.23 17:05, Vitaliy Fadeev wrote: Hi! You could model it oop style like this: https://run.dlang.io/is/MJb5Fk This solution might not be to your taste, as it involves interfaces, and classes and objects and garbage (all the news) ... another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian ```Behavior``` is beautiful code! But it contains a second ```new``` when ```Chip``` is created. One ```new``` is possible? Christian, really nice code! Does ```__vptr``` do the same thing ?
Re: change object class
On Friday, 22 September 2023 at 21:37:37 UTC, Imperatorn wrote: On Friday, 22 September 2023 at 14:03:40 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 12:53:28 UTC, Imperatorn wrote: You're basically just describing polymorphism. I can post an example tomorrow, it's midnight here now. Thank you. Of course! It's interesting to look at the solutions to choose the best one.
Re: change object class
On Friday, 22 September 2023 at 19:50:17 UTC, Christian Köstlin wrote: another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian Thank, Christian ! True nice tasty solution with ```VTable```! And further... the project is growing. ``` void Draw() { DrawBG(); DrawFG(); } ``` And we want use ```DrawBG()``` code from ```initial``` in other states, like ```Selected```. How to use some functions from ```initial``` via ```VTable``` ? I see solution in ```classes``` and methods with ```override``` keyword. ```VTable``` does the same thing as ```__vptr``` ?
Re: change object class
On Friday, 22 September 2023 at 14:03:40 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 12:53:28 UTC, Imperatorn wrote: On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: [...] What I mean is, why not use other language constructs like mixins or inheritance with some mapping for example? Can you give an example? You're basically just describing polymorphism. I can post an example tomorrow, it's midnight here now.
Re: change object class
On 17.09.23 17:05, Vitaliy Fadeev wrote: Hi! I want to change a method ```Draw``` on a custom object when the ```MouseIn``` event occurs. This is known as "Change State" of the object: ```Init``` -> ```Hovered```. I want to change the state of an object by changing its class, like this: ```d this.__vptr = typeid(CLS).vtbl.ptr; ``` I have read the ABI and am confident in replacing ```__vptr``` as long as the classes contain the same fields and the same interfaces. Example: ```d // O // to!state // State_Init : O // Draw // State_Hovered : O // Draw // // o.to!State_Hovered // o.to!State_Init class O { void to(CLS)() { // if (same fields && same interfaces && same instance size) this.__vptr = cast(immutable(void*)*)typeid(CLS).vtbl.ptr; } } State_Init : O void Draw() { /* ... */ } State_Hovered : O void Draw() { /* ... */ } ``` when MouseIn: ```d ... o.to!State_Hovered(); ... ``` when MouseOut: ```d ... o.to!State_Init(); ... ``` It works! But I want to ask how to make this 100% the best of the best? What should I consider before changing ```__vptr``` ? You could model it oop style like this: https://run.dlang.io/is/MJb5Fk This solution might not be to your taste, as it involves interfaces, and classes and objects and garbage (all the news) ... another option could be to model your own VTable in a struct like this: https://run.dlang.io/is/3LTjP5 Kind regards, Christian
Re: change object class
On Friday, 22 September 2023 at 12:53:28 UTC, Imperatorn wrote: On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... ``` Chip id name Sense() Draw() ``` instance ``` chip = new Chip(); ``` compiled to ``` chip __vtbl -> Chip __monitor Sense() idDraw() name ``` I want ``` chip __vtbl --+ id | name | |-> Chip_Hovered | Sense() | Draw() | +-> Chip_Hovered Sense() Draw() ``` What I mean is, why not use other language constructs like mixins or inheritance with some mapping for example? Can you give an example?
Re: change object class
On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... ``` Chip id name Sense() Draw() ``` instance ``` chip = new Chip(); ``` compiled to ``` chip __vtbl -> Chip __monitor Sense() idDraw() name ``` I want ``` chip __vtbl --+ id | name | |-> Chip_Hovered | Sense() | Draw() | +-> Chip_Hovered Sense() Draw() ``` What I mean is, why not use other language constructs like mixins or inheritance with some mapping for example?
Re: change object class
On Friday, 22 September 2023 at 03:33:08 UTC, Vitaliy Fadeev wrote: On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... the most correct ``` chip __vtbl ---+ // one of __monitor | id| name | |-> Chip // init | Sense() | Draw() | |-> Chip_Hovered // on mouseover | Sense() | Draw() | +-> Chip_Selected // on mouseclick Sense() Draw() ```
Re: change object class
On Friday, 22 September 2023 at 02:51:10 UTC, Vitaliy Fadeev wrote: ... ``` Chip id name Sense() Draw() ``` instance ``` chip = new Chip(); ``` compiled to ``` chip __vtbl -> Chip __monitor Sense() idDraw() name ``` I want ``` chip __vtbl --+ id | name | |-> Chip_Hovered | Sense() | Draw() | +-> Chip_Hovered Sense() Draw() ```
Re: change object class
On Thursday, 21 September 2023 at 18:19:47 UTC, Imperatorn wrote: On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: Hi! I want to change a method ```Draw``` on a custom object when the ```MouseIn``` event occurs. This is known as "Change State" of the object: ```Init``` -> ```Hovered```. [...] Interesting, but why would you want to do it that way? 😳 Q & A. You can check the logic. How to increase the battery life of a smartphone? Reducing operations. How to change the state of a button widget, for example, on mouseover? By changing the pointer to the Draw method. In addition to Draw, the widget has a Sense method. How to replace all pointers to methods at once? Replace the pointer with a class. (It's like a change of state! Exactly Turing's State Machine.) The object fields are the same. Behavior changes. The contents of the fields remain in memory. Only the pointer to the method table changes. Of course, this requires care and forethought. Perhaps the risks of changing class can be reduced by performing additional checks. Changing class is a convenient tool. I want to use it.
Re: change object class
On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: Hi! I want to change a method ```Draw``` on a custom object when the ```MouseIn``` event occurs. This is known as "Change State" of the object: ```Init``` -> ```Hovered```. [...] Interesting, but why would you want to do it that way? 😳
Re: change object class
On Sunday, 17 September 2023 at 17:10:16 UTC, evilrat wrote: On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: It works! But I want to ask how to make this 100% the best of the best? What should I consider before changing ```__vptr``` ? If that works for you with that constraint of having exact memory layout then it should be ok. No, this is Undefined Behavior and will likely cause you trouble in the future (as in: some very hard to debug bugs may appear). Better to store the state in the object and select the behavior using a switch on the state. -Johan
Re: change object class
On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: It works! But I want to ask how to make this 100% the best of the best? What should I consider before changing ```__vptr``` ? If that works for you with that constraint of having exact memory layout then it should be ok. This however is very uncommon pattern and your library users might reject it so keep that in mind if you are going to make public library. Other than that I would suggest at least to make that cast method to return a shallow copy because messing with "this" ptr can be dangerous (make sure to try it with const objects and optimized release builds before using this everywhere). An even better (at least safer, in theory) option would be to make "View" or handle struct that wraps an object(pointer) and tracks such transformations. Of course to think of it now there is yet another opportunity - why not to look for something like ECS then? Because you seem to already treat your objects purely as data containers, that way you can safely detach data from logic and reduce the scope of your components to keep them focused on one task. That is up to you of course.
Re: change object class
On Sunday, 17 September 2023 at 15:05:59 UTC, Vitaliy Fadeev wrote: ... Playground: https://run.dlang.io/is/hjcLCk
change object class
Hi! I want to change a method ```Draw``` on a custom object when the ```MouseIn``` event occurs. This is known as "Change State" of the object: ```Init``` -> ```Hovered```. I want to change the state of an object by changing its class, like this: ```d this.__vptr = typeid(CLS).vtbl.ptr; ``` I have read the ABI and am confident in replacing ```__vptr``` as long as the classes contain the same fields and the same interfaces. Example: ```d // O // to!state // State_Init: O // Draw // State_Hovered : O // Draw // // o.to!State_Hovered // o.to!State_Init class O { void to(CLS)() { // if (same fields && same interfaces && same instance size) this.__vptr = cast(immutable(void*)*)typeid(CLS).vtbl.ptr; } } State_Init : O void Draw() { /* ... */ } State_Hovered : O void Draw() { /* ... */ } ``` when MouseIn: ```d ... o.to!State_Hovered(); ... ``` when MouseOut: ```d ... o.to!State_Init(); ... ``` It works! But I want to ask how to make this 100% the best of the best? What should I consider before changing ```__vptr``` ?
Re: class Object with Dependency Injection
On Sunday, 18 June 2023 at 16:58:15 UTC, Ali Çehreli wrote: The problem is with the deduced type of 'services'. I don't know the mechanism behind it but the common type of 'truck' and 'ship' are deduced to be Object. Apparently, their interfaces don't take part in that decision. I don't know why. This is very interesting because it looks like a bug. Why is there no problem in an abstracted object, but things get confused in the interface (ITransport)? On Sunday, 18 June 2023 at 16:58:15 UTC, Ali Çehreli wrote: One solution is to help the compiler by casting them to your desired interface: In fact, there is no need to cast: ```d interface ITransport { string deliver(); } //... void main() { auto truck = new Truck; ITransport ship = new Ship; /* or ITransport truck = new Truck; auto ship = new Ship; // or ITransport truck = new Truck; ITransport ship = new Ship;//*/ } ``` SDB@78
Re: class Object with Dependency Injection
On 6/18/23 07:37, Salih Dincer wrote: >auto truck = new Truck; >auto ship = new Ship; > >auto services = [ truck, ship ]; The problem is with the deduced type of 'services'. I don't know the mechanism behind it but the common type of 'truck' and 'ship' are deduced to be Object. Apparently, their interfaces don't take part in that decision. I don't know why. One solution is to help the compiler by casting them to your desired interface: auto services = [ cast(ITransport)truck, cast(ITransport)ship ]; Or you can put the casts inside a function that could hide the complexity below: import std.algorithm; import std.range; auto services = [ truck, ship ].map!(s => cast(ITransport)s).array; Ali
class Object with Dependency Injection
Hi, below is an example of DI-dependency injection with 3 versions nested in the code. If you remove the leading // characters, you will not get the "no property `deliver` for `service` of type `object.Object`" error. Because version-2I with interface wants its methods to depend on Object.. ```d //abstract class /* toggle-code interface //* ^---version 2A */ ITransport { string deliver(); } class Ship : ITransport { override string deliver() { return "Ship Deliver"; } } class Truck : ITransport { override string deliver() { return "Truck Deliver"; } } abstract class Logistics { ITransport createTransport(); auto operations() { return createTransport.deliver(); } } class RoadLogistics : Logistics { override ITransport createTransport() { return new Truck(); } } class SeaLogistics : Logistics { override ITransport createTransport() { return new Ship(); } } import std.stdio; void main() { // DI version 1: auto sl = new SeaLogistics; auto rl = new RoadLogistics; auto logistics = [ sl, rl ]; foreach(deliver; logistics) { auto str = deliver.operations(); str.length.writeln(": ", str); } import std.range : repeat; "÷ ".repeat(9).writefln!"%-(%s%)"; // A->I version 2: auto truck = new Truck; auto ship = new Ship; auto services = [ truck, ship ]; foreach(service; services) { auto str = service.deliver(); str.length.writeln(": ", str); } } ``` Maybe using an abstract class instead of interface or not using auto will solve the problem, but I can't accept the situation! I wonder what makes the interface special? SDB@79
Re: Given an object, how to call an alias to a member function on it?
On Wednesday, 3 May 2023 at 11:38:46 UTC, Adam D Ruppe wrote: On Tuesday, 2 May 2023 at 13:57:23 UTC, Steven Schveighoffer wrote: Isn't that what `__traits(child)` is for? https://dlang.org/spec/traits.html#child Yes, `__traits(child, object, method_alias)(args)` is the way to do it. This doesn’t work, but a slight modification does the trick: ```d --- a.d #line 3 "a.d" // for run.dlang.io struct S { private void f() {} } alias Sf = S.f; --- b.d #line 12 "b.d" // for run.dlang.io import a; void main() { S s; __traits(child, s, Sf)(); // error: Error: struct `a.S` function `f` is not accessible (&__traits(child, s, Sf))(); // ok } ``` Thanks for making me aware of `__traits(child)`.
Re: Given an object, how to call an alias to a member function on it?
On Wednesday, 3 May 2023 at 11:26:00 UTC, ag0aep6g wrote: On 03.05.23 13:13, Nick Treleaven wrote: void fun(alias method)(C c) { void delegate() dg = &c.method; dg(); } No, it doesn't. You're not using the alias. You're just accessing `c.method` directly. If the actual method weren't called "method", you'd get an error. Sorry, you're right.
Re: Given an object, how to call an alias to a member function on it?
On Tuesday, 2 May 2023 at 13:57:23 UTC, Steven Schveighoffer wrote: Isn't that what `__traits(child)` is for? https://dlang.org/spec/traits.html#child Yes, __traits(child, object, method_alias)(args) is the way to do it.
Re: Given an object, how to call an alias to a member function on it?
On 03.05.23 13:13, Nick Treleaven wrote: On Tuesday, 2 May 2023 at 13:06:41 UTC, ag0aep6g wrote: void fun(alias method)(C c) { void delegate() dg; dg.funcptr = &method; dg.ptr = cast(void*) c; dg(); } This also works: void fun(alias method)(C c) { void delegate() dg = &c.method; dg(); } No, it doesn't. You're not using the alias. You're just accessing `c.method` directly. If the actual method weren't called "method", you'd get an error.
Re: Given an object, how to call an alias to a member function on it?
On Tuesday, 2 May 2023 at 13:06:41 UTC, ag0aep6g wrote: void fun(alias method)(C c) { void delegate() dg; dg.funcptr = &method; dg.ptr = cast(void*) c; dg(); } This also works: void fun(alias method)(C c) { void delegate() dg = &c.method; dg(); }
Re: Given an object, how to call an alias to a member function on it?
On 5/2/23 8:52 AM, Quirin Schroll wrote: How do I invoke the member function in a reliable way? Given `obj` of the type of the object, I used `mixin("obj.", __traits(identifier, memberFunc), "(params)")`, but that has issues, among probably others, definitely with visibility. (The member function alias is a template parameter.) Isn't that what `__traits(child)` is for? https://dlang.org/spec/traits.html#child -Steve
Re: Given an object, how to call an alias to a member function on it?
On 02.05.23 14:52, Quirin Schroll wrote: How do I invoke the member function in a reliable way? Given `obj` of the type of the object, I used `mixin("obj.", __traits(identifier, memberFunc), "(params)")`, but that has issues, among probably others, definitely with visibility. (The member function alias is a template parameter.) Construct a delegate from the alias and the object, and call that delegate: class C { int field = 42; void method() { import std.stdio; writeln(field); } } void fun(alias method)(C c) { void delegate() dg; dg.funcptr = &method; dg.ptr = cast(void*) c; dg(); } void main() { fun!(C.method)(new C); /* prints "42" */ }
Given an object, how to call an alias to a member function on it?
How do I invoke the member function in a reliable way? Given `obj` of the type of the object, I used `mixin("obj.", __traits(identifier, memberFunc), "(params)")`, but that has issues, among probably others, definitely with visibility. (The member function alias is a template parameter.)
Re: Assocative array lookup for object
On Wednesday, 12 April 2023 at 13:09:07 UTC, Ali Çehreli wrote: Not every type is null'able but nullable. ;) So, a design may use the following: https://dlang.org/library/std/typecons/nullable.html I implemented Handler into the Voldermort build, which Walter loved so much. For convenience, I put an alias between the template and the function. But Nullable didn't work, instead it's returning T.init... ```d template Handler(alias A) { alias T = typeof(A); auto Handler() { struct Impl { T*[string] data; void set(string key, ref T value) { data[key] = &value; } auto opIndex(string key) { if (auto ret = key in data) { return **ret; } return T.init;/* import std.typecons : Nullable; return Nullable!T.init;//*/ } auto opSlice() { T[] result; foreach (ref value; data.values) result ~= *value; return result; } } return Impl(); } } import std.stdio; void main() { struct List { string product; float price; } auto fruits = [ List("Manderin", 3.79), List("Orange", 2.99), List("Kiwi", 0.59), ]; auto handlers = Handler!fruits; handlers.set("fruits", fruits); // please try it: ^--v foreach(h; handlers["fruit"]) { h.product.write(": "); h.price.writeln(" €"); } auto handler = Handler!(List()); import std.conv : text; foreach(i, ref fruit; fruits) { handler.set(i.text, fruit); } handler[].writeln; } /* Prints: Manderin: 3.79 € Orange: 2.99 € Kiwi: 0.59 € [List("Kiwi", 0.59), List("Manderin", 3.79), List("Orange", 2.99)] */ ``` SDB@79
Re: Assocative array lookup for object
On 4/12/23 04:35, Salih Dincer wrote: > I made a little mistake and I'll fix it before someone rub nose in it :) You asked for it! :) >auto opIndex(string key) { > if(auto ret = key in data) > { >return *ret; > } > return null; >} Not every type is null'able but nullable. ;) So, a design may use the following: https://dlang.org/library/std/typecons/nullable.html Ali
Re: Assocative array lookup for object
On Wednesday, 12 April 2023 at 04:57:58 UTC, Salih Dincer wrote: I think you want to do an encapsulation like below. ```d auto opIndex(string key) => *(key in data); ``` I made a little mistake and I'll fix it before someone rub nose in it :) ```d auto opIndex(string key) { if(auto ret = key in data) { return *ret; } return null; } assert(handler["D Lang"] == &foo); assert(handler["null"] is null); ``` SDB@79
Re: Assocative array lookup for object
On Wednesday, 12 April 2023 at 01:16:17 UTC, Chris Katko wrote: Should I be using opEquals? Or something different? The problem with 'alias this' here is I want to wrap access to the insides with getter functions that do various things like logging and error checking. I think you want to do an encapsulation like below. ```d class Handler(T) { T*[string] data; auto set(string key, ref T value) => data[key] = &value; auto opIndex(string key) => *(key in data); } void main() { class Bitmap {} Bitmap foo; auto handler = new Handler!Bitmap; handler.set("D Lang", foo); assert(handler["D Lang"] == &foo); } ``` SDB@79
Re: Assocative array lookup for object
You want the operator overload opIndex inside your class. https://dlang.org/spec/operatoroverloading.html#array
Assocative array lookup for object
```D class bitmapHandler { bitmap*[string] bmps; void get(string name){return bmps[name]; /* plus other code */} } void usage() { bitmapHandler bh; bitmap foo = bh.get("bar"); // works bitmap foo2 = bh["bar"]; // desired } ``` Should I be using opEquals? Or something different? The problem with 'alias this' here is I want to wrap access to the insides with getter functions that do various things like logging and error checking. I mean, if I ruined some encapsulation, I could make a function called "bh" and have the usage: ```D bh("bar"); ``` and have it access a singleton object.
DMD: what's the proper way to get a list of symbols from a Module object?
Hello, I am playing a little bit with DMD to get familiar with it (just to get a basic overview of it) I'm trying to come up with a proof of concept for https://github.com/dlang/DIPs/blob/master/DIPs/DIP1044.md ```D enum Tester { KNOWN = 1, WITHAUTO = 2 } void func(Tester a, Tester b) { } void main() { func(Tester.KNOWN, auto.WITHAUTO); } ``` The idea is to reuse auto, basically do like tuple, create a ``StructDeclaration`` and inside put a ``VarDeclaration`` just to remember what is the identifier, then once it tries to search for the symbol, we hijack it and try to search globally instead I came up with this: https://github.com/ryuukk/dmd/commit/cb86d398b68501fd334c090745e946db7b27ff97 It seems to follow the logic i have in mind, the problem is whenever i try to search for the symbol given the identifier i saved I had to set the module as parent of the ``StructDeclaration`` created to get a starting point The problem is the field ``members`` from ``Module`` only seems to list ``object`` module when it is trying to search for the symbol There should also be ``Tester`` with should be an ``EnumDeclaration``, why is it not listed? Am i doing something incorrect (that's probably the case) Anyway, i'm blind at this point, if someone could provide some guidance, that would be kind of you!
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Sunday, 5 February 2023 at 03:38:04 UTC, thebluepandabear wrote: On Sunday, 5 February 2023 at 03:19:43 UTC, bachmeier wrote: Something of a puzzle that it works with Arch, though, but not Ubuntu/Mint. It doesn't sound like Arch has that problem. What problem doesn't Arch have, the missing symbol or the shared library one? The earlier post in this thread implied there were no problems on Arch. I'm wondering, after downgrading, do you get the shared library issue that I am currently dealing with? I'm not sure how to downgrade. I installed the package from the repos. I can't say a bug in the Ubuntu packaging would surprise me.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
Thanks. update: just set up a Manjaro vm and it seems to work, I guess I'll have no choice but to switch to Manjaro then if I want to use sfml
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Sunday, 5 February 2023 at 03:19:43 UTC, bachmeier wrote: On Saturday, 4 February 2023 at 23:51:17 UTC, thebluepandabear wrote: "Error: Missing Symbol, Message: sfText_getLineSpacing", "Error: Missing Symbol, Message: sfText_getLineSpacing"] source/app.d:19 void app.loadDyn() [0x55d86edd1931] source/app.d:24 _Dmain [0x55d86edd1954] ``` Oh yeah, that's another bug I had. You would need to downgrade the version to SFML_240. Something of a puzzle that it works with Arch, though, but not Ubuntu/Mint. It doesn't sound like Arch has that problem. What problem doesn't Arch have, the missing symbol or the shared library one? If it's the missing symbol one, I suspect the reason Arch doesn't have that issue is because it has a more updated package on its repo (AUR). Ubuntu has CSFML 2.5.0, not CSFML 2.5.1, which makes everything much more of a pain. That's exactly why you are getting those missing symbol issues, I believe. I did speak to the bindbc team about it, and that was the conclusion that we came to. In order to fix the issue and not have to downgrade, you would have to manually compile CSFML 2.5.1, which is a pain. I'm wondering, after downgrading, do you get the shared library issue that I am currently dealing with? Thanks.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Saturday, 4 February 2023 at 23:51:17 UTC, thebluepandabear wrote: "Error: Missing Symbol, Message: sfText_getLineSpacing", "Error: Missing Symbol, Message: sfText_getLineSpacing"] source/app.d:19 void app.loadDyn() [0x55d86edd1931] source/app.d:24 _Dmain [0x55d86edd1954] ``` Oh yeah, that's another bug I had. You would need to downgrade the version to SFML_240. Something of a puzzle that it works with Arch, though, but not Ubuntu/Mint. It doesn't sound like Arch has that problem.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
"Error: Missing Symbol, Message: sfText_getLineSpacing", "Error: Missing Symbol, Message: sfText_getLineSpacing"] source/app.d:19 void app.loadDyn() [0x55d86edd1931] source/app.d:24 _Dmain [0x55d86edd1954] ``` Oh yeah, that's another bug I had. You would need to downgrade the version to SFML_240.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Saturday, 4 February 2023 at 05:29:43 UTC, thebluepandabear wrote: I have tested on arch linux and everything works fine, i'll try to setup a linux mint / ubuntu VM tomorrow Thanks. It seems like an issue with my system then. I've been stuck on it for a week or so, but haven't been able to find the root cause of the issue. I did this on Ubuntu 22.04. `dub build` completes successfully. `dub run` outputs ``` object.Exception@source/app.d(19): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: Missing Symbol, Message: sfRenderTexture_createWithSettings", "Error: Missing Symbol, Message: sfRenderTexture_getMaximumAntialiasingLevel", "Error: Missing Symbol, Message: sfText_getLineSpacing", "Error: Missing Symbol, Message: sfText_getLineSpacing"] source/app.d:19 void app.loadDyn() [0x55d86edd1931] source/app.d:24 _Dmain [0x55d86edd1954] ```
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
I have tested on arch linux and everything works fine, i'll try to setup a linux mint / ubuntu VM tomorrow Thanks. It seems like an issue with my system then. I've been stuck on it for a week or so, but haven't been able to find the root cause of the issue.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Saturday, 4 February 2023 at 04:42:04 UTC, ryuukk_ wrote: Are you sure you have installed the version 2.5 in your system? Can you check in y our library folder if it's there? Nvm, i saw your github issue, looks like you have the proper version I have tested on arch linux and everything works fine, i'll try to setup a linux mint / ubuntu VM tomorrow
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
Are you sure you have installed the version 2.5 in your system? Can you check in y our library folder if it's there?
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
Could someone (that uses Linux) perhaps try and emulate my bug to see if it's an issue with the bindings or on my system? That would be greatly appreciated! Steps: 1. Open up the terminal and type in `sudo apt-get install libcsfml-dev` 2. Create a new D project and add the following to `dub.json`: ``` "dependencies": { "bindbc-sfml": "~>1.0.2", "bindbc-loader": "~>1.0.1" }, "versions": [ "SFML_Audio", "SFML_Graphics", "SFML_250" ], ``` 3. Add the following code to `app.d`: ```D import std.stdio; import bindbc.sfml; import std.string; import std.exception; import bindbc.loader; import std.conv; void loadDyn() { if (!loadSFML()) { string[] messages; foreach (const(ErrorInfo) err; errors) { string errorStr = to!string(err.error); string messageStr = to!string(err.message); messages ~= format("Error: %s, Message: %s", errorStr, messageStr); } throw new Exception(format("Fatal error(s) encountered whilst calling `loadSFML()` function: %s", messages)); } } void main() { loadDyn(); sfRenderWindow* renderWindow = sfRenderWindow_create(sfVideoMode(500, 500), "Snake Smooth Dynamics", sfWindowStyle.sfDefaultStyle, null); sfEvent event; while (renderWindow.sfRenderWindow_isOpen()) { while (renderWindow.sfRenderWindow_pollEvent(&event)) { if (event.type == sfEventType.sfEvtClosed) { renderWindow.sfRenderWindow_close(); } } renderWindow.sfRenderWindow_clear(sfYellow); renderWindow.sfRenderWindow_display(); } } ``` It should only take around 2-3 minutes. Regards, thebluepandabear
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Friday, 3 February 2023 at 19:44:07 UTC, bachmeier wrote: On Friday, 3 February 2023 at 12:23:40 UTC, thebluepandabear wrote: On Friday, 3 February 2023 at 11:43:46 UTC, thebluepandabear wrote: On Friday, 3 February 2023 at 11:37:43 UTC, bachmeier wrote: On Friday, 3 February 2023 at 10:15:37 UTC, thebluepandabear wrote: I recently did a fresh install of CSFML and I am getting this errors when running my csfml D bindings program: ``` object.Exception@source/app.d(38): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: libcsfml-system.so, Message: libsfml-system.so.2.5: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2, Message: libcsfml-system.so.2: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2.0, Message: libcsfml-system.so.2.0: cannot open shared object file: No such file or directory"] ``` We don't have the full compilation and loading details, but this part of the message seems unusual: "Error: libcsfml-system.so, Message: libsfml-system.so.2.5 One is `libcsfml` and the other is `libsfml`. Hi, It seems like it has changed since then, I am _no longer_ getting those conflicting errors, it's just 'libcsfml' for both instances. I am thinking of compiling CSFML from scratch to see if it will help, but I'd rather not since it seems complex. Furthermore, I would like to thank you for bringing up the compilation/loading details up. I'll send a snippet of that if I can figure out how to do so. nvm, im getting that error again It might be a bug in bindbc-sfml. The code is here: https://github.com/BindBC/bindbc-sfml/blob/master/source/bindbc/sfml/system.d#L231 Unbuntu stores the file in /usr/lib/x86_64-linux-gnu/libcsfml-system.so.2.5. Maybe the compiler doesn't know to look in /usr/lib/x86_64-linux-gnu. I sent an issue request to bindbc-sfml and they could not reproduce my bug or figure out why it was happening, but I wouldn't be surprised if it is a bug.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Friday, 3 February 2023 at 12:23:40 UTC, thebluepandabear wrote: On Friday, 3 February 2023 at 11:43:46 UTC, thebluepandabear wrote: On Friday, 3 February 2023 at 11:37:43 UTC, bachmeier wrote: On Friday, 3 February 2023 at 10:15:37 UTC, thebluepandabear wrote: I recently did a fresh install of CSFML and I am getting this errors when running my csfml D bindings program: ``` object.Exception@source/app.d(38): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: libcsfml-system.so, Message: libsfml-system.so.2.5: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2, Message: libcsfml-system.so.2: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2.0, Message: libcsfml-system.so.2.0: cannot open shared object file: No such file or directory"] ``` We don't have the full compilation and loading details, but this part of the message seems unusual: "Error: libcsfml-system.so, Message: libsfml-system.so.2.5 One is `libcsfml` and the other is `libsfml`. Hi, It seems like it has changed since then, I am _no longer_ getting those conflicting errors, it's just 'libcsfml' for both instances. I am thinking of compiling CSFML from scratch to see if it will help, but I'd rather not since it seems complex. Furthermore, I would like to thank you for bringing up the compilation/loading details up. I'll send a snippet of that if I can figure out how to do so. nvm, im getting that error again It might be a bug in bindbc-sfml. The code is here: https://github.com/BindBC/bindbc-sfml/blob/master/source/bindbc/sfml/system.d#L231 Unbuntu stores the file in /usr/lib/x86_64-linux-gnu/libcsfml-system.so.2.5. Maybe the compiler doesn't know to look in /usr/lib/x86_64-linux-gnu.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Friday, 3 February 2023 at 11:43:46 UTC, thebluepandabear wrote: On Friday, 3 February 2023 at 11:37:43 UTC, bachmeier wrote: On Friday, 3 February 2023 at 10:15:37 UTC, thebluepandabear wrote: I recently did a fresh install of CSFML and I am getting this errors when running my csfml D bindings program: ``` object.Exception@source/app.d(38): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: libcsfml-system.so, Message: libsfml-system.so.2.5: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2, Message: libcsfml-system.so.2: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2.0, Message: libcsfml-system.so.2.0: cannot open shared object file: No such file or directory"] ``` We don't have the full compilation and loading details, but this part of the message seems unusual: "Error: libcsfml-system.so, Message: libsfml-system.so.2.5 One is `libcsfml` and the other is `libsfml`. Hi, It seems like it has changed since then, I am _no longer_ getting those conflicting errors, it's just 'libcsfml' for both instances. I am thinking of compiling CSFML from scratch to see if it will help, but I'd rather not since it seems complex. Furthermore, I would like to thank you for bringing up the compilation/loading details up. I'll send a snippet of that if I can figure out how to do so. nvm, im getting that error again
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Friday, 3 February 2023 at 11:37:43 UTC, bachmeier wrote: On Friday, 3 February 2023 at 10:15:37 UTC, thebluepandabear wrote: I recently did a fresh install of CSFML and I am getting this errors when running my csfml D bindings program: ``` object.Exception@source/app.d(38): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: libcsfml-system.so, Message: libsfml-system.so.2.5: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2, Message: libcsfml-system.so.2: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2.0, Message: libcsfml-system.so.2.0: cannot open shared object file: No such file or directory"] ``` We don't have the full compilation and loading details, but this part of the message seems unusual: "Error: libcsfml-system.so, Message: libsfml-system.so.2.5 One is `libcsfml` and the other is `libsfml`. Hi, It seems like it has changed since then, I am _no longer_ getting those conflicting errors, it's just 'libcsfml' for both instances. I am thinking of compiling CSFML from scratch to see if it will help, but I'd rather not since it seems complex. Furthermore, I would like to thank you for bringing up the compilation/loading details up. I'll send a snippet of that if I can figure out how to do so.
Re: SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
On Friday, 3 February 2023 at 10:15:37 UTC, thebluepandabear wrote: I recently did a fresh install of CSFML and I am getting this errors when running my csfml D bindings program: ``` object.Exception@source/app.d(38): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: libcsfml-system.so, Message: libsfml-system.so.2.5: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2, Message: libcsfml-system.so.2: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2.0, Message: libcsfml-system.so.2.0: cannot open shared object file: No such file or directory"] ``` We don't have the full compilation and loading details, but this part of the message seems unusual: "Error: libcsfml-system.so, Message: libsfml-system.so.2.5 One is `libcsfml` and the other is `libsfml`.
SFML D bindings: libsfml-system.so.2.5: cannot open shared object file:
I recently did a fresh install of CSFML and I am getting this errors when running my csfml D bindings program: ``` object.Exception@source/app.d(38): Fatal error(s) encountered whilst calling `loadSFML()` function: ["Error: libcsfml-system.so, Message: libsfml-system.so.2.5: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2, Message: libcsfml-system.so.2: cannot open shared object file: No such file or directory", "Error: libcsfml-system.so.2.0, Message: libcsfml-system.so.2.0: cannot open shared object file: No such file or directory"] ``` I am using SFML D bindings (https://github.com/BindBC/bindbc-sfml): ```D void loadDyn() { if (!loadSFML()) { string[] messages; foreach (const(ErrorInfo) err; errors) { string errorStr = to!string(err.error); string messageStr = to!string(err.message); messages ~= format("Error: %s, Message: %s", errorStr, messageStr); } throw new Exception(format("Fatal error(s) encountered whilst calling `loadSFML()` function: %s", messages)); } } void main() { loadDyn(); sfRenderWindow* renderWindow = sfRenderWindow_create(sfVideoMode(500, 500), "Snake Smooth Dynamics", sfWindowStyle.sfDefaultStyle, null); sfEvent event; while (renderWindow.sfRenderWindow_isOpen()) { while (renderWindow.sfRenderWindow_pollEvent(&event)) { if (event.type == sfEventType.sfEvtClosed) { renderWindow.sfRenderWindow_close(); } } renderWindow.sfRenderWindow_clear(sfYellow); renderWindow.sfRenderWindow_drawSprite(snakeHeadSprite, null); renderWindow.sfRenderWindow_display(); } } ``` Things I've tried: - I found someone with a similar question: https://stackoverflow.com/questions/41516065/linux-sfml-cannot-open-shared-object-file, tried out some answers but to no avail - I tried to `sudo apt purge` every CSFML dependency (graphics, audo, etc) and reinstall each component (`csfml-audio`, `csfml-graphics`) manually etc, to no avail. - I tried to run `sudo ldconfig`... didn't work - As a last ditch effort I tried to manually move the shared object files to the `/usr/local/lib` directory (to try and perhaps trick the compiler to run the program?) but to no avail. - I tried to run on a new VM and still didn't work - I tried to set `LD_LIBRARY_PATH` environment variable The amount of layers I depend on make it impossible to find where the bug is from, there are a lot of separate things going on and it's very multilayered, I don't know where the issue is specifically coming from as it used to work just fine I ran the exact same commands to install CSFML previously, now when I do it it just refuses to run. The weird thing is when I ran a brand new virtual machine, installed those packages, still same issue. I am running Linux Mint 21.1, Ubuntu based. Relatively new PC. Help would be appreciated.
Re: Address of a class object
On Thursday, 5 January 2023 at 05:59:26 UTC, Ali Çehreli wrote: On 1/4/23 20:04, Paul wrote: >> (Again, there is no problem here; we are just learning.) >> Ali > > Do I have this much right? > ..with this output? Looks good to me. While we're here, you can force the class objects to be on the stack as well: scope MyClassVar1 = new MyClass(); I replaced 'auto' with 'scope'. Ali I was tinkering with this use of 'scope' and the math for pointer location, object size, and alignment started working out.
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
On Thursday, 26 January 2023 at 11:46:07 UTC, matheus wrote: On Tuesday, 24 January 2023 at 03:42:34 UTC, thebluepandabear wrote: ... if not please tell me and I will remove this... How you would do that? Matheus. The forums don't have a delete feature. I am used to most forums having a delete feature which is why I said that, I now realize I cannot remove posts on This forum.
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
On Tuesday, 24 January 2023 at 03:42:34 UTC, thebluepandabear wrote: ... if not please tell me and I will remove this... How you would do that? Matheus.
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
The example shows calls to `update()` in the setters and in the constructor. The D method for binding this looks like `void sfShape_update(sfShape* shape);`. Ur a legend bro... It fixed it... Calling this in the `Rectangle` constructor: ```D class RectangleShape : Shape { this(Vector2f size) { _size = size; setSize(_size); ptr.sfShape_update(); } ``` It is my fault on this one. Thank u sir.
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
On Tuesday, 24 January 2023 at 08:18:53 UTC, thebluepandabear wrote: On Tuesday, 24 January 2023 at 06:32:35 UTC, Christian Köstlin wrote: On 24.01.23 04:59, thebluepandabear wrote: Regards, thebluepandabear Btw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited... I do not know anything about sfml, but could you try a simpler shape, e.g. circle (that is a primitive on the native side). perhaps the winding order of your vertices is wrong? Kind regards, Christian thanks for the reply That also - unfortunately - doesn't seem to work. I would love to see some proper examples for creating shapes but the docs for bind-bc didn't have any :| As per https://www.sfml-dev.org/tutorials/2.5/graphics-shape.php#custom-shape-types: You must also call the update() protected function whenever any point in your shape changes, so that the base class is informed and can update its internal geometry. The example shows calls to `update()` in the setters and in the constructor. The D method for binding this looks like `void sfShape_update(sfShape* shape);`.
Re: Library object name collision
On Tuesday, 24 January 2023 at 09:54:01 UTC, frame wrote: Thanks! it works well with the `-op` switch, didn't know I can do with libraries. Only drawback is that every path now stored as absolute path - any way to store only a relative one? Ah never mind, it seems only to do this with phobos related debug links
Re: Library object name collision
On Tuesday, 24 January 2023 at 08:15:55 UTC, Richard (Rikki) Andrew Cattermole wrote: On 24/01/2023 8:59 PM, frame wrote: Also why have most objects an unique postfix in the name but those files havn't? It's mostly a `__ModuleInfoZ` or `__initZ` but not always. Symbols which end in __ModuleInfoZ are symbols that hold per-module information for features like unittests and module constructors. Symbols which end in __initZ hold information on types, specifically their default initialization state. So if these two are missing, and they should be there, you have a problem. It's a library - if any symbol is missing it will be a problem ;-) Now wrt. LNK4255, I'm not sure why its doing this. You haven't shown how you're building. But if you're doing it manually you may want to try: -od= write object & library files to directory -of=name output file to filename -op preserve source path for output files Doing it via dub, manually would be the `-lib` switch I guess. Thanks! it works well with the `-op` switch, didn't know I can do with libraries. Only drawback is that every path now stored as absolute path - any way to store only a relative one?
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
On Tuesday, 24 January 2023 at 06:32:35 UTC, Christian Köstlin wrote: On 24.01.23 04:59, thebluepandabear wrote: Regards, thebluepandabear Btw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited... I do not know anything about sfml, but could you try a simpler shape, e.g. circle (that is a primitive on the native side). perhaps the winding order of your vertices is wrong? Kind regards, Christian thanks for the reply That also - unfortunately - doesn't seem to work. I would love to see some proper examples for creating shapes but the docs for bind-bc didn't have any :|
Re: Library object name collision
On 24/01/2023 8:59 PM, frame wrote: Also why have most objects an unique postfix in the name but those files havn't? It's mostly a `__ModuleInfoZ` or `__initZ` but not always. Symbols which end in __ModuleInfoZ are symbols that hold per-module information for features like unittests and module constructors. Symbols which end in __initZ hold information on types, specifically their default initialization state. So if these two are missing, and they should be there, you have a problem. Now wrt. LNK4255, I'm not sure why its doing this. You haven't shown how you're building. But if you're doing it manually you may want to try: -od= write object & library files to directory -of=name output file to filename -op preserve source path for output files
Library object name collision
When creating a linker library under Windows and having module a/b/foo.d but also d/c/foo.d the linker afterwards is bailing out: .lib(foo.obj) : warning LNK4255: library contain multiple objects of the same name; linking object as if no debug info And when I did inspect the library it confirmed that the compiler just places the objects twice - contents looks like this: ``` 1.txt 1.types.obj 2.txt 2.types.obj ... foo.obj foo_1b34_260.obj foo.obj foo_1b44_991.obj ... ``` Which seems incorrect to me. Does the compiler use an external command to create the library or does it itself? Also why have most objects an unique postfix in the name but those files havn't? It's mostly a `__ModuleInfoZ` or `__initZ` but not always. How to deal with this? I could rename the files but can't do that without changing the module name too which sucks.
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
On 24.01.23 04:59, thebluepandabear wrote: Regards, thebluepandabear Btw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited... I do not know anything about sfml, but could you try a simpler shape, e.g. circle (that is a primitive on the native side). perhaps the winding order of your vertices is wrong? Kind regards, Christian
Re: Need some technical help an object oriented wrapper I am creating for bindbc.sfml
Regards, thebluepandabear Btw I understand this question is extremely complex, don't want to pressure anyone to help me because of that... but any sort of assistance or leads would be greatly... greatly apprecaited...
Need some technical help an object oriented wrapper I am creating for bindbc.sfml
Hello everyone 👋, hope everyone is having a good day. Hopefully I am allowed to ask technical questions here, if not please tell me and I will remove this. I am trying to create object oriented wrappers around `bindbc.sfml`, this is because I don't like the C-style syntax of CSFML. The C-style syntax is not right -- in my opinion -- for an object oriented language. Dealing with pointers all the time is also unsafe. This is not to say that CSFML isn't good -- it's great, and I've made some apps using `bindbc-sfml`. I just want to extend it to my liking with object oriented wrappers that can more closely match the C++ SFML syntax. For the wrappers, I created a `Shape` class. This `Shape` class is seen in the original C++ SFML implementation: ```D class Shape : Transformable, Drawable { void setTexture(sfTexture* texture, bool resetRect) { ptr.sfShape_setTexture(texture, resetRect); } void setTextureRect(IntRect rect) { ptr.sfShape_setTextureRect(rect.to_sfIntRect()); } void setFillColor(Color color) { ptr.sfShape_setFillColor(color.to_sfColor()); } void setOutlineColor(Color color) { ptr.sfShape_setOutlineColor(color.to_sfColor()); } void setOutlineThickness(float thickness) { ptr.sfShape_setOutlineThickness(thickness); } const(sfTexture)* getTexture() { return ptr.sfShape_getTexture(); } IntRect getTextureRect() { return ptr.sfShape_getTextureRect().toIntRect(); } Color getFillColor() { return ptr.sfShape_getFillColor().toColor(); } Color getOutlineColor() { return ptr.sfShape_getOutlineColor().toColor(); } float getOutlineThickness() { return ptr.sfShape_getOutlineThickness(); } size_t getPointCount() nothrow { return ptr.sfShape_getPointCount(); } Vector2f getPoint(size_t index) nothrow { return ptr.sfShape_getPoint(index).toVector2f_noThrow(); } FloatRect getLocalBounds() { return ptr.sfShape_getLocalBounds().toFloatRect(); } FloatRect getGlobalBounds() { return ptr.sfShape_getGlobalBounds().toFloatRect(); } private sfShape* ptr; } ``` The `sfShape` pointer isn't currently initialized, I'll get to that issue soon. As you can see, `Shape` extends the `Transformable` class and the `Drawable` interface. This again roughly matches what's seen in SFML. SFML.NET also did a similar wrapper for their CSFML C# bindings. What's great about SFML.NET is that you don't even know that you're using CSFML, this is because it feels just like C++ SFML. Now, I will create a `RectangleShape` which will be a subclass of the `Shape` class: (Btw I took a lot of inspiration from SFML.NET when it comes to these wrappers.) ```D class RectangleShape : Shape { this(Vector2f size) { _size = size; setSize(_size); } Vector2f getSize() { return _size; } void setSize(Vector2f size) { _size = size; } override { size_t getPointCount() { return 4; } Vector2f getPoint(size_t index) { final switch (index) { case 0: return Vector2f(0, 0); case 1: return Vector2f(_size.x, 0); case 2: return Vector2f(_size.x, _size.y); case 3: return Vector2f(0, _size.y); } } } private Vector2f _size; } ``` As you can see, the `Rectangle` class only overrides the `getPointCount` and `getPoint` methods. **These are the methods that the superclass - `Shape` - will use to construct the shape object for it to actually be drawable.** Now, let us add the following code to the `Shape` class so that we can construct a `Shape` via these two methods, which we assume that the child provides us a good implementation for: ```D class Shape : Transformable, Drawable { this() { ptr = sfShape_create(&getPointCount, &getPoint, cast(void*)this); } extern(C) private static ulong getPointCount(void* data) nothrow { return (cast(Shape)data).getPointCount(); } extern(C) private static sfVector2f getPoint(size_t index, void* data) nothrow { return (cast(Shape)data).getPoint(index).to_sfVector2f_noThrow(); } ``` I hear you asking, what's going on here? We are providing two callbacks to the `getPointCount` and `getPoint` methods via function pointers, and we're passing in the current object to the `data` `void*` pointer. It's kind of hard to understand, but if you read through it carefully you should get a rough idea of what's going on. Now, when we create a new instance of `Rectangle`, I will assume that the constructor will be called, the `sf_shape` ptr will be initialized