Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-08 Thread cc via Digitalmars-d-learn

Sample output:

Initializing.
User logged on: true
Starting request.
hid: 4838393704146785693
..
Request completed: NumberOfCurrentPlayers_t(1, 5828)
Terminating.


Not present: any indication that the registered callresult was 
executed.


Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-08 Thread cc via Digitalmars-d-learn

On Saturday, 9 June 2018 at 03:07:39 UTC, cc wrote:

I've put together a simplified test program here (124KB):


Here is a pastebin of the D source file updated with some 
additional comments at the end with the callback class 
definitions from the original header files

https://pastebin.com/M8hDXt6L


Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-08 Thread cc via Digitalmars-d-learn

On Friday, 8 June 2018 at 07:32:54 UTC, evilrat wrote:

On Friday, 8 June 2018 at 06:59:51 UTC, cc wrote:

On Friday, 8 June 2018 at 02:52:10 UTC, Mike Parker wrote:

On Friday, 8 June 2018 at 00:55:35 UTC, cc wrote:



class CImpl : CCallbackBase {
extern(C++) {


If anyone has any insight to provide it would be greatly 
appreciated, thanks!


I've not used any of the C++ interfacing features yet, but my 
understanding is the extern(C++) has to apply to the class 
declaration itself, not only the member functions:


extern(C++)
class CImpl : CCallbackBase {

Does that make a difference?


Tried wrapping the CImpl class in extern(C++), no luck.. tried 
final keyword on the methods too.  Thanks though.


Can you upload reduced example somewhere to play with?


I've put together a simplified test program here (124KB):
https://drive.google.com/uc?id=1VPxCcPShlYpGo8BggxniNlPH96iIRG8_=download

The official SDK can be downloaded here (including the 
steam_api.dll if you don't want to use the one in the zip for 
security):

https://partner.steamgames.com/doc/sdk
Although it may require a developer account to download.

Also I should note that Steam differentiates between "callbacks" 
(events that may be fired to the application that registers to 
listen for them at any time or multiple times) and "call results" 
(1:1 asynchronous requests, I believe).  This test so far is 
using call results.




Re: I want delete or change class's member name on compile-time

2018-06-08 Thread Ali Çehreli via Digitalmars-d-learn

On 06/08/2018 11:13 AM, Brian wrote:
> Like:
>
> class A
> {
>  string b;
>  string c;
> }
>
> compile-time to:
>
> class A
> {
>  string _b;
>  string c;
> }
>
> or:
>
> class A
> {
>  string c;
> }
>

If these are your classes you can use static if or version:

version = Z;// Can be provided as a compiler switch as well

class A
{
version (X) {
string b;

} else version (Y) {
string _b;
}

 string c;
}

void main () {
}

Or with static if:

class A {
static if (some_compile_time_condition) {
string _b;

} else static if (...) {
// ...

} else {
// ...

}
}

Ali



Re: I want delete or change class's member name on compile-time

2018-06-08 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/8/18 2:13 PM, Brian wrote:

Like:

class A
{
     string b;
     string c;
}

compile-time to:

class A
{
     string _b;
     string c;
}

or:

class A
{
     string c;
}



Not possible in D. What you are looking for is an AST macro, and D does 
not have those.


However, you can potentially create another type that mimics everything 
that A does except for one thing using compile-time introspection. But 
you won't be able to do that with the member functions.


-Steve


File.put()

2018-06-08 Thread Bastiaan Veelo via Digitalmars-d-learn
Writing a single value to binary file can be done in (at least) 
two ways. Let `f` be a `File`:


```
f.rawWrite(()[0 .. 1]);
```

or

```
f.lockingBinaryWriter.put(value);
```

The former way is little talked about, the latter is not even 
documented. As far as I can see, the latter resolves to the 
former [1] if we disregard locking, mode switching and keeping a 
reference count (on Windows).


Shouldn't there be a `File.put()` method for the case where you 
already know that the file is locked and in the right mode? The 
trick to convert a single value to a range so it can be feeded to 
`rawWrite` may not be obvious to everyone.


Or have I just overlooked the obvious way for writing single 
values?


[1] 
https://github.com/dlang/phobos/blob/v2.080.1/std/stdio.d#L3102




Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, June 08, 2018 03:51:11 David Bennett via Digitalmars-d-learn 
wrote:
> On Thursday, 7 June 2018 at 04:58:40 UTC, Jonathan M Davis wrote:
> > It would be trivial enough to create a wrapper template so that
> > you can do something like
> >
> > immutable n = ctfe!(foo());
> >
> > e.g.
> >
> > template ctfe(alias value)
> > {
> >
> > enum ctfe = value;
> >
> > }
>
> Would this be equivalent to using static immutable?
>
> static immutable n = foo();
>
> In this case both the compiletime and runtime values were
> calculated using cfte.

No, they're not equivalent. That template definition just forces the value
to be calculated at compile time. It doesn't change anything about the
variable itself. Making the variable static means that there is only one
instance of the variable across all calls to the function. So, its address
is not within the stack of the function. Given that the variable is
immutable and thus cannot be changed means that that distinction doesn't
matter a lot in this case, but there's still a difference. And if you make
the variables mutable, it makes a huge difference. e.g

auto n = ctfe!(foo());

vs

static n = foo();

In both cases, the value is calculated at compile time, but in the first
case, you get a unique copy for each function call that does not exist
beyond that function call, whereas in the second case, it's reused for each
function call, so if you mutate it, subsequent calls will see the mutated
value (which would not be true if the variable weren't static).

> Also back to the OP the way I think of enum, static types is like
> this:
>
> alias and enum create compiletime stuff from compiletime stuff.
> static creates runtime stuff from compiletime stuff.
>
> Is that view valid in most cases?

Sort of but not really. enums are just names for compile-time values. As
such, they have to be calculated at compile time. static variables on the
other hand really have nothing to do with compile time per se. It's just
that they have a single location in memory for the entire thread of the
program. So, they get initialized when the thread is created and not when
the function is called and as such have to have their initial value known at
compile time unless a static constructor is used to initialize them. They're
either intialized with the init value for their type or the value that
they're given when declared. The exact same thing happens with member
variables. e.g.

struct S
{
int i = foo();
}

makes it so that S.init.i is whatever value was the result of foo. If the
struct has a constructor, then that's the value of i before the constructor
is called. The init value for the struct must be known at compile time, so
any direct initialization is done at compile time (whereas if none is done,
then the init value for the type of the member variable is used). If the
member variable is const or immutable, then if it's directly initialized,
then it can't be assigned in the constructor, and if it's not directly
initialized, its init value is overwritten by the constructor and isn't
really used. But regardless, the init value must be known at compile time,
which means that any direct initialization must be calculated at compile
time.

So, the fact that static variables get their intial values at compile time
is just because of how they're intialized, not because of static
specifically being designed with compile-time anything in mind. The result
is that you then have a variable whose initial value was determined at
compile time and then can be manipulated at runtime (assuming that it's
mutable), but the key thing about static variables is their lifetime, not
that they're initialized at compile time.

If what you're really looking for is to calculate the value of a local
variable at compile-time, you're better off using an enum and then
initializing the local variable with the enum than using a static variable.
The only reason to use a static variable is if you specifically want a
variable whose lifetime is for the duration of the thread rather than the
duration of the function call. If you're using static just to get the value
calculated at compile time, you're increasing how much memory your thread
takes up when there really isn't a good reason to do so.

- Jonathan M Davis



Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread jmh530 via Digitalmars-d-learn

On Friday, 8 June 2018 at 17:09:54 UTC, H. S. Teoh wrote:


I would, if I had the time to spare to make such a chart.  
Perhaps you (or somebody here) could do it?  It *is* a wiki, 
after all.  Y'all don't have to wait for me to get around to 
it, the edit button is right there.



T


Fair point.


Re: WTF! new in class is static?!?!

2018-06-08 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, June 07, 2018 22:43:50 aliak via Digitalmars-d-learn wrote:
> On Thursday, 7 June 2018 at 21:32:54 UTC, Jonathan M Davis wrote:
> > struct S
> > {
> >
> > int* ptr = new int(42);
> >
> > }
>
> Is that supposed to compile? -> https://run.dlang.io/is/SjUEOu
>
> Error: cannot use non-constant CTFE pointer in an initializer
> &[42][0]

Not necessarily. It's the pointer equivalent of what the OP did with a
mutable class reference, and I was using it for demonstrative purposes. The
mutable class reference case didn't used to compile (it used to have to be
immutable). This example is just the logic of what happens if it's legal
with pointers too. If it hasn't been changed to be legal with pointers like
it has been with classes, then that's arguably a good thing.

- Jonathan M Davis



I want delete or change class's member name on compile-time

2018-06-08 Thread Brian via Digitalmars-d-learn

Like:

class A
{
string b;
string c;
}

compile-time to:

class A
{
string _b;
string c;
}

or:

class A
{
string c;
}



Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 08, 2018 at 02:57:26PM +, jmh530 via Digitalmars-d-learn wrote:
[...]
> May I suggest that you add a flow chart that gives a very high level
> understanding of the compiler steps. Like how Rust's introduction to
> MIR has:
> https://blog.rust-lang.org/2016/04/19/MIR.html

I would, if I had the time to spare to make such a chart.  Perhaps you
(or somebody here) could do it?  It *is* a wiki, after all.  Y'all don't
have to wait for me to get around to it, the edit button is right there.


T

-- 
Give a man a fish, and he eats once. Teach a man to fish, and he will sit 
forever.


Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 08, 2018 at 02:36:01PM +, Gopan via Digitalmars-d-learn wrote:
> On Friday, 8 June 2018 at 05:10:16 UTC, H. S. Teoh wrote:
> > All this talk of CTFE and "compile-time", along with the confusion
> > that arises from conflating everything done by the compiler into the
> > blanket term "compile-time" makes me want to scream:
> > 
> > https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time
> > 
> > 
> 
> 
> Hi Teoh,  Your article is a killer!  A must read for all serious
> users.  Can't we navigate to this article from the DLang site?  (I
> mean, if I don't know the specific url, how can I reach there?)
[...]

The goal is to eventually put this article among the main articles on
the wiki, but there are some loose ends that I need to clean up, and I
just haven't had the time to work on it.

Perhaps I should just invite others here to edit the article, clean it
up, and publish it, instead of letting it linger forever as a userpage.
I just don't have enough spare time right now to do it justice.


T

-- 
What do you call optometrist jokes? Vitreous humor.


allMembers trait does not work correctly for packages during recursion

2018-06-08 Thread Gokhan Yegit via Digitalmars-d-learn
I'm trying to create a template class that can be parameterized 
with a module and will be able to serialize and deserialize (and 
more) all types in that module and submodules that have a 
specific UDA or superclass.


My initial idea was to do a recursive search for types by 
starting from the module parameter and applying allMembers 
recursively to submodules and packages to find all types. There 
is a problem though:


meta/search.d (For searching the classes): 
https://pastebin.com/BHJwnFYB
meta/seq.d (For some AliasSeq operations): 
https://pastebin.com/frq9JLrM

net/test.d (For testing): https://pastebin.com/4XiUBZMb


Here the net.test imports meta.search. If I parameterize 
TransitiveSearchUDA with net.test, it finds struct X and calls 
TransitiveSearchUDA for the package meta, but the allMembers 
trait for that package comes up empty. It does however return the 
members of the meta package somewhat correctly (it does not 
return the search module, only the contents of the search module) 
if I directly call allMembers on it from net.test without 
TransitiveSearchUDA.


What is the problem here? Or is there a better way to perform my 
task?


Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread jmh530 via Digitalmars-d-learn

On Friday, 8 June 2018 at 05:10:16 UTC, H. S. Teoh wrote:
All this talk of CTFE and "compile-time", along with the 
confusion that arises from conflating everything done by the 
compiler into the blanket term "compile-time" makes me want to 
scream:


https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time



;-)

tl;dr: D's "compile-time" features consist of (at least) two 
distinct phases of code transformation: template expansion and 
CTFE, and having a proper understanding of exactly what they 
are and what the distinction between them is, will go a long 
way in clearing up a lot of the confusion commonly experienced 
by newcomers to D in regard to D's so-called "compile-time" 
features.



--T


May I suggest that you add a flow chart that gives a very high 
level understanding of the compiler steps. Like how Rust's 
introduction to MIR has:

https://blog.rust-lang.org/2016/04/19/MIR.html



Re: Confusion/trying to understand CTFE keywords

2018-06-08 Thread Gopan via Digitalmars-d-learn

On Friday, 8 June 2018 at 05:10:16 UTC, H. S. Teoh wrote:
All this talk of CTFE and "compile-time", along with the 
confusion that arises from conflating everything done by the 
compiler into the blanket term "compile-time" makes me want to 
scream:


https://wiki.dlang.org/User:Quickfur/Compile-time_vs._compile-time





Hi Teoh,  Your article is a killer!  A must read for all serious 
users.  Can't we navigate to this article from the DLang site?  
(I mean, if I don't know the specific url, how can I reach there?)


Thanks,
Gopan


Re: how to sort the container Array from std.container

2018-06-08 Thread ag0aep6g via Digitalmars-d-learn

On 06/08/2018 10:52 AM, Flaze07 wrote:
ah...well thank you, well...I did finds another way, but it is probably 
better to use linearRemove

I used
arr = make!( Array!uint )( remove( arr[], 2 );
so linearRemove is probably better


Instead of creating a new array, you could update the length of the 
existing one:


arr.length = remove(arr[], 2).length;

But linearRemove is probably clearer.


Re: how to sort the container Array from std.container

2018-06-08 Thread Flaze07 via Digitalmars-d-learn

On Wednesday, 6 June 2018 at 14:46:56 UTC, ag0aep6g wrote:

On 06/06/2018 04:20 PM, Flaze07 wrote:
hmm, and sorry for asking more, what about removing an element 
from it ? I found no remove operation that can remove from the 
middle ( removeAny and removeBack both removes the latest 
element, linearRemove receive Array!uint...which  don't know 
how to provide )


I think removeKey would be the container primitive for that. I 
don't know if there's a reason why it isn't implemented for 
Array. Maybe it's just an oversight.


You can use linearRemove like this:


import std.container.array: Array;
import std.stdio: writeln;
void main()
{
Array!int a = [1, 2, 100, 200, 300, 3, 4];
a.linearRemove(a[2 .. 5]);
/* Removes elements at indices 2, 3, and 4. */
writeln(a[]); /* Prints "[1, 2, 3, 4]". */
}



ah...well thank you, well...I did finds another way, but it is 
probably better to use linearRemove

I used
arr = make!( Array!uint )( remove( arr[], 2 );
so linearRemove is probably better


Re: Runtime introspection, or how to get class members at runtime Fin D

2018-06-08 Thread evilrat via Digitalmars-d-learn

On Friday, 8 June 2018 at 08:06:27 UTC, Arafel wrote:

On Thursday, 7 June 2018 at 13:07:21 UTC, evilrat wrote:


I don't think so. It clearly states that children must mixin 
too, which can mean it just grabs symbols in scope only, and 
base class has no way of knowing about its subclasses. It also 
has "agressive mode" that will make metadata for all public 
symbols(?) it can walk, this may or may not be helpful 
depending on your requirements.




Yes, that's what I understood from looking at it, but perhaps I 
was just missing something. I wonder though how the "agressive 
mode" would work with separate compilation / dlopen'ed 
libraries. Perhaps I should give it a try and see what happens.


Besides there is no way(not that I am aware of) to make self 
registering stuff happen, you still need to call it somewhere. 
The most transparent option is probably just doing a mixin in 
each module that performs registration of all module symbols 
in module ctor.
The point is that there is absolute requirement to make 
explicit call for that, be it a module ctor mixin, class mixin 
or even user provided registration both at compile time or run 
time.
But since it is MIT licensed you can probably use the code as 
the starting point and adjust to your own needs.




BTW plug-ins is something that is right now possible on 
Linux(not sure about support on other *NIX systems), but in a 
very primitive form on Windows.
This is related to DLL support issues(such as type information 
not being passed across process/DLL boundaries), these issues 
also may include runtime issues as well such as inability to 
delegate the GC, which will mean there will be 2(or more) 
concurrent running GC's. But again I am not aware of the 
current situation.


Well, I'm already tightly coupled to linux, so this is not a 
big concern for me :-)


I'll keep trying, as I said, my intention was to let plugin 
writers do it as easily as possible, but well, adding some kind 
of "register" function might be necessary in the end...


A.


Yep. Like I said probably the easiest to use way is to place 
single call in each module. And there probably no other solution, 
because modules creates sort of isolated graph via imports. And I 
am not aware of any way to get list of modules passed in with 
compiler invocation to perform some sort of centralized one-liner 
registration.


But anyway look at this, might give some tips on how it can be 
done


mixin
https://github.com/Circular-Studios/Dash/blob/b7d589ad4ca8993445c136b6a4ae170932bb7962/source/dash/components/component.d#L208

(note that it uses static this() - module constructor. I think 
this behavior was changed around 2015-2016 and now it will cause 
cyclic dependency errors when modules with ctors import each 
other)


usage
https://github.com/Circular-Studios/Dash/blob/b7d589ad4ca8993445c136b6a4ae170932bb7962/source/dash/components/lights.d#L12



Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-08 Thread realhet via Digitalmars-d-learn

On Friday, 8 June 2018 at 03:08:21 UTC, Mike Franklin wrote:
I recall similar issues with a project I was working on, but I 
don't remember all the details now.  Anyway, I ended up with 
this in the end.


Using main() instead of WinMain() did the trick too. Also it's 
simpler, so I choose this way. But it was also important to learn 
about the SUBSYSTEM and ENTRY linker options.


Thank you all very much!


Re: Runtime introspection, or how to get class members at runtime Fin D

2018-06-08 Thread Arafel via Digitalmars-d-learn

On Thursday, 7 June 2018 at 13:07:21 UTC, evilrat wrote:


I don't think so. It clearly states that children must mixin 
too, which can mean it just grabs symbols in scope only, and 
base class has no way of knowing about its subclasses. It also 
has "agressive mode" that will make metadata for all public 
symbols(?) it can walk, this may or may not be helpful 
depending on your requirements.




Yes, that's what I understood from looking at it, but perhaps I 
was just missing something. I wonder though how the "agressive 
mode" would work with separate compilation / dlopen'ed libraries. 
Perhaps I should give it a try and see what happens.


Besides there is no way(not that I am aware of) to make self 
registering stuff happen, you still need to call it somewhere. 
The most transparent option is probably just doing a mixin in 
each module that performs registration of all module symbols in 
module ctor.
The point is that there is absolute requirement to make 
explicit call for that, be it a module ctor mixin, class mixin 
or even user provided registration both at compile time or run 
time.
But since it is MIT licensed you can probably use the code as 
the starting point and adjust to your own needs.




BTW plug-ins is something that is right now possible on 
Linux(not sure about support on other *NIX systems), but in a 
very primitive form on Windows.
This is related to DLL support issues(such as type information 
not being passed across process/DLL boundaries), these issues 
also may include runtime issues as well such as inability to 
delegate the GC, which will mean there will be 2(or more) 
concurrent running GC's. But again I am not aware of the 
current situation.


Well, I'm already tightly coupled to linux, so this is not a big 
concern for me :-)


I'll keep trying, as I said, my intention was to let plugin 
writers do it as easily as possible, but well, adding some kind 
of "register" function might be necessary in the end...


A.



Re: Using stdin/out in a windows application bugs only when compiled to 64bit.

2018-06-08 Thread realhet via Digitalmars-d-learn

On Friday, 8 June 2018 at 02:44:13 UTC, Mike Parker wrote:

...you can get it with this:

dmd -m64 -L/SUBSYSTEM:console -L/ENTRY:WinMainCRTStartup foo.d


Thank You! It works with LDC -m64 as well.
And now that I repaired my VCRedist2015 the bat file test (my 
second code example) is working too.


Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-08 Thread evilrat via Digitalmars-d-learn

On Friday, 8 June 2018 at 06:59:51 UTC, cc wrote:

On Friday, 8 June 2018 at 02:52:10 UTC, Mike Parker wrote:

On Friday, 8 June 2018 at 00:55:35 UTC, cc wrote:



class CImpl : CCallbackBase {
extern(C++) {


If anyone has any insight to provide it would be greatly 
appreciated, thanks!


I've not used any of the C++ interfacing features yet, but my 
understanding is the extern(C++) has to apply to the class 
declaration itself, not only the member functions:


extern(C++)
class CImpl : CCallbackBase {

Does that make a difference?


Tried wrapping the CImpl class in extern(C++), no luck.. tried 
final keyword on the methods too.  Thanks though.


Can you upload reduced example somewhere to play with?


Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-08 Thread cc via Digitalmars-d-learn

On Friday, 8 June 2018 at 02:52:10 UTC, Mike Parker wrote:

On Friday, 8 June 2018 at 00:55:35 UTC, cc wrote:



class CImpl : CCallbackBase {
extern(C++) {


If anyone has any insight to provide it would be greatly 
appreciated, thanks!


I've not used any of the C++ interfacing features yet, but my 
understanding is the extern(C++) has to apply to the class 
declaration itself, not only the member functions:


extern(C++)
class CImpl : CCallbackBase {

Does that make a difference?


Tried wrapping the CImpl class in extern(C++), no luck.. tried 
final keyword on the methods too.  Thanks though.


Re: Passing C++ class to DLL for callbacks from D (Steam)

2018-06-08 Thread evilrat via Digitalmars-d-learn

On Friday, 8 June 2018 at 00:55:35 UTC, cc wrote:


I've defined it in D, as per 
https://dlang.org/spec/cpp_interface.html#classes :




change this to class, or even abstract class as shown in example


extern(C++) {
interface CCallbackBase {
//this() { m_nCallbackFlags = 0; m_iCallback = 0; }
void Run( void *pvParam );
		void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall );

int GetICallback();
int GetCallbackSizeBytes();

		enum { k_ECallbackFlagsRegistered = 0x01, 
k_ECallbackFlagsGameServer = 0x02 }

//uint8 m_nCallbackFlags;
//int m_iCallback;
//friend class CCallbackMgr;

//CCallbackBase( const CCallbackBase& );
//CCallbackBase& operator=( const CCallbackBase& );
}
}


add extern(C++) to class as well to


class CImpl : CCallbackBase {
extern(C++) {
this() { m_nCallbackFlags = 0; m_iCallback = 0; }
void Run( void *pvParam ) { writeln("Run1"); }
		void Run( void *pvParam, bool bIOFailure, SteamAPICall_t 
hSteamAPICall ) { writeln("Run2"); }

int GetICallback() { return m_iCallback; }
		int GetCallbackSizeBytes() { return 
NumberOfCurrentPlayers_t.sizeof; } // ordinarily use templates 
to determine what type struct ptr to return

}
uint8 m_nCallbackFlags;
int m_iCallback;
}



you also may or may not need to mark non-virtual C++ methods as 
final.


Of course I haven't used D for quite some time so I can be 
mistaken.


But the lesson I learned the hard way is that in D for 
extern(C++) you don't use interface(it simply has no mapping to 
C++ types?), and for defining COM-interfaces use interface or it 
will bite you.

I hope it helps.