Electrimate is a smart electricity meter that allows you to monitor
energy usage in different sections of your apartment and view the current electricity bill amount
Before you continue
Make sure the module is correctly installed
Make sure the sensors are connected
For any assistance contact our help desk
Please Read and Accept the End User License Agreement to Continue


--- title: Reflecting on Macros author: Jonathan Carroll date: '2023-06-10' categories: - julia - rstats - rust tags: - julia - rstats - rust slug: reflecting-on-macros editor_options: chunk_output_type: console ---
I’ve been following the drama of the RustConf Keynote Fiasco (RKNF, per @fasterthanlime) from a great distance - I’m not involved in that community beyond starting to learn the language. But the controversial topic itself Compile-Time Reflection seemed like something interesting I could learn something about.
I’ve been following the drama of the RustConf Keynote Fiasco (RKNF, per @fasterthanlime) from a great distance - I’m not involved in that community beyond starting to learn the language. But the controversial topic itself Compile-Time Reflection seemed like something interesting I could learn something about.
A good start is usually a Wikipedia page, and I found one called “Reflective programming” under the “MetaProgramming” category, where it defines
reflection is the ability of a process to examine, introspect, and modify its own structure and behavior
That sounds somewhat familiar from what metaprogramming I’ve read about. One of the
great features of R is the ability to inspect and rewrite functions, for example,
the body of the sd()
function (calculating the standard deviation of the input) looks
like
sd
## function (x, na.rm = FALSE)
## sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x),
## na.rm = na.rm))
## <bytecode: 0x5647347e3980>
## <environment: namespace:stats>
Trying to extract a “component” of that function results in the ever-classic error
sd[1]
## Error in sd[1]: object of type 'closure' is not subsettable
However, using body()
we can get to the components of the function
body(sd)
## sqrt(var(if (is.vector(x) || is.factor(x)) x else as.double(x),
## na.rm = na.rm))
body(sd)[1]
## sqrt()
and we can even mess with it (meaninglessly, in this case)
vals <- c(1, 3, 5, 7)
sd(vals)
## [1] 2.581989
my_sd <- sd
body(my_sd)[1] <- call("log")
my_sd # note that the function now (wrongly) uses log() instead of sqrt()
## function (x, na.rm = FALSE)
## log(var(if (is.vector(x) || is.factor(x)) x else as.double(x),
## na.rm = na.rm))
## <environment: namespace:stats>
my_sd(vals)
## [1] 1.89712
The Wikipedia page lists the following example of reflection in R
# Without reflection, assuming foo() returns an S3-type object that has method "hello"
obj <- foo()
hello(obj)
# With reflection
class_name <- "foo"
generic_having_foo_method <- "hello"
obj <- do.call(class_name, list())
do.call(generic_having_foo_method, alist(obj))
Using a more concrete data object and class, e.g. tibble::tibble
and summary
might be
clearer
library(tibble) # do.call doesn't like pkg::fun as a string
# Without reflection
obj <- tibble(a = 1:2, b = 3:4)
summary(obj)
## a b
## Min. :1.00 Min. :3.00
## 1st Qu.:1.25 1st Qu.:3.25
## Median :1.50 Median :3.50
## Mean :1.50 Mean :3.50
## 3rd Qu.:1.75 3rd Qu.:3.75
## Max. :2.00 Max. :4.00
# With reflection
class_name <- "tibble"
generic_having_foo_method <- "summary"
obj <- do.call(class_name, list(a = 1:2, b = 3:4))
obj
## # A tibble: 2 × 2
## a b
## <int> <int>
## 1 1 3
## 2 2 4
do.call(generic_having_foo_method, alist(obj))
## a b
## Min. :1.00 Min. :3.00
## 1st Qu.:1.25 1st Qu.:3.25
## Median :1.50 Median :3.50
## Mean :1.50 Mean :3.50
## 3rd Qu.:1.75 3rd Qu.:3.75
## Max. :2.00 Max. :4.00
So, maybe it’s more to do with being able to use a string containing the “name” of a function and go and find that function, or just the ability to generate functions on-demand based on non-function objects (?). Please, let me know if there’s a more enlightening explanation.
I still don’t think I understand that at all (more time required) but I did note in some additional research that “reflection” and “macros” are two very similar concepts. Now macros are something I’ve heard of at least, so I was off to do some more research.
Unfortunately, web searches for the terms “reflection” and “macro” turn up a lot of macro-lens photography results.
I’ve heard of macros in Julia where they’re used to “rewrite” an expression. This is a nice rundown
of the process, as are the official docs. These are
used in many places. One up-and-coming place is the new Tidier.jl which implements the tidyverse (at least the most common dplyr
and purrr
parts)
using macros (denoted with a @
prefix)
using Tidier
using RDatasets
movies = dataset("ggplot2", "movies");
@chain movies begin
@mutate(Budget = Budget / 1_000_000)
@filter(Budget >= mean(skipmissing(Budget)))
@select(Title, Budget)
@slice(1:5)
end
Rust uses macros for printing (amongst other things); println!()
is a macro,
apparently at least in part because it needs to be able to take an arbitrary
number of args, so one can write
>> println!("a = {}, b = {}, c = {}", 1, 2, 3)
a = 1, b = 2, c = 3
Rust has a shorthand macro for creating a new vector vec!()
>> let v = vec![2, 3, 4];
and also has the “debug macro” dbg!()
which is super handy - it prints out the expression you wrap, plus the value, so
you can inspect the current state with e.g.
>> dbg!(&v);
[src/lib.rs:109] &v = [
2,
3,
4,
]
This last one would be great to have in R… as a side note, we could construct a simple version with {rlang}
dbg <- function(x) {
ex <- rlang::f_text(rlang::enquos(x)[[1]])
ret <- rlang::eval_bare(x)
message(glue::glue("DEBUG: {ex} = {ret}"))
ret
}
a <- 1
b <- 3
x <- dbg(a + b)
## DEBUG: a + b = 4
y <- dbg(2*x + 3)
## DEBUG: 2 * x + 3 = 11
z <- 10 + dbg(y*2)
## DEBUG: y * 2 = 22
In all of these examples of macros, the code that is run is different to the code you write because the macro makes some changes before executing.
In R there isn’t a “proper” way to do this but we do have ways to manipulate code
and we do have ways to retrieve “unparsed” input, e.g. substitute()
. A quick look
for “macros in R” turned up a function in a package that is more than 20 years old (I was
only starting University when this came out and knew approximately 0 programming) and
comes with a journal article; gtools::defmacro()
by Thomas Lumley
has a construction for writing something that behaves like a macro.
That article is from 2001 when R 1.3.1 was being released. The example code made me do a double-take
library(gtools)
####
# macro for replacing a specified missing value indicator with NA
# within a dataframe
###
setNA <- defmacro(df, var, values,
expr = {
df$var[df$var %in% values] <- NA
}
)
# create example data using 999 as a missing value indicator
d <- data.frame(
Grp = c("Trt", "Ctl", "Ctl", "Trt", "Ctl", "Ctl", "Trt", "Ctl", "Trt", "Ctl"),
V1 = c(1, 2, 3, 4, 5, 6, 999, 8, 9, 10),
V2 = c(1, 1, 1, 1, 1, 2, 999, 2, 999, 999),
stringsAsFactors = TRUE
)
d
## Grp V1 V2
## 1 Trt 1 1
## 2 Ctl 2 1
## 3 Ctl 3 1
## 4 Trt 4 1
## 5 Ctl 5 1
## 6 Ctl 6 2
## 7 Trt 999 999
## 8 Ctl 8 2
## 9 Trt 9 999
## 10 Ctl 10 999
# Try it out
setNA(d, V1, 999)
setNA(d, V2, 999)
d
## Grp V1 V2
## 1 Trt 1 1
## 2 Ctl 2 1
## 3 Ctl 3 1
## 4 Trt 4 1
## 5 Ctl 5 1
## 6 Ctl 6 2
## 7 Trt NA NA
## 8 Ctl 8 2
## 9 Trt 9 NA
## 10 Ctl 10 NA
Wait - I thought… there’s no assignment in those last lines, but the data is
being modified!?! Sure enough, the internals of defmacro
make it clear that this
is the case, but it seemed like magic. Essentially, this identifies what needs to
happen, what it needs to happen to (via substitute()
), and makes it happen in the parent.frame()
. Neat! So, what else can we do with this?
I thought about it for a while and realised what could be a [te|ho]rrific one…
Just a couple of weeks ago, Danielle Navarro made a wish
not for the first time I find myself wishing that push() and pop() were S3 generics in #rstats
Now, if you’re not familiar with those, pop(x)
removes the first element of a structure x
(e.g. a vector) and returns that first value, leaving the original object x
containing only the remaining elements, whereas push(x, y)
inserts the value y
as the first element of x
, moving the remaining elements down the line. These show up more in object-oriented languages, but they
don’t exist in R.
If we define a vector a
containing some values
a <- c(3, 1, 4, 1, 5, 9)
and we wish to extract the first value, we can certainly do so with
a[1]
## [1] 3
but, due to the nature of R, the vector a
is unchanged
a
## [1] 3 1 4 1 5 9
Instead, we could remove the first value of a
with
a[-1]
## [1] 1 4 1 5 9
but again, a
remains unchanged - in order to modify a
we must redefine it as e.g.
a <- a[-1]
a
## [1] 1 4 1 5 9
If we wanted to build a pop()
function, we could use substitute()
to figure out
what the passed input object was, perform the extraction of the first element, and so on…
But as we’ve just seen, there’s a better way to define that - a macro!
r_pop <- gtools::defmacro(x, expr = {
ret <- x[1]
x <- x[-1]
ret
})
Now, if we use that on a vector
a <- c(3, 1, 4, 1, 5, 9)
r_pop(a)
## [1] 3
a
## [1] 1 4 1 5 9
It works!!!
Danielle wanted a Generic, though, so we can easily make pop()
a Generic and add methods for
some classes (which can be further extended).
To that end, I present a brand new package; {weasel}
This defines pop()
and push()
as Generics with methods defined for vector
s, list
s, and data.frame
s
a <- list(x = c(2, 3), y = c("foo", "bar"), z = c(3.1, 4.2, 6.9))
a
## $x
## [1] 2 3
##
## $y
## [1] "foo" "bar"
##
## $z
## [1] 3.1 4.2 6.9
x <- pop(a)
a
## $y
## [1] "foo" "bar"
##
## $z
## [1] 3.1 4.2 6.9
x
## [1] 2 3
a <- data.frame(x = c(2, 3, 4), y = c("foo", "bar", "baz"), z = c(3.1, 4.2, 6.9))
a
## x y z
## 1 2 foo 3.1
## 2 3 bar 4.2
## 3 4 baz 6.9
x <- pop(a)
a
## x y z
## 2 3 bar 4.2
## 3 4 baz 6.9
x
## x y z
## 1 2 foo 3.1
a <- c(1, 4, 1, 5, 9)
a
## [1] 1 4 1 5 9
push(a, 3)
a
## [1] 3 1 4 1 5 9
a <- data.frame(y = c("foo", "bar", "baz"), z = c(3.1, 4.2, 6.9))
a
## y z
## 1 foo 3.1
## 2 bar 4.2
## 3 baz 6.9
push(a, data.frame(y = 99, z = 77))
a
## y z
## 1 99 77.0
## 2 foo 3.1
## 3 bar 4.2
## 4 baz 6.9
I wrote this (simple) package as a bit of an exercise - I really don’t think you
should actually use it for anything. The “looks like it modifies in-place but actually
doesn’t” is really non-idiomatic for R. Nonetheless, I was really interested to see
that defmacro
can be used as a function definition that the dispatch machinery will respect. The only catch I’ve found so far is that I can’t use ellipses (...
) in the function signature.
I noticed that Dirk Schumacher built a similar defmacro
package more recently, but that appears
to be more aimed at building macros to be expanded on package load (funnily enough, “compile-time macros” - we’ve come full circle). This seems like a great opportunity for “inlining”
some functions. I’ll definitely be digging deeper into that one.
Let me know if you have a better explanation of any of the concepts I’ve (badly) described here; I’m absolutely just learning and following Julia Evans’ advice about blogging.
## ─ Session info ───────────────────────────────────────────────────────────────
## setting value
## version R version 4.1.2 (2021-11-01)
## os Pop!_OS 22.04 LTS
## system x86_64, linux-gnu
## ui X11
## language (EN)
## collate en_AU.UTF-8
## ctype en_AU.UTF-8
## tz Australia/Adelaide
## date 2023-06-17
## pandoc 3.1.1 @ /usr/lib/rstudio/resources/app/bin/quarto/bin/tools/ (via rmarkdown)
##
## ─ Packages ───────────────────────────────────────────────────────────────────
## package * version date (UTC) lib source
## blogdown 1.17 2023-05-16 [1] CRAN (R 4.1.2)
## bookdown 0.29 2022-09-12 [1] CRAN (R 4.1.2)
## bslib 0.4.1 2022-11-02 [3] CRAN (R 4.2.2)
## cachem 1.0.6 2021-08-19 [3] CRAN (R 4.2.0)
## callr 3.7.3 2022-11-02 [3] CRAN (R 4.2.2)
## cli 3.4.1 2022-09-23 [3] CRAN (R 4.2.1)
## crayon 1.5.2 2022-09-29 [3] CRAN (R 4.2.1)
## devtools 2.4.5 2022-10-11 [1] CRAN (R 4.1.2)
## digest 0.6.30 2022-10-18 [3] CRAN (R 4.2.1)
## ellipsis 0.3.2 2021-04-29 [3] CRAN (R 4.1.1)
## evaluate 0.18 2022-11-07 [3] CRAN (R 4.2.2)
## fansi 1.0.3 2022-03-24 [3] CRAN (R 4.2.0)
## fastmap 1.1.0 2021-01-25 [3] CRAN (R 4.2.0)
## fs 1.5.2 2021-12-08 [3] CRAN (R 4.1.2)
## glue 1.6.2 2022-02-24 [3] CRAN (R 4.2.0)
## gtools * 3.9.4 2022-11-27 [1] CRAN (R 4.1.2)
## htmltools 0.5.3 2022-07-18 [3] CRAN (R 4.2.1)
## htmlwidgets 1.5.4 2021-09-08 [1] CRAN (R 4.1.2)
## httpuv 1.6.6 2022-09-08 [1] CRAN (R 4.1.2)
## jquerylib 0.1.4 2021-04-26 [3] CRAN (R 4.1.2)
## jsonlite 1.8.3 2022-10-21 [3] CRAN (R 4.2.1)
## knitr 1.40 2022-08-24 [3] CRAN (R 4.2.1)
## later 1.3.0 2021-08-18 [1] CRAN (R 4.1.2)
## lifecycle 1.0.3 2022-10-07 [3] CRAN (R 4.2.1)
## magrittr 2.0.3 2022-03-30 [3] CRAN (R 4.2.0)
## memoise 2.0.1 2021-11-26 [3] CRAN (R 4.2.0)
## mime 0.12 2021-09-28 [3] CRAN (R 4.2.0)
## miniUI <IP_ADDRESS> 2018-05-18 [1] CRAN (R 4.1.2)
## pillar 1.8.1 2022-08-19 [3] CRAN (R 4.2.1)
## pkgbuild 1.4.0 2022-11-27 [1] CRAN (R 4.1.2)
## pkgconfig 2.0.3 2019-09-22 [3] CRAN (R 4.0.1)
## pkgload 1.3.0 2022-06-27 [1] CRAN (R 4.1.2)
## prettyunits 1.1.1 2020-01-24 [3] CRAN (R 4.0.1)
## processx 3.8.0 2022-10-26 [3] CRAN (R 4.2.1)
## profvis 0.3.7 2020-11-02 [1] CRAN (R 4.1.2)
## promises <IP_ADDRESS> 2021-02-11 [1] CRAN (R 4.1.2)
## ps 1.7.2 2022-10-26 [3] CRAN (R 4.2.2)
## purrr 1.0.1 2023-01-10 [1] CRAN (R 4.1.2)
## R6 2.5.1 2021-08-19 [3] CRAN (R 4.2.0)
## Rcpp 1.0.9 2022-07-08 [1] CRAN (R 4.1.2)
## remotes 2.4.2 2021-11-30 [1] CRAN (R 4.1.2)
## rlang 1.0.6 2022-09-24 [1] CRAN (R 4.1.2)
## rmarkdown 2.18 2022-11-09 [3] CRAN (R 4.2.2)
## rstudioapi 0.14 2022-08-22 [3] CRAN (R 4.2.1)
## sass 0.4.2 2022-07-16 [3] CRAN (R 4.2.1)
## sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.1.2)
## shiny 1.7.2 2022-07-19 [1] CRAN (R 4.1.2)
## stringi 1.7.8 2022-07-11 [3] CRAN (R 4.2.1)
## stringr 1.5.0 2022-12-02 [1] CRAN (R 4.1.2)
## tibble * 3.1.8 2022-07-22 [3] CRAN (R 4.2.2)
## urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.1.2)
## usethis 2.1.6 2022-05-25 [1] CRAN (R 4.1.2)
## utf8 1.2.2 2021-07-24 [3] CRAN (R 4.2.0)
## vctrs 0.5.2 2023-01-23 [1] CRAN (R 4.1.2)
## weasel * 0.1.0 2023-06-09 [1] local
## xfun 0.34 2022-10-18 [3] CRAN (R 4.2.1)
## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.1.2)
## yaml 2.3.6 2022-10-18 [3] CRAN (R 4.2.1)
##
## [1] /home/jono/R/x86_64-pc-linux-gnu-library/4.1
## [2] /usr/local/lib/R/site-library
## [3] /usr/lib/R/site-library
## [4] /usr/lib/R/library
##
## ──────────────────────────────────────────────────────────────────────────────


