Re: BetterC Bug? Intended Behavior? Asking Here As Unsure

2020-07-06 Thread Kayomn via Digitalmars-d-learn

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

2020-07-06 Thread Kayomn via Digitalmars-d-learn

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

2020-07-06 Thread Kayomn via Digitalmars-d-learn

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

2020-07-06 Thread Kayomn via Digitalmars-d-learn
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

2018-04-06 Thread Kayomn via Digitalmars-d-learn

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

2018-04-06 Thread Kayomn via Digitalmars-d-learn

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

2018-04-06 Thread Kayomn via Digitalmars-d-learn


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

2018-04-05 Thread Kayomn via Digitalmars-d-learn

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

2018-04-05 Thread Kayomn via Digitalmars-d-learn

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

2018-04-05 Thread Kayomn via Digitalmars-d-learn

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

2018-04-05 Thread Kayomn via Digitalmars-d-learn

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

2018-04-05 Thread Kayomn via Digitalmars-d-learn

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

2018-04-05 Thread Kayomn via Digitalmars-d-learn

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.

2018-02-28 Thread Kayomn via Digitalmars-d-learn

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.

2018-02-28 Thread Kayomn via Digitalmars-d-learn

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.

2018-02-28 Thread Kayomn via Digitalmars-d-learn

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.

2018-02-28 Thread Kayomn via Digitalmars-d-learn
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

2018-02-27 Thread Kayomn via Digitalmars-d-learn

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

2018-02-27 Thread Kayomn via Digitalmars-d-learn
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

2018-02-26 Thread Kayomn via Digitalmars-d-learn
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 = ();


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

2018-02-26 Thread Kayomn via Digitalmars-d-learn
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;
}