Stobber Posted April 19, 2016 Report Share Posted April 19, 2016 I want to decouple the producer of a set of data from the consumer which turns the data into a formatted string. The producer should run super fast, so I don't want it to spend effort formatting the data into a string; just throw the parameters (which the producer knows but the consumer doesn't) into a data structure and send that to the consumer. The consumer should be bindable to any shape of producer, so it doesn't want to know which parameters it'll get or how it should format them. This should be straightforward. I can send a "format string" along with the parameters so the consumer does whatever it's told by each producer. But LV's Format Into String primitive requires a fixed number of parameters at compile time! I'm trying to roll my own using regex or the tokenizer, but I realize I'll have to implement the whole format specifier syntax if I want it to work generically. Can anyone think of an easier solution? Preferably one that doesn't establish an external dependency on my code...I don't want to have to ship a VIPM with its own license terms or install a new .so/daemon on the cRIO. Quote Link to comment
GregSands Posted April 19, 2016 Report Share Posted April 19, 2016 Can you just do the formats one at a time and then concatenate? 1 Quote Link to comment
ensegre Posted April 19, 2016 Report Share Posted April 19, 2016 (edited) Is some restriction of the format specifier syntax acceptable? Namely, do you need to support $ order? Do you need to output some argument multiple times? If the correspondence parameter -> formatted form is 1:1, a loop on an array of variants containing arguments, plus one array of format strings could perhaps do? Or, one array of clusters (index of parameter, format string) to account for reshuffling and repetition, and then concatenate as suggested above? Edited April 19, 2016 by ensegre 1 Quote Link to comment
Stobber Posted April 19, 2016 Author Report Share Posted April 19, 2016 You're both onto what I've been working on since I posted. It's not as bad as I feared. I'll have to enforce ordered parameters, at least in the first pass, to minimize string mangling. Let me hammer on it a little more, and I'll try to upload a version that uses an array of variants for your review. Quote Link to comment
Stobber Posted April 19, 2016 Author Report Share Posted April 19, 2016 I didn't want bother implementing it for all simple data types, since my data's not in a Variant, but here's a first-pass example of how I got it done. Format Variant Array Into String LV9.vi Format Variant Array Into String LV15.vi Quote Link to comment
GregSands Posted April 20, 2016 Report Share Posted April 20, 2016 OpenG has a similar function in its String library for formatting a Variant into a String, though not for splitting up a multi-variable format. Like you, they've chosen to implement a subset of the possible formatting commands. Alternatively, you might have success with an XNode which effectively scripts the wiring between Unbundle (assuming your data is in a cluster) and Format. Quote Link to comment
GregSands Posted April 20, 2016 Report Share Posted April 20, 2016 (edited) OK, so here's a very quick-and-dirty XNode to do what I think you're wanting. Don't use in any code you care lots about, though it should be ok if you always wire it up properly - i.e. errors are ignored, not handled FormatCluster.zip FormatCluster.zip Edited April 20, 2016 by GregSands File no longer linked to with site upgrade Quote Link to comment
shoneill Posted April 20, 2016 Report Share Posted April 20, 2016 (edited) Fast producer, extremely flexible consumer? Object queue (yeah LVOOP is a good choice here). Allows fully flexible parsing with minimal overhead in the producer (deals with no DD VIs). Receiver doesn't need to know ANYTHING about the formatting. BTW if you're thinking you can't send objecty by RT-FIFO, just send a DVR of the object instead. String formatter.zip Edited April 20, 2016 by shoneill 1 Quote Link to comment
Stobber Posted April 20, 2016 Author Report Share Posted April 20, 2016 (edited) OpenG has a similar function in its String library for formatting a Variant into a String, though not for splitting up a multi-variable format. Like you, they've chosen to implement a subset of the possible formatting commands. ...(assuming your data is in a cluster)... Insofar as I'm using Format Into String to do the actual formatting, I don't have to implement any of the formatting commands. I just have to scrape the variable's data type so I can cast it from the Variant. If my data were a cluster, the consumer would have to know its structure (data types, data names, shape of memory structure) at compile time. That would completely undo the objective of decoupling consumer from producer. OK, so here's a very quick-and-dirty XNode to do what I think you're wanting. Don't use in any code you care lots about, though it should be ok if you always wire it up properly - i.e. errors are ignored, not handled (Thanks, but if I can't use it in code I care about, what good is it? ) While this, when completely fleshed out, allows me to easily write a consumer that's correctly coupled to a particular producer at edit time, it still establishes coupling. My data producer won't always be a LV app, or even an app written by my team. I want to completely abstract the type and arrangement of the inbound data set from the consumer. It should just receive a "collection" and see that turned into a formatted string. Fast producer, extremely flexible consumer? Object queue (yeah LVOOP is a good choice here). Good point: By embedding the "format this data" algorithm into the data itself (via a method on the abstract type and data in the concrete type), I can hand abstract data to the consumer and let the data format itself. In a high-level sense, that's what I've done with my Variant implementation: The abstract data set is an array of Variants (which itself could be structure as a Variant if I wanted to get even more abstract about the structure), and the formatting algorithm is abstracted into a string provided with the data and a function (Format Into String) that processes the data. The queue is just a transport mechanism for getting the data and algorithm over to the consumer. Assuming the producer is always LV code, the queue is one of many good choices. On that note, since my producer isn't always LV code, a LV Object might limit my implementation, too. (I'd have to convert the data from another type into a LV Object, requiring knowledge of the concrete data type in the consumer.) But for LV-to-LV implementation, a queue of objects is a great way to go. Edited April 20, 2016 by Stobber Quote Link to comment
GregSands Posted April 20, 2016 Report Share Posted April 20, 2016 OK, I think I'm not fully understanding what you're trying to do, or even what a "collection" is. Your data is not in a Variant, not in a cluster, not in a class, perhaps not even in a LabVIEW type. Is it just a sequence of bytes, and you're using the format string to tell your Formatter how to interpret those bytes? In which case, going back to your first post, it seems to me that you do have to write your own implementation, though you can choose how general or specific you want to make it. But there's no advantage necessarily in being tied to the LabVIEW format syntax - your requirements may be substantially less, or greater, than what it provides. The code you originally provided seems entirely reasonable then, with the small adjustment of interpreting raw bytes rather than a variant. I guess you may also want to consider the option of sending the formatting only once (essentially defining the String representation of your data "object"), and reusing it for all of the data, especially as it sounds as though your producer is providing a lot of data very quickly, too fast to do the formatting itself. That sounds sortof like registering an object with your Formatter, and then just telling it the following data is of that type. Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.