--- layout: page status: publish published: true title: Class Members as Callbacks author: display_name: Tomas Restrepo login: tomasr email<EMAIL_ADDRESS>url: http://winterdom.com/ author_login: tomasr author_email<EMAIL_ADDRESS>author_url: http://winterdom.com/ wordpress_id: 1060 wordpress_url: http://winterdom.com/?page_id=1060 date: '2009-04-27 04:02:40 +0000' date_gmt: '2009-04-27 04:02:40 +0000' categories: - Uncategorized tags: [] comments: [] ---
This is a topic that pops up regularly on
Microsoft's Visual C++ newsgroups. In these
days, many people are changing, evolving from procedural designs to more object-oriented
ones. Under Windows, where callbacks are a necessary evil, this causes some trouble.
It's necessary to understand why the trouble arises in the first place.
As many of you know, callbacks are a special kind of function you don't call yourself directly.
Instead, you give a pointer to the function to another function, so that Windows can call
it when it's need it. An example of this are windows procedures, and enumeration functions.
To make this process work correctly, strict typedefs are define in the
Windows header files. If you try to use a class member as a callback, the compiler will
give you an error, saying that the member prototype does not match the required typedef.
You know you defined the member correctly, yet it doesn't work. So you try using the
address of operator '&', and all you get is a different error from the compiler. What's up?
The answer is simple, yet is not clearly stated anywhere. In C++, class member functions
have a hidden parameter on the stack, which is actually the this
pointer. That's what allows a member function to access other members in the particular
class instance.
There's only one way to get rid of the this pointer: making the member
static. This brings other, more important and hard to solve problems. If you can't access
the class from your callback, then what's the use of putting it in a class? You have to
find a way of getting around this limitation. The most ugly hack is, of course, putting the
instance of the class as a global variable, which the callback can access. While this solves the
problem, it isn't very object oriented, and it leads to code that can be hard to maintain.
Windows itself gives you the answer to this problem for many of the
most used callbacks. Many functions that require callbacks allow you to pass an extra, application
defined, parameter to the callback, which you can use to give the callback access to the class instance. An example of
this are the CreateWindow()
, EnumChildWindows()
, EnumResourceNames()
and many others.
The above mentioned solutions are the easiest ways to get around this
problem, but are not the only ones. If you're good in assembly (which I'm not, so I'm not even going
to try and explain it), you can write a little stub that allows you to use a non static member function as a callback.
For this you need to write a piece of inline assembly in a static member of the class, and use it
as callback. This stub then handles parameters to the *real* non static member that does the
real work. This is very similar to what Microsoft's own Active Template Library (ATL) does
for it's window procedure implementation.
A particular case of this problem is creating window classes.
Well, the easiest way is to use the mechanism provided by the Window creation
routines themselves. What you can do, is have your window class have a static
WndProc method, that you register as the window's window procedure. To give the
this pointer to WndProc
, you have to take a two step approach:
Pass the this pointer in the LPARAM
argument of
CreateWindow()
On WndProc
, when you handle WM_CREATE
, store the pointer
received on the window data, using SetWindowLong()
with GWL_USERDATA
index.
On Subsequent messages, you can then retrieve the instance
pointer through GetWindowLong()
, cast it back to your class and call through it.
One note though: If your class is a dialog wrapper, you can't use GWL_USERDATA
to store the pointer. Instead, you need to use the DWL_USER
index.


