Abstractioning away main/winMain

2015-09-04 Thread Prudence via Digitalmars-d-learn

Standard and Win32 apps are so old school!

I'd like to hide WinMain by wrapping it in an application 
class(more or less).


Essentially I have an Application class

class Application
{
   public static Application New(void delegate() entry)
   {

   }
}


 Another module

extern (Windows) int WinMain(...)
{


}

 User Module:


const MyApp = Application.New({ std.stdio.writeln("MY APP IS 
COOL"); });



But the lamba runs into a problem because of the static nature of 
the program... much less figuring out how to hook WinMain up into 
it.


Essentially I don't want the user ever to have to know how there 
entry point came into being but there is this funkyness about it 
because Application never gets any control to call the user's 
Entry function. Whats worse is that D tries to evaluate the 
lambda at compile time. It's as if D only allows non-static data 
inside functions.



The idea is to have WinMain actually call the Entry lamba 
function once it gets ran(transfer control)... but this seems to 
be difficult or impossible with D and I'm not sure why or, if 
not, how to get it to work without having to make the user jump 
through hoops.


I suppose I could create the Application(Using New instead of 
new) inside of WinMain, but the issue still remains on how to get 
the user entry point(I suppose some compile time reflection could 
be used?).


Any ideas?

(The main reason for doing this is to make it easier for writing 
portable apps)







Re: Abstractioning away main/winMain

2015-09-04 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 5 September 2015 at 01:43:43 UTC, Prudence wrote:

extern (Windows) int WinMain(...)


If you use WinMain in D, you'll also have to initialize the D 
runtime yourself, which will call static constructors and such.


You'd be better off just using a regular main() function, then 
passing the `-L/SUBSYSTEM:WINDOWS:5.0` option to dmd when 
building (at least on 32 bit, not sure if it is the same on 64 
bit or not) so the linker makes a gui app - same as it does when 
it detects a WinMain in the program.



const MyApp = Application.New({ std.stdio.writeln("MY APP IS 
COOL"); });


Remember, gui apps don't necessarily have a console, so writeln 
may fail!


(The main reason for doing this is to make it easier for 
writing portable apps)



Just using a regular main function is the most portable solution. 
Then just offer helper functions or something to help with the 
boilerplate.


Re: Abstractioning away main/winMain

2015-09-04 Thread Prudence via Digitalmars-d-learn
On Saturday, 5 September 2015 at 01:49:22 UTC, Adam D. Ruppe 
wrote:

On Saturday, 5 September 2015 at 01:43:43 UTC, Prudence wrote:

extern (Windows) int WinMain(...)


If you use WinMain in D, you'll also have to initialize the D 
runtime yourself, which will call static constructors and such.


You'd be better off just using a regular main() function, then 
passing the `-L/SUBSYSTEM:WINDOWS:5.0` option to dmd when 
building (at least on 32 bit, not sure if it is the same on 64 
bit or not) so the linker makes a gui app - same as it does 
when it detects a WinMain in the program.



const MyApp = Application.New({ std.stdio.writeln("MY APP IS 
COOL"); });


Remember, gui apps don't necessarily have a console, so writeln 
may fail!


Maybe, but the error relates to be being called statically.



(The main reason for doing this is to make it easier for 
writing portable apps)



Just using a regular main function is the most portable 
solution. Then just offer helper functions or something to help 
with the boilerplate.


Essentially that is what I'm doing. I have divided the app into 
different types using versioning. The application class is a 
generic wrapper for the main possibilities(win32, Win64, mac, 
linux, etc).


Basically WinMain is used when version is Win32 or Win64 so it is 
not a problem with the stuff you have mentioned. At some point I 
will make it all work but I need to get off the ground first. I 
can always force the user to jump through some hoops but I'd like 
to avoid that as much as possible since I'm the user and I don't 
like hoops.







Re: Abstractioning away main/winMain

2015-09-04 Thread Prudence via Digitalmars-d-learn

If I use functions instead of delegates it works.

I suppose the problem then is that the delegate can't create a 
fat pointer when used in a static context. (i.e., why the 
functions work)


The question is, then, Can I construct a delegate manually and 
supply my own context pointer?


e.g.,
class X { }

void foo() { }

constructDelegate(&foo, new X()) // Creates a void delegate() 
with context X




Re: Abstractioning away main/winMain

2015-09-04 Thread Alex Parrill via Digitalmars-d-learn

On Saturday, 5 September 2015 at 02:29:05 UTC, Prudence wrote:

If I use functions instead of delegates it works.

I suppose the problem then is that the delegate can't create a 
fat pointer when used in a static context. (i.e., why the 
functions work)


The question is, then, Can I construct a delegate manually and 
supply my own context pointer?


e.g.,
class X { }

void foo() { }

constructDelegate(&foo, new X()) // Creates a void delegate() 
with context X


How would the X instance get passed in?

You could try this:

class X {}
void foo(X x) {}

auto x = new X();
auto dg = () => foo(x);



Re: Abstractioning away main/winMain

2015-09-04 Thread anonymous via Digitalmars-d-learn
On Saturday 05 September 2015 03:43, Prudence wrote:

> Standard and Win32 apps are so old school!
> 
> I'd like to hide WinMain by wrapping it in an application
> class(more or less).
> 
> Essentially I have an Application class
> 
> class Application
> {
> public static Application New(void delegate() entry)
> {
> 
> }
> }
> 
> 
>  Another module
> 
> extern (Windows) int WinMain(...)
> {
> 
> 
> }
> 
>  User Module:
> 
> 
> const MyApp = Application.New({ std.stdio.writeln("MY APP IS
> COOL"); });
> 
> 
> But the lamba runs into a problem because of the static nature of
> the program... much less figuring out how to hook WinMain up into
> it.

Please provide self-contained code. Without key details it's hard to 
understand where things are going wrong.

I'm guessing your actual code essentially tries to do this:


class Application
{
void delegate() entry;
public static Application New(void delegate() entry)
{
auto a = new Application;
a.entry = entry;
return a;
}
}

const MyApp = Application.New({import std.stdio; std.stdio.writeln("MY APP 
IS COOL"); });
/* Error: non-constant nested delegate literal expression __lambda6 */

void main() /* or WinMain */
{
MyApp.entry();
}


This doesn't work because delegates and static initialization don't go 
together. You can use a static constructor:


const Application MyApp;
static this()
{
Application.New({import std.stdio; std.stdio.writeln("MY APP IS COOL"); 
});
}


Or you can make `entry` a function instead of a delegate:


class Application
{
void function() entry;
public static Application New(void function() entry)
{
...
}
}


> Essentially I don't want the user ever to have to know how there
> entry point came into being but there is this funkyness about it
> because Application never gets any control to call the user's
> Entry function. Whats worse is that D tries to evaluate the
> lambda at compile time. It's as if D only allows non-static data
> inside functions.
> 
> 
> The idea is to have WinMain actually call the Entry lamba
> function once it gets ran(transfer control)... but this seems to
> be difficult or impossible with D and I'm not sure why or, if
> not, how to get it to work without having to make the user jump
> through hoops.
> 
> I suppose I could create the Application(Using New instead of
> new) inside of WinMain, but the issue still remains on how to get
> the user entry point(I suppose some compile time reflection could
> be used?).
> 
> Any ideas?

I'm probably being naive and the following falls short somehow, but how 
about this:


/* your module */
void function() userMain;

void main() /* or WinMain */
{
/* ... stuff ... */
userMain();
/* ... stuff ... */
}

/* user module: */
/* import your module; */
static this()
{
userMain = {import std.stdio; std.stdio.writeln("MY APP IS COOL"); };
}



Re: Abstractioning away main/winMain

2015-09-04 Thread anonymous via Digitalmars-d-learn
On Saturday 05 September 2015 07:52, anonymous wrote:

> This doesn't work because delegates and static initialization don't go
> together. You can use a static constructor:
> 
> 
> const Application MyApp;
> static this()
> {
> Application.New({import std.stdio; std.stdio.writeln("MY APP IS
> COOL");

Should be: MyApp = Application.New({...});

> });
> }
> 



Re: Abstractioning away main/winMain

2015-09-07 Thread Kagamin via Digitalmars-d-learn

On Saturday, 5 September 2015 at 01:43:43 UTC, Prudence wrote:

Any ideas?


See how vibe does it.