Re: Asio Bindings?
On Thursday, 2 June 2016 at 04:52:50 UTC, Mithun Hunsur wrote: On Thursday, 2 June 2016 at 04:02:36 UTC, Pie? wrote: Does anyone know if there is any Asio bindings or direct D available that allows for IO? Check out vibe.d: https://vibed.org/ - it includes a fairly complete implementation of asynchronous I/O, among other things. Oh, lol, I should have mentioned I meant for audio! ;)
Re: Asio Bindings?
On Thursday, 2 June 2016 at 04:02:36 UTC, Pie? wrote: Does anyone know if there is any Asio bindings or direct D available that allows for IO? Check out vibe.d: https://vibed.org/ - it includes a fairly complete implementation of asynchronous I/O, among other things.
Asio Bindings?
Does anyone know if there is any Asio bindings or direct D available that allows for IO?
Re: adamdruppe: Drawing scaled image
On Thursday, 2 June 2016 at 03:37:01 UTC, Adam D. Ruppe wrote: On Thursday, 2 June 2016 at 03:19:20 UTC, Pie? wrote: I'm curious about how to draw a scaled image. There's a few general options: 1) Scale it yourself in-memory then draw. This is a pain, I don't think my public libraries have a scale method 2) If on MS Windows, you can resize the window as a user and it will stretch for you automatically. X on Linux doesn't support this though. 3) Again, on MS Windows, you could call StretchBlt yourself to scale and draw to it. 4) You can make an OpenGL texture and draw that at any scale/rotation. This is fairly involved and uses a totally different drawing system, but you can do it all with simpledisplay.d too. Also, png.d doesn't seem to work with alpha channel? png does, but simpledisplay doesn't (except for the OpenGL stuff, of course). Both the MemoryImage implementations (TrueColorImage and IndexedImage) have a rgba thing internally so you could blend yourself before drawing (color.d has an alphaBlend function, undocumented though), but if you want it done automatically or in hardware, gotta use the opengl stuff. Which also leads me to, how to draw one image on to another? Gotta DIY there, I haven't written a function for that yet. It's not hard to do though, at least with MemoryImages. The simpledisplay Image is different - it is optimized for the platform so the bits change around (it doesn't have an alpha channel in all cases either). My terminal emulator does this.. here's the function: https://github.com/adamdruppe/terminal-emulator/blob/master/main.d#L296 so basically you copy the bits yourself, using the offset members to handle the platform-specific stuff. I didn't do alpha blending there though... but the blend function from color.d could do it. Doing alpha blending as we draw on the window needs new functions used... AlphaBlend on Windows and XRender on Linux IIRC. But since I tend to use OpenGL when I want to do lots of the blending I haven't been in a big rush to do it. Thanks, I'll look into it. I have tried OpenGL with simpledisplay but I cannot draw to the window. I assume other drawing methods are required? auto window = new SimpleWindow(600, 400, "Pong game!", OpenGlOptions.yes); window.setAsCurrentOpenGlContext(); //auto img = imageFromPng(readPng(cast(ubyte[]) read(args[1]))); // newer api, simpler but less control auto img = readPng(`x.png`); auto img2 = readPng(`y.png`); window.redrawOpenGlScene = delegate() { auto painter = window.draw(); painter.clear(); painter.drawImage(Point(10, 10), Image.fromMemoryImage(img2)); painter.drawImage(Point(10, 10), Image.fromMemoryImage(img)); }; //displayImage(Image.fromMemoryImage(img), window); window.eventLoop(50, // set a 50 ms timer pulls // This runs once per timer pulse delegate () { //auto painter = window.draw(); //painter.clear(); //painter.drawImage(Point(10, 10), Image.fromMemoryImage(img2)); //painter.drawImage(Point(10, 10), Image.fromMemoryImage(img)); window.redrawOpenGlSceneNow(); }, delegate (KeyEvent event) { }, delegate (MouseEvent event) { } ); If so, I can use gamehelpers.d to do the drawing of the images? Thanks.
Re: adamdruppe: Drawing scaled image
On Thursday, 2 June 2016 at 03:19:20 UTC, Pie? wrote: I'm curious about how to draw a scaled image. There's a few general options: 1) Scale it yourself in-memory then draw. This is a pain, I don't think my public libraries have a scale method 2) If on MS Windows, you can resize the window as a user and it will stretch for you automatically. X on Linux doesn't support this though. 3) Again, on MS Windows, you could call StretchBlt yourself to scale and draw to it. 4) You can make an OpenGL texture and draw that at any scale/rotation. This is fairly involved and uses a totally different drawing system, but you can do it all with simpledisplay.d too. Also, png.d doesn't seem to work with alpha channel? png does, but simpledisplay doesn't (except for the OpenGL stuff, of course). Both the MemoryImage implementations (TrueColorImage and IndexedImage) have a rgba thing internally so you could blend yourself before drawing (color.d has an alphaBlend function, undocumented though), but if you want it done automatically or in hardware, gotta use the opengl stuff. Which also leads me to, how to draw one image on to another? Gotta DIY there, I haven't written a function for that yet. It's not hard to do though, at least with MemoryImages. The simpledisplay Image is different - it is optimized for the platform so the bits change around (it doesn't have an alpha channel in all cases either). My terminal emulator does this.. here's the function: https://github.com/adamdruppe/terminal-emulator/blob/master/main.d#L296 so basically you copy the bits yourself, using the offset members to handle the platform-specific stuff. I didn't do alpha blending there though... but the blend function from color.d could do it. Doing alpha blending as we draw on the window needs new functions used... AlphaBlend on Windows and XRender on Linux IIRC. But since I tend to use OpenGL when I want to do lots of the blending I haven't been in a big rush to do it.
adamdruppe: Drawing scaled image
I found your git hub and tried simpledisplay and png. I had virtually no problems getting them working from the get go! Thanks for your hard work!!! You deserve a cookie, or a million bucks! I'm curious about how to draw a scaled image. I would like to have a "global" scale for my image drawing. Is there a way to apply a global transform efficiently?(not all image drawing though, just some). Also, png.d doesn't seem to work with alpha channel? I did a quick "alpha" search and simpledisplay.d says it doesn't work with alpha yet, except for openGL. How hard would this be to add? Obviously it requires composting the underlying bits. I will be working on a buffer for all window drawing, one large non-alpha bitmap that I draw everything to, hence it should be somewhat fast to compose. Which also leads me to, how to draw one image on to another? Basically I want to setup a sort of triple buffer(if necessary, or just single) sprite rendering engine(well, not really but it's equivalent to it). Is simple display and png capable of doing this without too much trouble?
Re: Can I get a more in-depth guide about the inline assembler?
On Thursday, 2 June 2016 at 00:52:48 UTC, ZILtoid1991 wrote: On Thursday, 2 June 2016 at 00:51:15 UTC, ZILtoid1991 wrote: I could get the code working with a bug after replacing pmulhuw with pmullw, but due to integer overflow I get a glitched image. I try to get around the fact that pmulhuw stores the high bits of the result either with multiplication or with bit shifting. I forgot to mention that I had to make pointers for the arrays I used in order to be able to load them. I'm not familiar with the MMX instruction set, however glancing at the source again I notice the const registers are (of course) arrays. Those two where you're loading the constants you should probably create/convert the pointers as appropriate, or if they are an Enum value I think they will be dropped in and work fine. (the value being 0x0100_0100_0100_0100 and 0x0001_0001_0001_0001 I believe, based on the short layout). Maybe you already had that solved or the compiler does something I don't know...
Re: Can I get a more in-depth guide about the inline assembler?
On Thursday, 2 June 2016 at 00:51:15 UTC, ZILtoid1991 wrote: On Wednesday, 1 June 2016 at 23:35:40 UTC, Era Scarecrow wrote: On Wednesday, 1 June 2016 at 23:23:49 UTC, ZILtoid1991 wrote: I could get the code working with a bug after replacing pmulhuw with pmullw, but due to integer overflow I get a glitched image. I try to get around the fact that pmulhuw stores the high bits of the result either with multiplication or with bit shifting. I forgot to mention that I had to make pointers for the arrays I used in order to be able to load them.
Re: Quite sure a simple basic problem...
On Thursday, 2 June 2016 at 00:37:58 UTC, WhatMeWorry wrote: I've got a fairly complex D project (25+ modules) that has grown haphazardly over time. So it is not well designed. But I want to get the thing fully ported before refining the code. (that's called refactoring, I believe?) Anyway, there is a new module called audio.d which which has all the sound functionality. And in the (main.d) module is a code snippet like so void main(string[] argv) { // . . . auto blop = new AlurePlaySound("../bleep.wav"); blop.play(); // . . . } So all is well and good except I need to place the sound in another module (game.d) where collisions are detected. I tried: module game; import main; // is this as ugly as I think it is? if (collision[0]) // If collision make sound blop.play(); but this returns: game.d(501): Error: undefined identifier 'blop' So can someone tell me what various solutions to this problem or type of problems? I presume there are quick and dirty solutions (like here) and more elegant solutions? Would this type of problem fall under the domain of "scope". Like in global scope. But I don't think D has such a concept. Thanks. Since blop is being declared inside your main() function, it isn't visible to other modules or functions. You're right that the issue is a problem of "scope". Importing your main module will work, but you must declare your as a global variable outside the main() function. i.e. -- module main; AlurePlaySound blop; void main() { //etc... blop = new AlurePlaySound("../beep.wav"); //etc... } -- module game; import main; void collision() { blop.play(); //or whatever } If your game loop is running in a separate thread, then I think you'll want to use: __gshared AlurePlaySound blop; for the declaration, since variables are thread-local by default. Using global variables is generally frowned upon for production code because you can never be sure which functions are modifying it. But for a quick hack, it works! A better option might be to make a third module with a class containing all your audio objects, initialize it in main(), and then pass it to your main game loop. -Jon
Re: Can I get a more in-depth guide about the inline assembler?
On Wednesday, 1 June 2016 at 23:35:40 UTC, Era Scarecrow wrote: On Wednesday, 1 June 2016 at 23:23:49 UTC, ZILtoid1991 wrote: After some debugging, I found out that the p pointer becomes null at the end instead of pointing to a value. I have no experience with using in-line assemblers (although I made a few Hello World programs for MS-Dos with a stand-alone assembler), so I don't know when and how the compiler will interpret the types from D. In the assembler the variable names actually become just the offset to where they are in the stack in relation to BP. So if you want the full pointer you actually need to convert it into a register first and then just use that register instead. So This should be correct. //unless you are going to actually use ubyte[4] here, just making a pointer will work instead, so cast(uint*) probably ubyte[4] src = *cast(ubyte[4]*)(palette.ptr + 4 * *c); ubyte[4] *p = cast(ubyte[4]*)(workpad + (offsetX + x)*4 + offsetY); asm{//moving the values to their destinations movd ESI, src[EBP]; //get source pointer movd EDI, p[EBP]; //get destination pointer movd MM0,[EDI]; //use directly movd MM1,[ESI]; movqMM5, alpha; movqMM7, alphaMMXmul_const1; movqMM6, alphaMMXmul_const2; movd [EDI], MM4; } I could get the code working with a bug after replacing pmulhuw with pmullw, but due to integer overflow I get a glitched image. I try to get around the fact that pmulhuw stores the high bits of the result either with multiplication or with bit shifting.
Quite sure a simple basic problem...
I've got a fairly complex D project (25+ modules) that has grown haphazardly over time. So it is not well designed. But I want to get the thing fully ported before refining the code. (that's called refactoring, I believe?) Anyway, there is a new module called audio.d which which has all the sound functionality. And in the (main.d) module is a code snippet like so void main(string[] argv) { // . . . auto blop = new AlurePlaySound("../bleep.wav"); blop.play(); // . . . } So all is well and good except I need to place the sound in another module (game.d) where collisions are detected. I tried: module game; import main; // is this as ugly as I think it is? if (collision[0]) // If collision make sound blop.play(); but this returns: game.d(501): Error: undefined identifier 'blop' So can someone tell me what various solutions to this problem or type of problems? I presume there are quick and dirty solutions (like here) and more elegant solutions? Would this type of problem fall under the domain of "scope". Like in global scope. But I don't think D has such a concept. Thanks.
Re: Unittests run without error when done individually, but when unittesting the package some fail
On Wednesday, June 01, 2016 23:58:52 pineapple via Digitalmars-d-learn wrote: > How this could possibly be happening is confounding me and I have > no idea if it's something I missed or some contrived compiler bug. > > This is the package.d that previously I've compiled with unittest > every so often as a way of doing regression testing - > https://github.com/pineapplemachine/mach.d/blob/master/mach/range/package.d > > Currently, when compiled as is, tests in `indexof` and `contains` > (a depending module) fail. If those two are commented out, > everything else passes. If either of those modules is unittested > individually, rather than with the others as part of the package, > everything passes. > > What's going on here? Well, if you haven't already tried it, I'd advise adding some print statements to verify that the tests are actually running in both cases and that something isn't going wrong to cause the failing tests to not be run in the case where they seem to be passing. - Jonathan M Davis
Unittests run without error when done individually, but when unittesting the package some fail
How this could possibly be happening is confounding me and I have no idea if it's something I missed or some contrived compiler bug. This is the package.d that previously I've compiled with unittest every so often as a way of doing regression testing - https://github.com/pineapplemachine/mach.d/blob/master/mach/range/package.d Currently, when compiled as is, tests in `indexof` and `contains` (a depending module) fail. If those two are commented out, everything else passes. If either of those modules is unittested individually, rather than with the others as part of the package, everything passes. What's going on here?
Re: Can I get a more in-depth guide about the inline assembler?
On Wednesday, 1 June 2016 at 23:23:49 UTC, ZILtoid1991 wrote: After some debugging, I found out that the p pointer becomes null at the end instead of pointing to a value. I have no experience with using in-line assemblers (although I made a few Hello World programs for MS-Dos with a stand-alone assembler), so I don't know when and how the compiler will interpret the types from D. In the assembler the variable names actually become just the offset to where they are in the stack in relation to BP. So if you want the full pointer you actually need to convert it into a register first and then just use that register instead. So This should be correct. //unless you are going to actually use ubyte[4] here, just making a pointer will work instead, so cast(uint*) probably ubyte[4] src = *cast(ubyte[4]*)(palette.ptr + 4 * *c); ubyte[4] *p = cast(ubyte[4]*)(workpad + (offsetX + x)*4 + offsetY); asm{//moving the values to their destinations movd ESI, src[EBP]; //get source pointer movd EDI, p[EBP]; //get destination pointer movd MM0,[EDI]; //use directly movd MM1,[ESI]; movqMM5, alpha; movqMM7, alphaMMXmul_const1; movqMM6, alphaMMXmul_const2; movd [EDI], MM4; }
Can I get a more in-depth guide about the inline assembler?
Here's the assembly code for my alpha-blending routine: ubyte[4] src = *cast(ubyte[4]*)(palette.ptr + 4 * *c); ubyte[4] *p = cast(ubyte[4]*)(workpad + (offsetX + x)*4 + offsetY); asm{//moving the values to their destinations movdMM0, p; movdMM1, src; movqMM5, alpha; movqMM7, alphaMMXmul_const1; movqMM6, alphaMMXmul_const2; punpcklbw MM2, MM0; punpcklbw MM3, MM1; paddw MM6, MM5; //1 + alpha psubw MM7, MM5; //256 - alpha pmulhuw MM2, MM6; //src * (1 + alpha) pmulhuw MM3, MM7; //dest * (256 - alpha) paddw MM3, MM2; //(src * (1 + alpha)) + (dest * (256 - alpha)) psrlw MM3, 8; //(src * (1 + alpha)) + (dest * (256 - alpha)) / 256 //moving the result to its place; packuswbMM4, MM3; movdp, MM4; emms; } The two constants being referred here: static immutable ushort[4] alphaMMXmul_const1 = [256,256,256,256]; static immutable ushort[4] alphaMMXmul_const2 = [1,1,1,1]; alpha is a ushort[4] containing the alpha value four times. After some debugging, I found out that the p pointer becomes null at the end instead of pointing to a value. I have no experience with using in-line assemblers (although I made a few Hello World programs for MS-Dos with a stand-alone assembler), so I don't know when and how the compiler will interpret the types from D.
Re: Speed up `dub`.
Hahahaa. Who could possibly think that `build.sh` builds dub in debug mode? With -release -O -inline -m64 it runs 5 times faster : P. It made my day...
Re: Creating a "fixed-range int" with opDispatch and/or alias this?
On Wednesday, 1 June 2016 at 19:59:51 UTC, Mark Isaacson wrote: FWIW, the fixed range int part of this question is just an example, I'm mostly just interested in whether this idea is possible without a lot of bloat/duplication. I suspect not.. Here's how std.typecons.Proxy is doing it: https://github.com/dlang/phobos/blob/master/std/typecons.d#L5109
Re: Using referenceCounters
On Wednesday, 1 June 2016 at 18:14:33 UTC, Begah wrote: I started using reference counters for my assets in my application : - Images - Models - For my resource manager I started out with something similar to what you're describing, but I eventually changed the design which turned out to be an immense improvement so I'll just describe that ^^ - Differentiate between the type implementing a resource, and handles to a resource. - Split up the resource manager, which stores the 'real' resource for a given handle, and the cache where you look up resources by name. A stripped down version of the resource manager looks something like this: template ResourceManager(ResourceType) { struct HandleImpl { ~this() { // Destroy the resource, make sure you mark the corresponding slot in the array as free } size_t slot; } alias Handle = RefCounted!HandleImpl; private ResourceType[] resources; // When creating a resource add it to the manager and pass around the opaque handle instead. Handle add(ResourceType resource) { // Find an empty slot in the resources array, put the resource there, and return a handle pointing to that slot. } // This should be used sparingly. Most code shouldn't care about resource implementation. The parts that do can get at it via this function, but shouldn't hold on to the reference longer than necessary. ResourceType getActualResource(Handle handle) { ... } // This allows you to hot-swap resources while keeping the resource implementation logically const. Hot-swapping is extremely valuable, I've always found myself wanting to support it sooner or later. I've tried to do it in different ways, but it always ended up in a mess. Using handles on the other hand turned out to be clean and easy. void update(Handle handle, ResourceType newResource) { ... } } Note that it doesn't allow you to search for resource by name or anything, this is just a simple mapping between handles and the resource implementation. It doesn't store instances of the RefCounted handles itself, so there are no issues with resources not being cleaned up. Now when you have this in place you can build a caching mechanism on top of it: template ResourceCache(ResourceType, alias loadByName) { alias Manager = ResourceManager!ResourceType; Manager.Handle[string] cache; Manager.Handle get(string name) { // Check if the resource is already in the cache, if not load it using the loadByName function and store it. } void purge() { // the keys property allocates a new array with the AA keys, which is important since we're modifying the AA. foreach(key; cache.keys) { // This is the part you were actually interested in. It's important to take a pointer to the handle here, and not reference it directly. I had some issues with that in the past, I'm not sure if that's still the case. auto ptr = key in cache; if(ptr.refCountedStore.refCount == 1) // If this is the last reference { destroy(*ptr); // I'm not sure if this is still necessary, there was some issue with AAs in the past. It may be fixed today. Destroying the handle doesn't hurt either way so I left it in. cache.remove(key); } } } } So cached resources don't get cleaned automatically if you don't call purge, but that's usually the right thing to do anyways. For example when you're changing scenes (I assume this is for some kind of game?) you can simply destroy the current scene, load another, then purge the cache, without having to reload resources used by both scene 1 and 2. Another upside is that this doesn't require every resource to be named / backed by file. Resources can be dynamically generated at runtime without special casing anywhere.
Creating a "fixed-range int" with opDispatch and/or alias this?
I'm trying to create a type that for all intents and purposes behaves exactly like an int except that it limits its values to be within a certain range [a,b]. Theoretically, I would think this looks something like: struct FixedRangeInt { this(int min, int max, int value=0) { this.min = min; this.max = max; this.value = value; } auto opDispatch(string name, T...)(T args) { auto backup = value; scope (failure) value = backup; auto result = mixin(`value.` ~ name ~ `(args)`); if (value < min || value > max) { throw new Exception("Operation put value out of range"); } return result; } int min; int max; int value; } But that code doesn't work for simple cases, like: FixedRangeInt(0, 100) x; x += 5; It looks like opDispatch doesn't participate in resolution of operator overloads. Is there any way I can achieve my desired result? I know alias this forwards operations like +=, but with alias this I cannot wrap the operation to do the bounds checking. FWIW, the fixed range int part of this question is just an example, I'm mostly just interested in whether this idea is possible without a lot of bloat/duplication.
Re: Is there any overhead iterating over a pointer using a slice?
On Tuesday, 31 May 2016 at 20:52:20 UTC, Johan Engelen wrote: On Tuesday, 31 May 2016 at 18:55:18 UTC, Gary Willoughby wrote: If I have a pointer and iterate over it using a slice, like this: T* foo = &data; foreach (element; foo[0 .. length]) { ... } Is there any overhead compared with pointer arithmetic in a for loop? Use the assembly output of your compiler to check! :-) It's fun to look at. For example, with GDC: http://goo.gl/Ur9Srv No difference. cheers, Johan That's pretty nice.
Re: Calling C++ code with pointer** argument
On Wednesday, 1 June 2016 at 16:16:26 UTC, Kagamin wrote: Can you declare it as const char*const* one the C++ side? Just to state the problem clearly, D's const is transitive, C++ it is not. C linkage doesn't care about const, so you can specify it however you want. In C++ the const is included in the mangling, so it must match the declaration between C++ and D. Transitive meaning that const will apply to all elements pointed to. This is why you see linker complain about not being able to find char const * const *
Re: Using referenceCounters
I can see two option but neither of them is really portable : I can set _store public in std.typecons or i could create a setter method. Neither of these options is portable because i need to directly edit the librarie's source code so i can't jump from one computer to the next without having those changes.
Using referenceCounters
I started using reference counters for my assets in my application : - Images - Models - Such as : alias ModelType = RefCounted!Model; struct Model { static ModelType create(Mesh mesh, Shader shader) { ModelType model = ModelType(); model.mesh = mesh; model.shader = shader; return model; } } I worked fine and compiled, but now i also want to keep a reference of the created models : static ModelType[string] loadedModels; static ModelType load(string modelName) { ModelType model = null; switch(extensions) { case "obj": model = loadObjModel(modelName, shader); break; case "dae": model = loadColladaModel(modelName); break; default: abort(extensions ~ " not supported model file format"); } loadedModels[modelName] = model; // This creates a reference, so i need to get rid of it model.refCountedStore()._store._count--; // Something like that model.modelName = modelName; return model; } So i create load a model, and the reference counter is at one ( normal ). Now i store this model in the associative array but i do not want it to count in the reference count. Unfortunatly _store is private. How can i go about making the reference in the associative array be canceled?
Re: Calling C++ code with pointer** argument
On Wednesday, 1 June 2016 at 07:29:56 UTC, abad wrote: That does work, though I have to explicitly cast it in my caller as well. Like this: doesNotLink(cast(const(char)**)baz2); It's a bit troublesome as my code will include quite a lot of calls like this. Casting is not necessary with the method call with the single pointer argument, as it seems to get const'ed automatically. Can you declare it as const char*const* one the C++ side?
Regex replace followed by number.
So I have ran into an issue where I want to replace a string with regex. but i cant figure out how to replace items followed by a number. i use "$1001" to do paste first match but this thinks I'm trying using match 1001 but if i try ${1}001 it gives me an error saying that it cant match the other "}" perhaps D uses a different syntax but i couldn't find any documentation on the replace side. The following code renames files. arg 1 - path arg 2 - regex match arg 3 - regex replace -- import std.file; import std.path; import std.regex; import std.range; import std.stdio:writeln; void main(string[] args){ bool preview; Regex!char myreg; string replacment; if(!args[1].buildNormalizedPath.isValidPath){writeln("Path is invalid! "); return;} try{myreg = regex(args[2]);} catch(RegexException e) {writeln("Invalid Regex command");return;} try{replacment = args[3];} catch(Exception e) {writeln("Needs replacment string");return;} if(args.length < 5){ preview = true; writeln("result is preview only add extra arg for action"); }else{preview = false;} size_t longest=0; foreach (string name; dirEntries(buildNormalizedPath(args[1].driveName(),args[1].stripDrive()) , SpanMode.shallow)) { if(name.isFile){ longest = (longest>name.baseName.length) ? longest : name.length; } } foreach (string name; dirEntries(buildNormalizedPath(args[1].driveName(),args[1].stripDrive()) , SpanMode.shallow)) { if(name.isFile){ if(preview){ writeln("From:",name.baseName," ".repeat(longest-name.baseName.length).join,"to:",replaceAll(name.baseName, myreg,replacment )); }else{ std.file.rename(name,replaceAll(name, myreg,replacment )); } } } } -
Re: Preferred method of creating objects, structs, and arrays with deterministic memory management
On Wednesday, 1 June 2016 at 08:53:01 UTC, Rene Zwanenburg wrote: I was wondering: what's the preferred method for deterministic memory management? You can annotate your functions as @nogc. The compiler will disallow any potential GC use, including calling other functions that are not @nogc. P0nce is doing real time audio stuff, iirc he's using a thread with a @nogc entry point for the strictly real-time parts, and regular GC-using code in another thread for everything else. Yes, GC is a minor concern for me. I'm happy to use the GC in UI stuff next to the @nogc part. As tired as the expression is, it's a "best of both world" situation. I tried GC.disable(), it was bringing lots of stability problems because not all my code was @nogc and rogue allocations occured. I guess I deserved it? I'm a heavy user of the GC-proof resource class "idiom" which turn your turn the GC into a leak detector: https://p0nce.github.io/d-idioms/#GC-proof-resource-class That way you can make polymorphic resources with relative safety. Exception safety is harder though for class objects. Usually struct should be used. I'd say D has a more complex story for resources, but it's not necessary a bad story. When writing a writeln("hello world"); I don't really want to think about who owns the string "hello world". That's what affine types are about, one size fits all.
Re: D, GTK, Qt, wx,…
How can we build QtE5 and/or the examples? Download qte5.zip from github. Unzip it to qte5-master. If you have Windows 32 then copy qte5-master/windows32/QtE5Widgets32.dll to folder qte5-master. Copy RunTime Qt-5 (all files and folders from qte5-master/windows32/rt_Qt5_windows32.zip) to qte5-master folder. Copy files from qte5-master/examples to qte5-master folder. Make: dmd example1 qte5 Run: example1
Re: Base64 of String without casting
On Wednesday, 1 June 2016 at 09:31:51 UTC, tcak wrote: I understand that Base64 uses Ranges, and since String is seen and used as unicode by Ranges (please tell me if I am wrong). I am guessing, for this reason, auto btoa = std.base64.Base64.encode("Blah"); doesn't work. You need to be casting the string to ubyte[] to make it work which doesn't look and feel nice at all. Can/shall we add another alias into the module for encode method, so it accepts a string, and casts it to ubyte[] by itself? This should do the trick: https://dlang.org/phobos/std_string.html#.representation
Base64 of String without casting
I understand that Base64 uses Ranges, and since String is seen and used as unicode by Ranges (please tell me if I am wrong). I am guessing, for this reason, auto btoa = std.base64.Base64.encode("Blah"); doesn't work. You need to be casting the string to ubyte[] to make it work which doesn't look and feel nice at all. Can/shall we add another alias into the module for encode method, so it accepts a string, and casts it to ubyte[] by itself?
Re: Preferred method of creating objects, structs, and arrays with deterministic memory management
I was wondering: what's the preferred method for deterministic memory management? You may be interested in RefCounted. It only works for structs, not classes, but it's still useful. - Classes/Structs have constructors and destructors. I am unconfident with my knowledge as to how this works with malloc and free. malloc() and free() operate on a lower level, they only care about raw memory. When you malloc() some space, you can construct an object there using emplace(), and it can be destructed by using detroy(). - Many features and types use the GC such as exceptions, the new keyword, and all arrays except statics. It's important to differentiate static arrays, and slices with static storage. For example: class C { static int[] someSlice; // This is a slice with static storage. The memory it is referring to may be GC allocated, but it doesn't have to (this is true for all slices btw). int[4] someStaticArray; // This is a static array, i.e. an array with a fixed length. In D static arrays are value types, so it's allocated in its enclosing scope and copied when you pass it around. } - std.container.array can be used for deterministic arrays, but has the issue of dangling pointers. There is probably a good solution to this, but I don't know it. I don't know of any dangling pointer issues with Array. It's possible to create cycles resulting in a leak, but that's only likely to happen if you heavily rely on refcounting everything. - There seems to be no way to completely turn off the GC. That is, never have the runtime allocate the memory used by the GC. Like Rikki said, if you really want to the GC can be replaced with an asserting stub. This isn't as hard as it sounds, just add something like the file he linked to to your project. Since all declarations are extern(C) there is no name mangling, and the linker will prefer your own definitions over the ones in druntime. I don't recommend you do this though unless you really know what you're doing. This are the pieces I've gathered, but I don't really know what's true or how to use this knowledge. Some ideas I've gleaned may also be outdated. Does anyone know the "correct" way one would go about a non-GC program, and if a program can be ran without ever instantiating a GC? Has there been any progress on reducing the std library's usage of the GC? You can annotate your functions as @nogc. The compiler will disallow any potential GC use, including calling other functions that are not @nogc. P0nce is doing real time audio stuff, iirc he's using a thread with a @nogc entry point for the strictly real-time parts, and regular GC-using code in another thread for everything else.
Re: Preferred method of creating objects, structs, and arrays with deterministic memory management
On Wednesday, 1 June 2016 at 07:59:50 UTC, Anthony Monterrosa wrote: I've recently been trying to convince a friend of mine that D has at least the functionality of C++, and have been learning the language over C++ for a few months. Memory management is pretty important to him, and a subject I'm honestly curious about as well. I was wondering: what's the preferred method for deterministic memory management? [...] You should watch this year's dconf keynote. The plan is to make the GC usage opt-in. There is also the company weka that does high performance storage and turned off the gc entirely and allocates all exception on startup.vstartup. Their CTO gave a really nice talk too. http://dconf.org/2016/talks/zvibel.html If you want to convince your friend, tell him that using the GC is more productive and he still can do manual memory management or use RefCounted if really needed for the performance. That being said also reference counting and other techniques come at a cost. Btw The videos aren't up yet, but the live stream is archived.
Re: Preferred method of creating objects, structs, and arrays with deterministic memory management
On 01/06/2016 7:59 PM, Anthony Monterrosa wrote: I've recently been trying to convince a friend of mine that D has at least the functionality of C++, and have been learning the language over C++ for a few months. Memory management is pretty important to him, and a subject I'm honestly curious about as well. I was wondering: what's the preferred method for deterministic memory management? I don't know much about this topic relative to most (Java background), but this is what I've found: - Classes/Structs have constructors and destructors. I am unconfident with my knowledge as to how this works with malloc and free. They get called once memory has been allocated and before it is deallocated. - core.memory can be used to call malloc and its buddies. It allows determined management, but will still use the GC if something isn't collected (presumably for leaks). No. core.memory provides an interface to the GC, not malloc and friends. - Many features and types use the GC such as exceptions, the new keyword, and all arrays except statics. Not all arrays. Slices are not required to use the GC, just don't go appending to it. - Allocators in "std.experimental.allocators" still use the GC, but give more control for class/struct objects. GCAllocator uses the GC yes. It is the default one for theAllocator() and processAllocator(). However there are others such as Mallocator which do not use the GC but directly call malloc and friends. - std.container.array can be used for deterministic arrays, but has the issue of dangling pointers. There is probably a good solution to this, but I don't know it. - There seems to be no way to completely turn off the GC. That is, never have the runtime allocate the memory used by the GC. Oh but you can! https://github.com/dlang/druntime/blob/master/src/gcstub/gc.d Now imagine replacing all those useful little function implementations with assert(0); Then you can never use the GC! - Andreau had a discussion in 2009 about how this issue might be handled, but there didn't seem to be an obvious consensus (http://forum.dlang.org/thread/hafpjn$1cu8$1...@digitalmars.com?page=1) This are the pieces I've gathered, but I don't really know what's true or how to use this knowledge. Some ideas I've gleaned may also be outdated. Does anyone know the "correct" way one would go about a non-GC program, and if a program can be ran without ever instantiating a GC? Has there been any progress on reducing the std library's usage of the GC? People view the GC as a bad thing. Most of the time it is only ever a good thing. You're not writing a AAA game here and even then you might be able to get away with it by just being a little bit careful and disabling it. If you have some code that needs to be speed up? Sure preallocate memory will always give you speed boosts. But the GC generally won't cause that many problems especially if its disabled for the hot places.
Preferred method of creating objects, structs, and arrays with deterministic memory management
I've recently been trying to convince a friend of mine that D has at least the functionality of C++, and have been learning the language over C++ for a few months. Memory management is pretty important to him, and a subject I'm honestly curious about as well. I was wondering: what's the preferred method for deterministic memory management? I don't know much about this topic relative to most (Java background), but this is what I've found: - Classes/Structs have constructors and destructors. I am unconfident with my knowledge as to how this works with malloc and free. - core.memory can be used to call malloc and its buddies. It allows determined management, but will still use the GC if something isn't collected (presumably for leaks). - Many features and types use the GC such as exceptions, the new keyword, and all arrays except statics. - Allocators in "std.experimental.allocators" still use the GC, but give more control for class/struct objects. - std.container.array can be used for deterministic arrays, but has the issue of dangling pointers. There is probably a good solution to this, but I don't know it. - There seems to be no way to completely turn off the GC. That is, never have the runtime allocate the memory used by the GC. - Andreau had a discussion in 2009 about how this issue might be handled, but there didn't seem to be an obvious consensus (http://forum.dlang.org/thread/hafpjn$1cu8$1...@digitalmars.com?page=1) This are the pieces I've gathered, but I don't really know what's true or how to use this knowledge. Some ideas I've gleaned may also be outdated. Does anyone know the "correct" way one would go about a non-GC program, and if a program can be ran without ever instantiating a GC? Has there been any progress on reducing the std library's usage of the GC?
Re: Calling C++ code with pointer** argument
On Wednesday, 1 June 2016 at 07:17:04 UTC, Mike Parker wrote: On Wednesday, 1 June 2016 at 07:09:16 UTC, abad wrote: Try this: extern(C++) void DoesNotLink(const(char)**); That does work, though I have to explicitly cast it in my caller as well. Like this: doesNotLink(cast(const(char)**)baz2); It's a bit troublesome as my code will include quite a lot of calls like this. Casting is not necessary with the method call with the single pointer argument, as it seems to get const'ed automatically. And I don't know if this was just a typo in your post, but also note that you 'D'oesNotLink in the CPP source you pasted and 'd'oesNotLink in the D code. That was just a typo.
Re: Calling C++ code with pointer** argument
On Wednesday, 1 June 2016 at 07:17:04 UTC, Mike Parker wrote: On Wednesday, 1 June 2016 at 07:09:16 UTC, abad wrote: What's happening? I know there are differences in const behavior between D and C++, but can't figure a way around it. Any sort of casting trick I tried doesn't seem to help. Try this: extern(C++) void DoesNotLink(const(char)**); And I don't know if this was just a typo in your post, but also note that you 'D'oesNotLink in the CPP source you pasted and 'd'oesNotLink in the D code.
Re: Calling C++ code with pointer** argument
On Wednesday, 1 June 2016 at 07:09:16 UTC, abad wrote: D source: extern(C++) void thisWorks(const char* test); extern(C++) void doesNotLink(const char** test); void main() { char* baz1; char** baz2; thisWorks(baz1); doesNotLink(baz2); } CPP source: #include void thisWorks(const char* test) { printf("hi\n"); } void DoesNotLink(const char** test) { // not reached } The error given by the linker: test.d:(.text._Dmain+0x21): undefined reference to `doesNotLink(char const* const*)' What's happening? I know there are differences in const behavior between D and C++, but can't figure a way around it. Any sort of casting trick I tried doesn't seem to help. Try this: extern(C++) void DoesNotLink(const(char)**);
Calling C++ code with pointer** argument
D source: extern(C++) void thisWorks(const char* test); extern(C++) void doesNotLink(const char** test); void main() { char* baz1; char** baz2; thisWorks(baz1); doesNotLink(baz2); } CPP source: #include void thisWorks(const char* test) { printf("hi\n"); } void DoesNotLink(const char** test) { // not reached } The error given by the linker: test.d:(.text._Dmain+0x21): undefined reference to `doesNotLink(char const* const*)' What's happening? I know there are differences in const behavior between D and C++, but can't figure a way around it. Any sort of casting trick I tried doesn't seem to help.