task can't take a class method

helxi brucewayneshit at gmail.com
Mon Nov 19 16:10:15 UTC 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.


More information about the Digitalmars-d-learn mailing list