Re: Why is the following failing?

2024-01-25 Thread Hipreme via Digitalmars-d-learn

On Thursday, 25 January 2024 at 15:20:01 UTC, ryuukk_ wrote:

```D
void main()
{
char[32] id = 0;
const(char)* str = "hello";

id = str[0 .. 6];
}

```


it should be a simple memcpy, why DMD complain?

``onlineapp.d(6): Error: mismatched array lengths 32 and 6 for 
assignment `id[] = str[0..6]```


I'm too tired to notice something obvious?



You need to slice your `id` variable to be the required size. 
You're trying to assign the complete `id` variable to a slice of 
size 6.


i.e: that should be used instead `id[0..6] = str[0..6]`


Re: D is a great language, but I've had a bad experience getting started

2023-12-14 Thread Hipreme via Digitalmars-d-learn

On Thursday, 14 December 2023 at 12:30:35 UTC, Renato wrote:
Hi, I have been trying D for the last few days... I am only 
writing because I really, really like the language! It's 
absolutely stunning how the features it has are simple, well 
designed and at the same time incredibly advanced! All with an 
extremely fast compiler, which is almost unbelievable.





Yeah, D has a really bad experience in MacOS. If you want to use 
it on mac, I suggest using LDC. And the package managers doesn't 
do D justice. You want to get the zip and setup the environment 
variables yourself, this is the best way to make it work.


The "D recommended way" to install is by using the install.sh 
script, found at https://dlang.org/install.html


I personally never used GDC since I develop on Windows 99% of the 
time (the other time is only used on the other platforms when I 
need to develop specific things for them).



The error you're seeing is related to a DC variable. The D 
Compiler variable. I would guess this is a problem caused by your 
package manager when installing D.


I've been developing a game engine which does compiler execution 
for the user because it can get quite hard to understand 
depending on the size of the project.






Re: D: How would one make a shared dynamically linked D library?

2023-11-08 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 8 November 2023 at 11:48:58 UTC, BoQsc wrote:
I would like to export some functionality as external shared 
dynamically linked D library.


Is it possible to do that in D Language and what are 
limitations?


A simple `writeln` example would be great.

What I expect is an executable that uses functions, variables, 
classes, modules from compiled external shared D dynamic 
library.


Example of shared dynamic libraries depending on other shared 
dynamic libraries would be great as well.


For a complete reference, check: 
https://wiki.dlang.org/Win32_DLLs_in_D


Create a dub project.
Set its targetType to `dynamicLibrary`.


Now, create a function:
```d
module dllmodule;

version(Windows)
{
import core.sys.windows.dll;
mixin SimpleDllMain;
}

export extern(C) void helloWorld()
{
import std.stdio;
writeln("DLL: Hello World");
}
```

Now, when you enter `dub`, you'll get a .dll on windows, and a 
.so on linux.

You can use any compiler of your preference.


Now, whenever you need to load this dll, you'll need to call:

```d
module my_app;

extern(C) void function helloWorld();

void main()
{
import core.runtime;
void* dllmodule = Runtime.loadLibrary("dllmodule.dll");
version(Windows)
{
import core.sys.windows.dll;
helloWorld =  
cast(typeof(helloWorld))GetProcAddress(dllmodule, "helloWorld");

}
else version(Posix)
{
import core.sys.posix.dlfcn;
helloWorld = cast(typeof(helloWorld))dlsym(dllmodule, 
"helloWorld");

}
helloWorld();
}
```

With that, there it is.
You also may need to call `core.runtime.rt_init()` if you're not 
calling from D


Re: druntime homebrew: setup and compile a single project with its own stdlib

2023-10-28 Thread Hipreme via Digitalmars-d-learn
On Saturday, 28 October 2023 at 18:37:37 UTC, Dmitry Ponyatov 
wrote:
I want to play with reimplementing some tiny set of standard D 
library, mostly for language learning, and need some advice
- is it possible to use `dub` both for building custom druntime 
and test app?
- or I must write some batch or Makefile and call `dmd` 
compiler directly onto every file?
- what `dmd`/`dub` command line options forces it to drop 
system-wide druntime/phobos and use custom local .so / .a 
library in place of it?



- is it possible to use `dub` both for building custom druntime 
and test app?

Yes, my engine does that

what `dmd`/`dub` command line options forces it to drop  
system-wide druntime/phobos and use custom local .so / .a 
library in place of it?


If you have a module source file with the same name you want to 
replace, the build will prioritize your own version.


Re: How to use ".stringof" to get the value of a variable and not the name of the variable (identifier) itself?

2023-10-10 Thread Hipreme via Digitalmars-d-learn

On Monday, 9 October 2023 at 18:25:15 UTC, rempas wrote:

On Monday, 9 October 2023 at 17:42:48 UTC, Imperatorn wrote:


You could just add your own int to string I guess?


That will be a good idea! I'll do it in the future if that is 
the case, as it's not important, and I want to finish my job. 
Thank you and have a great day!


My engine has its own implementation of toString(long), which 
does not have dependency with the C runtime:


https://github.com/MrcSnm/HipremeEngine/blob/master/modules/util/source/hip/util/conv.d#L180C1-L208C2

I have reimplemented the entire conv module since it is one of 
mostly used module and it pulled down a lot of things, so, with 
my util module I was able to make my program much smaller too.





Re: malloc error when trying to assign the returned pointer to a struct field

2023-09-08 Thread Hipreme via Digitalmars-d-learn

On Friday, 8 September 2023 at 07:59:37 UTC, rempas wrote:

I do have the following struct:

```d
struct Vec(T) {
private:
  T* _ptr = null; // The pointer to the data
  u64 _cap = 0;   // Total amount of elements (not bytes) we 
can store


public:
  /* Create a vector by just allocating memory for it. The null 
terminator is not set for
 strings as, the vector is considered empty and we should  
first push something to it

 in order to use it! */
  this(i64 size) {
this._len = 0;
this._cap = size;

static if (is(T == char)) { size += 1; } // Additional 
space for the null terminator

this._ptr = cast(T*)malloc(size);
  }
}
```

That's some minimal code that I do have just to showcase it. 
So, some times, this work will works, some others, it will give 
me the following error:


`Fatal glibc error: malloc.c:2594 (sysmalloc): assertion 
failed: (old_top == initial_top (av) && old_size == 0) || 
((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) 
&& ((unsigned long) old_end & (pagesize - 1)) == 0)`


The problem seems to happen when the pointer that is returned 
from `malloc` is assigned to the `_ptr` field. If I just assign 
it to a variable and don't assign anything to `_ptr`, it will 
work!


Is there any possible that there is a compiler bug? I do use 
ldc2 and `betterC`!




Hello, not completely unrelated to your problem, I have also done 
something like that, and when you're in D, don't use simply a 
pointer and length like that, use the `slice` operator.


See references:

https://tour.dlang.org/tour/en/basics/slices
https://dlang.org/spec/operatoroverloading.html#array-ops


For example, you can make your pointer a lot safer by doing:

```d
size_t length = 5;
int* pointer = cast(int*)malloc(int.sizeof * length); //Don't
int[] mallocArray = (cast(int*)malloc(int.sizeof * 
length))[0..length]; //Do

```

On the second way, you'll get bound checks, thus, making it 
safer. Also, no need to keep track of your length separately 
anymore.


This is good practice in D language and you'll find yourself 
using this instead in the future.


And yes, this works in betterC, it is a simple runtime check, 
completely `@nogc @safe nothrow` and every other kind of thing 
you would want.


Re: D DLL crashes if not run on the main thread

2023-09-05 Thread Hipreme via Digitalmars-d-learn

On Tuesday, 5 September 2023 at 22:45:28 UTC, raven09 wrote:

Hi,
I've compiled a DLL using D and intended to use it with a C# 
winforms app using P/Invoke. Everything works wonderfully as 
long as it is called from the main thread (at least I assume 
that it not being on the main thread is causing the issues). If 
I start a new thread and try using any function imported from 
the DLL the program will instantly crash. Debugging the 
winforms app with VS shows that it does indeed crash on that 
function call, but does not provide any more information. 
Further testing I did was writing a test DLL that basically 
just contained `` extern(C) export int TestMe() { return 5; }`` 
and calling it in a new C# program: it worked fine until I put 
it in a separate thread.


[...]


Hi, maybe you could try putting your DLL load function inside the 
thread which you're calling your function? Maybe there could be 
something related to that.


Hipreme's Tip of of the day #09 - Using D shared libraries with dub

2023-09-04 Thread Hipreme via Digitalmars-d-learn

Hello again!

--
As of some requests in DConf, I'll post here some things related 
(or not) to dub recipes.
Since there is so many ways to build D and dub is quite the main 
way, I'll try to show other uncommon ways to use it, this is more 
recommended to bigger projects since the standard one is enough 
for most.


I have been involved with some problems while dealing with shared 
libraries. Specifically on Windows and here I am writing how you 
can integrate shared libraries to your project, since it is a 
super powerful tool for plugin development:



For a dub.json configuration, let's first build your shared 
library:


```json
"name": "shared_lib",
"targetType": "dynamicLibrary",
"dflags-ldc": [
  "--link-defaultlib-shared"
]
```


The `--link-defaultlib-shared` here is the secret. It makes the D 
runtime be shared between the main D program and the shared 
library, with that, you'll get cool features such:


