pipeProcess not returning immediately
I am running ffplay.exe and my application does not return immediately from pipeProcess. I have to close ffplay for my program to continue execution. pipeProcess is suppose to return immediately/run asynchronously, and it does with ffmpeg or other programs that return. (which I do not know if it is returning immediately or not on those because they execute so quickly) But I have a feeling it is not running asynchronously at all. Any ideas? This is on windows and simply calling pipeProcess directly with a simple "ffplay filename" example. ffplay opens up a window showing the spectrogram while the file is playing. After I close it out, my app then does what it is suppose to. This suggests the pipeProcess is not running asynchronously. void ExecuteCommand(T...)(T args) { foreach(t; AliasSeq!T) static assert(is(t == string), typeof(this).stringof~":"~__PRETTY_FUNCTION__~" requires string arguments!"); pipes = pipeProcess([args[0], (AliasSeq!args)[1..$]], Redirect.stdout); } call it like ExecuteCommand("ffplay.exe", "test.wav");
Re: wrapping a C style delegate
On Saturday, 26 August 2017 at 00:27:47 UTC, Ali Çehreli wrote: I think you need a variation of intermediateCallback() below. I passed the address of the delegate as userData but you can construct any context that contains everything that you need (e.g. the address of ms). import std.stdio; // The C struct struct Struct { int i; } // Some C type enum ErrorEnum { zero } // Some C function taking a callback ErrorEnum SomeAPIaddCallback(Struct* s, void function(Struct*, ErrorEnum status, void *userData) callback, void *userData, uint flags) { writeln("SomeAPIaddCallback called for object ", s); writeln("Calling the callback..."); callback(s, ErrorEnum.zero, userData); return ErrorEnum.zero; } // The callback to pass to the C function void intermediateCallback(Struct * s, ErrorEnum status, void *userData) { writeln("intermediateCallback called"); auto cb = cast(void delegate(ErrorEnum)*)userData; (*cb)(status); } // The D wrapper always passes intermediateCallback to the C function struct MyStruct { Struct * s; void addCallback(void delegate(ErrorEnum ee) callback) { SomeAPIaddCallback(s, , , 0); } } void main() { auto s = Struct(42); auto ms = MyStruct(); ms.addCallback((ErrorEnum ee) { writefln("The callback is called with %s for %s", ee, ms.s); }); } Ali I was thinking of something along those lines: but what about the lifetime of the passed delegate (the address of a local variable)? How can I ensure that it won't segfault when callback goes out of scope? I could new it with the GC but a) I'd rather have the wrapper be @nogc and b) i'd have to hold a reference to it or pin it because SomeAPIaddCallback will be in a driver somewhere and wouldn't get scanned by the GC.
Re: wrapping a C style delegate
On 08/25/2017 04:00 PM, Nicholas Wilson wrote: On Friday, 25 August 2017 at 13:49:20 UTC, Kagamin wrote: You're not specific enough. What would be semantics of such wrapper? The C function I'm trying to wrap takes a function pointer which is essentially a delegate, but not quite: ErrorEnum function(Struct* s, void function(Struct*, ErrorEnum status, void *userData) callback, void *userData, uint flags) SomeAPIaddCallback; I want to make it a member function of a wrapping struct so I can call it like MyStruct ms = ... ms.addCallback((ErrorEnum ee) { ... }); instead of SomeAPIaddCallback(ms.s,(Struct*, ErrorEnum status, void *userData) { ... } /*doesn't become a delegate */,null,0); I'm not sure how to do it. I think you need a variation of intermediateCallback() below. I passed the address of the delegate as userData but you can construct any context that contains everything that you need (e.g. the address of ms). import std.stdio; // The C struct struct Struct { int i; } // Some C type enum ErrorEnum { zero } // Some C function taking a callback ErrorEnum SomeAPIaddCallback(Struct* s, void function(Struct*, ErrorEnum status, void *userData) callback, void *userData, uint flags) { writeln("SomeAPIaddCallback called for object ", s); writeln("Calling the callback..."); callback(s, ErrorEnum.zero, userData); return ErrorEnum.zero; } // The callback to pass to the C function void intermediateCallback(Struct * s, ErrorEnum status, void *userData) { writeln("intermediateCallback called"); auto cb = cast(void delegate(ErrorEnum)*)userData; (*cb)(status); } // The D wrapper always passes intermediateCallback to the C function struct MyStruct { Struct * s; void addCallback(void delegate(ErrorEnum ee) callback) { SomeAPIaddCallback(s, , , 0); } } void main() { auto s = Struct(42); auto ms = MyStruct(); ms.addCallback((ErrorEnum ee) { writefln("The callback is called with %s for %s", ee, ms.s); }); } Ali
Re: wrapping a C style delegate
On Friday, 25 August 2017 at 13:49:20 UTC, Kagamin wrote: You're not specific enough. What would be semantics of such wrapper? The C function I'm trying to wrap takes a function pointer which is essentially a delegate, but not quite: ErrorEnum function(Struct* s, void function(Struct*, ErrorEnum status, void *userData) callback, void *userData, uint flags) SomeAPIaddCallback; I want to make it a member function of a wrapping struct so I can call it like MyStruct ms = ... ms.addCallback((ErrorEnum ee) { ... }); instead of SomeAPIaddCallback(ms.s,(Struct*, ErrorEnum status, void *userData) { ... } /*doesn't become a delegate */,null,0); I'm not sure how to do it.
How do I create a fileWatcher with an onFileChange event using spawn?
Something like this: module file_watcher; import std.concurrency; import std.file; import std.signals; import std.datetime; void fileWatcher(Tid tid, string filename, int loopSleep) { auto modified0 = timeLastModified(filename); while (true) { modified = timeLastModified(filename); if (modified > modified0) { modified0 = modified; //if (onFileChange !is null) //onFileChange(receiver); } sleep(dur!"msecs"(loopSleep)); } } But I'm not sure how to send the onFiledChange event.
Re: testing for deprecation
On Thursday, 1 September 2016 at 11:13:42 UTC, rikki cattermole wrote: That is a first that somebody wanted it. Bug report please! I just ran across this with deprecated { void foo(); } void main() { pragma(msg, __traits(getAttributes, foo)); } producing just tuple(). I came across this when looping through the members of a module and wanting to skip the deprecated ones. I did a quick look in Bugzilla and didn't find anything. Do you know if anyone filed anything I may have missed?
spawnProcess: Exit parent process without terminating child process
Hi guys, I want execute a process. I know, I can execute a process using "spawnProcess" or "executeShell". But I want exit the parent. My code for testing purposes is the following: int main(string[] asArgs_p) { if ( (asArgs_p.length >= 2) && asArgs_p[1].isDir() ) { while(1) {} } else { import std.process; spawnProcess([asArgs_p[0], "test"]); } return 0; } So, starting the application without any parameter, it calls "spawnProcess" with an parameter. Now, I want that the parent process (the process started without parameter) terminates, while the created process remains running. At the moment, the parent process creates the child and remains open (because of the while(1)-loop). Any ideas how I can exit the parent and keep the child process running?
Re: (SIMD) Optimized multi-byte chunk scanning
On Friday, 25 August 2017 at 09:40:28 UTC, Igor wrote: As for a nice reference of intel intrinsics: https://software.intel.com/sites/landingpage/IntrinsicsGuide/ Wow, what a fabulous UX!
Re: Multi dimensional array format priting
On Friday, 25 August 2017 at 17:41:31 UTC, Vino.B wrote: On Friday, 25 August 2017 at 17:02:53 UTC, Jonathan M Davis wrote: On Friday, August 25, 2017 16:45:16 Vino.B via Digitalmars-d-learn wrote: Hi, Request your help on the below issue, Issue : While appending data to a array the data is getting duplicated. Program: import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; string[] Subdata; void main () { auto dFiles = dirEntries("C:\\Temp\\TEAM", SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= d[0]; Subdata ~= d[1].toSimpleString; writeln(Subdata); } } Output: ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851"] - duplicate line ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851", "C:\\TempTEAM\\test5.xlsx", "2017-Aug-25 23:38:14.486421"] You keep printing out the entire array on every iteration of the loop, so of course, you're going to see stuff output multiple times. If you did something like import std.stdio; void main() { int[] arr; foreach(i; 0 .. 5) { arr ~= i * 10; writeln(arr); } } then you'd get the output [0] [0, 10] [0, 10, 20] [0, 10, 20, 30] [0, 10, 20, 30, 40] whereas if you did import std.stdio; void main() { int[] arr; foreach(i; 0 .. 5) arr ~= i * 10; writeln(arr); } then you'd just get [0, 10, 20, 30, 40] - Jonathan M Davis Hi All, Thank you very much, that was my mistake. The main idea is to implement parallelism and now i get only single data as there are 2 files in each of the folders, but it is listing only 1 per folder. import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; import std.parallelism; string[] Subdata; auto Dirlst = [ "C:\\Temp\\TEAM", "C:\\Temp\\PROD_TEAM"]; string[] Test (string Fs) { auto dFiles = dirEntries(Fs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= d[0]; Subdata ~= d[1].toSimpleString; } return Subdata; } void main () { foreach (string Fs; Dirlst[0 .. $]) { auto TestTask = task(, Fs); TestTask.executeInNewThread(); auto TestTaskData = TestTask.yieldForce; writefln("%-63s %.20s", TestTaskData[0], TestTaskData[1]); } } Output: C:\Temp\TEAM\Test.pdf 2017-Aug-24 18:23:00 C:\Temp\\PROD_TEAM\DND1.pdf 2017-Aug-25 23:38:04 The folder C:\Temp\TEAM contains 2 files and folder C:\Temp\\PROD_TEAM contain 4 files but it display only 1 file per folder. Hi, I was able to find the solution, thank you very much, please let me know if there are any good logic than below, import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; import std.parallelism; string[][] Subdata; auto Dirlst = [ "C:\\Temp\\TEAM" ]; string[][] CleanFiles (string Fs) { auto dFiles = dirEntries(Fs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= [d[0], d[1].toSimpleString[0 .. 20]]; } return Subdata; } void main () { foreach (string Fs; Dirlst[0 .. $]) { auto MCleanTask = task(, Fs); MCleanTask.executeInNewThread(); auto MCleanTaskData = MCleanTask.yieldForce; foreach(i; MCleanTaskData[0 .. $]) writefln("%-(%-63s %)", i); } } From, Vino.B
Re: Choosing between enum arrays or AliasSeqs
On Friday, 25 August 2017 at 08:27:41 UTC, Jacob Carlborg wrote: Since you're converting the returned index to a bool, can't you use "canFind" instead? immutable englishIndefiniteArticles = [`a`, `an`]; bool isEnglishIndefiniteArticle(S)(S s) { return englishIndefiniteArticles.canFind(s); } `s.canFind` has time-complexity O(s.length) Opposite to the template-parameter overload of `among` which has O(1), making all the difference performance-wise in my case.
Re: Appending data to array results in duplicate's.
On Friday, 25 August 2017 at 17:02:53 UTC, Jonathan M Davis wrote: On Friday, August 25, 2017 16:45:16 Vino.B via Digitalmars-d-learn wrote: Hi, Request your help on the below issue, Issue : While appending data to a array the data is getting duplicated. Program: import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; string[] Subdata; void main () { auto dFiles = dirEntries("C:\\Temp\\TEAM", SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= d[0]; Subdata ~= d[1].toSimpleString; writeln(Subdata); } } Output: ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851"] - duplicate line ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851", "C:\\TempTEAM\\test5.xlsx", "2017-Aug-25 23:38:14.486421"] You keep printing out the entire array on every iteration of the loop, so of course, you're going to see stuff output multiple times. If you did something like import std.stdio; void main() { int[] arr; foreach(i; 0 .. 5) { arr ~= i * 10; writeln(arr); } } then you'd get the output [0] [0, 10] [0, 10, 20] [0, 10, 20, 30] [0, 10, 20, 30, 40] whereas if you did import std.stdio; void main() { int[] arr; foreach(i; 0 .. 5) arr ~= i * 10; writeln(arr); } then you'd just get [0, 10, 20, 30, 40] - Jonathan M Davis Hi All, Thank you very much, that was my mistake. The main idea is to implement parallelism and now i get only single data as there are 2 files in each of the folders, but it is listing only 1 per folder. import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; import std.parallelism; string[] Subdata; auto Dirlst = [ "C:\\Temp\\TEAM", "C:\\Temp\\PROD_TEAM"]; string[] Test (string Fs) { auto dFiles = dirEntries(Fs, SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= d[0]; Subdata ~= d[1].toSimpleString; } return Subdata; } void main () { foreach (string Fs; Dirlst[0 .. $]) { auto TestTask = task(, Fs); TestTask.executeInNewThread(); auto TestTaskData = TestTask.yieldForce; writefln("%-63s %.20s", TestTaskData[0], TestTaskData[1]); } } Output: C:\Temp\TEAM\Test.pdf 2017-Aug-24 18:23:00 C:\Temp\\PROD_TEAM\DND1.pdf 2017-Aug-25 23:38:04 The folder C:\Temp\TEAM contains 2 files and folder C:\Temp\\PROD_TEAM contain 4 files but it display only 1 file per folder.
Re: Appending data to array results in duplicate's.
On Friday, August 25, 2017 16:45:16 Vino.B via Digitalmars-d-learn wrote: > Hi, > > Request your help on the below issue, > > Issue : While appending data to a array the data is getting > duplicated. > > Program: > import std.file: dirEntries, isFile, SpanMode; > import std.stdio: writeln, writefln; > import std.algorithm: filter, map; > import std.array: array; > import std.typecons: tuple; > > string[] Subdata; > void main () > { > auto dFiles = dirEntries("C:\\Temp\\TEAM", > SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , > a.timeCreated)).array; > foreach (d; dFiles) >{ > Subdata ~= d[0]; > Subdata ~= d[1].toSimpleString; > writeln(Subdata); > } > } > > Output: > > ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851"] - > duplicate line > ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851", > "C:\\TempTEAM\\test5.xlsx", "2017-Aug-25 23:38:14.486421"] You keep printing out the entire array on every iteration of the loop, so of course, you're going to see stuff output multiple times. If you did something like import std.stdio; void main() { int[] arr; foreach(i; 0 .. 5) { arr ~= i * 10; writeln(arr); } } then you'd get the output [0] [0, 10] [0, 10, 20] [0, 10, 20, 30] [0, 10, 20, 30, 40] whereas if you did import std.stdio; void main() { int[] arr; foreach(i; 0 .. 5) arr ~= i * 10; writeln(arr); } then you'd just get [0, 10, 20, 30, 40] - Jonathan M Davis
Re: Appending data to array results in duplicate's.
On Friday, 25 August 2017 at 16:45:16 UTC, Vino.B wrote: Hi, Request your help on the below issue, Issue : While appending data to a array the data is getting duplicated. Program: import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; string[] Subdata; void main () { auto dFiles = dirEntries("C:\\Temp\\TEAM", SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= d[0]; Subdata ~= d[1].toSimpleString; writeln(Subdata); } } Output: ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851"] - duplicate line ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851", "C:\\TempTEAM\\test5.xlsx", "2017-Aug-25 23:38:14.486421"] From, Vino.B You are consecutively appending to an array in each loop iteration step, i.e. you are buffering, and you're printing the current state of the buffer (all previously buffered elements) in each loop iteration. I can't see any duplication going on, what exactly to you wish to accomplish?
Appending data to array results in duplicate's.
Hi, Request your help on the below issue, Issue : While appending data to a array the data is getting duplicated. Program: import std.file: dirEntries, isFile, SpanMode; import std.stdio: writeln, writefln; import std.algorithm: filter, map; import std.array: array; import std.typecons: tuple; string[] Subdata; void main () { auto dFiles = dirEntries("C:\\Temp\\TEAM", SpanMode.shallow).filter!(a => a.isFile).map!(a => tuple(a.name , a.timeCreated)).array; foreach (d; dFiles) { Subdata ~= d[0]; Subdata ~= d[1].toSimpleString; writeln(Subdata); } } Output: ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851"] - duplicate line ["C:\\Temp\\TEAM\\test1.pdf", "2017-Aug-24 18:23:00.8946851", "C:\\TempTEAM\\test5.xlsx", "2017-Aug-25 23:38:14.486421"] From, Vino.B
Re: Long File path Exception:The system cannot find the path specified
On Friday, 25 August 2017 at 09:08:44 UTC, zabruk70 wrote: On Thursday, 24 August 2017 at 18:02:24 UTC, vino wrote: Thanks for your support, was able to resolve this issue. Hello. IMHO, it will be better, if you will share your solution for other peoples :) Hi, Please find the solution below, basically i converted the path to UNC path as below Solution: auto unc = "?\\"~i; auto dFiles = dirEntries(unc, SpanMode.shallow).filter!(a => a.isDir && !globMatch(a.baseName, "*DND*")).array; Program: import std.file: dirEntries, isFile, SpanMode, remove, rmdirRecurse, exists, mkdir; import std.stdio: writeln, writefln, File; import std.algorithm: filter; import std.array: array; import std.path: globMatch, baseName; /**/ /* Global Valiables */ /**/ int SizeDir = 10; /**/ /* Folder Lists */ /**/ auto SizeDirlst = [ "N:\\PROD_TEAM", "P:\\TEAM" ]; /**/ /* Function : Size of Non DND Dir List*/ /**/ void SizeDirList (string[] SzDNDlst) { ulong subdirTotal = 0; foreach (string i; SzDNDlst[0 .. $]) { auto unc = "?\\"~i; auto dFiles = dirEntries(unc, SpanMode.shallow).filter!(a => a.isDir && !globMatch(a.baseName, "*DND*")).array; foreach (d; dFiles) { auto SdFiles = dirEntries(d, SpanMode.breadth).array; foreach (f; SdFiles) { subdirTotal += f.size; } ulong subdirTotalGB = (subdirTotal/1024/1024/1024); if (subdirTotalGB > SizeDir) { writefln("%-63s %s", d[0].replace("?\\", ""), subdirTotalGB); } subdirTotal = 0; } } } // /* Main */ // void main () { SizeDirList(SizeDirlst); }
Re: wrapping a C style delegate
You're not specific enough. What would be semantics of such wrapper?
Re: (SIMD) Optimized multi-byte chunk scanning
On Wednesday, 23 August 2017 at 22:07:30 UTC, Nordlöw wrote: I recall seeing some C/C++/D code that optimizes the comment- and whitespace-skipping parts (tokens) of lexers by operating on 2, 4 or 8-byte chunks instead of single-byte chunks. This in the case when token-terminators are expressed as sets of (alternative) ASCII-characters. For instance, when searching for the end of a line comment, I would like to speed up the while-loop in size_t offset; string input = "// \n"; // a line-comment string import std.algorithm : among; // until end-of-line or file terminator while (!input[offset].among!('\0', '\n', '\r') { ++offset; } by taking `offset`-steps larger than one. Note that my file reading function that creates the real `input`, appends a '\0' at the end to enable sentinel-based search as shown in the call to `among` above. I further recall that there are x86_64 intrinsics that can be used here for further speedups. Refs, anyone? On line comments it doesn't sound like it will pay off since you would have to do extra work to make sure you work on 16 byte aligned memory. For multi-line comments maybe. As for a nice reference of intel intrinsics: https://software.intel.com/sites/landingpage/IntrinsicsGuide/
Re: Long File path Exception:The system cannot find the path specified
On Thursday, 24 August 2017 at 18:02:24 UTC, vino wrote: Thanks for your support, was able to resolve this issue. Hello. IMHO, it will be better, if you will share your solution for other peoples :)
Re: Choosing between enum arrays or AliasSeqs
On 2017-08-25 08:12, Nordlöw wrote: Thanks! Your advice led to the following sample solution import std.meta : aliasSeqOf; immutable englishIndefiniteArticles = [`a`, `an`]; bool isEnglishIndefiniteArticle(S)(S s) { return cast(bool)s.among!(aliasSeqOf!englishIndefiniteArticles); } Is this the preferred way? Since you're converting the returned index to a bool, can't you use "canFind" instead? immutable englishIndefiniteArticles = [`a`, `an`]; bool isEnglishIndefiniteArticle(S)(S s) { return englishIndefiniteArticles.canFind(s); } Could a template-parameter overload to `among` (perhaps calling it something slighty different) be defined that takes an immutable array as argument to prevent the conversion to the `AliasSeq` prior to the call? I guess. Currently none of the existing overloads take an array, immutable or otherwise. They expect the values to be give as separate arguments. -- /Jacob Carlborg
Re: Web servers in D
On 2017-08-25 07:25, Hasen Judy wrote: What libraries are people using to run webservers other than vibe.d? Don't get me wrong I like the async-io aspect of vibe.d but I don't like the weird template language and the fact that it caters to mongo crowd. I think for D to a have good web story it needs to appeal to serious backend developers, not hipsters who go after fads (mongodb is a fad, jade/haml is a fad). Why would a backend developer care about front end stuff like jade/haml? Just don't use those parts ;) I probably need to combine several libraries, but the features I'm looking for are: - Spawn an HTTP server listening on a port, and routing requests to functions/delegates, without hiding the details of the http request/response objects (headers, cookies, etc). - Support for websockets - Runs delegates in fibers/coroutines - Basic database connectivity (No "orm" needed; just raw sql). It depends on which database you need to connect to. For PostgreSQL there's ddb [1] and for MySQL there's mysql-native [2]. - When iterating the result set of a sql query, has the ability to automatically map each row against a struct, and throw if the structure does not match. I don't know about mysql-native, but for ddb you can use the PGCommand class and the executeQuery or executeRow to execute the query and specify the struct that should be returned. - More generally, map any arbitrary object (such as json) to a struct. Something like Zewo/Reflection package for swift[0]. vibe.d has built-in support for serialization [3]. [0]: https://github.com/Zewo/Reflection I feel like Vibe.d satisfies my first 3 requirements, but for the rest I will probably have to look for something else. [1] http://code.dlang.org/packages/ddb [2] http://code.dlang.org/packages/mysql-native [3] http://vibed.org/api/vibe.data.serialization -- /Jacob Carlborg
Re: Terminating a thread (which is blocking)
On Thursday, 24 August 2017 at 07:23:15 UTC, Timothy Foster wrote: I've started a thread at the beginning of my program that waits for user input: `thread = new Thread().start;` `static void checkInput(){ foreach (line; stdin.byLineCopy) { ... } }` I need to stop checking for user input at some point in my program but I'm not sure how to kill this thread. `thread.yield();` called from my main thread doesn't kill it and I'm not sure how to send a message to the input checking thread to get it to terminate itself when `stdin.byLineCopy` just sits there and blocks until user input is received. If you're on Linux, you can try pthread_kill. Otherwise don't block. Define a shared boolean variable that says if the thread should stop. Wait for the input for some time and break, check the condition variable, try to read again or break and so on.
Re: Web servers in D
On Friday, 25 August 2017 at 06:15:35 UTC, Eugene Wissner wrote: There is collie [1]. Never used. Can't say a lot about it. arsd [2] has a lot of interesting web stuff: event loop, FastCGI/SimpleCGI; web-, DOM-, mail-utilities. And the last but not least I'm running currently a small web server serving static files based on tanya [3]. Once I'm ready to write a web-framework on top of it, it would be what you mention: no compile-time templates, no jade-style templates, since I dislike these too. But unfortunately it is not something can be used now. [1] https://github.com/huntlabs/collie [2] https://github.com/adamdruppe/arsd [3] https://github.com/caraus-ecms/tanya Thanks. Those are some interesting links. FWIW I kind of like compile-time templates. I just don't like jade (or coffee-script, or stylus, or all these languages that try to remove the punctuation and curly braces, and all signs of structure).
Re: Tools to help me find memory leaks?
I always use "valgrind --tool=massif" + "massif-visualizer". Gives me a nice timeline allowing to find quickly who the big memory consumers (allocation sites) are.
Re: Web servers in D
On Friday, 25 August 2017 at 05:25:09 UTC, Hasen Judy wrote: What libraries are people using to run webservers other than vibe.d? Don't get me wrong I like the async-io aspect of vibe.d but I don't like the weird template language and the fact that it caters to mongo crowd. I think for D to a have good web story it needs to appeal to serious backend developers, not hipsters who go after fads (mongodb is a fad, jade/haml is a fad). I probably need to combine several libraries, but the features I'm looking for are: - Spawn an HTTP server listening on a port, and routing requests to functions/delegates, without hiding the details of the http request/response objects (headers, cookies, etc). - Support for websockets - Runs delegates in fibers/coroutines - Basic database connectivity (No "orm" needed; just raw sql). - When iterating the result set of a sql query, has the ability to automatically map each row against a struct, and throw if the structure does not match. - More generally, map any arbitrary object (such as json) to a struct. Something like Zewo/Reflection package for swift[0]. [0]: https://github.com/Zewo/Reflection I feel like Vibe.d satisfies my first 3 requirements, but for the rest I will probably have to look for something else. There is collie [1]. Never used. Can't say a lot about it. arsd [2] has a lot of interesting web stuff: event loop, FastCGI/SimpleCGI; web-, DOM-, mail-utilities. And the last but not least I'm running currently a small web server serving static files based on tanya [3]. Once I'm ready to write a web-framework on top of it, it would be what you mention: no compile-time templates, no jade-style templates, since I dislike these too. But unfortunately it is not something can be used now. [1] https://github.com/huntlabs/collie [2] https://github.com/adamdruppe/arsd [3] https://github.com/caraus-ecms/tanya
Re: Choosing between enum arrays or AliasSeqs
On Thursday, 24 August 2017 at 22:38:29 UTC, Meta wrote: https://dlang.org/phobos/std_meta.html#aliasSeqOf Thanks! Your advice led to the following sample solution import std.meta : aliasSeqOf; immutable englishIndefiniteArticles = [`a`, `an`]; bool isEnglishIndefiniteArticle(S)(S s) { return cast(bool)s.among!(aliasSeqOf!englishIndefiniteArticles); } Is this the preferred way? Could a template-parameter overload to `among` (perhaps calling it something slighty different) be defined that takes an immutable array as argument to prevent the conversion to the `AliasSeq` prior to the call? More here: https://github.com/nordlow/phobos-next/blob/c7d9a0f9c3280fc7852584ee2be387646a5f7857/src/grammar.d#L49