Template unique IDs per type
I was recently looking up how to assign a unique ID based on each different implementation of a templated type (NOT per instance, but per unique type). For example: class MyTemplate(T) { //the ? where the actual number would go const int type_id = ?; } void main() { auto a = new MyTemplate!(int)(); //a.type_id = 0 auto b = new MyTemplate!(string)(); //b.type = 1 auto c = new MyTemplate!(int)(); //c.type_id = 0 auto d = new MyTemplate!(double)();//d.type_id = 2 } There's some solutions to this sort of thing at this stackoverflow question in c++ which are possible at run-time: http://stackoverflow.com/questions/8596490/counting-with-template-metaprogramming BUT I was wondering with CTFE and/or mixins would it be possible to do this at compile time?
Re: Template unique IDs per type
On Friday, 12 July 2013 at 03:56:50 UTC, JS wrote: sure, each type name is unique. All you have to do is convert them to an int... use a hash or some other method or just use the string names. If you need the id's to be continuous try to use an set(array) of the type names. Not sure if the last method works well with ctfe's though. Hmm, I think in my case I may need them to be sequential from 0 (though order doesn't matter). I'm beginning to think it just isn't possible, as there is no way to store state during compilation, and thus no way to count how far along we are in ids. I'm not sure what you mean by try to us an set(array) of type names.
Re: Template unique IDs per type
On Friday, 12 July 2013 at 04:42:28 UTC, Jonathan M Davis wrote: On Friday, July 12, 2013 05:15:43 Roderick Gibson wrote: I was recently looking up how to assign a unique ID based on each different implementation of a templated type (NOT per instance, but per unique type). For example: class MyTemplate(T) { //the ? where the actual number would go const int type_id = ?; } void main() { auto a = new MyTemplate!(int)(); //a.type_id = 0 auto b = new MyTemplate!(string)(); //b.type = 1 auto c = new MyTemplate!(int)(); //c.type_id = 0 auto d = new MyTemplate!(double)();//d.type_id = 2 } There's some solutions to this sort of thing at this stackoverflow question in c++ which are possible at run-time: http://stackoverflow.com/questions/8596490/counting-with-template-metaprogra mming BUT I was wondering with CTFE and/or mixins would it be possible to do this at compile time? You can't have any kind of global mutable state in CTFE, so there's no way for different template instantiations to share data like that. You could generate IDs based on the types (e.g. a hash) and get different values that way (though it might be tricky to do that in a way that would guarantee no collisions), but if you want some kind of incrementing ID across them, I think that you're stuck with a runtime solution. Now, it's probably possible to use static constructors to use global mutable state to intialize all of those IDs when the program starts up, which would initialize the IDs to incrementing values, so they could be immutable if you wanted, but that would still be at runtime. - Jonathan M Davis Hmm, I'll look into the static constructors, as that sounds like a fairly ideal solution anyway. I was more just curious to see if the problem was solvable in D at compile time (as it seems to be a fairly common request in C++).
Re: Template unique IDs per type
On Friday, 12 July 2013 at 04:42:28 UTC, Jonathan M Davis wrote: Now, it's probably possible to use static constructors to use global mutable state to intialize all of those IDs when the program starts up, which would initialize the IDs to incrementing values, so they could be immutable if you wanted, but that would still be at runtime. - Jonathan M Davis As a follow up, here's what it looks like, and it works perfectly: alias size_t component_type; class Component(T) : BaseComponent { static immutable component_type component_type_id; static this() { component_type_id = component_type_counter++; } } class BaseComponent { static component_type component_type_counter; }
Re: Handling different types gracefully
On Tuesday, 2 July 2013 at 06:54:58 UTC, bearophile wrote: Roderick Gibson: Variant is a possiblity. How is the performance with large containers of these, since these structures will likely hold the majority of the data in the game? You probably have to benchmark yourself. (But I have suggested an Algebraic). Bye, bearophile I should know the types at compile time, so I will be using it most likely, but reading the docs it looks like Algebraic is built on top of the same structure as Variant. Is there any difference in implementation?
Re: Handling different types gracefully
On Tuesday, 2 July 2013 at 21:45:57 UTC, bearophile wrote: Roderick Gibson: I should know the types at compile time, so I will be using it most likely, but reading the docs it looks like Algebraic is built on top of the same structure as Variant. Is there any difference in implementation? Take a look at the Phobos source code, it's much faster than waiting for my answer. Algebraic is built on top of VariantN. Algebraic accepts only a limited number of types, while Variant doesn't have such limitation. So Algebraic is type safe. And maybe Algebraic can ideally be implemented more efficiently than a Variant because to denote the contained type an enum suffices, instead of a TypeInfo. Please take a look at VariantN if it contains the enum or a Typeinfo or something else. Bye, bearophile Thanks, I'll do that. Thanks for the help, bearophile!
Handling different types gracefully
I'm asking because I'm doing some game development in D and I've come upon the entity component architecture, and it looks like a good way to handle the complexity and interdependency that games seem to have. The components wind up being plain old data types (I currently use structs), with systems that actually modify and interact with them on a per-entity basis. The basic idea is that you compose entities (basically just an id) with various components to give the specific functionality you need for that particular game object. The whole entity system is just a database for the different subsystems to query for entities (just an id) which have components that fulfill their criteria (for example a physics subsystem might only be interested in entities with the components position, movement, and collision, while a render subsystem might only be interested in entities with components position, mesh, sprite). There's also the reverse where the subsystems register which components they are looking for and then the entity system serves up entities that match the criteria. The standard way to store components is just to subclass them from a base class Component and then store a pointer to them in a Component[] in an overall entity manager. But then you have to do things like type casting the pointers when you return the queries, which seems a bit rough. It also feels wrong to make them inherit a class for the SOLE reason of getting around the type system. Anyway, I think I'm just rubber ducking a bit here, but I'm wondering if there's another way to do this, if someone has any experience with this sort of system. As an example of what I'm looking for, say there is a class Entities, with some type of container that could hold arrays of different component types (this is the part that really stumps me). I'd like to be able to do something like: ... auto entities = new Entities(); auto entity_id = entities.createEntity(); entities.addComponent!(position)(entity_id, pos); entities.addComponent!(movement)(entity_id, mov); entities.addComponent!(collision)(entity_id, col); auto physics_data = entities.getEntitiesWithComponents!(position, movement, collision)(); The two big requirements are some kind of regular, queryable structure to hold the components (of different types), and the ability to filter by type. Is anything like that remotely possible?
Re: Handling different types gracefully
On Monday, 1 July 2013 at 12:16:50 UTC, bearophile wrote: Roderick Gibson: auto entities = new Entities(); auto entity_id = entities.createEntity(); entities.addComponent!(position)(entity_id, pos); entities.addComponent!(movement)(entity_id, mov); entities.addComponent!(collision)(entity_id, col); auto physics_data = entities.getEntitiesWithComponents!(position, movement, collision)(); The two big requirements are some kind of regular, queryable structure to hold the components (of different types), and the ability to filter by type. Is anything like that remotely possible? If the possible types are know, then there's std.variant.Algebraic, otherwise there is a free Variant or VariantN. They are not perfect, but maybe they are good enough for you. Bye, bearophile Variant is a possiblity. How is the performance with large containers of these, since these structures will likely hold the majority of the data in the game? Waiting for multiple alias this ?? And opDispatch to respond to unimplemented components. I'm not sure what you mean by this.
Re: Direlect3 with Mono-D
On Monday, 22 April 2013 at 20:57:56 UTC, Dementor561 wrote: On Monday, 22 April 2013 at 20:47:32 UTC, Minas Mina wrote: If you aren't comfortable with either C++ or D I would suggest to do the tutorials with C++, as there are no OpenGL tutorials for D. Don't try to learn two things at the same time. No, I am comfortable with C++, I learned it in College. It is just that a lot of the names between the two different contexts confuse me. For example, I am looking to find the equivalent in Derelict3 for GLFW_FSAA_SAMPLES, but I can not find it anywhere. I don't know anything about glfw as I use the SDL bindings, but my experience with the SDL stuff is that it is identical to c/c++. I can very easily use c/c++ opengl and sdl source and tutorials to translate it into D. There are some gotchas, mostly with using references and pointers, but nothing terribly hard to figure out.
Re: Direlect3 with Mono-D
On Sunday, 21 April 2013 at 15:21:00 UTC, Dementor561 wrote: On Saturday, 20 April 2013 at 22:25:42 UTC, Roderick Gibson wrote: On Saturday, 20 April 2013 at 15:49:47 UTC, Dementor561 wrote: I have all the needed files to use Direlect3, and I have Mono-D installed on Xamarin, I was wondering how I could put it all together in a project. If you want to develop for derelict, I have no idea. If you just want to use it, then I can help. The first step is to build it. Derelict3 makes it pretty easy, just build the build.d file and run the batch file. Here's a guide with pictures after you have built it. http://imgur.com/a/chV8W I have it all built, but I still get an error after I followed the instructions... http://imgur.com/a/eBDbE Doesn't look like a derelict3 error. Did you follow the steps at the end of installing Mono-D here: http://mono-d.alexanderbothe.com/?page_id=9 Near the bottom you have to set up includes for phobos and the druntime
Re: Direlect3 with Mono-D
On Sunday, 21 April 2013 at 15:21:00 UTC, Dementor561 wrote: On Saturday, 20 April 2013 at 22:25:42 UTC, Roderick Gibson wrote: On Saturday, 20 April 2013 at 15:49:47 UTC, Dementor561 wrote: I have all the needed files to use Direlect3, and I have Mono-D installed on Xamarin, I was wondering how I could put it all together in a project. If you want to develop for derelict, I have no idea. If you just want to use it, then I can help. The first step is to build it. Derelict3 makes it pretty easy, just build the build.d file and run the batch file. Here's a guide with pictures after you have built it. http://imgur.com/a/chV8W I have it all built, but I still get an error after I followed the instructions... http://imgur.com/a/eBDbE Oh, you need a main function. Every program needs one, just like C/C++. It's where your program starts. void main() { }
Re: Direlect3 with Mono-D
On Sunday, 21 April 2013 at 19:49:14 UTC, Dementor561 wrote: Well, sorta. When I add import derelict.glfw3.glfw3; it says the library could not be resolved... Do I need to add something to the library somewhere? Any library you use you have to add to the project linker settings. Derelict3 separates them into separate libraries so you aren't forced to include the entire thing if you don't need some pieces. Here's the include for glfw: http://imgur.com/xv4jesK
Could use some help with porting problems
So I needed a coherent noise generator and decided to look at libnoise. Noticing it was rather small I decided I would just port it over to d and be done with it, as I expected it would help me understand d a bit better (it has). My problems all seem to stem from the const qualifier, which is actually rather different between d and c++, and coming from a web programming background is somewhat alien to me. So my question is 1) How would I declare an array of pointers to const(Class)? That is, how do I declare an array such that the ARRAY is mutable, but the actual objects that it points to are not (ie you could change the pointers in the array, but you cannot change anything in a dereferenced object). Question 2 is why would this be giving me a (cast(const(Object)) is not an lvalue) error when I try to actually set a new source module? void SetSourceMod(int index, ref const(Mod) sourceMod) { assert (m_pSourceMod != null); if (index = GetSourceModCount () || index 0) { throw new ExceptionInvalidParam (); } m_pSourceMod[index] = sourceMod; } protected: /// An array containing the pointers to each source module required by /// this noise module. const(Mod)*[] m_pSourceMod; I am typically going to be passing in an object that derives from Mod (this class was named Module in libnoise c++, changed for obvious reasons) I'm not quite sure I explained clearly enough, so please ask if you need more clarification. Also if anyone is interested in the port (currently, modules that require no additional modules seem to work fine): https://bitbucket.org/kniteli/libnoise-d/src And the original source: http://libnoise.sourceforge.net/
Re: Could use some help with porting problems
On 2/7/2012 7:58 PM, Daniel Murphy wrote: It seems the problem you've run into is that a class reference cannot be tail-const. Pointers can be tail-const like this: const(Data)* but there is no way currently (there are proposals) to make only the data and not the reference const. A workaround is to use Rebindable in std.typecons. An array of references to const classes becomes: (Rebindable!const(Class))[] Thanks, both answers mentioned Rebindable, looks like it may be very useful. I actually did use the const(Class)* solution, which puts the referencing requirement on the caller, but that's not a huge deal.
Re: How convice people that D it's wonderfull in a hour ?
On 10/9/2011 5:18 PM, deadalnix wrote: Le 09/10/2011 12:00, Zardoz a écrit : Recently I've been asked if I could give a speech about D in my university. It will be of one hour of long. I not respond yet, but I think that I will do it. Actually I have the problem that I don't know well how explain well too many features and things of D that I like. I think that only talking about D's arrays and type system I will need around half-hour. Any recommendation of how I should focus it ? I think you should show through several exemples. AS IT IS UNIVERSITY, I guess your public will know about programming. Explain difference between struct and classes, and how it is great compared to C++ (no slicing for exemple). Show some stuffs about first class function and delegates (for callback for exemple) coppared to how painful it is in C++ or java (using interface and useless object) Then, gove a talk aboit metaprogramming (how you can implement behaviral pattern with no cost at runtime, how you can make very generic code like STL) and why it is way better than C++ (usability with stuffs like static if) or java (generic isn't metaprogramming). And last but not least : explain memory model and how it help to deal with multithrading problems where other languages usually aren't good. The point isn't to bash C++ or java, but to show how some problem you face in thoses languages can be solved elegantly in D. If your public knows others languages than java and C++, then adapt the speach to what they know. The threading model is what attracted me to D.
Re: Is there a way to set an alias to specific form of a template?
On 10/7/2011 7:33 PM, Andrej Mitrovic wrote: You don't have to rewrite Vector for multiple dimensions, methinks: class Vector(T...) { this(T t) {} } void main() { alias Vector!(float, float) vec2f; auto v = new vec2f(1.0,1.0); } You'll probably have to play with `static if`, template constraints, and stuff like that. I got this working, found an odd bug though. This code, alias Vector!(float, float) vec2f; alias Vector!(double, double) vec2d; alias Vector!(float, float, float) vec3f; public struct Vector(T...) { int dim = 0; this(T...)(T args) { dim = args.length; } unittest { auto v = new vec2f(1.2f, 1.5f); vec2f d = new vec2f(1.1f, 1.4f); assert(v.dim == 2); assert(d.dim == 2); } } will pass the first assert and fail on the second. Checking out the contents of v.length and d.length with writeln gives the correct answer on the first and 2 1 RANDOMHEXCODE on the second. Very strange.
Re: Is there a way to set an alias to specific form of a template?
On 10/7/2011 11:35 PM, Ali Çehreli wrote: On Fri, 07 Oct 2011 18:29:26 -0700, Roderick Gibson wrote: This may be the completely wrong approach, but I am basically thinking of something like this (I am aware this will not compile, it's psuedocode): class Vector(T) { ... //definition here } alias Vector(float, float) vec2f; auto v = new vec2f(1.0,1.0); I am making a templated Vector class (a mathematical vector) that will have varying types (thus a template) and dimensions (via variadic functions), so that the same template definition will work for 2d or 3d vectors (or 4d, etc). I then want the programmer to be able to define the specific forms that he wants so he can easily keep track of them (without getting confused about which is a 2d integer vector and which is a 3d float vector), and then use those forms in a type safe manner. Is this even possible? If it is, but it's the wrong way to do it, what's the right way? Basically I wanted to write it once and not worry about writing it again to handle different types and dimensions (no vec2i class, or vec2f, or vec3f, or vec3i, etc). Templates easily handles the type requirement, but what about the dimensional requirement? Am I just going to have to rewrite it when I add dimensions? You can take advantage of 'Template Value Parameters' and 'Typesafe Variadic Functions': http://www.d-programming-language.org/ template.html#TemplateValueParameter http://www.d-programming-language.org/function.html class Vector(T, int N) { T[N] elements; this(T[] elements ...) { this.elements = elements; } } alias Vector!(double, 2) Vec2D; alias Vector!(double, 3) Vec3D; void main() { auto v2d = new Vec2D(2.2, 2.2); auto v3d = new Vec3D(3.3, 3.3, 3.3); // Alternatively, all parameters at once: auto v3d_too = new Vec3D([ 33, 33, 33, ]); } (Some would find 'size_t N' to be more appropriate since N is a dimension.) Ali I decided this would be the best way, thank you. One question though, I noticed with this method that you can only assert that the dimension and the parameter list length match at runtime (ie, someone could instantiate a vec2d as vec2d(2.2, 2.2, 3.1) and the compiler will happily accept it), I'm guessing constraints are what's needed, but I don't know how to get the parameter count at compile time, only at runtime (via elements.length). The compiler *should* know the length at compile time shouldn't it? I managed to get it to at least stop the compilation with this(T[N] elements...) but the error messages are terrible. Is there a better way, perhaps using a static assert?
Re: Simple I know, but could use some help compiling with make
On 10/5/2011 7:46 AM, Ola Ost wrote: I had exactly this problem too, I asked on the Derelict forums: http://www.dsource.org/forums/viewtopic.php?t=5856sid=8ebff671fafec3bd8962ddfceaf99eb8 At the moment I've resolved this by building Derelict with make, first a normal full build, then a second run using the cleandi target, which removes the generated di files. I've set up the Derelict lib and include paths in dmd's sc.ini file, so I just have to call 'rdmd main.d' to build and run. Hmm, so it's a bug in rdmd trying to compile the .di files or something?
Is there a way to set an alias to specific form of a template?
This may be the completely wrong approach, but I am basically thinking of something like this (I am aware this will not compile, it's psuedocode): class Vector(T) { ... //definition here } alias Vector(float, float) vec2f; auto v = new vec2f(1.0,1.0); I am making a templated Vector class (a mathematical vector) that will have varying types (thus a template) and dimensions (via variadic functions), so that the same template definition will work for 2d or 3d vectors (or 4d, etc). I then want the programmer to be able to define the specific forms that he wants so he can easily keep track of them (without getting confused about which is a 2d integer vector and which is a 3d float vector), and then use those forms in a type safe manner. Is this even possible? If it is, but it's the wrong way to do it, what's the right way? Basically I wanted to write it once and not worry about writing it again to handle different types and dimensions (no vec2i class, or vec2f, or vec3f, or vec3i, etc). Templates easily handles the type requirement, but what about the dimensional requirement? Am I just going to have to rewrite it when I add dimensions?
Simple I know, but could use some help compiling with make
It's my first foray into the arcana of makefiles and command line compiling. My makefile looks like this: IMPORT = -IC:\Dlang\dmd2\src\ext\Derelict2\import LIB_PATHS = -LC:\Dlang\dmd2\src\ext\Derelict2\lib LIB_INCLUDES = DerelictSDL.lib DerelictGL.lib DerelictUtil.lib all: dmd src/main.d src/display.d src/renderdata.d src/vector2d.d\ $(IMPORT) $(LIB_PATHS) $(LIB_INCLUDES) I think I just don't know how to give the compiler what it wants. I can build it manually by simply including the full paths to each of those libraries, but I'd rather avoid having to do that unless necessary. Is there something I'm just missing?
Re: Simple I know, but could use some help compiling with make
On 9/29/2011 2:15 PM, Nick Sabalausky wrote: Nick Sabalauskya@a.a wrote in message news:j62msu$205t$1...@digitalmars.com... Roderick Gibsonknit...@gmail.com wrote in message news:j62d4i$1d8l$1...@digitalmars.com... It's my first foray into the arcana of makefiles and command line compiling. My makefile looks like this: IMPORT = -IC:\Dlang\dmd2\src\ext\Derelict2\import LIB_PATHS = -LC:\Dlang\dmd2\src\ext\Derelict2\lib LIB_INCLUDES = DerelictSDL.lib DerelictGL.lib DerelictUtil.lib all: dmd src/main.d src/display.d src/renderdata.d src/vector2d.d\ $(IMPORT) $(LIB_PATHS) $(LIB_INCLUDES) I think I just don't know how to give the compiler what it wants. I can build it manually by simply including the full paths to each of those libraries, but I'd rather avoid having to do that unless necessary. Is there something I'm just missing? build.bat: @echo off rdmd --build-only -ofmyApp -IC:\Dlang\dmd2\src\ext\Derelict2\import -L+C:\Dlang\dmd2\src\ext\Derelict2\lib\ DerelictSDL.lib DerelictGL.lib DerelictUtil.lib DerelictGLU.lib src/main.d Note: 1. After the @echo off, that's supposed to be one line. 2. rdmd instead of dmd 3. Only one .d file is given: The one with main() 4. The .d file is the *last* param. Or to make it a little cleaner: @echo off IMPORT = -IC:\Dlang\dmd2\src\ext\Derelict2\import LIB_PATHS = -L+C:\Dlang\dmd2\src\ext\Derelict2\lib\ LIB_INCLUDES = DerelictSDL.lib DerelictGL.lib DerelictUtil.lib DerelictGLU.lib EXE_NAME = myApp rdmd --build-only -of%EXE_NAME% %IMPORT% %LIB_PATHS% %LIB_INCLUDES% src/main.d Of course, you can use rdmd with make too, but I've never really liked dealing with make. Very cool, thanks for going to all the trouble. It only takes the one souce file, does rdmd build out other files automatically?
Re: Simple I know, but could use some help compiling with make
On 9/29/2011 2:39 PM, Nick Sabalausky wrote: Roderick Gibsonknit...@gmail.com wrote in message news:j62nvo$2237$1...@digitalmars.com... On 9/29/2011 2:15 PM, Nick Sabalausky wrote: Nick Sabalauskya@a.a wrote in message news:j62msu$205t$1...@digitalmars.com... Roderick Gibsonknit...@gmail.com wrote in message news:j62d4i$1d8l$1...@digitalmars.com... It's my first foray into the arcana of makefiles and command line compiling. My makefile looks like this: IMPORT = -IC:\Dlang\dmd2\src\ext\Derelict2\import LIB_PATHS = -LC:\Dlang\dmd2\src\ext\Derelict2\lib LIB_INCLUDES = DerelictSDL.lib DerelictGL.lib DerelictUtil.lib all: dmd src/main.d src/display.d src/renderdata.d src/vector2d.d\ $(IMPORT) $(LIB_PATHS) $(LIB_INCLUDES) I think I just don't know how to give the compiler what it wants. I can build it manually by simply including the full paths to each of those libraries, but I'd rather avoid having to do that unless necessary. Is there something I'm just missing? build.bat: @echo off rdmd --build-only -ofmyApp -IC:\Dlang\dmd2\src\ext\Derelict2\import -L+C:\Dlang\dmd2\src\ext\Derelict2\lib\ DerelictSDL.lib DerelictGL.lib DerelictUtil.lib DerelictGLU.lib src/main.d Note: 1. After the @echo off, that's supposed to be one line. 2. rdmd instead of dmd 3. Only one .d file is given: The one with main() 4. The .d file is the *last* param. Or to make it a little cleaner: @echo off IMPORT = -IC:\Dlang\dmd2\src\ext\Derelict2\import LIB_PATHS = -L+C:\Dlang\dmd2\src\ext\Derelict2\lib\ LIB_INCLUDES = DerelictSDL.lib DerelictGL.lib DerelictUtil.lib DerelictGLU.lib EXE_NAME = myApp rdmd --build-only -of%EXE_NAME% %IMPORT% %LIB_PATHS% %LIB_INCLUDES% src/main.d Of course, you can use rdmd with make too, but I've never really liked dealing with make. Very cool, thanks for going to all the trouble. It only takes the one souce file, does rdmd build out other files automatically? What rdmd does is takes the file with main(), figures out all the .d files needed, checks if any of them have been changed, and if so, it sends them all to dmd to be compiled. If you omit the --build-only it will also run the program you built. The full format for rdmd is: rdmd {params for dmd and rdmd} main.d {params for main.exe} So if you have: //main.d import std.stdio; void main(string[] args) { writeln(Hello, args[1]); } Then you can do this: rdmd main.d Joe Hello Joe It's an awesome tool. You can run just rdmd by itself to see all it's options. Be aware though, rdmd has some issues if you're not using at least DMD 2.055. Hmm, looks like it would be awesome, unfortunately it spits out a bunch of previous definition different errors on the linker, in relation to the libraries. Oh well, I seem to be able to get it working with dmd for now.