- A single GC (don't use more than 1)
- Able to share errors between those runtimes (you can do 
try/catch between them)

- More debug information

If you're using a shared library, you have a dependency and is on 
Windows, you'll need a special flag for avoiding a bug right now, 
this is some example:


```json
"name": "shared_lib",
"targetType": "dynamicLibrary",
"dependencies": {"my_dependency": {"path": "libs/my_dependency"}},
"dflags-ldc": [
  "--link-defaultlib-shared"
],
"lflags-windows-ldc": [
"/WHOLEARCHIVE:my_dependency"
]
```


You can see the new linker flag `/WHOLEARACHIVE` followed by the 
dependency (output name) `my_dependency`. This is required for 
every dependency ~~because linkers are bad~~.


Basically your symbols get stripped out when including a library 
to your shared library and this fixes the problem. As of 2023, a 
solution to that is being researched, but don't let that stop you 
from using shared libraries.





Re: Options for Cross-Platform 3D Game Development

2023-07-06 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 5 July 2023 at 22:27:46 UTC, Andrew wrote:
So, I've gotten the itch to have a go at game development in D, 
after doing a bit of it in Java last year. I've previously used 
LWJGL, which is a java wrapper for OpenGL, OpenAL, GLFW, and 
some other useful libs.


The problem is, apparently OpenGL is deprecated for apple 
devices, so I don't really want to use that unless there are no 
decent alternatives.


So far, the most promising I've seen is 
[bindbc-bgfx](https://code.dlang.org/packages/bindbc-bgfx), but 
it's been a pain to set up due to having to build the bgfx 
codebase, which requires a specific version of glibc that my 
distro (Linux Mint) doesn't offer yet.


Are there any other recommendations for cross-platform 
rendering libraries? Of course I could use a pre-made game 
engine like Unity or Godot, but for me, most of the fun is in 
making the engine.



To be honest, I'm accepting anyone on Hipreme Engine that is 
willing to help adding a shader transpiler or cross compiler. 
Right now I got an abstraction over opengl, direct3d and metal, 
for almost every basic stuff out there, which is really simple. 
Having the shaders being written once is pretty much the next 
step but I can't focus on that.


You'll have a better experience with Hipreme Engine than mostly 
of the options you get here since you'll have a complete cross 
compilation env for you requiring no configuration at all.


Re: Unresolvable dependencies to package

2023-04-14 Thread Hipreme via Digitalmars-d-learn

On Friday, 14 April 2023 at 20:30:56 UTC, el machine code wrote:
so my question why am i'm getting this error and how do i fix 
this?


You need to make those depends on the same version somehow.
From what I've looked. Luna maintains its own fork of 
bindbc-imgui. You're probably taking from another repository i.e: 
Not the one inochi creator uses.


You'll need to clone https://github.com/Inochi2D/bindbc-imgui 
somewhere


Then you'll need to look into your dub.selections.json to point 
"bindbc-imgui" to this folder.


Re: Is it possible to make a library (dll/so) from separated .d files?

2023-04-03 Thread Hipreme via Digitalmars-d-learn

On Monday, 3 April 2023 at 09:08:42 UTC, dog2002 wrote:

Hello. The title sounds weird, but I try to explain it better.

In Unreal Engine and Unity, source code files don't use main() 
and other important functions. They have only a class. Like 
this:


```
class SomeClass: someInterface
{
AFunctionFromTheInterface1()
{

}

AFunctionFromTheInterface2()
{

}
}
```

And then all the source code files will be compiled into a 
single .dll/.so library, so the game engine can use one in a 
game.


I don't know what compiler does Unreal Engine use, but it uses 
C++.


Is it possible to do so in D?



Yes, actually, this is the very same approach I've done for my 
engine, since holding the main function I can take care of boring 
platform details.


For doing that you'll need some way to make your main program 
know about your class. The way I do that is by defining another 
entry function which is always defined enemy you have a game 
project.



You can take a look at 
https://github.com/MrcSnm/HipremeEngine/blob/66618c7783d62107bcaad393d5af5b86c9387b34/api/source/hip/api/package.d#L58



The user uses that engine mixin template, which will add the 
engine entry point to your game script, after that, whenever my 
engine loads the Dll, it will know what function to call and what 
scene it should spawn


Re: My tiny program still can't get FreeImage.dll to load... GLFW.dll library loads no problem...

2023-03-15 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 15 March 2023 at 22:09:35 UTC, WhatMeWorry wrote:
I appreciate all the help people have given me previously. So 
I've made everything super simple.  The dub.sdl file consists 
of four lines:



- Solution to this problem: Checking whether it exists is 
completely irrelevant if you don't pass absolute path to it. 
Plus, the load function checks whether it exists on system32 too. 
For a DLL to be load, it must be beside you .exe file. That 
means: exists() is relative to your working directory, dll load 
is relative to the directory the .exe is.


- Better solution: There's no point into using libfreeimage. In D 
we already have Gamut[1] and [2] arsd:image_files. Both solutions 
is better suited to working with D as they use actual D syntax 
and features to make your code faster and safer, there will be no 
need to have a C compiler nor to pack a DLL together with your 
program.


[1]: https://code.dlang.org/packages/gamut
[2]: https://code.dlang.org/packages/arsd-official%3Aimage_files


Re: const in functions

2023-03-12 Thread Hipreme via Digitalmars-d-learn

On Sunday, 12 March 2023 at 15:09:45 UTC, Salih Dincer wrote:

Hi,

As someone who has used const very little in my life, I want to 
learn and ask: What are consts used in function parameters for; 
isn't there a copy already?





Const is used for you not be able to change your values inside 
references. This is why we have const methods for example:


```d

class Test
{
private int a;
int getA() const {return a;}
}
```

By having this property in your method, it says you're 
guaranteeing that Test won't be changed when this method is 
called, then, it'll be less time trying to find what mutated the 
object, so, use it as much as you can, but never overuse it since 
it is a pain to deal with.


Const for value types is also used for not mutating them inside 
the function also leading to less debugging.


Another use case for them is for compiler being able to infer 
some optimizations. If your variable is `immutable`, it becomes 
implicitly `__gshared`, which does not uses Thread Local Storage, 
another good thing for optimization in both memory and access.


Re: Can nice D code get a bit slow?

2023-03-08 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 8 March 2023 at 10:49:32 UTC, Markus wrote:
Hi, sorry for the broad and vague question. I have read in some 
reddit post about benchmarks, that some code didn't use the 
final keyword on methods in a sense that final would make it 
faster, I believe.


[...]


Don't bother with it. This kind of optimization is done when 
compiling with -O, and I really doubt about your bottleneck being 
that you're calling a virtual call. Wait when you actually need 
to optimize before making your code ugly.


Re: How to build a static lib properly?

2023-03-08 Thread Hipreme via Digitalmars-d-learn

On Monday, 6 March 2023 at 05:59:09 UTC, Mike Parker wrote:

On Monday, 6 March 2023 at 02:09:23 UTC, ryuukk_ wrote:




dub should build a static library for the project i build, 
that includes each library it uses that are referenced as 
"library" since the default is "staticLibrary" according to 
rikki


What you're asking for is a different use case. `staticLibrary` 
is for compiling a specific dub package as a static library. It 
does not imply that all of that package's dependencies should 
also be compiled into a single static library. Nor should it.


You're asking for a package and its dependencies to be bundled 
for use outside of the dub ecosystem as a single static 
library. I won't say it's not a legitimate use case, it's just 
not one that dub currently supports, nor was it originally 
intended to (I wouldn't expect it to be a common one either, 
but then again common expectations are always changing).


As a potential dub enhancement, e.g., `staticLibraryBundle`, I 
do agree it's worth exploring. I don't believe you can expect 
every package to "just work" in that environment. As Steve 
mentioned, there will always be link-time dependencies to any 
shared libraries on which those bundled libraries depend. And 
some packages may be set up in a way that causes issues, as 
Rikki noted when he said he had to make some tweaks on his 
successful build.


But for the time being, dealing with static libraries in D is 
just the same as dealing with them in the C and C++ world. They 
always have been a PITA to deal with, and that's why the trend 
in recent years has been to move away from them. Build tools 
like dub hide them from you when used as intended. It's when 
you mix build systems that you run into trouble.


Still, I suggest you send an email to soc...@dlang.org as part 
of the Gripes and Wishes campaign so that this gets added into 
the dataset. Anything that enhances dub's usability should be 
looked at.



Having a way to define a static library bundle is really great. 
It does help a lot when you create a package where it is 
initialized in non D code.


Right now, this is the third time I'm going to need it for my 
engine, for MacOS I need to manually assign my dependencies, and 
having only the main code as a library doesn't work for that 
purpose. I have done before a simple program which executes dub 
describe for taking the dependencies then I build the program as 
a staticLibrary, problem is that this requires a 2-pass build and 
it is not standard.





Debugging memory leaks

2023-02-15 Thread Hipreme via Digitalmars-d-learn
I want to know if there is some way to debug memory leaks in 
runtime.


I have been dealing with that by using a profiler and checking D 
runtime function calls. Usually those which allocates has high 
cpu usage so it can be easy for those bigger ones. While for the 
smaller ones, this approach doesn't seem to work and looking into 
my task manager I can see it increasing the memory usage very 
slowly.


I wanted to know if there is an option to do that on RUNTIME. 
--vgc is not a good option as I don't care about allocations that 
happens on initialization code.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-02-09 Thread Hipreme via Digitalmars-d-learn
On Thursday, 9 February 2023 at 22:34:29 UTC, ProtectAndHide 
wrote:

On Thursday, 9 February 2023 at 20:05:06 UTC, Ali Çehreli wrote:

On 2/8/23 04:07, zjh wrote:

> Last time, someone proposed to add `private` like `C++'s`,

We've discussed the 'private' topic very many times already. 
C++'s private necessitate the 'friend' keyword, which comes 
with it's own problems.


Besides, D has zero problems with its private implementation 
in the sense that there has been zero bugs related to it being 
that way. Given the number of individuals who bring this topic 
up over and over up is so few that I don't think there is a 
common problem.


Do you have actual bugs related to this? "Wanting" the 
inclusion of a feature is sufficient.


In contrast, I use D every day and love its relaxed attitude 
towards private.


> and then it
> was the same,they are always unwilling to add facilities
useful

That is not correct. The truth is, nobody is jumping to 
implementations just because some people think they are 
useful. There are always valid reasons for including a feature 
or not.


Ali


You mentioned previously that D implements various things in 
unprincipled ways.


I guess, if one wants to use D, one has to be comfortable with 
this.


But using a relaxed attitude towards the implementation of such 
a common and important abstraction, that in turn allows me to 
so easily shoot myself in the foot, is not really an attractive 
feature .. to me ;-)


btw. When a newbie to D raises ideas, suggestions, etc... and 
you counter them with (in essence) 'we don't need that in D, 
but go write a dip if you think we do' attitude, is a real turn 
off.





Most of the time, when people use "private", they are actually 
shooting their users which can't even extend their class. I 
rarely see code which people use "protected" instead and I find 
that pretty lacking. One thing is hiding memory allocation 
details on your class, other thing is hiding a property which 
could and should be controlled when extended in a class.


To be fair I'm more often than not against private variables. 
Most of the time it only caused me headaches because there was a 
lot of unimplemented features and I could not simply fork the 
project. This is not only in D. I got that in Java, Haxe, C#. 
Thankfully those languages has ways to simply ignore the private 
attribute, which can't be done in D.


Anyway, I'm not against static classes and I don't think they 
would bring any inherent problems, they should not cause 
regression and they should be easy to implement as the compiler 
already has the tools for it


Re: A potential use-case for template mixins?

2023-02-06 Thread Hipreme via Digitalmars-d-learn

On Monday, 6 February 2023 at 12:22:19 UTC, Matt wrote:
I am (still) writing a 3D graphics engine, and was considering 
my choices for a scene graph.


Originally, I was going to use classes derived from my base 
SceneNode class for the nodes of the graph, but would this 
instead be a better situation to use template mixins instead of 
potentially having to include a lot of information in the base 
class? Or should I go with the traditional "everything is 
derived from the base class"?


I understand if this is light on details, I'll try and provide 
more if necessary, but I'm really not far into the design 
beyond this, and was wondering which would make for an easier 
path in the future


Use classes. Mixin template are only relevant to types which 
understands the mixin template or when you want to create a 
similar object with similar behavior, but they mustn't be the 
same thing. That means, you need to ducktype everything in order 
to work which could bring a template hell in your code. Unless 
you try to do generics in your code or make it componetized 
rather than inherited, but that could affect your coding style by 
manually passing the node that your object has, this can be quite 
the manual work though.


Re: hasUDA alternatives?

2023-01-28 Thread Hipreme via Digitalmars-d-learn

On Saturday, 28 January 2023 at 16:29:35 UTC, Anonymouse wrote:
I use `hasUDA`, `getUDAs` and `getSymbolsByUDA` fairly heavily 
in my project. dmd requires some 3.2Gb to compile it, a dub 
recompilation taking somewhere around 8-14 seconds, depending 
on the phase of the moon. It's not too bad, admittedly.


Stuff like this, naturally taken out of all context:

```
static if (isSerialisable!member)
{
import std.path : buildNormalizedPath;

static if (hasUDA!(this.tupleof[i], Resource))
{
member = 
buildNormalizedPath(state.settings.resourceDirectory, member);

}
else static if (hasUDA!(this.tupleof[i], Configuration))
{
member = 
buildNormalizedPath(state.settings.configDirectory, member);

}
}
```

```
private alias allEventHandlerFunctionsInModule =
Filter!(isSomeFunction, getSymbolsByUDA!(thisModule, 
IRCEventHandler));

```

```
enum isSetupFun(alias T) = (getUDAs!(T, 
IRCEventHandler)[0]._when == Timing.setup);
enum isEarlyFun(alias T) = (getUDAs!(T, 
IRCEventHandler)[0]._when == Timing.early);
enum isLateFun(alias T) = (getUDAs!(T, 
IRCEventHandler)[0]._when == Timing.late);
enum isCleanupFun(alias T) = (getUDAs!(T, 
IRCEventHandler)[0]._when == Timing.cleanup);
alias hasSpecialTiming = templateOr!(isSetupFun, isEarlyFun, 
isLateFun, isCleanupFun);

alias isNormalEventHandler = templateNot!hasSpecialTiming;

alias setupFuns = Filter!(isSetupFun, 
this.allEventHandlerFunctionsInModule);
alias earlyFuns = Filter!(isEarlyFun, 
this.allEventHandlerFunctionsInModule);
alias lateFuns = Filter!(isLateFun, 
this.allEventHandlerFunctionsInModule);
alias cleanupFuns = Filter!(isCleanupFun, 
this.allEventHandlerFunctionsInModule);
alias pluginFuns = Filter!(isNormalEventHandler, 
this.allEventHandlerFunctionsInModule);

```

If `hasUDA` and friends are so bad[1] [2] [3], what can I use 
instead?


I need them to work at compile-time. `hasUDA` just needs to 
evaluate to true or false, but for `getUDAs` and 
`getSymbolsByUDA` I need them to resolve to symbols (and not 
string names of symbols).


Do I have any alternatives?

[1]: 
https://forum.dlang.org/post/bwekufskjmknllapz...@forum.dlang.org

[2]: https://forum.dlang.org/post/tm02a6$nk3$1...@digitalmars.com
[3]: 
https://forum.dlang.org/post/nzlnwbcezwyopjfia...@forum.dlang.org




So, for that, having an exclude keyword would be nice. But for 
right now, I would like to check a better solution with you. 
Building my entire engine takes in LDC 250mb, in DMD I wasn't 
able to check but it seems to use really little.


From [2], FeepingCreature says that using udaIndex is better than 
using hasUDA and getUDAs.


getUDAs can be simply changed to `__traits(getAttributes, 
yourMemberHere)`.


Many std.traits things actually uses `Filter!()` which is a 
recursive template using `static if` + `AliasSeq`. Recursive 
templates are super heavy. In general, recursive functions always 
spells "slow" in any place.


The best thing to avoid in phobos are those recursive kinds, 
specially if you're using for too many places.


So, what can I do if I wish to construct a better filter? Well. 
Construct an array of indices to your filtered types instead of 
an AliasSeq. It is impossible to construct procedurally an 
AliasSeq without using recursive templates. That way you could 
iterate through those indices instead.


It is a little more manual work, but it is better on long run 
specially when you're not going to keep changing your reflection 
functions any soon



So, avoid Filter which seems to be your main bottleneck there. 
Specially because you will iterate all members many times. It is 
always best to do a single iteration and using the same data.


Your code seems to be analogous to doing:

```d
alias setupFuns = Filter!(isSetupFun, 
this.allEventHandlerFunctionsInModule);
alias earlyFuns = Filter!(isEarlyFun, 
this.allEventHandlerFunctionsInModule);


///Pseudo code expanded representation:


template setupFuns alias pred)
{
alias Filter = AliasSeq!();
static foreach (member; Module)
static if (pred!arg)
Filter = AliasSeq!(Filter, arg);
}
template earlyFuns(alias pred)
{
alias Filter = AliasSeq!();
static foreach (member; Module)
static if (pred!arg)
Filter = AliasSeq!(Filter, arg);
}
```

A better solution would be:

```d

static foreach(mem; __traits(allMembers, thisModule))
{
static if(is(typeof(__traits(getMember, thisModule, mem)) 
== EarlyFunc))
else static if(is(typeof(__traits(getMember, thisModule, 
mem)) == LateFunc))


}
```

That way, you would avoid: Recursive template executed a lot of 
times + you would use reflection once (iterate once vs iterate n 
times).


Re: Hipreme's #8 Tip of the day - Using custom runtime with dub projects

2023-01-22 Thread Hipreme via Digitalmars-d-learn

On Sunday, 22 January 2023 at 17:06:13 UTC, evilrat wrote:

On Sunday, 22 January 2023 at 16:57:56 UTC, Hipreme wrote:


The way to use dub's packages is by using the DFLAGS. With 
DFLAGS, I can set the import path to my own DRuntime and own 
std. That way I can make the dependencies behave more or less 
the same, this is an example of what is being done now:


Keep in mind that you'll probably need to setup some env 
variables such as mine done for making your script a little 
more portable to other developer's PCs. I would really like if 
there was a way to define global dflags on dub though.


Can't you just use env variable[1] and put into dub dflags like 
this?


https://github.com/Superbelko/ohmygentool/blob/cc75d915a8df8bdc2bba628df305d421151994a1/dub.json#L11


_(note that some of the listed predefines doesn't work in some 
sections though, a bug maybe?)_
[1] 
https://dub.pm/package-format-json.html#environment-variables


Nope. Those DFLAGS environment variable is used to affect 
projects such as my dependencies. For example, my dependency 
needs to be built using my own runtime. The dflags defined in the 
dub.json only affect the current project, not its dependencies


Hipreme's #8 Tip of the day - Using custom runtime with dub projects

2023-01-22 Thread Hipreme via Digitalmars-d-learn
I have been working with WebAssembly for at least 1 entire month 
into getting my entire Game Engine and DRuntime ported to it. As 
I'm almost reaching the point of the new announcement, I come 
here to show how I've done DUB's dependency compatibility with a 
custom runtime.


The way to use dub's packages is by using the DFLAGS. With 
DFLAGS, I can set the import path to my own DRuntime and own std. 
That way I can make the dependencies behave more or less the 
same, this is an example of what is being done now:



```
set DFLAGS=-I=%HIPREME_ENGINE%/modules/d_std/source ^
-I=%HIPREME_ENGINE%/build/wasm/runtime/webassembly/arsd-webassembly ^
-preview=shortenedMethods ^
-L-allow-undefined ^
-fvisibility=hidden ^
-d-version=CarelessAlocation

dub build --build=debug -c wasm  
--arch=wasm32-unknown-unknown-wasm

```


So, when dub tried to build their dependencies, your custom 
runtime overrides D's default ones. In that case I'm overriding 
both D std and D core/** and object.d


Keep in mind that you'll probably need to setup some env 
variables such as mine done for making your script a little more 
portable to other developer's PCs. I would really like if there 
was a way to define global dflags on dub though.


Re: How to write a library

2023-01-21 Thread Hipreme via Digitalmars-d-learn

On Saturday, 21 January 2023 at 22:53:19 UTC, Matt wrote:
I am trying to write a graphics engine for my university 
capstone project, and really wanted to give it a try in D, as 
both a talking point, and because I love the language. I'm 
using dub to build the library, and the demo application 
that'll use it.


However, I've come across a problem. In C/C++, when you build a 
library, you compile and link the source, then provide the 
header files for the library user to include. I have built the 
library, but what is the D equivalent to header files, and what 
do I have to do to prepare and use my library in another 
project?


For using your thing as a library you need to do 2 things:

1: Include the library files by using `importPaths` on dub or -I= 
on your favorite compiler

2: Add the linker flag to include the library.


importPaths don't compile your source files. Only templates and 
some ctfe features can be used when using importPaths.


Re: Non-ugly ways to implement a 'static' class or namespace?

2023-01-20 Thread Hipreme via Digitalmars-d-learn
On Friday, 20 January 2023 at 11:28:23 UTC, thebluepandabear 
wrote:

Hi,

In Java/C# you can create purely static classes.

These are classes whose methods are all static, the classes 
cannot be derived from or instantiated:


```
static class Algo {
void drawLine(Canvas c, Pos from, Pos to) { .. };
}
```




There are 2 solutions for that. One involved doing a private 
implementation:


```d
module drawer.impl;
void drawLine(...)
```

Then, you create another file:

```d
module drawer;
public import Algo = drawer.impl;
```
After that, you can use it as `Algo.drawLine`.


With a single file, you can do:
```d

final class Algo
{
@disable this();
static:
void drawLine(...){}
}
```


Re: How to access private variable of outer class from an inner struct

2023-01-15 Thread Hipreme via Digitalmars-d-learn
On Sunday, 15 January 2023 at 12:44:51 UTC, thebluepandabear 
wrote:


Thanks.

How will the variable `outer` become the reference to the 
current `X` object (if that makes sense?). Does the compiler do 
it automatically?



You'll have to create your struct like `return Y(this)`. It 
basically depends on how you're using the struct




Re: Mixin helper help

2023-01-12 Thread Hipreme via Digitalmars-d-learn

On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:

I'm obviously doing something wrong, but don't quite understand.

```d
mixin template helper() {
  mixin("writeln(12);");
}

struct Foo {
  void opDispatch(string name)() {
import std.stdio;
mixin helper!();
//mixin("writeln(12);");
  }
}

void main() {
  Foo.init.opDispatch!"bar"();
}
```

The compiler emits these errors about the mixin 
("writeln(12);"):

unexpected `(` in declarator
basic type expected, not `12`
found `12` when expecting `)`
no identifier for declarator `writeln(_error_)`
semicolon expected following function declaration
declaration expected, not `)`

Why does the commented code work but the mixin not? Thanks for 
any pointers.


`mixin template` cannot be used like that. The only statement it 
accepts are declaration statements: Look at 
https://dlang.org/spec/module.html#MixinDeclaration


It says it must compile to a valid DeclDef, which means you can't 
put code like that.




Mixin templates are used only for declaring new variables, types 
and functions, it can't simply put call statements like that. You 
could do this by simply calling a function such as:


```d
void helper()
{
writeln(12);
}
```

I think you'll need to comment more on your problem if you wish 
specialized help


Hipreme's #7 Tip of the day - Using the out parameters

2022-12-31 Thread Hipreme via Digitalmars-d-learn
So, after some time using D, I found out that `out` isn't used in 
so many cases, but when used, it can be quite confusing, because 
if you don't read the documentation, it will be unclear that 
something is an `out` parameter, specially if you're reading a 
code that is not yours. Before using `out`, I found myself using 
more the address operator (&), because it made clear that the 
target variable would be initialized, but there is an even better 
and safer way to do that:


So, the best practice when using `out` parameters that I found 
right now and it becomes way clearer and can increase your 
performance if you're in a hot path is by void initializing your 
out variable, e.g:


```d

void initializeFloat(out float f){f = 0.0f;}
void main()
{
float myFloat = void;
initializeFloat(myFloat);
}

```

See that without the `void` initialization, all that rests is the 
function name which is quite readable `initializeFloat` so, 
something should happen to it. But there are cases which your 
naming won't be enough expressive to say that you're using an 
`out` parameter. This situation, void initialization (no 
initialization at all), is both faster and self documenting for 
your code, so, try to remember that feature, it took me some time 
to start using and I just remembered it existed when I was 
dealing with returning float vertices and there was so many that 
it appeared on my profiler.


Re: Idiomatic D using GC as a library writer

2022-12-04 Thread Hipreme via Digitalmars-d-learn

On Sunday, 4 December 2022 at 09:53:41 UTC, vushu wrote:

Dear dlang community.


I am unsure about what idiomatic D is.

Some of the Dconf talks tells people just to use the GC, until 
you can't afford

it.

If there are documents that describes what idiomatic D is then 
I would appreciate it.



So my questions are:


What are your thoughts about using GC as a library writer?


If you wan't to include a library into your project aren't you 
more inclined to use a


library which is gc free?



If that is true, then idiomatic D doesn't apply for library 
writers.


Since to get most exposure as a D library writer you kinda need 
to make it gc free right?




Cheers.



"Until you can't afford", is something really extreme. There is a 
bunch of ways to deal with GC memory, what I would say that can't 
afford is when you're constantly allocating memory and because of 
that, making the program more prone to execute a collection. I 
haven't had any problem with the GC yet. If you think your 
program is slow, pass it on a profiler and you'll know the real 
problem. Don't think too much about that or else you're gonna 
lose a heck lot of productivity and end up creating needlessly 
unsafe code.


If you're still gonna be hard headed against the GC, at least use 
slices when allocating from malloc, makes your code safe, 
readable and less variables to think about. Don't use raw 
pointers unnecessarily, and right now, the only reason pointers 
have been used in my code base was not for allocated memory, but 
for being able to modify a variable from another place when you 
need to store a variable reference. If you're only gonna modify 
it inside the function, use `ref` instead.


Re: Can we ease WASM in D ?

2022-11-23 Thread Hipreme via Digitalmars-d-learn
On Wednesday, 16 November 2022 at 22:51:31 UTC, bioinfornatics 
wrote:

Dear community,

I look some day ago to the D wasm page:
-> https://wiki.dlang.org/Generating_WebAssembly_with_LDC

And since then I ask myself can we at  compile time convert a D 
code to an extern C code for wasm ?


Indeed, if a library/framework  would wrap this to let end user 
write his code in plain D that would be awesome.


So did you think it is possible to do it by using 
metaprogramming, mixin, mixin template, mixin string … ?


Thanks for your ideas



It should not be too hard to do that using mixin templates. The 
concept is the same from my `@ExportD` that I'm using on my 
engine.


What `@ExportD` does is to create a new function based on the 
function target function  [or even classes] which all it does is 
call that (or even attach a GC.root as needed ), and generates 
factory functions for classes or create some `extern(C) export` 
the function.


I have done the same thing also for Lua and Java, don't seem that 
hard to do it with WASM. The only difference is that you will 
need to mixin template yourself (I do it at the end of file), 
then I iterate through the module members containing your `@wasm` 
UDAs, and generate the functions needed.


Remember that you could also use things such as 
`@wasm("myNewFunctionName")` and handle such cases.


But for me, working with D without a D runtime is simply not 
worth. That being said, if we had a working D runtime for WASM I 
would be adapting my engine to support it too.


Re: Can't assign extern(C) function pointer to D variable?

2022-11-22 Thread Hipreme via Digitalmars-d-learn

On Tuesday, 22 November 2022 at 21:11:37 UTC, XavierAP wrote:
I was surprised when it didn't compile, though I immediately 
found it understandable...

Already read through https://dlang.org/spec/interfaceToC.html
and https://wiki.dlang.org/Bind_D_to_C

[...]



You need to create an alias containing your callback type.

```d

alias DCallback = extern(C) void function();
DCallback cb;
cb = yourCFunction;
```


Re: Get the class name without casting the type

2022-11-15 Thread Hipreme via Digitalmars-d-learn
On Tuesday, 15 November 2022 at 11:42:59 UTC, Alexander Zhirov 
wrote:

Is there any way to get the name of class B?

```d
interface A {
string text();
}

class B : A {
override string text() {
return ": It's ok!";
}
}

void main() {
A[] a = cast(A[]) new B[3];
B b = new B();
fill(a, b);
foreach (val ; a) {
writeln(typeof(val).stringof, val.text());
}
}
```

Output:

```sh
A: It's ok!
A: It's ok!
A: It's ok!
```


You can do it as `val.classinfo.name`


Hipreme's #6 Tip of the day - Knowing when and how to use dub's Have_version

2022-11-13 Thread Hipreme via Digitalmars-d-learn
Although I really don't like many things about how dub does, it 
brings many facilities. Imagine the following project structure:


Project A is using library B

Now, imagine that our `module b` has the following code:

```d
module b;

void print(string s){imported!"std.stdio".writeln(s);}

else version(Have_A)
{
void printA(string s){imported!"std.stdio".writeln("Printing 
from A!");}

}
```

Now, using the project A:

```d
module a;

void main()
{
  import b;
  printA("Printing from my project");
}
```

Now, do try to build it.

It compiles! But then you get a linker error! `Unresolved 
external function printA`.
Now, do you understand why this just happened? If you execute 
`dub --verbose` You will be able to understand what just happened:


Build command for B: `dmd b.d -lib`
Build command for A: `-Imodule/b -version=Have_A b.lib a.d`


So: Your function printA does not get included in the process! As 
when the `b.lib` was built, there wasn't any version for doing 
the implementation, but when A imported B, it basically imports B 
as:


```d
void print(string s);
void printA(string s);
```

So, it won't be actually implementing your function, it just 
knows about the symbol existence, so, why should you ever use 
Have_version?


The following code for B would have worked:
```d
module b;
//Same thin above void print(string s)...

version(Have_A)
{
   public import a.print_a_implementation;
}
```

That way `module a.print_a_implementation` and then, you can 
guarantee that your code will be included (if 
print_a_implementation.d exists in your project)!


So, the key way to think about this is by when thinking about 
using `version(Have_LibraryNameHere)`, you will need to think 
about a 2 compiler passes, one for implementing the functions, 
another for including them. If you remember that, you won't do 
the same mistake as me :)


Hipreme's #5 Tip of the day - Avoid raw pointers at all cost

2022-11-11 Thread Hipreme via Digitalmars-d-learn
Attention, C and C++ programmers are more likely to use what I'm 
going to talk about.


If you're a C++ programmer, you're probably thinking about 
shared/unique pointers. But that's not what this is about.


Take the `void*` type. This type can be pretty much anything, 
this is "okay" if you wanted to make your code more generic, but 
there is a much better way to handle that. Look at that code:


```d
import core.stdc.stdlib;
void* myInt = malloc(int.sizeof);
*(cast(int*)myInt) = 500;
writeln(*(cast(int*)myInt));
free(myInt);
```

This is a code that can be common to happen on C, but you can do 
it a lot better. You can actually make your casting a bit saving 
information about its size, you could do it with a struct, but 
you could also do it with one of the D features: slicing:

```d
import core.stdc.stdlib;
void[] myInt = malloc(int.sizeof)[0..int.sizeof);
```
Now, you will have information saved on how much info is 
allocated on your int by doing `myInt.length`. Which means that 
any attempt to assign data to the pointed location, this location 
will be bound checked.



Another thing I strongly recommend is not using malloc. The first 
reason is that it makes your code harder to read, unsafe, 
untraceable and longer.

If you just use instead:

```d
void[] myInt = new void[int.sizeof];
```

Will basically have the same effect of the code before in terms 
of usage, no import, less to write, traceable code (-profile=gc).


Now, if you need to use that just for the sake of generic data 
and no heap allocation is really needed, I must recall on your 
mind the underused `union` and the underused `std.variant` (aka 
Tagged Union). My own way to use union if you don't need the 
tagged union as you already know how your data flow works, this 
is a pattern that I shall do it from now on (specially because 
you won't be casting your data all the way instead of just using 
`cast(Something*)(voidPointerData)`:



This is an example of my generic audio buffer pool for various 
audio APIs

```d
union HipAudioBuffer
{
version(OpenAL)
{
import openal;
ALuint al;
}
version(OpenSLES)
{
import opensles.slinterface;
SLIBuffer* sli;
}
version(XAudio2)
{
import directx.xaudio2;
XAUDIO2_BUFFER* xaudio;
}
}
```

Then, instead of just casting your data from void*, you can just 
access the "cast" itself as a property.





Re: Passing a string by reference

2022-11-08 Thread Hipreme via Digitalmars-d-learn
On Tuesday, 8 November 2022 at 12:30:50 UTC, Alexander Zhirov 
wrote:
Do I understand correctly that in order for me to pass a string 
when creating an object, I must pass it by value? And if I have 
a variable containing a string, can I pass it by reference?


Should I always do constructor overloading for a type and a 
reference to it?
In the case of the variable `c`, a drop occurs. Why? An object 
is not being created on the stack?


```d
import std.stdio : writeln;

class A
{
private string str = "base";

this(ref string str)
{
writeln("type reference string");
this.str = str;
}

this(string str)
{
writeln("type string");
this.str = str;
}

this() {}

void print()
{
writeln(str);
}
}

void main()
{
auto a = new A("Hello, World!"); // this type string
a.print();
string text = "New string";
auto b = new A(text); // this type reference string
b.print();
A c;
c.print();  // segmentation fault! Why not "base"?
}

```



You forgot to assign "c" to anything, I think you meant:
`A c = b;`
Read that segmentation fault as null pointer exception.

Whenever you assign something to `ref type something`, it will 
basically be the same as writing `myVariable = *something;` in C 
code, so, in that case, it won't make any difference.


The `ref` attribute only means that if you change your string 
inside the code that takes by ref, it will reflect when 
returning, such as:

```d
void modifyString(ref string input)
{
   input~= "Now it is modified";
}
string text = "New string";
modifyString(text);
writeln(text); //"New stringNow it is modified"
```



Re: Linking not working properly Windows 11

2022-11-05 Thread Hipreme via Digitalmars-d-learn

On Saturday, 5 November 2022 at 19:19:09 UTC, bauss wrote:

On Saturday, 5 November 2022 at 14:54:52 UTC, Hipreme wrote:

[...]


I have both VS 2019 and 2022, but only 2019 has c++ build tools 
etc. I assume that should be fine?


[...]


You forgot to put \link.exe in the path


Re: Linking not working properly Windows 11

2022-11-05 Thread Hipreme via Digitalmars-d-learn

On Saturday, 5 November 2022 at 14:14:16 UTC, bauss wrote:
On Saturday, 5 November 2022 at 13:42:08 UTC, rikki cattermole 
wrote:
Try ldc, if that works then its just a missing library that 
needs to be linked against regarding MS CRT.


Using LDC doesn't seem to work either, it has similar linking 
problems.


```
lld-link: error: undefined symbol: fileno
referenced by 
druntime-ldc.lib(dmain2.obj):(_d_print_throwable)
referenced by 
phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File4syncMFNeZv)
referenced by 
phobos2-ldc.lib(stdio.obj):(_D3std5stdio4File13windowsHandleMFNdZPv)

referenced 18 more times


lld-link: error: undefined symbol: execv
referenced by 
phobos2-ldc.lib(process.obj):(_D3std7process6execv_FIAyaIAQfZi)


lld-link: error: undefined symbol: execve
referenced by 
phobos2-ldc.lib(process.obj):(_D3std7process7execve_FIAyaIAQfIQeZi)


lld-link: error: undefined symbol: execvp
referenced by 
phobos2-ldc.lib(process.obj):(_D3std7process7execvp_FIAyaIAQfZi)


lld-link: error: undefined symbol: execvpe
referenced by 
phobos2-ldc.lib(process.obj):(_D3std7process8execvpe_FIAyaIAQfIQeZi)


lld-link: error: undefined symbol: tzset
referenced by 
phobos2-ldc.lib(timezone.obj):(_D3std8datetime8timezone9LocalTime9singletonFNeZ12__dgliteral4MFNaNbNiNfZOb)

Error: linking with LLD failed
ldc2 failed with exit code 1.
```

Not sure what to do at this point.


Just posted the other day how to use the MSVC Linker on windows. 
Using LLD is quite complicated in my experience because I was 
getting a lot of undefined symbols from the libcmt.


Check this post: 
https://forum.dlang.org/thread/frixfbbucsbgcrsvm...@forum.dlang.org


Remember that for using the MSVC Linker you will need to have 
visual studio build tools on your PC (or install the visual 
studio with desktop development with C++).

Then you can modify your `sc.ini` and it should work.



Re: Hipreme's #4 Tip of the day - Don't use package.d

2022-11-05 Thread Hipreme via Digitalmars-d-learn

On Saturday, 5 November 2022 at 01:34:04 UTC, ryuukk_ wrote:

On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote:
Package.d is a real problem existing on our currently modules 
design. First is that it means to take the directory name to 
use as a module.


This is a problem for 3 reasons:

1. You won't be able to find your module by the file name. 
This is incredibly common, for instance, in Visual Studio 
Code, when you hit CTRL+P and type the file name, nope, you 
will need to write path/to/folder/package.d, beyond that, when 
you search package.d there will be so many files with the same 
name.


2. As being an exception to how the module system works, this 
has already caused me a few headaches (inexplicable bugs), 
that happens with symbols aliasing, when the time it happened, 
I had no idea on what it could be and I don't even remember 
how I solved, instead, I only knew it was related to package.d.


3. I'm currently having a bug on my API module that every 
duplicated file name, even when located at different 
directories(modules), are generating duplicate symbol. The 
major problem is that this is currently undebuggable, as the 
MSVC Linker does not show the full directory of the 
libraries/object files that caused this clash, not even the 
symbol!


The duplicate symbol currently only happens in MSVC Linker, 
which makes me think if the bug is in the D language or the 
linker itself, as on LLD this does not happen.
So, my current advice is always try making your file names 
unique, this will bring a much better debuggability in your 
project.


i use that feature a lot, just search with the folder name, 
then "package"


https://i.imgur.com/cHb7isl.png

it's also very useful to avoid having all of your code in a 
giant unreadable single file


it's also very useful to avoid using dub.. just an import path 
to the folder and that's it


https://i.imgur.com/Wy6WOXK.png

also very useful when you want to simplify using importc, put 
your c files under the c folder, and the package.d, public 
import the c files, and you can put some helper code in D 
there, very nice to have



I believe that needing to write `package.d` manually is pretty 
useless. Most of the time it means "import everything from this 
directory". The only real usage that helped me is when I needed 
to create a `version(Release) import something.opt; else 
version(Debug) import something.hotload;` basically.


But that does not really require package.d.
Those historic issues that Adam said are the real cause of their 
current design.


Take into account how would you do it in Java. `import 
mypackage.*;` is how it was done, and I haven't never had any 
problem doing this, and this is pretty descriptive.


package.d feels a lot more Haxe's `import.hx`, but it has a main 
difference that import.hx is a REAL special file that changes a 
bit on what happens on your source files. They are automatically 
included in its dir/subdir (think of a per directory object.d).


The problem is that I'm not saying package.d is worthless, but it 
is a pool of bugs in the language that needs a real fix and only 
that post has already showed 4 bugs people have had. (Although I 
still don't like searching files by package.d, it is counter 
intuitive).


Re: Hipreme's #4 Tip of the day - Don't use package.d

2022-11-04 Thread Hipreme via Digitalmars-d-learn

On Friday, 4 November 2022 at 16:21:17 UTC, z wrote:

On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote:

...


What do we use instead?
I won't lie about the fact package.d forced me to workaround 
elusive "bugs" in my usage(1) but what is the alternative if we 
don't want to work around it?


(1)(ime : had cases of package.d requiring compiler specific 
pragmas for LDC, and dub can't find the package's `source` 
files at all if it's a multi file subpackage intended to be 
imported only, i never got it working with `package.d`, only a 
single source file setup `*packagename*.d` would work...)



You can use any name instead. The only difference between an 
ordinary source file and a package.d is the module name. For 
instance, if you're inside the filesystem directory, you can 
change the name to literally anything and import instead. To make 
my engine's names unique I have been using a convention for the 
package.d names as an abbreviation of the directory name plus 
`definitions` or something like that.


Re: Hipreme's #4 Tip of the day - Don't use package.d

2022-11-04 Thread Hipreme via Digitalmars-d-learn

On Friday, 4 November 2022 at 14:11:55 UTC, bauss wrote:

On Friday, 4 November 2022 at 10:57:12 UTC, Hipreme wrote:

...


I disagree completely with being against package.d.

Having used D for like a decade at this point, I've never 
experienced any issues with it.


Most issues seems to be for newcomers and people who aren't 
entirely familiar with how D modules and packages work.


package.d is absolutely essential in some cases.


Literally my linker error disappeared after I changed it to 
another name.
And I can't see how essential package.d is, there's no D 
difference in the code written.


As it being the exception inside our compiler, it is an entire 
pool for bugs to get wild out there.


Hipreme's #4 Tip of the day - Don't use package.d

2022-11-04 Thread Hipreme via Digitalmars-d-learn
Package.d is a real problem existing on our currently modules 
design. First is that it means to take the directory name to use 
as a module.


This is a problem for 3 reasons:

1. You won't be able to find your module by the file name. This 
is incredibly common, for instance, in Visual Studio Code, when 
you hit CTRL+P and type the file name, nope, you will need to 
write path/to/folder/package.d, beyond that, when you search 
package.d there will be so many files with the same name.


2. As being an exception to how the module system works, this has 
already caused me a few headaches (inexplicable bugs), that 
happens with symbols aliasing, when the time it happened, I had 
no idea on what it could be and I don't even remember how I 
solved, instead, I only knew it was related to package.d.


3. I'm currently having a bug on my API module that every 
duplicated file name, even when located at different 
directories(modules), are generating duplicate symbol. The major 
problem is that this is currently undebuggable, as the MSVC 
Linker does not show the full directory of the libraries/object 
files that caused this clash, not even the symbol!


The duplicate symbol currently only happens in MSVC Linker, which 
makes me think if the bug is in the D language or the linker 
itself, as on LLD this does not happen.
So, my current advice is always try making your file names 
unique, this will bring a much better debuggability in your 
project.




Hipreme's #3 Tip of the day - Changing DMD linker on Windows

2022-11-01 Thread Hipreme via Digitalmars-d-learn
The linker used on Windows when installing DMD is pretty much 
decided on how your PC was setup.


- If you had Visual Studio installed on your windows for "Desktop 
Development with C++" before downloading DMD (from the site and 
setup), you will pretty have MSVC Linker as a default.
- If you installed DMD before Visual Studio without that 
extension, your default linker will be LLD linker.


There is 2 ways to change your linker for DMD:

1. Open a Command Prompt and type `set 
LINKCMD=path\to\the\linker`.
2. Open your D windows installation folder (usually 
C:\D\dmd2\windows\bin), and edit `sc.ini`. There will be 
[Environment]. Below [Environment], you just type the same thing 
as above. So basically, for my folder system, I can use both:


**LLD**:
`LINKCMD=C:\D\dmd2\windows\bin\lld-link.exe`
**MSVC**:
`LINKCMD=C:\Program Files\Microsoft Visual 
Studio\2022\Community\VC\Tools\MSVC\14.33.31629\bin\Hostx86\x64\link.exe`


Notice that there is no `""` (string literal), although you can 
find that on other places, that actually causes an error on 
windows.


This can be useful for making your program link faster (lld is 
well known for that). But there are cases that you're going to 
need the MSVC one. Specially today that I was getting the error 
while trying to build with LLD:


Error 0xc7b “Application was unable to start correctly”


This was solved after changing my linker back to MSVC.


Re: Importing modules under DUB on Windows

2022-10-26 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 26 October 2022 at 22:51:53 UTC, DLearner wrote:

On Wednesday, 26 October 2022 at 18:53:58 UTC, Hipreme wrote:

On Wednesday, 26 October 2022 at 18:37:00 UTC, DLearner wrote:
On Wednesday, 26 October 2022 at 16:58:08 UTC, H. S. Teoh 
wrote:
On Wed, Oct 26, 2022 at 04:20:01PM +, DLearner via 
Digitalmars-d-learn wrote:

[...]


Maybe try instead:

"importPaths": [ "C:\\Users\\..." ]

since the error message indicates that it expects an array, 
not a string.



T


Thanks for this.
Following your suggestion, seems that DUB found the module 
(as it got through to the linking step without complaint), 
but then the linker failed to resolve the function name.


However, when I moved the module to the project `'source'` 
directory (and took out the `importPaths` JSON entry), 
everything worked.


But I don't really want to do this - the module is my 
collection of utilities, used in a variety of projects, so 
doesn't really belong within one specific project.


Best regards


The linker failed to resolve because it didn't include the 
symbols you imported.

Think of import a way to the compiler resolve the compilation.
Think of source a way to both the compiler and the linker to 
resolve compilation and linking.


If you give only the import path, you will need a library.

What you actually want is to put your new importPath to the 
JSON array `sourcePaths`


Added `"sourcePaths": [ "C\\Users\\..." ]`
Unfortunately failed with 
`core.exception.AssertError@source\dub\internal\vibecompat\inet\path.d(222): Trying to append absolute path.`


I tried to construct a relative path to the module directory 
from the project directory, that didn't work either.


Okay. So this error is very strange, the other thing I can give 
you advice is:
If your other thing is another dub project, you can add it as a 
dependency by putting in your dub.json


```json
"dependencies" : {
   "your_project_name" : {"path" : "your/path/here"}
}
```

AFAIK, there is no problem in putting an absolute path 
dependency, in fact, I'm using things from another drive letter.


Re: Importing modules under DUB on Windows

2022-10-26 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 26 October 2022 at 18:37:00 UTC, DLearner wrote:

On Wednesday, 26 October 2022 at 16:58:08 UTC, H. S. Teoh wrote:
On Wed, Oct 26, 2022 at 04:20:01PM +, DLearner via 
Digitalmars-d-learn wrote:

Hi

Never used DUB before.
Wanted to use a function stored in a module outside the main 
source.


Main source has `import ;`

Put a line into the JSON: `"importPaths": "C:\\Users\\..."` 
pointing to the directory holding the module.


`dub run` failed with `Expected JSON array, got string`.


Maybe try instead:

"importPaths": [ "C:\\Users\\..." ]

since the error message indicates that it expects an array, 
not a string.



T


Thanks for this.
Following your suggestion, seems that DUB found the module (as 
it got through to the linking step without complaint), but then 
the linker failed to resolve the function name.


However, when I moved the module to the project `'source'` 
directory (and took out the `importPaths` JSON entry), 
everything worked.


But I don't really want to do this - the module is my 
collection of utilities, used in a variety of projects, so 
doesn't really belong within one specific project.


Best regards


The linker failed to resolve because it didn't include the 
symbols you imported.

Think of import a way to the compiler resolve the compilation.
Think of source a way to both the compiler and the linker to 
resolve compilation and linking.


If you give only the import path, you will need a library.

What you actually want is to put your new importPath to the JSON 
array `sourcePaths`





Re: Hipreme's #2 Tip of the day - Reducing .di files dependency

2022-10-26 Thread Hipreme via Digitalmars-d-learn
On Tuesday, 25 October 2022 at 12:29:50 UTC, Andrey Zherikov 
wrote:

On Sunday, 23 October 2022 at 20:12:46 UTC, Hipreme wrote:
This will greatly reduce the number of import and dependencies 
you need if you ever need to distribute a library.


Could you elaborate more on the benefit? Does it reduce 
compilation time for dependency? If so then how much?


The main problem of that is when you actually get an import the 
user does not need to know.
This is especially useful for dub projects, which if you import 
an internal dependency of the project, think of a renderer.


I have the HipremeRenderer which uses OpenGL and DirectX-D. What 
if I show that I'm importing directx-d which is so huge? What if 
I'm just showing my .di files and the library file? The user 
would not be able to use the library without getting directx-d. 
And even worse, if I already guarantee that my renderer is self 
contained, why would I make someone need to import another 
library just to use mine? This is how it helps, the compilation 
times depends on how much code your dependency have, if it was 
std.regex, it could save you 2 to 3 seconds.


Hipreme's #2 Tip of the day - Reducing .di files dependency

2022-10-23 Thread Hipreme via Digitalmars-d-learn
For reducing a D Interface file dependency when generating it 
with the `-H` flag for DMD, you can't import a module on the top 
level.

Take a look at that example:
```d
module a;
import std.stdio;
void printSomething(string a)
{
   writeln(a);
}
```

If you generate the .di interface file while using dmd, it will 
pretty much generate:


```d
module a;
import std.stdio;
void printSomething(string a);
```
Using the import inside the function scope, it will make the work 
easier for dmd:

```d
module a;
void printSomething(string a)
{
import std.stdio;
writeln(a);
}
```

Will actually generate only:
```d
module a;
void printSomething(string a);
```

This will greatly reduce the number of import and dependencies 
you need if you ever need to distribute a library.


Re: [Help Needed] - Debugging compilation time

2022-10-22 Thread Hipreme via Digitalmars-d-learn

On Friday, 21 October 2022 at 18:10:39 UTC, ryuukk_ wrote:

I tried your project:

Linux x64

```
git clone https://github.com/MrcSnm/HipremeEngine.git
cd HipremeEngine
dub build (once to download dependencies if any)
time dub build -f


real0m4.604s
user0m3.686s
sys 0m0.900s
```

4.6 sec for a FULL rebuild doesn't seem that bad

and

```
real0m1.730s
user0m1.480s
sys 0m0.245s

```

after editing one module, not bad at all

As other people say:

LDC for release with optimizations
DMD for development

THat's what i personally do



I'm not using anti virus :c

Seems that Linux really is significantly faster for building , 
1.7secs for a rebuild seems pretty nice for me, though I can't 
say it happens the same on my ground




[Help Needed] - Debugging compilation time

2022-10-21 Thread Hipreme via Digitalmars-d-learn
Hey guys, I have been complaining a lot of time right now from D 
compilation speed at least for my project.


I have:
- Underused CTFE
- Underused Templates
- Avoided importing standard libraries
- Created a multi module projects for better code reuse

Those are all the techniques I have tried to maintain my 
compilation times lower, yet, It still builds slow even when 
using the --combined (which does a single compiler run on dub)


So, doesn't matter if all is imported at once or not, it seems 
the problem seems to be somewhere in my project which I've been 
unable to find. I wanted to show someone who is more experienced 
on the time trace from LDC to check what I've been doing wrong.


This time trace took 9 seconds. DMD takes 7 seconds to build my 
project. Adam has built his entire arsd in 2.5 seconds, while my 
PC is faster and arsd is much bigger than my project, this does 
not make any sense. So I would gladly wish you guys help:


My repository: https://github.com/MrcSnm/HipremeEngine/
My time trace: https://ufile.io/gmvw1wlu (This time trace will be 
in air for 30 days only)


Hipreme's #1 Tip of the day

2022-10-19 Thread Hipreme via Digitalmars-d-learn
Hey guys, I'm going to start making a tip of the day (although 
I'm pretty sure I won't be able to give every day a tip), but 
those things are really interesting to newcomers to know and may 
be obvious to some of the old schoolers there.


Always public import a type that the user (including you) is 
expected to interact with:


Imagine we have a module A that define a tree

```d
module a;
struct Tree(T){}
```

If you create a module b containing a function that returns a 
tree:


```d
module b;
import a;
Tree!string getDirectoryTree(string entry){return null;}
```
This is virtually unusable! One must `public import a: Tree;`

This will make your API a lot easier to interact with, keep in 
mind to always public import some type that is used from another 
dependency like this, but try to not overdo it.


Re: warning LNK4255 - How to solve this warning

2022-10-18 Thread Hipreme via Digitalmars-d-learn

On Tuesday, 18 October 2022 at 19:38:39 UTC, Ali Çehreli wrote:

On 10/18/22 12:26, Hipreme wrote:

> Is there any way to know which files produced this error or
at least the
> symbol names that are clashing? I'm totally helpless about
this error.

There is 'nm' on Posix systems that lists symbols in object 
files (including libraries and programs).


Ali


I have added under lflags :
"/VERBOSE" which activates the verbose mode and "/WX" which 
treats the warnings as errors (because there is just so many 
things on linking step)


I found some functions but nothing of them feels out of the 
ordinary.
Treating this module as sourceLibrary instead of staticLibrary 
doesn't cause this warning though


warning LNK4255 - How to solve this warning

2022-10-18 Thread Hipreme via Digitalmars-d-learn
I get the warning `warning LNK4255: library contain multiple 
objects of the same name; linking object as if no debug info` 
when dealing a project with multiple static libraries.


Is there any way to know which files produced this error or at 
least the symbol names that are clashing? I'm totally helpless 
about this error.


Re: How to check if a class has a specific overload for member x?

2022-07-31 Thread Hipreme via Digitalmars-d-learn

On Sunday, 31 July 2022 at 19:25:51 UTC, Hipreme wrote:
I wish to generate some functions using mixin template and I 
wish to check if the current class already has an specific 
overload with parameters (A, B).


What I'm currently trying is doing `__traits(getOverloads, T, 
"foo")`, and then checking if its type are equal. But it seems 
hackish, and I would like to make something like 
`hasOverload!(Test, "foo", int(int a, int b) const)` or 
something like that.



Seems that is how it should be checked:

```d
enum hasOverload(T, string member, FuncType)()
{
bool ret;
static foreach(overload; __traits(getVirtualMethods, T, 
member))
if(is(typeof(overload) == FuncType) && 
!__traits(isAbstractFunction, overload))

ret = true;
return ret;
}
```


How to check if a class has a specific overload for member x?

2022-07-31 Thread Hipreme via Digitalmars-d-learn
I wish to generate some functions using mixin template and I wish 
to check if the current class already has an specific overload 
with parameters (A, B).


What I'm currently trying is doing `__traits(getOverloads, T, 
"foo")`, and then checking if its type are equal. But it seems 
hackish, and I would like to make something like 
`hasOverload!(Test, "foo", int(int a, int b) const)` or something 
like that.


Iterating over mixin template members

2022-07-28 Thread Hipreme via Digitalmars-d-learn
So, I've came to a situation where I must use mixin template for 
defining members overloads, like:

```d
mixin template OverloadGen()
{
static if(hasMethod!(typeof(this), "add", int, int))
{
float add(float x, float y){return x+y;}
}
static if(hasMethod!(typeof(this), "mul", int, int))
{
float mul(float x, float y){return x*y;}
}
}

```


I know this example is obvious, but I'm using this for a far more 
complex, so I need that to work.


The current way I tried to solve that was using string mixins 
such as:


```d
enum mixOverloadGen()
{
return q{
mixin OverloadGen __ogen__;
static foreach(mem; __traits(allMembers, __ogen__))
{
mixin("alias ",mem," = __ogen__.",mem,";");
}
};
}

class Tester
{
int add(int, int){return 0;}
mixin(mixOverloadGen);
}
```

The problem doing that is that I can have access to `__ogen__`, 
which makes code like that valid: `tester.__ogen__.add`. I can't 
make `private mixin OverloadGen __ogen__`, because I won't be 
able to publicly access my overloads.



And doing `static foreach(mem; mixin OverloadGen)` is also 
invalid, tried with allMembers, so, this is my current solution, 
the other thing I could do is instead of aliasing to the mixin 
members, I could make them private and declare a public function 
inside my string mixin which calls those, which is just wasteful: 
increase compile time, runtime usage and code complexity.


Re: null == "" is true?

2022-07-12 Thread Hipreme via Digitalmars-d-learn

On Tuesday, 12 July 2022 at 16:40:38 UTC, H. S. Teoh wrote:
On Tue, Jul 12, 2022 at 04:27:44PM +, Antonio via 
Digitalmars-d-learn wrote:

It works

```d
void main()
{
   assert(null=="");
}
```

why?


Because an empty string is, by default, represented by an empty 
slice of the null pointer.


Do not rely on this, however; it's possible sometimes to get an 
empty string that isn't null, e.g., if you incrementally shrink 
a slice over a string until it's empty. In that case, .ptr will 
not be null, but the string will still be empty.  Always 
compare strings against "" rather than null, because the latter 
may not do what you think it does sometimes.



T


Yup, always compare the string with "". I have had this kind of 
problem a bunch of times, comparing it with null but it is not 
actually null


How to debug thread code

2022-07-10 Thread Hipreme via Digitalmars-d-learn
I'm stuck in a racing condition right now and I'm unable to run a 
debugger on the code. Usually I was using Visual Studio 2019 for 
debugging my code, but it shows the following message:


"Your app has entered a break state, but there is no code to show 
because all threads were executing external code (typically 
system or framework code)."


I can only access the main thread code which stops on my semaphore


Re: Improve a simple event handler

2022-01-19 Thread Hipreme via Digitalmars-d-learn

On Sunday, 16 January 2022 at 20:01:09 UTC, JN wrote:

On Saturday, 15 January 2022 at 23:15:16 UTC, JN wrote:


Is there some way I could improve this with some D features? 
My main gripes with it are:




Managed to dramatically simplify it to 10 lines of code with 
variadic templates.


```d
import std.stdio;

struct Event(T...)
{
void function(T)[] listeners;

void addListener(void function(T) handler)
{
listeners ~= handler;
}

void emit(T args)
{
foreach (listener; listeners)
{
listener(args);
}
}
}

void onResize(uint newWidth, uint newHeight)
{
writefln("Resized: %d %d", newWidth, newHeight);
}

void main()
{
Event!(uint, uint) windowResizeEvent;
windowResizeEvent.addListener();

windowResizeEvent.emit(1000, 2000);
}
```

I am very happy with this solution.



My advice is to make your listeners return a boolean. This 
boolean is used to basically stop propagating the event. And 
debugging it seems really hard to be honest, so, incrementing it 
a little, I would do:



```d

struct ListenerInfo
{
  string name;
  string file;
  uint line;
  string registeredAt;
}
struct Event(T...)
{
  bool function(T)[] listeners;
  ListenerInfo[] info;
  void addListener(bool function(T) handler, string name, string 
file = __FILE__, uint line = __LINE__, string registeredAt = 
__PRETTY_FUNCTION__)

  {
 listeners~= handler;
 info~= ListenerInfo(name, file, line, registeredAt);
  }

  void emit(T args)
  {
foreach(i, l; listeners)
{
  if(l(args))
  {
writeln(info[i]);
break;
  }
}
  }
}

```

You could even extend this concept further by making it return an 
enum value for actually removing the listener when executed, 
stopping propagation. Or you could have access to the listener 
info inside the arguments too.




Re: Debug symbols from libs not being linked on windows

2022-01-19 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 02:31:31 UTC, Hipreme wrote:
I have separated my project in a bunch of modules to be 
compiled separated. But it seems I have lost my debugging power 
since then. I would like to know if there is any workaround 
beside not using it as a lib.


I'm using it from dub and it is has the debug options on them:
```
"buildOptions": [
"debugMode",
"debugInfo",
"debugInfoC"
],
```

And on every lib too.



I had some errors about "duplicate object file, linking without 
debug info", an error that really should not exist as D works in 
modules. But I have renamed the necessary modules for getting rid 
of that message.


After that, the problem was fixed by doing `dub clean 
--all-packages`, thanks rikki!







Re: Throw stack trace from program kill

2022-01-19 Thread Hipreme via Digitalmars-d-learn

On Sunday, 16 January 2022 at 18:03:53 UTC, Paul Backus wrote:

On Sunday, 16 January 2022 at 15:15:07 UTC, Hipreme wrote:
Is there some way to throw a stack trace when killing the 
program from the CTRL+C from the terminal?


It would help a lot into debugging occasional infinity loops


On POSIX, you can use the `sigaction` function to install a 
signal handler for `SIGINT`, the signal generated by CTRL+C. To 
terminate the program with a stack trace, simply have the 
signal handler `throw` an `Error`.


Here's an example program that demonstrates the technique:

```d
import core.sys.posix.signal;

extern(C) void handleCtrlC(int)
{
throw new Error("Killed by CTRL+C");
}

void main()
{
sigaction_t act = { sa_handler:  };
int errcode = sigaction(SIGINT, , null);

f(); // call some functions
}

void f() { g(); }

void g() { h(); }

void h()
{
while (1) {} // wait for ctrl+c
}

```

Make sure to compile with the `-g` option if you want your 
stack trace to have filenames and line numbers.


```d
import std.stdio;

version(Posix)
{
import core.sys.posix.signal;
extern(C) void handleCtrlC(int)
{
throw new Error("Killed by CTRL+C");
}

bool setupSignal()
{
sigaction_t act = {sa_handler: };
int errCode = sigaction(SIGINT, , null);
return errCode == 0;
}
}
else version(Windows)
{
import core.sys.windows.windef;
import core.sys.windows.wincon;
extern(Windows) BOOL handleCtrlC(DWORD dwType)
{
switch(dwType)
{
case CTRL_C_EVENT:
throw new Error("Killed by CTRL+C");
break;
case CTRL_BREAK_EVENT:
throw new Error("Killed by break");
break;
default:
throw new Error("Killed by unknown event");
break;
}
return TRUE;
}
bool setupSignal()
{
return 
SetConsoleCtrlHandler(cast(PHANDLER_ROUTINE), TRUE) 
== TRUE;

}
}
else{bool setupSignal(){return false;}}

void a(){b();}
void b(){c();}
void c(){for(;;){}}

void main(string[] args)
{
if(!setupSignal)
writeln("Could not setup signal, exiting.");
else
a();
}
```


This is my current solution. The problem is that on Windows, it 
actually has the stack trace:


```
0x76909A63 in CtrlRoutine 
  0x76BD6359 
in BaseThreadInitThunk
   0x76FF7B74 in 
RtlGetAppContainerNamedObjectPath 
0x76FF7B44 in 
RtlGetAppContainerNamedObjectPath

```

If I throw that error on the Ctrl, it actually shows a message 
box:


`The exception unknown software exception (0xe0441) occurred 
in the application at location: ...`


Maybe there is some specific formatting for throwing exceptions 
to Windows recognize it?


Re: Function prototype overloading does not work ?

2022-01-19 Thread Hipreme via Digitalmars-d-learn

On Wednesday, 19 January 2022 at 08:47:27 UTC, Enjoys Math wrote:

```
module expr;

import dots;
import operator;
import equation;
import var;
import var_expr;
import zz_const;

class Expr
{
public:
   void opBinary(string op)(string s) const
   {
  static if (op == "+")
  {
 Expr right = null;

 if (s == ".." || s == "..." || s == "")
 {
right = new Dots();
 }

 if (right !is null)
return new Op("+", [this, right]);
  }
   }

   override string toString() const
   {
  assert(0);
   }

   Expr sub(Expr x, Expr y)
   {
  if (this == x)
 return y;
  return this;
   }

   Expr sub(Expr x, ref Var y)
   {
  return sub(x, new VarExpr(y));
   }

   Expr sub(ref Var x, Expr y)
   {
  return sub(new VarExpr(x), y);
   }

   Expr sub(int x, Expr y)
   {
  return sub(ZZ(x), y);
   }

   Expr sub(Expr x, int y)
   {
  return sub(x, ZZ(y));
   }

   Expr sub(ref Var x, ref Var y)
   {
  return sub(new VarExpr(x), new VarExpr(y));
   }

   Expr sub(ref Var x, int y)
   {
  return sub(new VarExpr(x), ZZ(y));
   }

   Expr sub(int x, ref Var y)
   {
  return sub(ZZ(x), new VarExpr(y));
   }

   override bool opEquals(Object o) {
  return this is o;
   }
}
```
See all the overloads I had to make to sub in order to bypass 
identity assignment for classes.  I.e. Var can't be of type 
Expr.  Anyway, this approach is not working because code 
calling `Expr.sub(int, Var)` is not seeing the definitions.  It 
says no function matching those args, but clearly there are!



Firstly, in my opinion, you should be using `auto ref` which will 
do the same thing as generating by reference and by value 
declarations. Or you could even use `in` as the compiler will 
optimize the call for passing it by reference.


Now, you could have some self contained example for we being able 
to test it




Debug symbols from libs not being linked on windows

2022-01-18 Thread Hipreme via Digitalmars-d-learn
I have separated my project in a bunch of modules to be compiled 
separated. But it seems I have lost my debugging power since 
then. I would like to know if there is any workaround beside not 
using it as a lib.


I'm using it from dub and it is has the debug options on them:
```
"buildOptions": [
"debugMode",
"debugInfo",
"debugInfoC"
],
```

And on every lib too.


Throw stack trace from program kill

2022-01-16 Thread Hipreme via Digitalmars-d-learn
Is there some way to throw a stack trace when killing the program 
from the CTRL+C from the terminal?


It would help a lot into debugging occasional infinity loops


Re: Dynamically binding to D code using extern(D)

2021-09-30 Thread Hipreme via Digitalmars-d-learn
Okay, I do agree with you that I may have exaggerated with 
absolute intuitiveness, but I was talking about that 
intuitiveness for loading a symbol from a shared library.



You're limited to using C's types
- I think I don't understood what you meant with that, if the 
data type is known before head, it is possible to just declare it 
from the other side



On Thursday, 30 September 2021 at 22:30:30 UTC, jfondren wrote:
- you can't use overloading, lazy parameters, default values; 
you can't rely on scope parameters, etc., etc.


- That seems to be pretty much more a problem for dynamically 
loading a function, although default values can be mirrored to in 
D API.



- you can't casually hand over GC-allocated data and expect the 
other side to handle it right, or structs with lifetime 
functions that you expect to be called


- That is another problem that doesn't seem related to the 
external linkage too, handling GC-allocated data with extern(D) 
doesn't stop it from it being garbage collected, I'm fixing that 
kind of error right now again.


separate applications and some form of interprocess 
communication (pipes, unix sockets, TCP sockets) instead of 
function calls.


- I'm pretty interested in how to make that thing work, but I 
think that would change a lot in how I'm designing my code, and 
with that way, it would probably become absolutely data oriented, 
right?


Dynamically binding to D code using extern(D)

2021-09-30 Thread Hipreme via Digitalmars-d-learn
I write this post as both a learning tool, a question and an 
inquiry.


There are just a lot of drawbacks in trying to do function 
exporting while using D.


That interface is absurdly confuse and that is probably why I've 
never seen a project here which made an use of extern(D) while 
using a DLL.


While I'm making my DLL's generation, there are a lot of pitfalls 
that I can feel into.


**Simple Function**

```

module something;
extern(D) export int sum(int a, int b){return a + b;}
```

The correct way to bind to that function would be:

```

module app;
import core.demangle

int function(int a, int b) sum;

void main()
{
sum = cast(typeof(sum))GetProcAddress(someDll, 
mangleFunc!(typeof(sum)("something.sum");

}

```

And that should be it for loading a simple function.

Now, lets make our case a bit more complicated:

**Overloaded function**


```

module something;

extern(D) export int add(int a, int b)
{
return a + b;
}

extern(D) export float add(float a, float b)
{
   return a+b;
}
```


For loading those functions, the correct way would be

```

module app;
import core.demangle;


int function(int a, int b) sumInt;
float function(float a, float b) sumFloat;

int sum(int a, int b){return sumInt(a, b);}
float sum(float a, float b){return sumFloat(a,b);}

void main()
{
sumInt = cast(typeof(sumInt))GetProcAddress(dll, 
mangleFunc!(typeof(sumInt))("something.sum"));
sumFloat = cast(typeof(sumFloat))GetProcAddress(dll, 
mangleFunc!(typeof(sumFloat))("something.sum"));

}
```

Notice how much the overall complexity starts to increase as 
there seems to be no way to put get the overloads and there 
doesn't seem to be any advantage in using extern(D).



**Static Methods**

The only difference from the default functions is that we need to 
pass the class name as a module name.



**Static Methods returning user data**

That is mainly the reason I'm writing that post. It made me 
really wonder if I should really use extern(D).



This section will use 3 files because after all, there is really 
a (consistency?) problem



```
module supertest;
import ultratest;

class SuperTest
{
   extern(D) export static SuperTest getter(){return new 
SuperTest();}
   extern(D) export static UltraTest ultraGetter(){return new 
UltraTest();}


   import core.demangle;

   pragma(msg, 
mangleFunc!(typeof())("supertest.SuperTest.getter"));

   //Prints _D9supertest9SuperTest6getterFZCQBeQx
   pragma(msg, 
mangleFunc!(typeof())("supertest.SuperTest.ultraGetter"));
   //Prints 
_D9supertest9SuperTest11ultraGetterFZC9ultratest9UltraTest


}
```

```
module ultratest;
class UltraTest{}
```

```
module app;
import core.demangle;

void main()
{
   //???

}
```

As you can see at module supertest, the pattern seems to break 
when returning user data
for another module. From my knowledge, I don't know how could I 
get this function, specially because you will need to know: the 
module that you're importing the function + the module that where 
the userdata is defined for getting it.



It seems pretty insane to work with that.


extern(D) advantages:

-

extern(D) disadvantages:

- Code only callable in D(probably no other language as a 
demangler)
- I don't remember seeing any other code before in that post 
doing that, so, no documentation at all
- You will need to call the demangler for binding to a symbol, 
which in my project,  it could make each call to a unique type 
from the demangler costs 15KB
- You will need to know the module which you imported your 
function
- If your function returns userdata from another function, there 
doesn't seem to be any workaround
- Doesn't provide any overloading binding support though the 
language has support to overloading



extern(C) advantages:

- Code callable from any language as it is absolutely intuitive
- Well documented

extern(C) disadvantages:

- You will need to declare your function pointer as extern(C) or 
it will swap the arguments order.




I have not even entered in the case where I tried overloading 
static methods, which I think it would need to declarate aliases 
to the static methods typings for actually generating a mangled 
name.


I want to know if extern(D) is actually meant to not be touched. 
adr said that his use for that was actually when doing



extern(C):
//Funcs defined here


extern(D): //Resets the linkage to the default one


So, there are just too many disadvantages for doing extern(D) for 
binding it to any code, I would like to know where we can get 
more documentation than what I posted here right now (really, 
I've never saw any code binding to an extern(D) code). And I do 
believe that is the main reason why people usually don't use 
dynamic libs in D, it is just inviable as you would need to 
regenerate all the API yourself


Re: 0 cost template instantiation

2021-09-29 Thread Hipreme via Digitalmars-d-learn

On Thursday, 30 September 2021 at 03:21:51 UTC, jfondren wrote:

On Thursday, 30 September 2021 at 03:13:28 UTC, jfondren wrote:

As provided, loadSymbol without the "static if":

965K libhipengine_api.a

with `mixin(loadSymbol("name"))` instead of a template:

749K libhipengine_api.a


The difference goes down to 66K vs. 60K with `dub -brelease 
--compiler=gdc`. ldc's not as slim but still much better than 
dmd, and -brelease is actually much less significant. So dmd's 
the main culprit for the bloat here. huh.


But since you have importPaths-ldc perhaps you weren't using 
dmd to begin with.



Yup. The mixin(loadSymbol("")) seems the best way to do.

I believe that should be the option for loading separated symbols 
while loadSymbols version is the best for loading a lot of 
symbols(IDK how expensive is mixing a lot of functions) as it 
costs 1KB per instantiation.


I'm actually using DMD and LDC, dmd compiles a bit faster, but I 
use ldc for deploying it. Never used GDC.






Re: 0 cost template instantiation

2021-09-29 Thread Hipreme via Digitalmars-d-learn

On Thursday, 30 September 2021 at 02:22:35 UTC, jfondren wrote:

On Thursday, 30 September 2021 at 01:44:57 UTC, jfondren wrote:

On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote:
I have a template function that all it does is given a 
symbol, it loads a dll for its type + its name:


```
void loadSymbol(alias s, string symName = "")()
{
static if(symName == "")
s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr);
else
s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr);
}
```


If symName is always a string literal, then you don't need to 
append a "\0"; string literals always have a trailing NUL 
after them, and they autoconvert to const(char)[] so you don't 
need the .ptr either.


Playing around with this, with a mock-up of your code, doesn't 
change object size at all.


Is the actual source available, that you're seeing this with?


https://github.com/MrcSnm/HipremeEngine/tree/hotload/api

You may try messing at the module api.graphics.g2d.renderer2d

There is a function called initG2D

Try changing it from loadSymbols to each one loadSymbol.

You can just dub at the folder api.





Re: 0 cost template instantiation

2021-09-29 Thread Hipreme via Digitalmars-d-learn

On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote:
I have a template function that all it does is given a symbol, 
it loads a dll for its type + its name:


```
void loadSymbol(alias s, string symName = "")()
{
static if(symName == "")
s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr);
else
s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr);
}
```


The main problem is that this function is costing 2KB per 
instantiation, which is something pretty high. Specially if I 
inline, there is almost no cost when compared to its inline 
version. Trying to use pragma(inline, true) didn't do anything 
too.


If I understood correctly, mixin template would be some way to 
actually inline anything. The problem is that I can't have any 
kind of expression inside it, so, that's the only way I could 
think in how to do it.


Optimization seems to don't take care of that behaviour too.

I would like to know which approach could I take for making 
something like C's #define for that.


As this function could be really rewritten as a macro if I were 
coding in C, the cost is too high for a function that would be 
only a syntactic sugar





I could reduce by almost 100kb of code by instead of using the 
former option, I use:


```
void loadSymbols(Ts...)()
{
static foreach(s; Ts)
s = cast(typeof(s))_loadSymbol(_dll, s.stringof);
}
```

Then instead of making a call for each one, I just pass a list of 
templates, this would only create one instantiation per need.


I do still don't think that this should be the answer, as the 
alias problem is not yet  solved. It takes a lot of size for 
functions that could be only syntactic sugar, where C would be a 
lot better





Re: 0 cost template instantiation

2021-09-29 Thread Hipreme via Digitalmars-d-learn

On Thursday, 30 September 2021 at 01:56:42 UTC, Basile B. wrote:

On Thursday, 30 September 2021 at 01:09:47 UTC, Hipreme wrote:
I have a template function that all it does is given a symbol, 
it loads a dll for its type + its name:


```
void loadSymbol(alias s, string symName = "")()
{
static if(symName == "")
s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr);
else
s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr);
}
```


The main problem is that this function is costing 2KB per 
instantiation, which is something pretty high. Specially if I 
inline, there is almost no cost when compared to its inline 
version. Trying to use pragma(inline, true) didn't do anything 
too.


cant you just use a regular functions ? loading happens at 
runtime right ?



The entire reason to having that function is having that syntax 
which would pretty much do the monkey's job for me:


Instead of writing

myFunction = cast(typeof(myFunction))_loadSymbol(_dll, 
"myFunction");


I could write

loadSymbol!myFunction;

But if no other way is found of doing that, I will do the massive 
rewriting.


Anyway, I don't think the problem is not in the way I'm doing, 
but the output, as that template could easily be inlined


0 cost template instantiation

2021-09-29 Thread Hipreme via Digitalmars-d-learn
I have a template function that all it does is given a symbol, it 
loads a dll for its type + its name:


```
void loadSymbol(alias s, string symName = "")()
{
static if(symName == "")
s = cast(typeof(s))_loadSymbol(_dll, (s.stringof~"\0").ptr);
else
s = cast(typeof(s))_loadSymbol(_dll, (symName~"\0").ptr);
}
```


The main problem is that this function is costing 2KB per 
instantiation, which is something pretty high. Specially if I 
inline, there is almost no cost when compared to its inline 
version. Trying to use pragma(inline, true) didn't do anything 
too.


If I understood correctly, mixin template would be some way to 
actually inline anything. The problem is that I can't have any 
kind of expression inside it, so, that's the only way I could 
think in how to do it.


Optimization seems to don't take care of that behaviour too.

I would like to know which approach could I take for making 
something like C's #define for that.


As this function could be really rewritten as a macro if I were 
coding in C, the cost is too high for a function that would be 
only a syntactic sugar


D's dll and classes

2021-09-19 Thread Hipreme via Digitalmars-d-learn

I have a plenty of questions related to the DLL things, .di files.

Basically: I have a main program which would contain a lot of 
code. I have a secondary program which I want to call code from 
the main program, but it will be compiled as a DLL to the main 
program call a single entry point from that DLL.


I have been able to call that secondary okay, the problem is that 
the main is linked into the secondary in order to call the main 
program code. That causes problems related to initialization (as 
only the main should care) and a big binary size. I tried writing 
only .di file for it, but then it would only get undefined 
symbol. What I expected is:




A constains code
A.di contains interfacing code

B uses A.di interfacing code
B is compiled as a DLL


A loads B
A calls B