I'm using the Boost 1.64.0 MSM library to produce a hierarchical state machine. For test the transition mechanism, I implement a state machine like this
+------------------------------------------------+
| S |
| +-------------+ +-------------+ |
| | S1 | | S2 | |
| | +-------+ | | +-------+ | |
| | | S11 | | | | S21 | | |
| | +-------+ | | +-------+ | |
| +-------------+ +-------------+ |
| |
+------------------------------------------------+
So how to define transition from S11 to S21, according to the same situation described in wiki the transition execution sequence should be 'exit S11' -> 'exit S1' -> 'enter S2' -> 'enter S21'.
According to the document https://www.boost.org/doc/libs/1_66_0/libs/msm/doc/HTML/ch03s02.html#d0e875,
it is only possible to explicitly enter a sub- state of the target
but not a sub-sub state.
it is not possible to explicitly exit. Exit points must be used.
So you cannot do explicit exit from S11.
You can use exit point pseudo state instead of the explicit exit. And I recommend that use entry point pseudo state instead of the explicit entry.
Here is an example code of the entry point pseudo state
http://redboltz.wikidot.com/entry-point-pseudo-state
and the exit point pseudo state.
http://redboltz.wikidot.com/exit-point-pseudo-state
Related
Let's say we have 3 buffers (A, B, C) open in Vim arranged as follows
-----------------------------------------
| | |
| | |
| | |
| A | |
| | |
| | |
|------------------| B |
| | |
| | |
| C | |
| | |
| | |
-----------------------------------------
and we want to rearrange it as
-----------------------------------------
| | |
| | |
| | |
| | B |
| | |
| | |
| A |--------------------|
| | |
| | |
| | C |
| | |
| | |
-----------------------------------------
I know I can do this by closing C and reopening it after splitting B. Is there a simple way to do this where I don't have to close buffers and I can rearrange the windows directly?
You wouldn't "close" the buffer C, only the window that displays it.
Vim has dedicated normal mode commands for:
switching a window and the next one in a row or column,
rotating the whole window layout,
pushing a window to the far top, far right, far bottom, and far left,
but it doesn't have one for moving a window to an arbitrary point so, assuming the window you want to move has the focus, the command should look like this:
:q|winc w|sp c
which is not too shabby. You might be able to find a plugin that provides the level of control you are after on https://www.vim.org.
I currently have a spring-integration (v4.3.24) flow that looks like the following:
|
| list of
| filepaths
+----v---+
|splitter|
+----+---+
| filepath
|
+----------v----------+
|sftp-outbound-gateway|
| "get" |
+----------+----------+
| file
+---------------------+
| +----v----+ |
| |decryptor| |
| +----+----+ |
| | |
| +-----v------+ | set of transformers
| |decompressor| | (with routers before them
| +-----+------+ | because some steps are optional)
| | | that process the file;
| +--v--+ | call this "FileProcessor"
| | ... | |
| +--+--+ |
+---------------------+
|
+----v----+
|save file|
| to disk |
+----+----+
|
All of the channels above are DirectChannels - Yup, I know this is a poor structure. This was working fine for files in small numbers. But now, I have to deal with thousands of files which need to go through the same flow - benchmarks reveal that this takes ~ 1 day to finish processing. So, I'm planning to introduce some parallel processing to this flow. I want to modify my flow to achieve something like this:
|
|
+----------v----------+
|sftp-outbound-gateway|
| "mget" |
+----------+----------+
| list of files
|
+----v---+
|splitter|
+----+---+
one thread one | thread ...
+------------------------+---------------+--+--+--+--+
| file | file | | | | |
+---------------------+ +---------------------+
| +----v----+ | | +----v----+ |
| |decryptor| | | |decryptor| |
| +----+----+ | | +----+----+ |
| | | | | |
| +-----v------+ | | +-----v------+ | ...
| |decompressor| | | |decompressor| |
| +-----+------+ | | +-----+------+ |
| | | | | |
| +--v--+ | | +--v--+ |
| | ... | | | | ... | |
| +--+--+ | | +--+--+ |
+---------------------+ +---------------------+
| |
+----v----+ +----v----+
|save file| |save file|
| to disk | | to disk |
+----+----+ +----+----+
| |
| |
For parallel processing, I output the files from the splitter on to a ExecutorChannel with a ThreadPoolTaskExecutor.
Some of the questions that I have:
I want all of the "FileProcessor" steps for one file to happen on the same thread, while multiple files are processed in parallel. How can I achieve this?
I saw from this answer, that a ExecutorChannel to MessageHandlerChain flow would offer such functionality. But, some of the steps inside "FileProcessor" are optional (using selector-expression with routers to skip some of the steps) - ruling out using a MessageHandlerChain. I can rig up a couple of MessageHandlerChains with Filters inside, but this more or less becomes the approach mentioned in #2.
If #1 cannot be achieved, will changing all of the channel types starting from the splitter, from DirectChannel to ExecutorChannel help in introducing some parallelism? If yes, should I create a new TaskExecutor for each channel or can I reuse one TaskExecutor bean for all channels (I cannot set scope="prototype" on a TaskExecutor bean)?
In your opinion, which approach (#1 or #2) is better? Why?
If I perform global error handling, like the approach mentioned here, will the other files continue to process even if one file errors out?
It will work as you need by using an ExecutorChannel as an input to the decrypter and leave all the rest as direct channels; the remaining flow does not have to be a chain, each component will run on one of the executor's threads.
You will need to be sure all your downstream components are thread-safe.
Error handling should remain as is; each sub flow is independent.
Alright, I'm back. This time I'm trying to quickly select all of the values in a range which match values in a separate list, my first iteration will be to clear the contents of voided IDs, my second iteration will be to select those values and then replace them with corresponding new values.
I asked another question about VBA and was pointed in mentioning that I've tried to teach myself and find resources to work through these issues before but people seem to get pissed that I'm asking, if you could at least direct me to somewhere that I can learn about these matters (or even a place I can learn basic logic and have a list of usable functions without having to go through all the "How to make your first Excel VBA for some problem that nobody cares about" I would appreciate it)
Anyway I tried to watch a few videos and then hack together something but it seems pretty clear that the function they were using cannot be adapted for other uses. This is what I have at the moment:
Sub FilterElim()
finalRow = Range("g2").End(xlDown).Row
Range("A1").ClearContents _
Action:= xlClearContents, _
CriteriaRange: Range("Sheet4!B1:B10"), _
Unique:= False
End Sub
So based on some helpful questions I am making an edit to include an example and desired end
Example set:
Desired end result:
I presume I may need to perform a selection of some sort based on the Criteria before the ClearContents but I wasn't finding anything helpful on how to go about that. PLEASE and thank you.
| Contractor ID | Cont Name | Proj 1 | Proj 2 | Proj 3 | | | Old ID | Reconciliation |
|-----------------|-------------------|--------|--------|--------|---|---|--------|----------------|
| C1001 | Boba Fet | P1120 | | | | | P1001 | Void |
| C1003 | Jules Winnfield | P1031 | P1045 | | | | P1002 | P1010 |
| C1002 | Dom Cobb | P1001 | | | | | P1005 | Void |
| C1010 | Patrick Verona | P1020 | P1224 | P1251 | | | P1020 | Void |
| C1007 | Matt Damon | P1008 | P1005 | P1300 | | | P1045 | P1100 |
| C1004 | Ned Plimpton | P1002 | | | | | P1224 | P1300 |
| C1020 | Derek Zoolander | P1020 | P1290 | | | | | |
| C1009 | Charles Marlow | P1002 | P0090 | | | | | |
| C1011 | Robert Jordan | P1119 | | | | | | |
| C1015 | Perrin Aybara | P1200 | P1224 | | | | | |
| C1005 | Fuzzy Dunlop | P1005 | | | | | | |
| C1008 | Thomas A Anderson | P1001 | P1000 | | | | | |
| | | | | | | | | |
What makes you go for a VBA solution ?
Hard to do much without a glance of you data and expected result.
Non VBA option:
=IFERROR(INDEX($G$2:$G$15,MATCH(A32,$F$2:$F$15,0)),B32)
For a VBA option, you can try:
Option Explicit
Sub update_id()
Dim D1 As Object: Set D1 = CreateObject("scripting.dictionary")
Dim R1 As Range: Set R1 = Range("A2:A32")
Dim R2 As Range: Set R2 = Range("E2:E15")
Dim Rtmp As Range
For Each Rtmp In R2
D1(Rtmp.Value) = Rtmp.Offset(0, 1).Value
Next Rtmp
For Each Rtmp In R1
If D1.exists(Rtmp.Value) Then Rtmp.Offset(0, 1) = D1(Rtmp.Value)
Next Rtmp
End Sub
Working on the following set up :
Again, without a better understanding of your data and your issue, its hard to be more precise.
The following example just shows the pattern, my data much bigger.
I have a Table like
| Variable | String |
|:---------|-------:|
| V1 | Hello |
| V2 | little |
| V3 | World |
I have another table where different arrangements are defined
| Arrangement1 | Arrangement2 |
|:-------------|-------------:|
| V3 | V2 |
| V2 | V1 |
| V1 | V3 |
My output depending on the asked Arrangement (e.g. Arrangement1) should be
| Variable | Value |
|:---------|------:|
| V3 | World |
| V2 | little|
| V1 | Hello |
Till now I try to realize an approach with .find and array but think there might be an easier way (maybe with dictionary?) anyone an idea with good performance?
I usually have my Vim screen split into two vertical windows, each of which may be further horizontally split. Sometimes, I want to add or delete a vertical window. Is there a way to detect how many top-level vertical splits there are and add or remove vsplits as necessary?
For example, suppose my screen looks like this:
+--------+--------+
| | |
| | |
+--------+ |
| | |
| | |
| +--------+
| | |
+--------+--------+
I want :Columns 1 to give me
+--------+
| |
| |
+--------+
| |
| |
| |
| |
+--------+
by closing the two right-most windows.
I want :Columns 2 to do nothing, detecting that two columns are already open.
And I want :Columns 3 to give me
+--------+--------+--------+
| | | |
| | | |
+--------+ | |
| | | |
| | | |
| +--------+ |
| | | |
+--------+--------+--------+
I am fine if the function ignores vertical splits within horizontal splits. For example, if I had
+--------+
| |
| |
+---+----+
| | |
| | |
| | |
| | |
+---+----+
and I ran :Columns 2, I would get
+--------+--------+
| | |
| | |
+---+----+ |
| | | |
| | | |
| | | |
| | | |
+---+----+--------+
There is indeed a way, but it is involved; the first step is to count the currently-open vertical windows, and I don’t know of any built-in function that facilitates this. The working approach I found to it is basically to start at the first window (the top of the first — if not the entirety of the first — vertical split), and to then, using wincmd l, move to the next window to the right for as long as wincmd l moves to a new window, adding each to a count of open vertical windows including the first one. (I think this is what Gary Fixler referred to in the comments on the question.)
I started trying to write the code for posting here, and it grew to become larger than any function I would want to put in my ~/.vimrc, so I ended up turning it into a plugin which takes the above approach and provides the :Columns command; see Columcille (on vim.org at http://www.vim.org/scripts/script.php?script_id=4742.) The plugin also provides a command for similarly managing horizontal split windows: :Rows divides the current column (or the main window, if there are no open vertical splits) into the specified number of “rows.”