|
iota.lib.cpp
IOTA C++ Library
|
#include <extended.hpp>
Public Member Functions | |
| Extended (const std::string &host, const uint16_t &port, Crypto::SpongeType cryptoType=Crypto::SpongeType::KERL) | |
| Responses::GetBalancesAndFormat | getInputs (const Types::Trytes &seed, const int32_t &start, const int32_t &end, const int32_t &security, const int64_t &threshold) const |
| Responses::GetBalancesAndFormat | getBalancesAndFormat (const std::vector< Types::Trytes > &addresses, const int64_t &threshold, const int32_t &start, const int32_t &security, const Utils::StopWatch &stopWatch={}) const |
| Responses::GetNewAddresses | getNewAddresses (const Types::Trytes &seed, const uint32_t &index=0, const int32_t &security=2, bool checksum=false, const int32_t &total=0, bool returnAll=false) const |
| Models::Bundle | traverseBundle (const Types::Trytes &trunkTx) const |
| Models::Bundle | traverseBundle (const Types::Trytes &trunkTx, Types::Trytes bundleHash, Models::Bundle &bundle) const |
| std::vector< Models::Bundle > | bundlesFromAddresses (const std::vector< IOTA::Types::Trytes > &addresses, bool inclusionStates) const |
| std::vector< Models::Transaction > | findTransactionObjects (const std::vector< IOTA::Types::Trytes > &addresses) const |
| std::vector< Models::Transaction > | getTransactionsObjects (const std::vector< IOTA::Types::Trytes > &trx_hashes) const |
| std::vector< Models::Transaction > | findTransactionObjectsByBundle (const std::vector< IOTA::Types::Trytes > &input) const |
| Responses::GetInclusionStates | getLatestInclusion (const std::vector< Types::Trytes > &hashes) const |
| std::vector< Types::Trytes > | prepareTransfers (const Types::Trytes &seed, int security, std::vector< Models::Transfer > &transfers, const std::string &remainder, const std::vector< Models::Input > &inputs, bool validateInputs=true) const |
| Responses::GetBundle | getBundle (const Types::Trytes &transaction) const |
| Responses::GetTransfers | getTransfers (const Types::Trytes &seed, int start, int end, int security, bool inclusionStates) const |
| void | replayTransfer () const |
| Responses::SendTransfer | sendTransfer (const Types::Trytes &seed, int security, int depth, int minWeightMagnitude, std::vector< Models::Transfer > &transfers, const std::vector< Models::Input > &inputs, const Types::Trytes &address) const |
| std::vector< Models::Transaction > | sendTrytes (const std::vector< Types::Trytes > &trytes, const unsigned int &depth, const unsigned int &minWeightMagnitude) const |
| Responses::Base | broadcastAndStore (const std::vector< Types::Trytes > &trytes) const |
| Responses::FindTransactions | findTransactionsByAddresses (const std::vector< Types::Trytes > &addresses) const |
| Responses::FindTransactions | findTransactionsByTags (const std::vector< Types::Trytes > &tags) const |
| Responses::FindTransactions | findTransactionsByApprovees (const std::vector< Types::Trytes > &approvees) const |
| Responses::FindTransactions | findTransactionsByBundles (const std::vector< Types::Trytes > &bundles) const |
| Responses::GetAccountData | getAccountData (const Types::Trytes &seed, int index, int security, bool checksum, int total, bool returnAll, int start, int end, bool inclusionStates, long threshold) const |
| Types::Trytes | findTailTransactionHash (const Types::Trytes &hash) const |
| std::vector< Types::Trytes > | addRemainder (const Types::Trytes &seed, const unsigned int &security, const std::vector< Models::Input > &inputs, Models::Bundle &bundle, const Types::Trytes &tag, const int64_t &totalValue, const Types::Trytes &remainderAddress, const std::vector< Types::Trytes > &signatureFragments) const |
| Responses::ReplayBundle | replayBundle (const Types::Trytes &transaction, int depth, int minWeightMagnitude) |
| std::vector< Models::Transaction > | initiateTransfer (int securitySum, const Types::Trytes &inputAddress, const Types::Trytes &remainderAddress, std::vector< Models::Transfer > &transfers) const |
| Public Member Functions inherited from IOTA::API::Core | |
| Core (const std::string &host, const uint16_t &port) | |
| Responses::GetNodeInfo | getNodeInfo () const |
| Responses::GetNeighbors | getNeighbors () const |
| Responses::AddNeighbors | addNeighbors (const std::vector< std::string > &uris) const |
| Responses::RemoveNeighbors | removeNeighbors (const std::vector< std::string > &uris) const |
| Responses::GetTips | getTips () const |
| Responses::FindTransactions | findTransactions (const std::vector< Types::Trytes > &addresses, const std::vector< Types::Trytes > &tags, const std::vector< Types::Trytes > &approvees, const std::vector< Types::Trytes > &bundles) const |
| Responses::GetTrytes | getTrytes (const std::vector< Types::Trytes > &hashes) const |
| Responses::GetInclusionStates | getInclusionStates (const std::vector< Types::Trytes > &transactions, const std::vector< Types::Trytes > &tips) const |
| Responses::GetBalances | getBalances (const std::vector< Types::Trytes > &addresses, const int &threshold) const |
| Responses::GetTransactionsToApprove | getTransactionsToApprove (const int &depth) const |
| Responses::AttachToTangle | attachToTangle (const Types::Trytes &trunkTransaction, const Types::Trytes &branchTransaction, const int &minWeightMagnitude, const std::vector< Types::Trytes > &trytes) const |
| Responses::Base | interruptAttachingToTangle () const |
| Responses::Base | broadcastTransactions (const std::vector< Types::Trytes > &trytes) const |
| Responses::Base | storeTransactions (const std::vector< Types::Trytes > &trytes) const |
Extended API calls which will help do just about anything possible with IOTA. These are mostly wrapper functions of Core API calls. https://github.com/iotaledger/wiki/blob/master/api-proposal.md#proposed-api-calls
| std::vector< Types::Trytes > IOTA::API::Extended::addRemainder | ( | const Types::Trytes & | seed, |
| const unsigned int & | security, | ||
| const std::vector< Models::Input > & | inputs, | ||
| Models::Bundle & | bundle, | ||
| const Types::Trytes & | tag, | ||
| const int64_t & | totalValue, | ||
| const Types::Trytes & | remainderAddress, | ||
| const std::vector< Types::Trytes > & | signatureFragments | ||
| ) | const |
| seed | Tryte-encoded seed. |
| security | The security level of private key / seed. |
| inputs | List of inputs used for funding the transfer. |
| bundle | To be populated. |
| tag | The tag. |
| totalValue | The total value. |
| remainderAddress | If defined, this address will be used for sending the remainder value (of the inputs) to. |
| signatureFragments | The signature fragments. |
| Responses::Base IOTA::API::Extended::broadcastAndStore | ( | const std::vector< Types::Trytes > & | trytes | ) | const |
Wrapper function that does broadcastTransactions and storeTransactions.
| std::vector< Models::Bundle > IOTA::API::Extended::bundlesFromAddresses | ( | const std::vector< IOTA::Types::Trytes > & | addresses, |
| bool | inclusionStates | ||
| ) | const |
function to get the formatted bundles of a list of addresses.
| addresses | List of addresses. |
| inclusionStates | If true , it gets the inclusion states of the transfers. |
find transactions for addresses
filter tail/non tail transactions
find transactions for bundles of non tail transactions TODO: this will maybe re-query some tail transactions we already got (and we do filter that out in the next for loop) we maybe can filter the bundle list passed to findTransactionObjectsByBundle by restructuring the previous loop
add tail transactions found with findTransactionObjectsByBundle
| Types::Trytes IOTA::API::Extended::findTailTransactionHash | ( | const Types::Trytes & | hash | ) | const |
| hash | The hash of a transaction |
check if current trx is tail
if not, fetch based on bundle hash
| std::vector< Models::Transaction > IOTA::API::Extended::findTransactionObjects | ( | const std::vector< IOTA::Types::Trytes > & | addresses | ) | const |
Lookup transactions for given addresses and return a list of transaction objects
| addresses | Addresses for which transactions objects should be found |
get the transaction objects of the transactions
| std::vector< Models::Transaction > IOTA::API::Extended::findTransactionObjectsByBundle | ( | const std::vector< IOTA::Types::Trytes > & | input | ) | const |
Same as findTransactionObjects, but based on bundle hash
| input | Bundle hashes |
| Responses::FindTransactions IOTA::API::Extended::findTransactionsByAddresses | ( | const std::vector< Types::Trytes > & | addresses | ) | const |
Find the transactions which match the specified addresses.
| addresses | The list of addresses. |
| Responses::FindTransactions IOTA::API::Extended::findTransactionsByApprovees | ( | const std::vector< Types::Trytes > & | approvees | ) | const |
Find the transactions which match the specified approvees.
| approvees | The list of approvees of a transaction. |
| Responses::FindTransactions IOTA::API::Extended::findTransactionsByBundles | ( | const std::vector< Types::Trytes > & | bundles | ) | const |
Find the transactions which match the specified bundles.
| bundles | The list of bundle hashes that need to be extended to 81 chars by padding the hash with 9's. |
| Responses::FindTransactions IOTA::API::Extended::findTransactionsByTags | ( | const std::vector< Types::Trytes > & | tags | ) | const |
Find the transactions which match the specified tags.
| tags | The list of transaction tags. |
| Responses::GetAccountData IOTA::API::Extended::getAccountData | ( | const Types::Trytes & | seed, |
| int | index, | ||
| int | security, | ||
| bool | checksum, | ||
| int | total, | ||
| bool | returnAll, | ||
| int | start, | ||
| int | end, | ||
| bool | inclusionStates, | ||
| long | threshold | ||
| ) | const |
Similar to getTransfers, just that it returns additional account data
| seed | Tryte-encoded seed. It should be noted that this seed is not transferred. |
| security | The Security level of private key / seed. |
| index | Key index to start search from. If the index is provided, the generation of the address is not deterministic. Default is 0. |
| checksum | Adds 9-tryte address checksum. |
| total | Total number of addresses to generate. 0 for unlimited |
| returnAll | If true , it returns all addresses which were deterministically generated (until findTransactions returns null). |
| start | Starting key index. 0 to skip. |
| end | Ending key index. 0 to skip. |
| inclusionStates | If true , it gets the inclusion states of the transfers. |
| threshold | Min balance required. 0 to skip. |
| Responses::GetBalancesAndFormat IOTA::API::Extended::getBalancesAndFormat | ( | const std::vector< Types::Trytes > & | addresses, |
| const int64_t & | threshold, | ||
| const int32_t & | start, | ||
| const int32_t & | security, | ||
| const Utils::StopWatch & | stopWatch = {} |
||
| ) | const |
Gets the balances and formats the output.
| addresses | The addresses. |
| threshold | Min balance required. |
| start | Starting key index. |
| stopWatch | the stopwatch. |
| security | The security level of private key / seed. |
retrieve balances for all given addresses
retrieve balance for given address
skip if no balance
Add input to result and increase totalBalance of all aggregated inputs
TODO: is this break necessary? (that's the logic of the reference java client) threshold is defined as minimum balance expected, but here we stop the process whenever threshold is reached (if different from 0) so is it an expected behavior? If so, why so? Maybe we will get more clues further during the development of other API
| Responses::GetBundle IOTA::API::Extended::getBundle | ( | const Types::Trytes & | transaction | ) | const |
Gets the associated bundle transactions of a single transaction Does validation of signatures, total sum as well as bundle order
| transaction | Hash of a tail transaction |
get bundle hash for transaction
init curl
sums up transaction values
Absorb bundle hash + value + timestamp + lastIndex + currentIndex trytes.
if transaction has some value, we can processs next transactions
Find the subsequent txs with the remaining signature fragment
Check for total sum, if not equal 0 return error
Check if bundle hash is the same as returned by tx object
Last tx in the bundle should have currentIndex == lastIndex
Validate the signatures
| Responses::GetBalancesAndFormat IOTA::API::Extended::getInputs | ( | const Types::Trytes & | seed, |
| const int32_t & | start, | ||
| const int32_t & | end, | ||
| const int32_t & | security, | ||
| const int64_t & | threshold | ||
| ) | const |
Gets all possible inputs of a seed and returns them with the total balance. This is either done deterministically (by genearating all addresses until findTransactions is empty and doing getBalances), or by providing a key range to use for searching through.
| seed | Tryte-encoded seed. It should be noted that this seed is not transferred. |
| security | The Security level of private key / seed. |
| start | Starting key index. |
| end | Ending key index. |
| threshold | Min balance required. |
| Responses::GetInclusionStates IOTA::API::Extended::getLatestInclusion | ( | const std::vector< Types::Trytes > & | hashes | ) | const |
Wrapper function for getNodeInfo and getInclusionStates
| hashes | The hashes. |
| Responses::GetNewAddresses IOTA::API::Extended::getNewAddresses | ( | const Types::Trytes & | seed, |
| const uint32_t & | index = 0 , |
||
| const int32_t & | security = 2 , |
||
| bool | checksum = false , |
||
| const int32_t & | total = 0 , |
||
| bool | returnAll = false |
||
| ) | const |
Generates a new address from a seed and returns the remainderAddress. This is either done deterministically, or by providing the index of the new remainderAddress.
| seed | Tryte-encoded seed. It should be noted that this seed is not transferred. |
| security | Security level to be used for the private key / address. Can be 1, 2 or 3. |
| index | Key index to start search from. If the index is provided, the generation of the address is not deterministic. |
| checksum | Adds 9-tryte address checksum. |
| total | Total number of addresses to generate. |
| returnAll | If true , it returns all addresses which were deterministically generated (until findTransactions returns null). |
| std::vector< Models::Transaction > IOTA::API::Extended::getTransactionsObjects | ( | const std::vector< IOTA::Types::Trytes > & | trx_hashes | ) | const |
Lookup transactions for given transaction hashes and return a list of transaction objects
| trx_hashes | Hashes of the transactions to find |
get trytes forhashes
build response
| Responses::GetTransfers IOTA::API::Extended::getTransfers | ( | const Types::Trytes & | seed, |
| int | start, | ||
| int | end, | ||
| int | security, | ||
| bool | inclusionStates | ||
| ) | const |
Returns the transfers which are associated with a seed. The transfers are determined by either calculating deterministically which addresses were already used, or by providing a list of indexes to get the transfers from.
| seed | Tryte-encoded seed. It should be noted that this seed is not transferred. |
| security | The security level of private key / seed. |
| start | Starting key index. |
| end | Ending key index. |
| inclusionStates | If true , it gets the inclusion states of the transfers. |
| std::vector< Models::Transaction > IOTA::API::Extended::initiateTransfer | ( | int | securitySum, |
| const Types::Trytes & | inputAddress, | ||
| const Types::Trytes & | remainderAddress, | ||
| std::vector< Models::Transfer > & | transfers | ||
| ) | const |
Prepares transfer by generating the bundle with the corresponding cosigner transactions. Does not contain signatures.
| securitySum | The sum of security levels used by all co-signers. |
| inputAddress | Array of input addresses as well as the securitySum. |
| remainderAddress | Has to be generated by the cosigners before initiating the transfer, can be null if fully spent. |
If message or tag is not supplied, provide it Also remove the checksum of the address if it's there
validate input address
Create a new bundle
Iterate over all transfers, get totalValue and prepare the signatureFragments, message and tag
If message longer than 2187 trytes, increase signatureMessageLength (add 2nd transaction)
Get total length, message / maxLength (MaxTrxMsgLength trytes)
copy msg
While there is still a message, copy it
Else, get single fragment with MaxTrxMsgLength of 9's trytes
get current timestamp in seconds
If no tag defined, get 27 tryte tag.
Pad for required TagLength tryte length
Add first entry to the bundle
Sum up total value
Get inputs if we are sending tokens
Add input as bundle entry Only a single entry, signatures will be added later
Return not enough balance error
If there is a remainder value Add extra output to send remaining funds to
| Responses::ReplayBundle IOTA::API::Extended::replayBundle | ( | const Types::Trytes & | transaction, |
| int | depth, | ||
| int | minWeightMagnitude | ||
| ) |
Replays a transfer by doing Proof of Work again.
| transaction | The transaction. |
| depth | The depth. |
| minWeightMagnitude | The minimum weight magnitude. |
| void IOTA::API::Extended::replayTransfer | ( | ) | const |
Takes a tail transaction hash as input, gets the bundle associated with the transaction and then replays the bundle by attaching it to the tangle.
| Responses::SendTransfer IOTA::API::Extended::sendTransfer | ( | const Types::Trytes & | seed, |
| int | security, | ||
| int | depth, | ||
| int | minWeightMagnitude, | ||
| std::vector< Models::Transfer > & | transfers, | ||
| const std::vector< Models::Input > & | inputs, | ||
| const Types::Trytes & | address | ||
| ) | const |
Wrapper function that basically does prepareTransfers, as well as attachToTangle and finally, it broadcasts and stores the transactions locally.
| seed | Tryte-encoded seed |
| security | The security level of private key / seed. |
| depth | The depth. |
| minWeightMagnitude | The minimum weight magnitude. |
| transfers | Array of transfer objects. |
| inputs | List of inputs used for funding the transfer. |
| address | If defined, this address will be used for sending the remainder value (of the inputs) to. |
| std::vector< Models::Transaction > IOTA::API::Extended::sendTrytes | ( | const std::vector< Types::Trytes > & | trytes, |
| const unsigned int & | depth, | ||
| const unsigned int & | minWeightMagnitude | ||
| ) | const |
Wrapper function that gets transactions to approve, attaches to Tangle, broadcasts and stores.
| trytes | The trytes. |
| depth | The depth. |
| minWeightMagnitude | The minimum weight magnitude. |
| Models::Bundle IOTA::API::Extended::traverseBundle | ( | const Types::Trytes & | trunkTx | ) | const |
Basically traverse the Bundle by going down the trunkTransactions until the bundle hash of the transaction is no longer the same. In case the input transaction hash is not a tail, we return an error.
| trunkTx | Hash of a trunk or a tail transaction of a bundle. |
Check for invalid hash
| Models::Bundle IOTA::API::Extended::traverseBundle | ( | const Types::Trytes & | trunkTx, |
| Types::Trytes | bundleHash, | ||
| Models::Bundle & | bundle | ||
| ) | const |
Basically traverse the Bundle by going down the trunkTransactions until the bundle hash of the transaction is no longer the same. In case the input transaction hash is not a tail, we return an error.
| trunkTx | Hash of a trunk or a tail transaction of a bundle. |
| bundleHash | The bundle hash. |
| bundle | Bundle to be populated. |
get trytes for transaction
get transaction itself


public class Animator
extends java.lang.Object
| Modifier and Type | Field and Description |
|---|---|
private static long |
DEFAULT_DURATION
The default duration of the animation that shall be used if nothing is specified
|
private static int |
MAX_ALPHA
The maximum value of alpha for a fading animation
|
private static float |
MAX_SCALE
The maximum value that a view can be scaled to
|
private static float |
MID_ROTATION |
private static float |
MID_SCALE
The middle value that a view can be scaled to
|
private static int |
MIN_ALPHA
The minimum value of alpha for a fading animation
|
| Constructor and Description |
|---|
Animator() |
| Modifier and Type | Method and Description |
|---|---|
static android.view.animation.Animation |
createFadeInAnimation()
Function to create a fade in animation with the default duration
|
static android.view.animation.Animation |
createFadeInAnimation(long duration)
Function to create a fade in animation
|
static android.view.animation.Animation |
createFadeOutAnimation()
Function to create a fade out animation with the default duration
|
static android.view.animation.Animation |
createFadeOutAnimation(long duration)
Function to create a fade out animation
|
static android.view.animation.Animation |
createScaleAnimation(float from,
float to,
long duration)
Function to create a fade out animation
|
static android.view.animation.Animation |
createScaleDownAnimation()
Function to create a scale down animation with the default duration from 100% to 50%
|
static android.view.animation.Animation |
createScaleDownAnimation(long duration)
Function to create a scale up animation from 100% to 50%
|
static android.view.animation.Animation |
createScaleUpAnimation()
Function to create a scale up animation with the default duration from 50% to 100%
|
static android.view.animation.Animation |
createScaleUpAnimation(long duration)
Function to create a scale up animation from 50% to 100%
|
static android.view.animation.Animation |
createScaleUpCompleteAnimation()
Function to create a scale up animation with the default duration from 0% to 100%
|
static android.view.animation.Animation |
createSlideInFromBottom()
Function to create a sliding animation with the default duration from bottom
|
static android.view.animation.Animation |
createSlideInFromBottom(long duration,
long offset)
Function to create a sliding animation from bottom
|
static void |
createYFlipBackwardAnimation(android.view.View view)
Function to create a flip animation along the Y axis by -180 degrees with the default duration
|
static void |
createYFlipBackwardAnimation(android.view.View view,
long duration)
Function to create a flip animation along the Y axis by -180 degrees
|
static void |
createYFlipForwardAnimation(android.view.View view)
Function to create a flip animation along the Y axis by 180 degrees with the default duration
|
static void |
createYFlipForwardAnimation(android.view.View view,
long duration)
Function to create a flip animation along the Y axis by 180 degrees
|
private static long DEFAULT_DURATION
private static float MID_SCALE
private static float MAX_SCALE
private static int MAX_ALPHA
private static int MIN_ALPHA
private static float MID_ROTATION
public static android.view.animation.Animation createFadeInAnimation()
public static android.view.animation.Animation createFadeInAnimation(long duration)
duration
- the duration in milliseconds for which the animation would lastpublic static android.view.animation.Animation createFadeOutAnimation()
public static android.view.animation.Animation createFadeOutAnimation(long duration)
duration
- the duration in milliseconds for which the animation would lastpublic static android.view.animation.Animation createScaleUpAnimation()
public static android.view.animation.Animation createScaleUpAnimation(long duration)
duration
- the duration in milliseconds for which the animation would lastpublic static android.view.animation.Animation createScaleUpCompleteAnimation()
public static android.view.animation.Animation createScaleAnimation(float from, float to, long duration)
from
- the scale to start fromto
- the scale to end atduration
- the duration in milliseconds for which the animation would lastpublic static android.view.animation.Animation createScaleDownAnimation()
public static android.view.animation.Animation createScaleDownAnimation(long duration)
duration
- the duration in milliseconds for which the animation would lastpublic static android.view.animation.Animation createSlideInFromBottom()
public static android.view.animation.Animation createSlideInFromBottom(long duration, long offset)
duration
- the duration in milliseconds for which the animation would lastoffset
- the time offset in milliseconds after which the animation would startpublic static void createYFlipForwardAnimation(android.view.View view)
view
- the view that shall be flippedpublic static void createYFlipForwardAnimation(android.view.View view, long duration)
view
- the view that shall be flippedduration
- the duration in milliseconds for which the animation would lastpublic static void createYFlipBackwardAnimation(android.view.View view)
view
- the view that shall be flippedpublic static void createYFlipBackwardAnimation(android.view.View view, long duration)
view
- the view that shall be flippedduration
- the duration in milliseconds for which the animation would last


hackernews_tui
is a Terminal UI to browse Hacker News with vim-like key bindings.
hackernews_tui
is written in Rust with the help of Cursive TUI library. It uses HN Algolia search APIs to get Hacker News data.
The application mainly consists of the following views:
Story View
displaying a list of stories. There are different kinds of Story View
depending on the tag
it uses to filter stories:Front Page
: stories on the front-pageAll Stories
: all storiesAsk HN
: ask HN stories onlyShow HN
: show HN stories onlyJobs
: jobs stories onlyComment View
displaying a list of comments in a story.Serrch View
displaying a search bar and a list of stories matching the search query.If you are either
This application is a right tool for you :muscle:
Run cargo install hackernews_tui
to install the application as a binary.
master
branchRun
# git clone https://github.com/aome510/hackernews-TUI.git
# cd hackernews-TUI
# cargo build --release
to build the application then run
# ./target/release/hackernews_tui
to run the application
Run yay -S hackernews_tui
to install the application as an AUR package.
# pkgin install hackernews-tui
$ cd /usr/pkgsrc/www/hackernews-tui
# make install
A quick demo video made from hackernews_tui
version v0.5.0
:
In each View
, press <ctrl-h>
to see a list of supported keyboard shortcuts and their functionalities:
<ctrl-h>/<alt-h>
: Open the help dialog<ctrl-q>/<alt-q>
: Quit the application<ctrl-p>/<alt-p>
: Go to the previous view<ctrl-f>/<alt-f>
: Go to front page view<ctrl-s>/<alt-s>
: Go to search view<ctrl-z>/<alt-z>
: Go to all stories view<ctrl-x>/<alt-x>
: Go to ask HN view<ctrl-c>/<alt-c>
: Go to show HN view<ctrl-v>/<alt-v>
: Go to jobs viewView
j
: Focus the next storyk
: Focus the previous storyt
: Focus the story at the topb
: Focus the story at the bottom{story_id} g
: Focus the {story_id}-th story<enter>
: Go the comment view associated with the focused storyO
: Open in browser the link associated with the focused storyS
: Open in browser the focused storyn
: Go to the next pagep
: Go the previous paged
: Toggle sort by date/popularityq
: Filter stories past 24 hoursw
: Filter stories past weeke
: Filter stories past monthr
: Filter stories past yearj
: Focus the next commentk
: Focus the previous commentn
: Focus the next top level commentp
: Focus the previous top level commentl
: Focus the next comment with smaller or equal levelh
: Focus the previous comment with smaller or equal levelt
: Focus the comment at the topb
: Focus the comment at the bottomr
: Reload the comment view.O
: Open in browser the link associated with the discussed storyS
: Open in browser the discussed storyC
: Open in browser the focused comment{link_id} f
: Open in browser the {link_id}-th link in the focused commentIn SearchView
, there are two modes: Navigation
and Search
. The default mode is Search
.
Search
mode is similar to Vim's Insert mode, in which users can input the query string.

Key shortcuts:
i
: Enter Search
mode from Navigation
mode<esc>
: Enter Navigation
mode from Search
modeNavigation
mode also supports all StoryView
's key shortcuts beside q
,w
,e
,r
.
By default, the application will look for ~/.config/hn-tui.toml
as its configuration file.
You can specify the path by specifying the -c
or --config
argument when running the application:
hackernews_tui -c ~/.config/hn-tui.toml
For the further information about the config options, please refer to the example config file by running hackernews_tui --example-config
.
Note: all config options (as included in the example config file) are required. You can run
hackernews_tui --example-config > ~/.config/hn-tui.toml
then modify the config options in ~/.config/hn-tui.toml
based on your preferences.


Changelog
Version 1
Version 1.0.0
- New
#sun_info
method for sunset/sunrise times
- Add
:image_url
to simple forecast return hash
- Add
:date
, :weekday_name
, and :image_url
to complex forecast return data
- Improve documentation across the library. The recommended place for docs is now
GitHub Pages instead of RubyDocs.info
#get
is now private
- Remove
autoparse
parameter from #get
- Fix
#hurricane_data
by ignoring the WeatherError
thrown by that API
- Return
Time
and DateTime
objects instead of String
s for timestamp values across the library.
Version 0
Version 0.6.1
- Update to StringUtility 3.0
Version 0.6.0
- Error handling is much more generic now, with a single WeatherError which gets its message from the Weather
Underground API. With this is also the removal of the
verbose
option. Lastly, no method will return an error
silently, but actually fail
with the WeatherError.
language_key
is now an attribute accessor.
Version 0.5.3
- Update to HTTPClient 2.8
- Use pessimistic version requirements, and actually add version requirements for Rainbow and StringUtility.
Version 0.5.2
Version 0.5.1
- Update to HTTPClient 2.7 and Ruby 2.3
Version 0.5.0
- Add support for all Weather Underground Planner APIs.
Version 0.4.2
- No longer fails with an ArgumentError if the CLI is passed no arguments. Instead it outputs the usage information, so that it is actually a useful thing.
Version 0.4.1
Version 0.4.0
- New weatheruby executable.
- Fail when there are many results and it cannot get actual data.
- Many style fixes.
Version 0.3.1
- Fix forecast names to 10day, and made it apparent in documentation that the non-10 day methods are only for the next 3 days.
Version 0.3.0
- Proper error handling, with new initialization parameter verbose_errors.
Version 0.2.0
- New complex_forecast_10day and simple_forecast_20day.
- New complex_forecast and simple_forecast methods. It’s funny, complex_forecast uses the simpleforecast stuff from the API.
- New hurricane_data method.
- New record_low and record_high methods.
Version 0.1.0
- Intial version. Includes #conditions, #moon_phase, and #alerts.


INF4883 - Enterprise Architecture - Research - Enterprise Architecture at Work - Chapter 4
Communication of Enterprise Architectures
4.1 Introduction
Describing architectures is all about communication. If some architecture description is not used as a means of communication in some shape or form, then this description should not have been created in the first place. Whatever the role of an architecture description is, it always involves some communicative aspect. Consider, as an illustration, the potential uses of architecture descriptions as identified in the IEEE 1471 standard (IEEE Computer Society 2000):
Expression of the system and its (potential) evolution.
Analysis of alternative architectures.
Business planning for transition from a legacy architecture to a new architecture.
Communications among organisations involved in the development, production, fielding, operation, and maintenance of a system.
Communications between acquirers and developers as a part of contract negotiations.
Criteria for certifying conformance of implementations to the architecture.
Development and maintenance documentation, including material for reuse repositories and training material.
Input to subsequent system design and development activities.
Input to system generation and analysis tools.
Operational and infrastructure support; configuration management and repair; redesign and maintenance of systems, subsystems, and components.
Planning and budget support.
Preparation of acquisition documents (e.g., requests for proposal and statements of work).
Review, analysis, and evaluation of the system across the life cycle.
Specification for a group of systems sharing a common set of features, (e.g., product lines).
Each of these uses of architecture involves forms of communication. In this vein, in this chapter we present a ‘communication-aware’ perspective of enterprise architectures. In doing so, we provide both a theoretical and a practical perspective of the issues involved in the communication of enterprise architectures. The theoretical perspective will focus on communication during system development in general, where the word system should be interpreted as any open and active system, consisting of both human and computerised actors, that is purposely designed. The practical perspective will take shape as a set of practical guidelines that should aid architects in the selection (and definition) of architecture description languages and approaches that are apt for a specific (communication) situation.
Architecture descriptions are used to communicate the architecture of a planned or pre-existing system. This could be a system that is part of an enterprise, an organisation, a business, an information system, a software system, or the hardware infrastructure. The communication about the system and its architecture is likely to take place between different stakeholders of that system.
In this book, the primary focus is on architectural models of a graphical (as opposed to a textual or verbal) nature. One may refer to these as architectural models ‘in the narrow sense’. In this chapter, however, we are concerned with architecture descriptions in ‘the broader sense’. In other words, textual, verbal, or any other types of architecture descriptions are included.
At present, many description languages are already available to architects, while many more are being created by both academia and industry. Why all these languages? How does one select the language that is most apt in a given situation? Such questions beg for a well-conceived answer. In line with the old adage ‘practice what you preach’, we argue that just as proper requirements engineering is needed for the development of systems, proper requirements should also be formulated for languages and approaches that are to be used as vehicles for communication during system development. In formulating these requirements, several factors should be taken into account, such as the development goals, the communication goals, the concerns, personal goals, abilities, and attitudes of the actors involved, etc.
We set out to provide a theoretical underpinning of the issues involved, as well as practical guidelines that will aid architects in selecting the best approach for their architectural communicative needs. We will therefore start out with a theoretical exploration of the issues involved in communication during system development (Sects. 4.2 and 4.3), followed by the application of this exploration to the field of enterprise architecture (Sect. 4.4).
4.2 System Development as a Knowledge Transformation Process
In essence, we regard system development as a knowledge transformation process whereby conversations are used to share and create knowledge pertaining to both the system being developed, as well as the development process itself. The notion of ‘conversation’ should be interpreted here in the broadest sense, ranging from a single person producing an (architectural) description, via a one-on-one design or elicitation session, to a workshop with several stakeholders, and even the widespread dissemination of definitive architectures. This way of thinking provides a frame of thought with which one can better understand the (communicative) requirements posed on architecture description languages.
4.2.1 System Development Community
Given our focus on communication, it is important to identify the actors that can play a role in the communication that takes place during the system development process. These actors are likely to have some stake with regards to the system being developed. Examples of such actors are problem owners, prospective actors in the future system (such as the future ‘users’ of the system), domain experts, sponsors, architects, engineers, business analysts, etc.
These actors, however, are not the only ‘objects’ playing an important role in system development. Another important class of objects are the many different documents, models, forms, etc., that represent bits and pieces of knowledge pertaining to the system that is being developed. This entire group of objects, and the different roles they can play, is what we shall refer to as a system development community.
(We will clarify below why we regard documents as being part of the community.)
The actors in a system development community will (typically as a consequence of their stakes) have some specific interests with regards to the system being developed. This interest implies a sub-interest with regard to (the contents of) the system descriptions that are communicated within the community. This interest, in line with the ISO/IEC/IEEE 42010:2011 standard (ISO/IEC/IEEE 2011), is referred to as the concern of stakeholders.
Some examples of concerns are:
The current situation with regards to the computerised support of a business process.
The requirements of a specific stakeholder with regards to the desired situation.
The improvements, which a new system may bring, to a pre-existing situation in relation to the costs of acquiring the system.
The potential impact of a new system on the activities of a prospective user.
The potential impact of a new system on the work of the system administrators that are to maintain the new system.
4.2.2 System Development Knowledge
The system development community harbours knowledge about the system being developed. The communication occurring within a system development community essentially is aimed at creating, furthering, and disseminating this knowledge. Depending on their concerns, stakeholders will be interested in different knowledge topics pertaining to the system being developed.
We will now briefly explore the kinds of knowledge that are relevant to a system and its development; in other words, the knowledge topics that can be distinguished. In the next subsections, we will discuss in more detail in what ways this knowledge can be made (more) explicit.
During system development, members of the system development community will create and exchange knowledge pertaining to different topics. We can make a first distinction between the target domain pertaining to the system being developed and the project domain, about the development process itself. We have borrowed these terms from the Information Services Procurement Library (ISPL) (Franckson and Verhoef 1999). For both of these knowledge domains, further refinements can be made with regards to the possible topics. We identify the following additional characterisations:
Perspective: Artefacts, such as systems, can be considered from different perspectives. Some examples are:
business, application, and technology aspects of a (computerised) information system;
social, symbolical, and physical aspects of a system;
process, information, actors, and technology featuring in a system.
In Chap. 8, the notion of ‘viewpoint’ will be discussed in depth. A viewpoint takes a specific perspective of a system. The concept of viewpoint is, however, not synonymous with perspective as the former includes some additional items, such as the modelling language that is to be used to describe the system from the given perspective. In contrast, a perspective is purely ‘topical’.
Scope: Given a domain, such as a system or a development project, we can identify several scopes when approaching the domain: enterprise-wide, department-specific, task-specific, etc.
Design chain: When considering the design of some artefact, a distinction can be made between:
Purpose: to what purpose the artefact is needed.
Functionality: what functionality the artefact should provide to its environment.
Design: how it should realise this functionality.
Quality: how well it should do so
Costs: at what cost it may do so, and may be constructed.
This distinction applies to the target domain as well as the project domain. In the latter case, the project’s execution plan/strategy is the designed artefact. Based on the above distinction, knowledge topics can be characterised in terms of their focus on, for example, functionality or quality in isolation, or their focus on bridging the gaps between purpose, functionality, and design in terms of design rationale.
Historical perspective: Given an artefact with a design, one may consider different versions of this artefact’s design over time. In the case of a system, one may consider the current version, the version that will be in existence after the development project has finished, and the (sketchy) version of the ‘future’ system that serves as a navigational beacon in a sea of possibilities to guide future development. In the case of a development process, one may consider the execution plan/strategy that is being used at the moment, or the plan/strategy that was used before.
Abstraction level: When considering a domain, one may do so at several levels of abstraction. Various forms of abstraction can be distinguished: for example, type-instance, generalisation/is-a, encapsulation, and hiding of implementation details.
As mentioned before, depending on their concerns, stakeholders may be interested in different knowledge topics. For example, a financial controller will be interested in an investment perspective of the overall scope of a future system, a designer will be interested in all aspects of the design chain from different perspectives, etc.
4.2.3 Explicitness of Knowledge
The actors in a system development community have a need to communicate system development knowledge among each other. In the field of knowledge management, a key distinction is made between explicit and tacit knowledge (Nonaka and Takeuchi 1991). Explicit knowledge refers to knowledge that can be externalised in terms of some representation. With representation of knowledge, we refer to the process of encoding knowledge in terms of some language on some medium, e.g., creating an architecture model.
However, not all forms of knowledge lend themselves well to explicit representation. For example, the ability to maintain one’s balance on a bicycle is learned by (painful) trial and error rather than reading instructions. This knowledge is actively and personally passed on from generation to generation: parents assist their children in this process by encouraging them and by protecting them from serious injury during the trial-and-error process. In Nonaka and Takeuchi (1991), this is referred to as socialising as a means to transfer knowledge that cannot be made explicit. The type of knowledge concerned, which cannot easily be represented on a medium, is referred to as tacit knowledge.
Our focus is on the communication of system development knowledge by way of explicit representations, in other words explicit knowledge. In the context of this book, these representations mainly take the form of architecture descriptions. As discussed in Sect. 4.1, our initial theoretical considerations cover development of systems in general. In accordance with this generalisation we will, for now, use the terms systems description and system description language rather than the terms architecture description and architecture description language.
System descriptions are essentially forms of explicit knowledge pertaining to an existing/future system: its design, the development process by which it was/is to be created, the underlying considerations, etc. Given this focus, we can make a more precise classification with regards to what we mean by ‘explicitness’. Based on Franckson and Verhoef (1999) and Proper (2001), we identify the following dimensions of explicitness for representations of system development knowledge:
Formality: The degree of formality indicates the type of language used to represent the knowledge. Such a language could be formal, in other words a language with an underlying well-defined semantics in some mathematical domain, or it could be informal—not mathematically underpinned, typically natural language, graphical illustrations, animations, etc.
Quantifiability: Different aspects of the designed artefact, be it (part of) the target or the project domain, may be quantified. Quantification may be expressed in terms of volume, capacity, workload, effort, resource, usage, time, duration, frequency, etc.
Executability: The represented knowledge may, where it concerns artefacts with operational behaviour, be explicit enough so as to allow for execution. This execution may take the form of a simulation, a prototype, generated animations, or even fully operational behaviour based on executable specifications.
Comprehensibility: The knowledge representation may not be comprehensible to the indented audience. Tuning the required level of comprehensibility of the representation, in particular the representation language used, is crucial for effective communication. The representation language may offer special constructs to increase comprehension, such as stepwise refinements, grouping/clustering of topically related items/statements, etc.
Completeness: The knowledge representation may be complete, incomplete, or overcomplete with regards to the knowledge topic (see previous subsection) it intends to cover.
4.2.4 Transformations of Knowledge
During the development of a system, the knowledge about the system and its development will evolve. New insights emerge, designs are created, views are shared, opinions are formed, design decisions made, etc. These all lead to transformations of the ‘knowledge state’ of the development community as a whole. The transformations of this ‘knowledge state’ are brought about by conversations. This immediately raises the question: what are these ‘knowledge states’?
The discussion above already provides us with some insight into the answer to this question. The representations and the actors in a development community can both be seen as harbouring certain knowledge topics. As such, both representations and actors are (potential) knowledge carriers. Knowledge topics refer to some subdomain of the system being developed and/or its development process. The knowledge topics can therefore be classified further in terms of their focus, scope, etc., as discussed in Sect. 4.2.2.
The actual knowledge that is harboured by a knowledge carrier is not explicitly taken into account. The knowledge that is available from/on/in a knowledge carrier is a subjective notion. An aspect of this knowledge that we can reason about more objectively is its level of explicitness, as we have seen in Sect. 4.2.3.
The knowledge as it is present in a development community can be seen to evolve through a number of states. Knowledge first needs to be introduced into the community, either by creating the knowledge internally or importing it from outside the community. Once the knowledge has been introduced into a community, it can be shared among members of that community. Sharing knowledge between different actors may progress through a number of stages. We distinguish three major stages:
Aware: An actor may become aware of (possible) knowledge by way of the sharing by another actor.
Agreed: Once knowledge is shared, an actor can make up his or her own mind about it, and decide whether or not to agree to the knowledge shared.
Committed: Actors who agree to a specific knowledge topic may decide actually to commit to this knowledge. In other words, they may decide to adapt their future behaviour in accordance with this knowledge.
There is no way to determine objectively and absolutely the level of awareness, agreement, or commitment of a given set of actors. It is in the eyes of the beholder. Since these ‘beholders’ are actors in the system development community, we can safely assume that some of them will be able to (and have a reason to) judge the level of sharing of knowledge between sets of actors, and communicate about this.
4.3 Conversation Strategies
The knowledge transformations as discussed in the previous section are brought about by conversations. These conversations may range from ‘atomic’ actions involving a small number of actors, via discussions and workgroups, to the development process as a whole. This has been illustrated informally in Fig. 4.1.
Each conversation is presumed to have some knowledge goal: a knowledge state which the conversation aims to achieve (or to maintain). In achieving this goal, a conversation will follow a conversation strategy. Such a strategy is needed to achieve the goal of the conversation, starting out from the current state.
Conversations take place in some situation that may limit the execution of the conversation. We may characterise such a situation further in terms of situational factors:
Availability of resources: Refers to the availability of resources that can be used in a conversation. The availability of resources can be refined to more specific factors such as time for execution, actors, intellectual capacities needed from the actors, or financial means.
Complexity: The resources needed for the conversation, the knowledge being conversed about, etc., will exhibit a certain level of complexity. This complexity also influences the conversation strategy to be followed. Examples of such complexity factors, inspired by Franckson and Verhoef (1999), are the heterogeneity of the actors involved, the quantity of actors, complexity of the technology used, the complexity of the knowledge being conversed about, and the size of the gap between the initial knowledge state and the desired knowledge state.
Uncertainty: If you want to determine a conversation strategy fit for a given situation, you have to make assumptions about the knowledge goal, the initial state, the availability of resources, as well as the complexities of these factors. During the execution of a conversation, some of these assumptions may prove to be wrong. For example, the commitment of certain actors involved may be lower than anticipated (initial state); materials needed for a workshop may not be available on time (resources); during a requirements elicitation session it may come to the fore that the actors involved do not (yet) have enough knowledge about the future system and its impact to formulate/reflect on the requirements of the future system (initial state).
Note that it may actually be part of a conversation strategy to first initiate conversations that aim to reduce these uncertainties, in order to reduce potential adverse consequences.
If you formulate a conversation strategy, you should take all of the abovementioned factors into account. A conversation strategy should typically cover at least the following elements:
Execution plan: As we said before, a conversation can be composed of subconversations. Each of these subconversations focuses on a sub-goal, but they all contribute towards the goal of the conversation as a whole. The execution plan of a (composed!) conversation consists of a set of subconversations, together with a planned execution order.
Description languages: The description languages to be used in the conversation(s).
Media: The kind of media to be used during the conversation(s).
Cognitive mode: The cognitive mode refers to the way in which knowledge is gathered or processed by the actors involved in a conversation. We distinguish two options:
Analytical approach: When information is processed analytically, the available information is simplified through abstraction in order to reach a deeper and more invariant understanding. An analytical approach is typically used to handle complexity.
Experimental approach: When using an experimental approach, the project actors learn from doing experiments. The purpose is to reduce uncertainties by generating more information. Experiments can, for example, be based on prototypes, mock-ups, benchmark tests of migrated components, or other kinds of techniques which make the results of migration scenarios visible.
You may need to combine the two cognitive modes in specific situations, in particular in the case of conversations that are composed of several smaller subconversations.
Social mode: The social mode is the way in which the actors executing the system development process collaborate with the actors from the business domain. We distinguish two options:
Expert-driven: In an expert-driven approach, project actors (the experts) will produce descriptions on the basis of their own expertise, and interviews and observations of business actors. The descriptions can then be delivered to the business actors for remarks or approval.
Participatory: In a participatory approach, the project actors produce the descriptions in close cooperation with some or all the business actors, e.g., in workshops with presentations, discussions and design decisions. A participatory approach may allow the acquisition of knowledge, the refinement of requirements and the facilitation of organisational change.
Communication mode: We can distinguish a small number of basic patterns of communication here, as covered by combinations of the following five factors:
Speaker–hearer ratio: Most typically many to one, one to many, one to one, many to many.
Response: Simply whether or not an answer is expected from the hearer; if a response is indeed expected, one response may lead to a further response, leading to dialogue and turn taking.
Time lag: Whether or not communication takes some time between ‘speaking’ and ‘hearing’. Consider the difference between a telephone call and an e-mail message.
Locality: Whether or not there is a perceived distance between participants. Note that this is a relative notion; two people communicating via videophone between Tokyo and Amsterdam may feel ‘close’, while two people from different departments housed in the same building may feel ‘distant’. Distance can be not only physical, but also cultural.
Persistency: Whether or not a message can be kept after communication, i.e., can be ‘reread’. This is of course closely linked to the medium used, but it may also be related to the status of a document: persistency of a ‘temporary document’ or intermediary version may actually be counterproductive.
We can use combinations of these factors to typify many different modes of communication, which can have a major impact on the resources required for communication and the likelihood that a knowledge goal is reached. For example, one-to-many communication is relatively efficient and effective, assuming that no immediate (n:1) response is given; however, if a time lag is added, n:1 responses become possible but the one participant will have to invest much time to digest all these responses. Also, if n:1 responses are given rapidly, but the communication is persistent (e.g., people respond through altered copies of a file), then these responses are no problem except for the load on the recipient. And if many relatively distant people participate, in-depth and contextdependent communication will be difficult.
In a modelling context, not all combinations (communication modes) will be relevant, but it is still vital to consider things like ‘Do I expect anyone to respond to this model?’; ‘How many people will have to respond?’; ‘How distant are they?’; ‘How quick will the response (have to) be?’; ‘How long will it take me to process responses?’, etc.
A summary of this discussion is provided in Fig. 4.2. Given a knowledge goal, an initial state, and conversation situation, a conversation strategy can be determined, which should lead us from the initial state to the knowledge state as desired by the knowledge goal, taking into account the conversation situation at hand.
4.4 Architectural Conversations
After the theoretical discussions of the previous sections, we now return to the practice of communicating enterprise architectures. The situation as depicted in Sect. 4.2 may indeed portray the underlying mechanics in theory, but it still leaves practitioners with the question of how actually to produce such a conversation strategy. In all fairness, current research into these matters is still in its initial stages. The theoretical model as discussed above will have to be scientifically validated and refined. In addition, practical heuristics should be formulated, matching elements from conversation strategies to conversation situations and thus addressing the gap between the knowledge goal and the initial state.
Even so, we can already provide practitioners with some guidance in selecting conversation strategies to communicate about enterprise architectures, by reducing the discussion of selecting a conversation strategy to the selection of a class of architectural conversation in conjunction with an appropriate architectural viewpoint. To direct this selection, we will define a number of classes of architectural knowledge goals. The selected viewpoints identify what shall be conversed about, and what language (and language conventions) shall be used to do so, while the selected conversation technique identifies the style of conversation that is to be used.
So this section provides a discussion of the classes of architectural knowledge goals and conversation techniques that we distinguish within the context of enterprise architecture, as well as their relationship. In Chap. 8, the notion of viewpoint will be discussed in more detail, and additional heuristics on the selection of viewpoints and conversation types will be given.
4.4.1 Knowledge Goals
In Sect. 4.2.4, we identified three major stages in communicating knowledge: awareness, agreement, and commitment. Based on these and on the levels of sharing of knowledge and explicitness of knowledge as identified in Sect. 4.2.3, we can identify the following classes of knowledge goals that you may want to achieve in a conversation:
Introduction of knowledge: This refers to situations where there is a need to introduce into or create new knowledge in a (part of a) development community. These kinds of knowledge goals typically lead to training or awareness sessions.
Agreement to knowledge: With this class of knowledge goals, we refer to situations in which the mutual agreement of different stakeholders (with their own specific stakes and concerns!) needs to be improved or validated.
Commitment to knowledge: In these cases, the knowledge goal goes beyond that of achieving agreement. Stakeholders should be willing to act upon the knowledge they agree to.
Note that the introduction of knowledge, as described above, may pertain to a subset of the development community. At the start of a system development project, the development team may not (yet!) have knowledge pertaining to the specific application domain. Domain experts and other informants, by nature of their roles, do have this knowledge. The development community as a whole comprises at least both the development team and the domain experts. A domain analysis session involving, for example, a business analyst and a domain expert introduces (part of) the domain knowledge of the domain expert into the development team.
4.4.2 Conversation Techniques
In architecture development, we find a number of common conversation techniques where it concerns the communication of architectural models:
Brown-paper session: Structured brainstorm-like group session (up to about 15 people) in which items (keywords or short phrases) are elicited from the individuals in the group in answer to a question such as: ‘What are the key functionality issues in our current IT architecture?’ Typically, every individual item is written on a small adhesive note (‘PostIt’). The items are then collected on a sheet of paper (traditionally of the cheap brown kind) and, by means of an open and creative group process, structured and categorised. This may involve adding, deleting, merging, or changing items. Usually, a mediator or facilitator is involved.
Elicitation interview: An interview where an analyst puts informative questions to the informants. The aim is to gather knowledge from the informants. Interviews can be more or less ‘open’: they can be strictly focused or guided, but the conversation can also be left open to go where the interest of the interviewer or informants leads it.
Workshop: Involves one to, say, 15 people, working on a model or view interactively, mediated by an architect or analyst. This class also encompasses so-called joint modelling sessions. A popular, effective, and realistic technique is to project a view or model and have a facilitator adapt it in full view of the participants, thus generating immediate feedback. With a few participants, a workshop can of course simply take place behind a screen and keyboard.
Validation interview: An interview where an analyst will aim to find out if the view or model matches the views and expectations of an informant. This could be a view or model that has been communicated to the informants beforehand, or during the interview. A validation interview will typically be much more ‘closed’ than an elicitation interview: there will have to be some systematic approach by which validity of the view or model is checked.
Committing review: A group of stakeholders are presented with a number of alternative models or views and their impact. They are requested to select one alternative and commit to this alternative based on their insights into the potential impact. This typically involves a formal decision-making processes (Franckson and Verhoef 1999).
Presentation: Involves one to three people presenting a model or view to a group of, say, up to a hundred people. One may decide to elicit feedback, but this is usually gathered afterwards, in a more personal way, or at least 1:1 (e.g. through a round of feedback).
Mailing: A form of ‘mass’ communication, where a model or view is presented or handed over to a large number of people. Feedback may or may not be encouraged.
Even though we have not yet discussed viewpoints, we can already relate the identified knowledge goals to the conversation techniques. This is shown in Table 4.1, which is based on interviews and discussions with many architects from industry.
This table can fruitfully be used in practice to choose the conversation technique for the task and knowledge goal at hand. In Chap. 8, we will have a more in-depth look at the use of viewpoints to assist communication between the different stakeholders.
4.5 Summary
In the previous sections, we have presented both a theoretical and a practical perspective of the issues involved in the communication of enterprise architectures. The theoretical perspective described the communication during system development in general. Based on the one hand on this theoretical view and on the other hand on the experiences of architects, the practical perspective presented a number of practical guidelines and conversation techniques that should aid architects in the selection and definition of architecture description approaches that are fit for a specific communication situation.


Manage Affiliates
| Affiliate |
City |
State |
MSA |
CSA |
Environment |
Age |
Cpacity |
Ad Views |
View |
| Wurst Bar |
Ypsilanti |
MI |
Ann Arbor |
Detroit-Warren-Ann Arbor |
Casual |
25-34 |
200 |
18.7 p/w |
View |
| The Gandy Dancer |
Ann Arbor |
MI |
Ann Arbor |
Detroit-Warren-Ann Arbor |
Upscale |
35-55 |
300 |
18.7 p/w |
View |
| Ted's Chow'n'Plow Diner |
Detroit |
MI |
Ann Arbor |
Detroit-Warren-Ann Arbor |
Upscale |
35-55 |
300 |
18.7 p/w |
View |


|
plibsys
0.0.4
|
Condition variable. More...
Go to the source code of this file.
Typedefs | |
| typedef struct PCondVariable_ | PCondVariable |
| Condition variable opaque data structure. More... | |
Functions | |
| P_LIB_API PCondVariable * | p_cond_variable_new (void) |
| Creates a new PCondVariable. More... | |
| P_LIB_API void | p_cond_variable_free (PCondVariable *cond) |
| Frees PCondVariable structure. More... | |
| P_LIB_API pboolean | p_cond_variable_wait (PCondVariable *cond, PMutex *mutex) |
| Waits for a signal on a given condition variable. More... | |
| P_LIB_API pboolean | p_cond_variable_signal (PCondVariable *cond) |
| Emitts a signal on a given condition variable for one waiting thread. More... | |
| P_LIB_API pboolean | p_cond_variable_broadcast (PCondVariable *cond) |
| Emitts a signal on a given condition variable for all the waiting threads. More... | |
Condition variable.
A condition variable is an inter-thread synchronization primitive, often used in the classical 'producers-consumers' concurrent data access models.
The main idea is to notify waiting thread(s) for some events before they can enter a critical section. Hence the name of the primitive: a thread enters the critical section upon an accomplished condition. Compare it with a mutex where the thread enters the critical section as soon as no one holds a lock.
Several threads can be notified at once, but only one of them can enter the critical section. The order of the threads in that case is implementation dependent.
As the thread enters the critical section upon a condition it still requires a mutex to guard its code against concurrent access from other threads. The mutex provided in pair with a condition variable will be automatically locked on the condition, the thread should unlock it explicitly after leaving the critical section. That mutex is unlocked while waiting for the condition and should be locked prior calling the condition waiting routine.
The waiting thread behavior: create a new condition variable with p_cond_variable_new(), create and lock a mutex before a critical section and wait for a signal from another thread on this condition variable using p_cond_variable_wait().
The signaling thread behavior: upon reaching event time emit a signal with p_cond_variable_signal() to wake up a single waiting thread or p_cond_variable_broadcast() to wake up all the waiting threads.
After emitting the signal only the one thread will get the locked mutex back to continue executing the critical section.
It is implementation dependent whether a thread will receive a missed signal (when a notification from the one thread was emitted prior another thread has been called for waiting), so do not rely on this behavior.
Definition in file pcondvariable.h.
| typedef struct PCondVariable_ PCondVariable |
Condition variable opaque data structure.
Definition at line 82 of file pcondvariable.h.
| P_LIB_API pboolean p_cond_variable_broadcast | ( | PCondVariable * | cond | ) |
Emitts a signal on a given condition variable for all the waiting threads.
| cond | Condition variable to emit the signal on. |
After emitting the signal all the threads waiting for it will be waken up.
| P_LIB_API void p_cond_variable_free | ( | PCondVariable * | cond | ) |
| P_LIB_API PCondVariable* p_cond_variable_new | ( | void | ) |
Creates a new PCondVariable.
| P_LIB_API pboolean p_cond_variable_signal | ( | PCondVariable * | cond | ) |
Emitts a signal on a given condition variable for one waiting thread.
| cond | Condition variable to emit the signal on. |
After emitting the signal only the one thread waiting for it will be waken up. Do not rely on a queue concept for waiting threads. Though the implementation is intended to be much close to a queue, it's not fairly enough. Due that any thread can be waken up, even if it has just called p_cond_variable_wait() while there are other waiting threads.
| P_LIB_API pboolean p_cond_variable_wait | ( | PCondVariable * | cond, |
| PMutex * | mutex | ||
| ) |
Waits for a signal on a given condition variable.
| cond | Condition variable to wait on. |
| mutex | Locked mutex which will remain locked after waiting. |
The calling thread will sleep until the signal on cond arrived.


Pirate (ARRR) is a cryptocurrency that solves the issue of financial privacy on the blockchain through forced anonymous transactions. Protect your wallet and transactions with Pirate’s completely anonymous network. With forced private transactions, your privacy cannot be compromised by another users’ activity on the network. If you wish to learn more, please join the official Pirate Discord at https://pirate.black/discord/ or message FishyGuts#5085, who will be happy to help out.
100 messages
Before 05-Dec-19 12:00 AM
polycryptoblog27-Sep-18 04:30 PM
Well your getting half the blocks so it can't all be that bad
Flexatron27-Sep-18 04:30 PM
That's 0.1 btc a day or na
ComputerGenie 👴👴👴27-Sep-18 04:31 PM
a 4x increase in hash yields a near 5x increase in diff
so, ya, it is "that bad"
@Flexatron the whole order was a tad over 0.33 BTC(edited)
@And1_89 Due to fees, waiting, and BTC being BTC, the upchage for BTC would be 0.392175 BTC for 25k PIRATE(edited)
Flexatron27-Sep-18 04:43 PM
Lol
And1_8927-Sep-18 04:44 PM
i have 0,1 btc
for pirate buy
ComputerGenie 👴👴👴27-Sep-18 04:47 PM
There's your hookup @And1_89
---------------
NiceHash
2018-09-27 18:25:21
New speed limits will solve this issue. For now, you can try to set a lower speed limit for example 2 MH/s.
Thank you for understanding.(edited)
MH/s ugh
All I know is that I'm getting screwed and they aren't using any lube
It wouldn't be "so bad" if I were mining ZEC or just PIRATE, but for what I do this is killing my ROI(edited)
Speed at pool 14.8561 MSol /s
Speed paying 15.3534 MSol /s
on a 5.4 cap
0x0327-Sep-18 04:58 PM
i'm unsure yet if it's maybe just random, but since i switched to a fixed order, all the peaks are gone
(and the skies are grey)
ComputerGenie 👴👴👴27-Sep-18 04:58 PM
mine is a fixed order
0x0327-Sep-18 04:58 PM
hm
ComputerGenie 👴👴👴27-Sep-18 04:59 PM
I went with fixed because the idjits doing standard orders bid it up higher than fixed was


When I was a kid I wanted to become a bicycle repair man. Now I'm working at the
Anton Pannekoek Institute
as a scientific software engineer for the
AARTFAAC project, which
is also fun. Although I'm living in Amsterdam I'm temporarily in South Africa
working on software for
the Square Kilometre Array.
In my spare time I make
beer and
music.


P2Pool
> Graphs
Periods:
Current:
Local rate
Local rate reflected in shares
Current payout to default address
Pool rate
Peers
Miners
Desired version rates
Traffic rate
Bitcoind GetBlockTemplate Latency
Memory Usage


---
layout: base
---
We are Open San Diego
We are a Code for America Brigade, which means we’re civic-minded volunteers of techies, creatives, business people and other civic-stakeholders that contribute our talents toward improving the way our local governments and community organizations work.
See what kind of things brigades do, and watch the TED talk given by Jennifer Pahlka, Founder of Code for America.


abstract class BaseOperation : ByteSerializable, JsonSerializable
Represents base operation model in Graphene blockchain
Author
Daria Pechkovskaya
<init> |
Represents base operation model in Graphene blockchain BaseOperation(type: OperationType) |
extensions |
var extensions: Extensions |
fee |
Required amount of fee AssetAmount to operation abstract var fee: AssetAmount |
id |
val id: Byte |
type |
var type: OperationType |
toJsonObject |
Converts entity to json object representation open fun toJsonObject(): JsonElement |
toString |
open fun toString(): String |
KEY_FEE |
const val KEY_FEE: String |
AccountCreateOperation |
Class used to encapsulate operations related to the OperationType.ACCOUNT_CREATE_OPERATION class AccountCreateOperation : BaseOperation |
AccountUpdateOperation |
Represents blockchain operation for updating an existing account. class AccountUpdateOperation : BaseOperation |
BlockRewardOperation |
Virtual operation that indicates payout of block reward class BlockRewardOperation : BaseOperation |
ContractOperation |
Base implementation of contract operation abstract class ContractOperation : BaseOperation |
ContractTransferOperation |
Represents blockchain operation for transferring amount from contract. class ContractTransferOperation : BaseOperation |
CreateAssetOperation |
Encapsulates asset creation information class CreateAssetOperation : BaseOperation |
GenerateBitcoinAddressOperation |
Generates address for botcoin network transfers for required target account account class GenerateBitcoinAddressOperation : BaseOperation |
GenerateEthereumAddressOperation |
Generates address for ethereum network transfers for required target account account class GenerateEthereumAddressOperation : BaseOperation |
IssueAssetOperation |
Encapsulates asset issue operation information class IssueAssetOperation : BaseOperation |
SidechainBurnSocketOperation |
Encapsulates ethereum asset withdraw information class SidechainBurnSocketOperation : BaseOperation |
SidechainERC20BurnSocketOperation |
Encapsulates erc20 token erc20Token burning information in ECHO network class SidechainERC20BurnSocketOperation : BaseOperation |
SidechainERC20DepositSocketOperation |
Encapsulates erc20 token erc20TokenAddress deposit information class SidechainERC20DepositSocketOperation : BaseOperation |
SidechainERC20IssueSocketOperation |
Encapsulates erc20 token erc20Token issue information in ECHO network class SidechainERC20IssueSocketOperation : BaseOperation |
SidechainERC20RegisterTokenOperation |
Registers ethereum ERC20 token by ethAddress in ECHO network class SidechainERC20RegisterTokenOperation : BaseOperation |
SidechainIssueSocketOperation |
Encapsulates ethereum asset issue information class SidechainIssueSocketOperation : BaseOperation |
TransferOperation |
Encapsulates transfer information class TransferOperation : BaseOperation |
WithdrawBitcoinOperation |
Transfers bitcoin asset from echo blockchain to bitcoin address class WithdrawBitcoinOperation : BaseOperation |
WithdrawERC20Operation |
Transfers value amount ethereum token erc20Token to ethereum address ethAddress class WithdrawERC20Operation : BaseOperation |
WithdrawEthereumOperation |
Transfers ethereum asset from echo blockchain to ethereum address class WithdrawEthereumOperation : BaseOperation |


Word Completion With Probable Suggestions in percentages
Enter the Begining portion*:
Select Reference Source*:
words.txt(default)
2600-0.txt(slow)
Top 10 Results:
Submit