Re: BetterC Bug? Intended Behavior? Asking Here As Unsure
On Monday, 6 July 2020 at 21:09:57 UTC, kinke wrote: Similar case here; the 'varargs' end up in a GC-allocated array. I've recently changed `scope` slice params, so that array literal arguments are allocated on the caller's stack instead; so adding `scope` for these variadics *should* probably do the same: void tester(Test test, scope Test[] tests...); This doesn't seem to be the case as the issue persists in the same manner. https://run.dlang.io/is/LcaKeu
Re: BetterC Bug? Intended Behavior? Asking Here As Unsure
On Monday, 6 July 2020 at 20:25:11 UTC, Kayomn wrote: example is forgetting to supply an arrange length when array length*
Re: BetterC Bug? Intended Behavior? Asking Here As Unsure
On Monday, 6 July 2020 at 20:20:44 UTC, Stanislav Blinov wrote: I'd say the original error should be reported on bugzilla, if it isn't already; if only for the error message which is ridiculously obscure. Yeah, you're tellin' me lol. I spent the better part of the day tracking this one down, and the error file and line numbers display it as having occured at the callsite rather than the actual problem areas. Though, admittedly I'm kind of used to seeing this error message since it appears any time you try and do something that relies on type info in betterC, intentionally or not. A notable example is forgetting to supply an arrange length when declaring a stack array, or it'll try to create a runtime-allocated array. I'll open a report for this shortly if it is a bug if there isn't one already. For now, that template is an adequate workaround.
BetterC Bug? Intended Behavior? Asking Here As Unsure
Something discovered in the D Language Code Club Discord server with the help of Wild is that the following code: struct Test { ~this() {} } void tester(Test test, Test[] tests...) { } extern(C) void main() { tester(Test(), Test()); } Raises the "TypeInfo cannot be used with ~betterC" error. It seems to be due to an inclusion of both the destructor and the non-vararg and vararg argument matching from testing. Anyone know a way around this without resulting to the rather hacky solution of just having 1 argument and always assuming that at least 1 argument is present? Here is a code demo setup for demonstrating the potential problem: https://run.dlang.io/is/A6oIpl
Re: Compile-time variables
On Friday, 6 April 2018 at 14:15:08 UTC, Kayomn wrote: On Friday, 6 April 2018 at 13:55:55 UTC, nkm1 wrote: [...] Figured I had a handle on how it worked doing but guess not. One final question, however. [...] Nevermind, I'm blind. I missed the post-increment in newID().
Re: Compile-time variables
On Friday, 6 April 2018 at 13:55:55 UTC, nkm1 wrote: On Friday, 6 April 2018 at 13:10:23 UTC, Kayomn wrote: ID tags are unique and spsecific to the class type. There shouldn't be more than one type ID assigned to one class type. The idea behind what it is I am doing is I am implementing a solution to getting a type index, similar to std.variant.Variant.type(). The way that I implemented this in C++ is like so: inline unsigned int getNodeTypeID() { static unsigned int lastID = 0; return lastID++; } template inline unsigned int getNodeTypeID() { static unsigned int typeID = getNodeTypeID(); return typeID; } In this C++ example I am exploiting the fact that templates are generated at compile-time to execute getNodeTypeID for each new type instance generated. After initial type generation, whenever they are called at runtime they were return the ID assigned to that function template instance that was generated at compile-time. It's pretty simple, and to be honest I'm surprised this has been causing me such a headache implementing it in D. That's because the C++ code doesn't do what you think it does. Apparently you think that getNodeID() is executed at compile time. This is not the case, which you can verify by adding "constexpr" to it: $ g++ -std=c++14 -Wall -Wextra -c -o example example.cpp main.cpp: In function ‘constexpr unsigned int getNodeTypeID()’: main.cpp:2:25: error: ‘lastID’ declared ‘static’ in ‘constexpr’ function static unsigned int lastID = 0; In fact, you're "exploiting" the fact that static variables in C++ can be initialized at runtime (which is probably not what you want). The equivalent D code is: uint newID() { static uint lastID; return lastID++; } uint getNodeID(T)() { static bool inited; static uint id; if (!inited) { id = newID(); inited = true; } return id; } (yes, C++ does insert some hidden bool that tells it whether the variable was initialized or not). Naturally, you can't use that for constructing switches or other compile time constructs. Figured I had a handle on how it worked doing but guess not. One final question, however. I've implemented this test bed with your example to what I think is your exact implementation, but it seems to be giving unexpected output. import std.stdio; uint newID() { static uint lastID; return lastID; } uint getNodeID(T)() { static bool inited; static uint id; if (!inited) { id = newID(); inited = true; } return id; } class Node {} class Sprite {} class Camera {} void main() { // Test 01. writeln("Test 01."); writeln(getNodeID!(Node)(),'\t',getNodeID!(Sprite)(),'\t',getNodeID!(Camera)()); // Test 02. writeln("Test 02."); writeln(getNodeID!(Node)(),'\t',getNodeID!(Sprite)(),'\t',getNodeID!(Camera)()); } Output: Performing "debug" build using gdc for x86_64. dlangtest ~master: building configuration "application"... Running ./dlangtest Test 01. 0 0 0 Test 02. 0 0 0 Have I misunderstood something?
Re: Compile-time variables
Besides this, I tried something with types used as user defined attributes. https://dlang.org/spec/attribute.html#uda Automatic compile time tagging is not my speciality, however, I think is also achievable with mixins somehow? But I don't know how to workaround the bug https://issues.dlang.org/show_bug.cgi?id=18718 at this moment... https://run.dlang.io/is/DmBhO5 Does the default case handle an unspecified class or does it handle a class which is specified, but is not mentioned in any of previous cases? So in this example code the switch table is being used for loading data serialized into text. If the class cannot determine the node ID or it uses the default node type ID (e.g. the Node type if super "Node") it will create a simple node, as you can always be sure no matter what the type there will be sufficient information stored in the data to construct a default Node. Another information shortage is: are the tags exclusive or not? So, is it possible that a class has more then one tag (still being unique (tuple))? ID tags are unique and spsecific to the class type. There shouldn't be more than one type ID assigned to one class type. The idea behind what it is I am doing is I am implementing a solution to getting a type index, similar to std.variant.Variant.type(). The way that I implemented this in C++ is like so: inline unsigned int getNodeTypeID() { static unsigned int lastID = 0; return lastID++; } template inline unsigned int getNodeTypeID() { static unsigned int typeID = getNodeTypeID(); return typeID; } In this C++ example I am exploiting the fact that templates are generated at compile-time to execute getNodeTypeID for each new type instance generated. After initial type generation, whenever they are called at runtime they were return the ID assigned to that function template instance that was generated at compile-time. It's pretty simple, and to be honest I'm surprised this has been causing me such a headache implementing it in D.
Re: Compile-time variables
On Friday, 6 April 2018 at 02:18:28 UTC, Kayomn wrote: On Friday, 6 April 2018 at 01:22:42 UTC, Kayomn wrote: On Friday, 6 April 2018 at 01:14:37 UTC, ketmar wrote: Kayomn wrote: [...] it is already done for you, free of charge. class Node {} class RootNode : Node {} class SpriteNode : Node {} void main () { auto nodeId1 = typeid(Node); auto nodeId2 = typeid(SpriteNode); auto comparison = typeid(Node); Node n = new SpriteNode(); assert(typeid(Node) is typeid(Node)); // obviously assert(typeid(SpriteNode) !is typeid(Node)); // sure assert(typeid(Node) is nodeId1); assert(typeid(n) is nodeId2); } Oh neat, thanks. I've been really scraping my head over this, and was worried I wouldn't be able to keep supporting my D version of the project. Hmm... doesn't seem to operate at compile-time, which is an issue if I want to use it in case switch table like I was going to: switch (queryInteger(childJson,"type")) { case NodeType.Sprite: child = this.addChild!(Sprite)(childName); break; default: child = this.addChild!(Node)(childName); break; } Wrong example code, here's the correct example: switch (queryString(childJson,"type")) { case (typeof (Sprite).name): child = this.addChild!(Sprite)(childName); break; case (typeof (Camera).name): child = this.addChild!(Camera)(childName); break; default: child = this.addChild!(Node)(childName); break; }
Re: Compile-time variables
On Friday, 6 April 2018 at 01:22:42 UTC, Kayomn wrote: On Friday, 6 April 2018 at 01:14:37 UTC, ketmar wrote: Kayomn wrote: [...] it is already done for you, free of charge. class Node {} class RootNode : Node {} class SpriteNode : Node {} void main () { auto nodeId1 = typeid(Node); auto nodeId2 = typeid(SpriteNode); auto comparison = typeid(Node); Node n = new SpriteNode(); assert(typeid(Node) is typeid(Node)); // obviously assert(typeid(SpriteNode) !is typeid(Node)); // sure assert(typeid(Node) is nodeId1); assert(typeid(n) is nodeId2); } Oh neat, thanks. I've been really scraping my head over this, and was worried I wouldn't be able to keep supporting my D version of the project. Hmm... doesn't seem to operate at compile-time, which is an issue if I want to use it in case switch table like I was going to: switch (queryInteger(childJson,"type")) { case NodeType.Sprite: child = this.addChild!(Sprite)(childName); break; default: child = this.addChild!(Node)(childName); break; }
Re: Compile-time variables
On Friday, 6 April 2018 at 01:14:37 UTC, ketmar wrote: Kayomn wrote: [...] it is already done for you, free of charge. class Node {} class RootNode : Node {} class SpriteNode : Node {} void main () { auto nodeId1 = typeid(Node); auto nodeId2 = typeid(SpriteNode); auto comparison = typeid(Node); Node n = new SpriteNode(); assert(typeid(Node) is typeid(Node)); // obviously assert(typeid(SpriteNode) !is typeid(Node)); // sure assert(typeid(Node) is nodeId1); assert(typeid(n) is nodeId2); } Oh neat, thanks. I've been really scraping my head over this, and was worried I wouldn't be able to keep supporting my D version of the project.
Re: Compile-time variables
I'll give a better example of what it is I'm trying to do. These are node types. Their contents are not important in this explanation, only that they operate as a tree structure. class Node; class RootNode : Node; class SpriteNode : Node; The result of getNodeID on a specific type is always the same. A value representing it that is applied during compilation. The value does not matter to the programmer, only that it is unique and gets applied. -- uint nodeId1 = getNodeID!(Node)(); // 0. uint nodeId2 = getNodeID!(SpriteNode)(); // 1. uint comparison = getNodeID!(Node)(); // 0. // True. if (getNodeID!(Node)() == getNodeID!(Node)()) { } // False. if (getNodeID!(SpriteNode)() == getNodeID!(Node)()) { } --
Re: Compile-time variables
On Friday, 6 April 2018 at 00:21:54 UTC, H. S. Teoh wrote: On Thu, Apr 05, 2018 at 11:53:00PM +, Kayomn via Digitalmars-d-learn wrote: [...] [...] [...] [...] `lastID`, as declared above, are runtime variables. The 'static' in this case just means it's thread-local, rather than allocated on the stack. You cannot modify these variables at compile-time. [...] You appear to be wanting to increment a global variable during compile-time. Unfortunately, there is no such thing as a compile-time global variable. You will have to find some other way to implement what you want. One way to do this would be to use compile-time introspection to construct a list of nodes, and then use a CTFE function or static foreach to generate node IDs all at once. For example: string generateEnum(T...)() { if (__ctfe) { // only run at compile-time string code = "enum NodeIds {"; foreach (ident; T) { code ~= ident ~ ", "; } code ~= "}"; return code; } else assert(0); } alias MyNodes = List!( // Just an example; you probably want to generate this // list via introspection, e.g. via __traits(getMembers) // or something like that. identifier1, identifier2, ... ); mixin(generateEnum!MyNodes); // defines `enum NodeIds` static assert(NodeIds.identifier1 == 0); static assert(NodeIds.identifier2 == 1); ... There are probably other ways to do it too, but I chose enum because it naturally assigns incrementing IDs to its members, so it's a convenient construct for this purpose. T I think I didn't explain well enough, I'm not trying to generate an enum from a list of pre-defined known quantities. The idea is that a compile-time generic function exists and it generates a unique identifier for that node. My reasons for doing this is to remove the need to keep a master enum that holds an identifying value for each node. I've implemented this same thing in C++ before and it was extremely straightforward.
Compile-time variables
Hi, I've got a scene graph which contains multiple inheriting types. As such, I've been tagging them with a type enum for whenever I need to do things such as loading a structure from binary. Up until now I've been using an enum that looks like this: --- enum NodeType : uint { None, Root, Sprite, Camera } --- I'm trying to implement a dynamic type ID assignment system that utilizes D generics to generate an incremental, unique identifier for each node without needing to continuously update a master list. This is what I have so far: --- alias NodeTypeID = uint; enum NodeTypeID getNodeID() { static NodeTypeID lastID = 0; return lastID++; } enum NodeTypeID getNodeID(T)() { static NodeTypeID typeID = getNodeID(); return typeID; } --- The expectation is that this is executed at compile time, generating a specific function for the given generic parameter each time the generic is used, incrementing the static variable by 1 and having the compiled generic functions essentially contain magic number unique to its type. So, I would be able to employ this like so: --- switch (someNodeTypeID) { case getNodeID!(Sprite)(): // Sprite node-specific behavior. break; case getNodeID!(Camera)(): // Camera node-specific behavior. break; default: // Default behavior. break; } --- However, I've been struggling with an error pertaining to getNodeType. The return statement of lastID++ is flagging the error "Static variable cannot be read at compile time." I may just be taking too much of a C++ lens to this, but to me this seems like it should work? Am I missing a qualifier or something here?
Re: DerelictGL3 and glBegin() access violation.
On Wednesday, 28 February 2018 at 16:58:38 UTC, Mike Parker wrote: On Wednesday, 28 February 2018 at 16:47:49 UTC, Kayomn wrote: Yeah, I knew they were deprecated, just weren't aware Derelict doesn't load them. Thanks though, I'd been up and down the Derelict docs page and I didn't see anything about this. Yeah, I decided against documenting the older version as I don't encourage people to use it. I understand some people will have to, which is why I'll still add bugfixes if necessary, but as soon as is reasonable I'm going to kill it. I was originally was only using them to make sure I could render something. When they weren't working however I was wondering if I mis-configured something.
Re: DerelictGL3 and glBegin() access violation.
On Wednesday, 28 February 2018 at 14:02:48 UTC, Mike Parker wrote: On Wednesday, 28 February 2018 at 12:02:27 UTC, Kayomn wrote: import derelict.opengl3.gl3; Whoa. Just noticed this. That's an older version of DerelictGL3 you're using there. You should really be using the latest version of both DerelictGL3 and DerelictGLFW3. The -alpha versions are what I recommend. They're perfectly fine, despite the -alpha in the version tag. But if you want to continue with the old 1.x version of DerelictGL3, then you can get access to the deprecated stuff by replacing the `gl3` import with `gl` can using `DerelictGL` in place of `DerelictGL3`: import derelict.opengl3.gl; ... DerelictGL.load(); DerelictGL.reload(); Note that this also loads all of the same stuff as DerelictGL3, so you don't need to make use of that anywhere. Yeah, I knew they were deprecated, just weren't aware Derelict doesn't load them. Thanks though, I'd been up and down the Derelict docs page and I didn't see anything about this.
Re: DerelictGL3 and glBegin() access violation.
On Wednesday, 28 February 2018 at 12:36:37 UTC, bauss wrote: On Wednesday, 28 February 2018 at 12:02:27 UTC, Kayomn wrote: [...] Most likely a library issue. Are you sure that you link to the libraries correctly etc.? I'm using DUB for package management and linking and any library loading I'm using I'm remembering to load. This bug seems to be happening on both Windows and Linux with the same configuration and there's no other topics on it from Google searches that appear to be having the same issue.
DerelictGL3 and glBegin() access violation.
Maybe I'm missing something, but whenever I attempt to call glBegin() with anything my program immediately encounters an access violation. I've got a very simple setup, with this being my main: import base.application; import derelict.opengl3.gl3; import derelict.glfw3.glfw3; int main(string[] args) { DerelictGL3.load(); version (Windows) { DerelictGLFW3.load(".\\dll\\glfw3.dll"); } else { DerelictGLFW3.load(); } return Application(args).run(); } And I'm remembering to reload after creating the GL context in the window class: public this(int width,int height,string title) { if (glfwInit()) { // Hint configuration. glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR,3); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR,3); glfwWindowHint(GLFW_RESIZABLE,false); glfwWindowHint(GLFW_OPENGL_PROFILE,GLFW_OPENGL_CORE_PROFILE); this.nextTick = Time.getTicks(); this.handle = glfwCreateWindow( this.width = width, this.height = height, toStringz(this.title = title), null, null ); if (this.handle is null) { // Failure. Debug.log("GLFW Error: Failed to create window handle instance."); glfwTerminate(); } else { import derelict.opengl3.gl3 : DerelictGL3; // Set positon. glfwSetWindowPos(this.handle,100,100); glfwMakeContextCurrent(this.handle); DerelictGL3.reload(); } } else { Debug.log("GLFW Error: Failed to intialize."); } } Is this a DerelictGL3 bug? Am I missing something else that I should be initializing? Other things like glClear() seem to be working fine.
Re: Derelict GLFW3 and dynamic linking on Linux
On Tuesday, 27 February 2018 at 13:14:38 UTC, Mike Parker wrote: On Tuesday, 27 February 2018 at 12:00:20 UTC, Kayomn wrote: [...] It *is* a version problem. The exception is a SymbolLoadException, which means the loader found the library just fine (you can see it in the file name, libglfw.so.3.1). However, it attempted to load `glfwSetWindowIcon` and failed. If you check the GLFW 3 documentation [1] you'll find the following: [...] Thanks for clearing that up, it's been bugging me for a while.
Derelict GLFW3 and dynamic linking on Linux
Hi, I've been working on something using Windows and now I'm attempting to build it on Linux with Dub, however I appear to be having an issue. import base.application; import derelict.opengl3.gl3; import derelict.glfw3.glfw3; int main(string[] args) { DerelictGL3.load(); version (Windows) { DerelictGLFW3.load(".\\dll\\glfw3.dll"); } else { DerelictGLFW3.load("/usr/lib/x86_64-linux-gnu/libglfw.so"); } return Application(args).run(); } I've checked that the provided library object referenced exists, regardless every time I compile I get this same symbol loading error without fail: derelict.util.exception.SymbolLoadException@../../.dub/packages/derelict-util-2.0.6/source/derelict/util/exception.d(35): Failed to load symbol glfwSetWindowIcon from shared library /u sr/lib/x86_64-linux-gnu/libglfw.so.3.1 I was reading this GitHub issue, and they seemed to describe the issue as being version incompatibilities: https://github.com/DerelictOrg/DerelictGLFW3/issues/9 However, I'm certain I'm using the correct GLWF version for my project.
Re: Aliasing member's members
On Monday, 26 February 2018 at 21:04:51 UTC, TheFlyingFiddle wrote: On Monday, 26 February 2018 at 20:50:35 UTC, Kayomn wrote: [...] Don't think you can alias member variables directly. You could do this though: struct Player { Entity entity; ref auto pos() inout { return entity.position; } } Which will give you most of what you want. Although if you want to take the address of pos you have to use auto addr = &player.pos(); Damn, was hoping to keep my structs as plain old data-structures. Thanks for the info, guess I won't be doing this then.
Aliasing member's members
I've been experimenting with D's Better C mode, and I have a question regarding something that I started thinking about after watching one of Jonathon Blow's talks on data-oriented programming - more specifically the aspect of fake "inheritance" I have the following code. My question is if it's possible to use alias in a similar way to Jonathon's own language Jai and its using keyword, referencing the internal Vector2 as Player.pos instead of Player.entity.position: import core.stdc.stdio : printf; uint idCounter = 0; struct Vector2 { double x,y; } struct Entity { uint id; Vector2 position; } struct Player { Entity entity; alias pos = Entity.position; } Player createPlayer(Vector2 position) { Player player; player.entity.id = idCounter++; player.entity.position = position; return player; } int main(string[] args) { Player player = createPlayer(Vector2(50.0,50.0)); printf( "[Player]\nid: %d\nPosition: %lf x %lf\n", player.entity.id, player.pos.x, player.pos.y ); return 0; }