Thread overview
task can't take a class method
Nov 19, 2018
helxi
Nov 19, 2018
helxi
Nov 19, 2018
John Chapman
Nov 19, 2018
helxi
November 19, 2018
I want to create a task out of an object's method. My Class is:

public class Calldd
{
private:
    const string tmpFileName = "/tmp/nixwriter.progress.txt";
    string deviceName, sourceFileName;

public:
    this(in string sourceFileName, in string deviceName)
    {
        this.sourceFileName = sourceFileName;
        this.deviceName = deviceName;
    }

    int dd()
    {
        static ddcount = 0;
        ++ddcount;
        scope (success)
            --ddcount;
        if (ddcount > 1)
            return 1;
        // Running dd again should be made impossible by the user from the UI level
        // I'm not making the code any more complicated

        import std.format : format;

        immutable string command = format("pkexec dd if=/%s of=%s bs=4M status=progress 2>%s && sync",
                sourceFileName, deviceName, tmpFileName);

        return executeShell(command).status;
    }

    double parse()
    {
        import std.file : readText, getSize;
        import std.string : splitLines, isNumeric;
        import std.range : front, back, split;
        import std.conv : to;

        try
        {
            if (!(tmpFileName.exists))
                return 0;
            auto text = tmpFileName.readText();
            if (text.splitLines().length == 0)
                return 0;
            if (text.splitLines().back().split().front().isNumeric())
                return text.splitLines().back().split().front()
                    .to!double * 100 / (getSize(sourceFileName));
        }
        catch (Exception e)
        {
            // Sanitize exceptions
        }
        return 0;
    }

    ~this()
    {
        import std.file : exists, remove;

        if (tmpFileName.exists())
            remove(tmpFileName);
    }

}

My call site:

        trigger.addOnClicked(delegate void(Button _) {
            // ...
            auto sourceFileName = fcb.getFilename(),
                deviceName = parseDeviceName(deviceCombo.getActiveText());

            auto ddCall = new Calldd(sourceFileName, deviceName);
            import std.parallelism : task;

            auto proc = task!ddCall.dd(); // <-- compilation failure
            proc.executeInNewThread();

        });


The compiler says:
$ dub build
Performing "debug" build using /usr/bin/dmd for x86_64.
gtk-d:gtkd 3.8.3: target for configuration "library" is up to date.
nixwriter ~master: building configuration "application"...
/usr/include/dlang/dmd/std/parallelism.d(507,34): Error: no property opCall for type backend.Calldd, did you mean new Calldd?
/usr/include/dlang/dmd/std/parallelism.d(835,16): Error: template instance `ui.PrimaryWindow.this.__dgliteral4.Task!(ddCall)` error instantiating
source/ui.d(200,25):        instantiated from here: task!(ddCall)
/usr/bin/dmd failed with exit code 1.

I gather that I have to define an OpCall for this. I thought about calling the constructor inside the OpCall. But the ctor needs two values itself. However the OpCall is being called implicitly(?) somewhere. How can I get around this?
Note that the method dd() itself takes no params.
November 19, 2018
On Monday, 19 November 2018 at 16:10:15 UTC, helxi wrote:
> ...

Oh wait never mind I was missing a bracket:

            auto proc = task!(ddCall.dd());

Now I have another thing to worry about: ddcall.dd() cannot be read at compile time.



November 19, 2018
On Monday, 19 November 2018 at 16:29:01 UTC, helxi wrote:
> On Monday, 19 November 2018 at 16:10:15 UTC, helxi wrote:
>> ...
>
> Oh wait never mind I was missing a bracket:
>
>             auto proc = task!(ddCall.dd());
>
> Now I have another thing to worry about: ddcall.dd() cannot be read at compile time.

You're attempting to execute "dd" at compile time. You should be able to pass the function to a task in a couple of ways:

1) task(&ddCall.dd)
2) task!(ddCall.dd)

November 19, 2018
On Monday, 19 November 2018 at 17:18:14 UTC, John Chapman wrote:
> 1) task(&ddCall.dd)

Thanks, that helped.